PERFORCE change 82535 for review

Victor Cruceru soc-victor at FreeBSD.org
Thu Aug 25 15:44:05 GMT 2005


http://perforce.freebsd.org/chv.cgi?CH=82535

Change 82535 by soc-victor at soc-victor_82.76.158.176 on 2005/08/25 15:43:30

	Added the SNMP instrumentation for tcpListenerTable.
	Also fixed a bug in tcpConnectionTable.

Affected files ...

.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp46/Makefile#3 edit
.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp46/tcp46_snmp.c#5 edit

Differences ...

==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp46/Makefile#3 (text+ko) ====

@@ -30,7 +30,7 @@
 
 MOD=	tcp46
 
-SRCS=	tcp46_snmp.c \
+SRCS=	tcp46_snmp.c 
 	
 WARNS?=	6
 #Not having NDEBUG defined will enable assertions and a lot of output on stderr

==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp46/tcp46_snmp.c#5 (text+ko) ====

@@ -173,17 +173,25 @@
 	size_t		xinpgen_len;		/*the allocated len of the above vector */
 	u_int		tcp_estab_count;	/*value for the scalar named tcpCurrEstab*/
 	u_int		tcp4_total;		/*the number of tcp4 entries*/
-	u_int		all_tcp_total;		/*the number of tcp4 and tcp6 entries*/
+	u_int		all_tcp_total;		/*the number of tcp4 and tcp6 entries (without listeners)*/
+	u_int		listen_tcp_total;	/*the number of tcp4 and tcp6 entries in listen state*/
 	
 	struct tcp_index *tcp4oids;		/*snmp vector for the tcp4 table; malloc'd*/
 	size_t		tcp4oids_len;		/*the allocated len of the above vector */
 
-	struct tcp_index *all_tcpoids;		/*snmp vector for the unigied v4 and v6 tcp table; malloc'd*/
+	struct tcp_index *all_tcpoids;		/*snmp vector for the unified v4 and v6 tcp table; malloc'd*/
 	size_t		all_tcpoids_len;	/*the allocated len of the above vector */
 
-		
+	struct tcp_index *listen_tcpoids;	/*snmp vector for the unified v4 and v6 listners tcp table; malloc'd*/
+	size_t		listen_tcpoids_len;	/*the allocated len of the above vector */
+
+				
 };
 
+/*
+ * Global variable used to hold all the data
+ * related to this SNMP module
+ */
 static
 struct tcp46_state tcp46_state_g;
 
@@ -230,6 +238,12 @@
 		tcp46_state_g.all_tcpoids_len = 0;
 	}
 
+	if (tcp46_state_g.listen_tcpoids != NULL && tcp46_state_g.listen_tcpoids_len > 0) {
+		free(tcp46_state_g.listen_tcpoids);
+		tcp46_state_g.listen_tcpoids = NULL;
+		tcp46_state_g.listen_tcpoids_len = 0;
+	}
+
 	if (tcp46_state_g.xinpgen != NULL && tcp46_state_g.xinpgen_len > 0) {
 		free(tcp46_state_g.xinpgen);
 		tcp46_state_g.xinpgen = NULL;
@@ -319,6 +333,263 @@
 	tcp46_loading_v
 };
 
+/*
+ * Add an entry into the list associated with the old/ deprecated
+ * tcpConnTable
+ */
+static
+void handle_old_tcp4_entry (struct tcp_index *oid, struct xtcpcb *tp) {
+	in_addr_t inaddr;
+	
+	assert(oid != NULL);
+	assert(tp != NULL);
+	/*next is the encoding for the SNMP table index*/
+	oid->index.len = 10;
+	inaddr = ntohl(tp->xt_inp.inp_laddr.s_addr);
+	oid->index.subs[0] = (inaddr >> 24) & 0xff;
+	oid->index.subs[1] = (inaddr >> 16) & 0xff;
+	oid->index.subs[2] = (inaddr >>  8) & 0xff;
+	oid->index.subs[3] = (inaddr >>  0) & 0xff;
+	oid->index.subs[4] = ntohs(tp->xt_inp.inp_lport);
+	inaddr = ntohl(tp->xt_inp.inp_faddr.s_addr);
+	oid->index.subs[5] = (inaddr >> 24) & 0xff;
+	oid->index.subs[6] = (inaddr >> 16) & 0xff;
+	oid->index.subs[7] = (inaddr >>  8) & 0xff;
+	oid->index.subs[8] = (inaddr >>  0) & 0xff;
+	oid->index.subs[9] = ntohs(tp->xt_inp.inp_fport);
+	
+}
+
+/*
+ * Add a __v4__ entry into the list associated with the new (combined v4 & v6)
+ * tcpConnectionTable
+ */
+static
+void handle_new_tcp4_entry (struct tcp_index *all_oid, struct xtcpcb *tp) {
+	in_addr_t inaddr;
+	assert(all_oid != NULL);
+	assert(tp != NULL);
+	/*next is the encoding for the SNMP table index*/
+	
+	all_oid->index.len = 12;
+	all_oid->index.subs[0] = IAT_ipv4;
+	inaddr = ntohl(tp->xt_inp.inp_laddr.s_addr);
+	all_oid->index.subs[1] = (inaddr >> 24) & 0xff;
+	all_oid->index.subs[2] = (inaddr >> 16) & 0xff;
+	all_oid->index.subs[3] = (inaddr >>  8) & 0xff;
+	all_oid->index.subs[4] = (inaddr >>  0) & 0xff;
+	all_oid->index.subs[5] = ntohs(tp->xt_inp.inp_lport);
+	all_oid->index.subs[6] = IAT_ipv4;
+	inaddr = ntohl(tp->xt_inp.inp_faddr.s_addr);
+	all_oid->index.subs[7] = (inaddr >> 24) & 0xff;
+	all_oid->index.subs[8] = (inaddr >> 16) & 0xff;
+	all_oid->index.subs[9] = (inaddr >>  8) & 0xff;
+	all_oid->index.subs[10] = (inaddr >>  0) & 0xff;
+	all_oid->index.subs[11] = ntohs(tp->xt_inp.inp_fport);
+	
+	/*FIX ME: this doesn't work*/
+	all_oid->so_pgid = tp->xt_socket.so_pgid;
+
+}
+
+/*
+ * Add a __v6__ entry into the list associated with the new (combined v4 & v6)
+ * tcpConnectionTable
+ */
+static
+void handle_new_tcp6_entry (struct tcp_index *all_oid, struct xtcpcb *tp) {
+	int i = 0;
+	assert(all_oid != NULL);
+	assert(tp != NULL);
+	/*next is the encoding for the SNMP table index*/
+	all_oid->index.len = 36;
+	all_oid->index.subs[0] = IAT_ipv6;
+	for (i=0; i<16; i++) {
+		all_oid->index.subs[1+i] = tp->xt_inp.in6p_laddr.s6_addr[i];
+		all_oid->index.subs[19+i] = tp->xt_inp.in6p_faddr.s6_addr[i];
+	}
+	all_oid->index.subs[17] = ntohs(tp->xt_inp.in6p_lport);
+	all_oid->index.subs[18] = IAT_ipv6;
+	all_oid->index.subs[35] = ntohs(tp->xt_inp.in6p_fport);
+	
+	/*FIX ME: this doesn't work*/
+	all_oid->so_pgid = tp->xt_socket.so_pgid;
+
+}
+
+
+/*
+ * returns 1 if one duplicate listener found
+ * and 0 otherways
+ */
+static
+int
+check_duplicate6_listner(struct tcp_index *listener_oid, struct xtcpcb *tp){
+	struct tcp_index *_oid = NULL;
+	u_int i = 0;
+	static 
+	uint32_t zero_ip6[] ={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+	
+	if (tcp46_state_g.listen_tcpoids_len == 0) {
+		/*empty list, no duplicates*/
+		return 0;
+	}
+	if ( tp->xt_inp.inp_laddr.s_addr != INADDR_ANY ) {
+		TCP46_DPRINTF((stderr, "V4 [%s] Skipped one listener (not an INADDR_ANY v4).\n ", 
+		__func__)); 		
+		return 0;
+	}
+	TCP46_DPRINTF((stderr, "V4: [%s] Adding INADDR_ANY v4 listener with port %d.\n ", 
+			__func__,
+			ntohs(tp->xt_inp.inp_lport))); 	
+			
+	
+	for (_oid = tcp46_state_g.listen_tcpoids; 
+		_oid != listener_oid && i < tcp46_state_g.listen_tcpoids_len;
+		i++, _oid++ )
+	{
+		if ( _oid->index.subs[0] == IAT_ipv6 ) {
+			if ( _oid->index.subs[17] == ntohs(tp->xt_inp.inp_lport) ){
+				TCP46_DPRINTF((stderr, "V4: [%s] Got listener with port %d.\n ", 
+					__func__,
+					_oid->index.subs[5])); 		
+				
+				if (memcmp(&zero_ip6[0], 
+					&_oid->index.subs[1], 
+					sizeof(zero_ip6)) == 0) {
+					/*got it*/
+					_oid->index.len = 3;	
+					_oid->index.subs[0] = IAT_unknown;
+					_oid->index.subs[1] = 0; /*zero/ empty octet sting*/
+					_oid->index.subs[2] = ntohs(tp->xt_inp.inp_lport);
+					return 1;
+				}
+			}
+		}	
+	}
+	return 0;
+}
+
+/*
+ * returns 1 if one duplicate listener found
+ * and 0 otherways
+ */
+static
+int
+check_duplicate4_listner(struct tcp_index *listener_oid, struct xtcpcb *tp){
+	struct tcp_index *_oid = NULL;
+	u_int i = 0;
+	static 
+	uint32_t zero_ip4[] = { 0, 0, 0, 0 };
+	
+	if (tcp46_state_g.listen_tcpoids_len == 0) {
+		/*empty list, no duplicates*/
+		return 0;
+	}
+	if ( !IN6_IS_ADDR_UNSPECIFIED(&tp->xt_inp.in6p_laddr) ) {
+		TCP46_DPRINTF((stderr, "[%s] Skipped one listener (not an UNSPECIFIED v6).\n ", 
+		__func__)); 		
+		return 0;
+	}
+	TCP46_DPRINTF((stderr, "[%s] Adding UNSPECIFIED v6 listener with port %d.\n ", 
+			__func__,
+			ntohs(tp->xt_inp.in6p_lport))); 	
+			
+	for (_oid = tcp46_state_g.listen_tcpoids; 
+		_oid != listener_oid && i < tcp46_state_g.listen_tcpoids_len;
+		i++, _oid++ )
+	{
+		if ( _oid->index.subs[0] == IAT_ipv4 ) {
+			if ( _oid->index.subs[5] == ntohs(tp->xt_inp.in6p_lport) ) {
+				TCP46_DPRINTF((stderr, "[%s] Got listener with port %d.\n ", 
+					__func__,
+					_oid->index.subs[5])); 		
+						
+				if (memcmp(&zero_ip4[0], 
+					&_oid->index.subs[1], 
+					sizeof(zero_ip4)) == 0) {
+					/*got it*/	
+					_oid->index.len = 3;
+					_oid->index.subs[0] = IAT_unknown;
+					_oid->index.subs[1] = 0; /*zero/ empty octet sting*/
+					_oid->index.subs[2] = ntohs(tp->xt_inp.in6p_lport);
+					return 1;
+				}
+			}
+		}	
+	}
+	return 0;
+}
+
+/*
+ * Add a __v4__ entry into the list associated with the combined v4 & v6
+ * tcpListenerTable
+ * Check for duplicates as described in the MIB:
+ *            1. For an application willing to accept both IPv4 and
+ *              IPv6 datagrams, the value of this object must be
+ *              ''h (a zero-length octet-string), with the value
+ *              of the corresponding tcpListenerLocalAddressType
+ *              object being unknown (0).
+ * Returns 1 if the duplicate was found and processed.
+ * Returns 0 if the entry was new 
+ */
+static
+int handle_tcp4_listener_entry (struct tcp_index *listener_oid, struct xtcpcb *tp) {
+	in_addr_t inaddr;
+	assert(listener_oid != NULL);
+	assert(tp != NULL);
+	if ( check_duplicate6_listner( listener_oid, tp ) == 1 ) {
+		return 1;
+	}
+	/*next is the encoding for the SNMP table index*/
+	listener_oid->index.len = 6;
+	listener_oid->index.subs[0] = IAT_ipv4;
+	inaddr = ntohl(tp->xt_inp.inp_laddr.s_addr);
+	listener_oid->index.subs[1] = (inaddr >> 24) & 0xff;
+	listener_oid->index.subs[2] = (inaddr >> 16) & 0xff;
+	listener_oid->index.subs[3] = (inaddr >>  8) & 0xff;
+	listener_oid->index.subs[4] = (inaddr >>  0) & 0xff;
+	listener_oid->index.subs[5] = ntohs(tp->xt_inp.inp_lport);
+	/*FIX ME: this doesn't work*/
+	listener_oid->so_pgid = tp->xt_socket.so_pgid;
+	return 0;
+
+}
+
+/*
+ * Add a __v6__ entry into the list associated with the combined v4 & v6
+ * tcpListenerTable
+ * Check for duplicates as described in the MIB:
+ *            1. For an application willing to accept both IPv4 and
+ *              IPv6 datagrams, the value of this object must be
+ *              ''h (a zero-length octet-string), with the value
+ *              of the corresponding tcpListenerLocalAddressType
+ *              object being unknown (0).
+ * Returns 1 if the duplicate was found and processed.
+ * Returns 0 if the entry was new 
+ */
+static
+int handle_tcp6_listener_entry (struct tcp_index *listener_oid, struct xtcpcb *tp) {
+	int i = 0;
+	assert(listener_oid != NULL);
+	assert(tp != NULL);
+	if ( check_duplicate4_listner( listener_oid, tp ) == 1 ) {
+		return 1;
+	}
+	
+	/*next is the encoding for the SNMP table index*/
+	listener_oid->index.len = 18;
+	listener_oid->index.subs[0] = IAT_ipv6;
+	for (i=0; i<16; i++) {
+		listener_oid->index.subs[1+i] = tp->xt_inp.in6p_laddr.s6_addr[i];
+	}
+	listener_oid->index.subs[17] = ntohs(tp->xt_inp.in6p_lport);
+	
+	/*FIX ME: this doesn't work*/
+	listener_oid->so_pgid = tp->xt_socket.so_pgid;
+	return 0;
+
+}
 
 static int
 fetch_tcp(void)
@@ -326,8 +597,8 @@
 	size_t len;
 	struct xinpgen *ptr = NULL;
 	struct xtcpcb *tp = NULL;
-	struct tcp_index *oid = NULL, *all_oid = NULL;
-	in_addr_t inaddr;
+	struct tcp_index *oid = NULL, *all_oid = NULL, *listen_oid = NULL;
+
 
 	len = sizeof(tcp46_state_g.tcpstat);
 	if (sysctlbyname("net.inet.tcp.stats", &tcp46_state_g.tcpstat, &len, NULL, 0) == -1) {
@@ -362,6 +633,7 @@
 	tcp46_state_g.tcp_estab_count = 0;
 	tcp46_state_g.tcp4_total = 0;
 	tcp46_state_g.all_tcp_total = 0;
+	tcp46_state_g.listen_tcp_total = 0;
 	
 	/*First count the endpoints*/
 	for (ptr = (struct xinpgen *)(void *)((char *)tcp46_state_g.xinpgen + tcp46_state_g.xinpgen->xig_len);
@@ -398,6 +670,8 @@
 			/*for connection in listen state we have a separate table*/
 			if ( tp->xt_tp.t_state != TCPS_LISTEN ) {
 				tcp46_state_g.all_tcp_total++;
+			} else {
+				tcp46_state_g.listen_tcp_total++;	
 			}
 		}
 		if (tp->xt_tp.t_state == TCPS_ESTABLISHED ||
@@ -406,10 +680,11 @@
 		}	
 	}
 
-	TCP46_DPRINTF((stderr, "[%s] Got %d tcp4 connections and %d tcp{4,6} connections.\n ", 
+	TCP46_DPRINTF((stderr, "[%s] Got %d tcp4 connections, %d tcp{4,6} connections, %d tcp{4,6} listeners.\n ", 
 		__func__, 
 		tcp46_state_g.tcp4_total,
-		tcp46_state_g.all_tcp_total)); 
+		tcp46_state_g.all_tcp_total,
+		tcp46_state_g.listen_tcp_total)); 
 
 	/*Then reallocate the SNMP holder for v4 if needed*/
 	if (tcp46_state_g.tcp4oids_len < tcp46_state_g.tcp4_total) {
@@ -436,6 +711,19 @@
 		tcp46_state_g.all_tcpoids = all_oid;
 		tcp46_state_g.all_tcpoids_len = tcp46_state_g.all_tcp_total;
 	}
+	
+	/*Then reallocate the SNMP holder for v4 & v6 listeners if needed*/
+	if (tcp46_state_g.listen_tcpoids_len < tcp46_state_g.listen_tcp_total) {
+		listen_oid = realloc(tcp46_state_g.listen_tcpoids, 
+			tcp46_state_g.listen_tcp_total * sizeof(tcp46_state_g.listen_tcpoids[0]));
+		if (listen_oid == NULL) {
+			free(tcp46_state_g.listen_tcpoids);
+			tcp46_state_g.listen_tcpoids_len = 0;
+			return (0);
+		}
+		tcp46_state_g.listen_tcpoids = listen_oid;
+		tcp46_state_g.listen_tcpoids_len = tcp46_state_g.listen_tcp_total;
+	}
 
 
 	/*Finally fill in the SNMP indexes*/
@@ -444,9 +732,14 @@
 
         memset(tcp46_state_g.all_tcpoids, 0, 
 		tcp46_state_g.all_tcp_total * sizeof(tcp46_state_g.all_tcpoids[0]) );
-				
+
+        memset(tcp46_state_g.listen_tcpoids, 0, 
+		tcp46_state_g.listen_tcp_total * sizeof(tcp46_state_g.listen_tcpoids[0]) );
+								
 	oid = tcp46_state_g.tcp4oids;
 	all_oid = tcp46_state_g.all_tcpoids;
+	listen_oid = tcp46_state_g.listen_tcpoids;
+	
 	for (ptr = (struct xinpgen *)(void *)((char *)tcp46_state_g.xinpgen + tcp46_state_g.xinpgen->xig_len);
 	     ptr->xig_len > sizeof(struct xinpgen);
              ptr = (struct xinpgen *)(void *)((char *)ptr + ptr->xig_len)) {
@@ -464,19 +757,7 @@
 		if ( (tp->xt_inp.inp_vflag & INP_IPV4) == INP_IPV4) {
 			/*START processing for the old/ deprecated v4 only table*/
 			oid->tp = tp;
-			oid->index.len = 10;
-			inaddr = ntohl(tp->xt_inp.inp_laddr.s_addr);
-			oid->index.subs[0] = (inaddr >> 24) & 0xff;
-			oid->index.subs[1] = (inaddr >> 16) & 0xff;
-			oid->index.subs[2] = (inaddr >>  8) & 0xff;
-			oid->index.subs[3] = (inaddr >>  0) & 0xff;
-			oid->index.subs[4] = ntohs(tp->xt_inp.inp_lport);
-			inaddr = ntohl(tp->xt_inp.inp_faddr.s_addr);
-			oid->index.subs[5] = (inaddr >> 24) & 0xff;
-			oid->index.subs[6] = (inaddr >> 16) & 0xff;
-			oid->index.subs[7] = (inaddr >>  8) & 0xff;
-			oid->index.subs[8] = (inaddr >>  0) & 0xff;
-			oid->index.subs[9] = ntohs(tp->xt_inp.inp_fport);
+			handle_old_tcp4_entry(oid, tp);
 			oid++;
 			/*END processing for the old/ deprecated v4 only table*/
 			
@@ -484,52 +765,49 @@
 			if ( tp->xt_tp.t_state != TCPS_LISTEN ) {
 				/*START processing for the new v4/v6 table*/
 				all_oid->tp = tp;
-				/*FIX ME: this doesn't work*/
-				all_oid->so_pgid = ((struct  xtcpcb *)ptr)->xt_socket.so_pgid;
-				all_oid->index.len = 12;
-				all_oid->index.subs[0] = IAT_ipv4;
-				inaddr = ntohl(tp->xt_inp.inp_laddr.s_addr);
-				all_oid->index.subs[1] = (inaddr >> 24) & 0xff;
-				all_oid->index.subs[2] = (inaddr >> 16) & 0xff;
-				all_oid->index.subs[3] = (inaddr >>  8) & 0xff;
-				all_oid->index.subs[4] = (inaddr >>  0) & 0xff;
-				all_oid->index.subs[5] = ntohs(tp->xt_inp.inp_lport);
-				all_oid->index.subs[6] = IAT_ipv4;
-				inaddr = ntohl(tp->xt_inp.inp_faddr.s_addr);
-				all_oid->index.subs[7] = (inaddr >> 24) & 0xff;
-				all_oid->index.subs[8] = (inaddr >> 16) & 0xff;
-				all_oid->index.subs[9] = (inaddr >>  8) & 0xff;
-				all_oid->index.subs[10] = (inaddr >>  0) & 0xff;
-				all_oid->index.subs[11] = ntohs(tp->xt_inp.inp_lport);
-
+				handle_new_tcp4_entry(all_oid, tp);
 				all_oid++;
 				/*END processing for the new v4/v6 table*/
+			} else {
+				if (handle_tcp4_listener_entry(listen_oid, tp) == 0 ){
+					listen_oid->tp = tp;
+					listen_oid++;
+				} else {
+					/*this was a duplicate one*/
+					assert(tcp46_state_g.listen_tcp_total > 1);
+					tcp46_state_g.listen_tcp_total--;
+				}
 			}
 
 			
 		} else if ((tp->xt_inp.inp_vflag & (INP_IPV6 | INP_IPV6PROTO)) != 0 ) {
 			if ( tp->xt_tp.t_state != TCPS_LISTEN ) {
-				int i =0;
+
 				/*START processing for the new v4/v6 table*/
 				all_oid->tp = tp;
-				/*FIX ME: this doesn't work*/
-				all_oid->so_pgid = ((struct  xtcpcb *)ptr)->xt_socket.so_pgid;
-				all_oid->index.len = 36;
-				all_oid->index.subs[0] = IAT_ipv6;
-				for (i=0; i<16; i++) {
-					all_oid->index.subs[1+i] = tp->xt_inp.in6p_laddr.s6_addr[i];
-					all_oid->index.subs[19+i] = tp->xt_inp.in6p_faddr.s6_addr[i];
-				}
-				all_oid->index.subs[17] = ntohs(tp->xt_inp.in6p_lport);
-				all_oid->index.subs[18] = IAT_ipv6;
-				all_oid->index.subs[35] = ntohs(tp->xt_inp.in6p_fport);
+				handle_new_tcp6_entry(all_oid, tp);
 				all_oid++;
 				/*END processing for the new v4/v6 table*/
+			}else {
+				if (handle_tcp6_listener_entry(listen_oid, tp) == 0 ){
+					listen_oid->tp = tp;
+					listen_oid++;
+				} else {
+					/*this was a duplicate one*/
+					assert(tcp46_state_g.listen_tcp_total > 1);
+					tcp46_state_g.listen_tcp_total--;
+				}
 			}
 
+
 		}
 	}
 
+	TCP46_DPRINTF((stderr, "[%s] Got %d tcp{4,6} DISTINCT listeners.\n ", 
+		__func__, 
+		tcp46_state_g.listen_tcp_total)); 
+		
+	
 	/*Keep the lists sorted ins SNMP index ordering*/
 	qsort( tcp46_state_g.tcp4oids, 
 		tcp46_state_g.tcp4_total, 
@@ -541,6 +819,12 @@
 		sizeof(tcp46_state_g.all_tcpoids[0]), 
 		tcp_compare);
 
+	qsort( tcp46_state_g.listen_tcpoids, 
+		tcp46_state_g.listen_tcp_total, 
+		sizeof(tcp46_state_g.listen_tcpoids[0]), 
+		tcp_compare);
+
+
 	return (0);
 }
 
@@ -658,9 +942,9 @@
 
 
 /*
- * This is the deprecated TCP Connection table
+ * This is the SNMP handler for the deprecated TCP Connection table
  * tcpConnTable
-*/
+ */
 int	
 op_tcpConnTable( struct snmp_context *ctx __unused, struct snmp_value *value,
     u_int sub, u_int iidx __unused, enum snmp_op op)
@@ -770,6 +1054,10 @@
 	return (SNMP_ERR_NOERROR);
 }
 
+/*
+ * This is the SNMP handler for the new (v4 & v6) TCP Connection table
+ * tcpConnectionTable
+ */
 int	
 op_tcpConnectionTable( struct snmp_context *ctx __unused, struct snmp_value *value,
     u_int sub, u_int iidx __unused, enum snmp_op op)
@@ -878,11 +1166,65 @@
 }
 
 int	
-op_tcpListenerTable( struct snmp_context *ctx __unused, 
-	struct snmp_value *value __unused, 
-	u_int sub __unused, 
-	u_int iidx __unused, 
-	enum snmp_op curr_op __unused) {
-	return  (SNMP_ERR_NOSUCHNAME);
+op_tcpListenerTable(  struct snmp_context *ctx __unused, struct snmp_value *value,
+    u_int sub, u_int iidx __unused, enum snmp_op op)
+{
+	u_int i;
+
+	if (tcp46_state_g.tcp_tick < this_tick)
+		if (fetch_tcp() == -1)
+			return (SNMP_ERR_GENERR);
+
+	switch (op) {
+
+	  case SNMP_OP_GETNEXT:
+		for (i = 0; i < tcp46_state_g.listen_tcp_total; i++)
+			if (index_compare(&value->var, sub, 
+				&tcp46_state_g.listen_tcpoids[i].index) < 0)
+				break;
+		if (i == tcp46_state_g.listen_tcp_total)
+			return (SNMP_ERR_NOSUCHNAME);
+			
+		index_append(&value->var, sub, 
+			&tcp46_state_g.listen_tcpoids[i].index);
+		break;
+
+	  case SNMP_OP_GET:
+		for (i = 0; i < tcp46_state_g.listen_tcp_total; i++)
+			if (index_compare(&value->var, sub, 
+				&tcp46_state_g.listen_tcpoids[i].index) == 0)
+				break;
+				
+		if (i == tcp46_state_g.listen_tcp_total)
+			return (SNMP_ERR_NOSUCHNAME);
+		break;
+
+	  case SNMP_OP_SET:
+		return (SNMP_ERR_NOT_WRITEABLE);
+
+	  case SNMP_OP_ROLLBACK:
+	  case SNMP_OP_COMMIT:
+	  default:
+		abort();
+	}
+	
+	assert(	tcp46_state_g.listen_tcpoids[i].index.len == 3 ||
+		tcp46_state_g.listen_tcpoids[i].index.len == 6 || 
+		tcp46_state_g.listen_tcpoids[i].index.len == 18);			
+	
+	switch (value->var.subs[sub - 1]) {
+
+	  case LEAF_tcpListenerProcess:
+	  	/*this is from hrSWRunTable, where the index is pid + 1 */
+		/*FIX ME: this doesn't work*/
+		value->v.integer = ( tcp46_state_g.listen_tcpoids[i].so_pgid == 0 ? 0 : 
+					tcp46_state_g.listen_tcpoids[i].so_pgid + 1 ); 
+		break;
+	  default:
+	  	assert(0);	
+		return (SNMP_ERR_NOSUCHNAME);
+	}
+	return (SNMP_ERR_NOERROR);
+
 }
 


More information about the p4-projects mailing list