PERFORCE change 82514 for review

Victor Cruceru soc-victor at FreeBSD.org
Wed Aug 24 22:31:13 GMT 2005


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

Change 82514 by soc-victor at soc-victor_82.76.158.176 on 2005/08/24 22:30:42

	Finished the SNMP instrumentation for tcpConnectionTable ( v4 and v6 ).
	For now both tcpConnectionTable and the deprecated tcpConnTable are read-only.

Affected files ...

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

Differences ...

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

@@ -39,5 +39,5 @@
 	
 DEFS=	${MOD}_tree.def
 BMIBS=	TCP-MIB.txt INET-ADDRESS-MIB.txt
-LDADD=	
+
 .include <bsd.lib.mk>

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

@@ -79,6 +79,7 @@
 #include <netinet/tcp_var.h>
 #include <netinet/tcp_timer.h>
 #include <netinet/tcp_fsm.h>
+#include <netinet/in.h>
 #include <string.h>
 #include <stdlib.h>
 #include <assert.h>
@@ -128,10 +129,20 @@
 	TCPS_deleteTCB =	12
 };		    
 
+enum InetAddressType {
+	IAT_unknown	=	0,
+	IAT_ipv4	=	1,
+	IAT_ipv6	=	2,
+	IAT_ipv4z	=	3,
+	IAT_ipv6z	=	4,
+	IAT_dns		=	16
+};		    
+
 
 struct tcp_index {
 	struct asn_oid	index;
 	struct xtcpcb	*tp;
+	pid_t		so_pgid;
 };
 
 static int
@@ -156,15 +167,21 @@
 
 struct tcp46_state {
 	struct clockinfo clock_info;
-	uint64_t tcp_tick;		/*agent tick when this struct was last updated*/
-	struct tcpstat tcpstat;		/*holder for tcp stats*/
-	struct xinpgen *xinpgen;	/*holder for data get via sysctl; malloc'd*/
-	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*/
+	uint64_t	tcp_tick;		/*agent tick when this struct was last updated*/
+	struct tcpstat	tcpstat;		/*holder for tcp stats*/
+	struct xinpgen	*xinpgen;		/*holder for data get via sysctl; malloc'd*/
+	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*/
+	
+	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*/
+	size_t		all_tcpoids_len;	/*the allocated len of the above vector */
 
-	struct tcp_index *tcp4oids;	/*snmp vector for the tcp4 table; malloc'd*/
-	size_t tcp4oids_len;		/*the allocated len of the above vector */
+		
 };
 
 static
@@ -207,6 +224,12 @@
 		tcp46_state_g.tcp4oids_len = 0;
 	}
 
+	if (tcp46_state_g.all_tcpoids != NULL && tcp46_state_g.all_tcpoids_len > 0) {
+		free(tcp46_state_g.all_tcpoids);
+		tcp46_state_g.all_tcpoids = NULL;
+		tcp46_state_g.all_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;
@@ -303,7 +326,7 @@
 	size_t len;
 	struct xinpgen *ptr = NULL;
 	struct xtcpcb *tp = NULL;
-	struct tcp_index *oid = NULL;
+	struct tcp_index *oid = NULL, *all_oid = NULL;
 	in_addr_t inaddr;
 
 	len = sizeof(tcp46_state_g.tcpstat);
@@ -338,6 +361,7 @@
 
 	tcp46_state_g.tcp_estab_count = 0;
 	tcp46_state_g.tcp4_total = 0;
+	tcp46_state_g.all_tcp_total = 0;
 	
 	/*First count the endpoints*/
 	for (ptr = (struct xinpgen *)(void *)((char *)tcp46_state_g.xinpgen + tcp46_state_g.xinpgen->xig_len);
@@ -369,18 +393,25 @@
 		if ( (tp->xt_inp.inp_vflag & INP_IPV4) == INP_IPV4) {
 			tcp46_state_g.tcp4_total++;
 		}
-
+		
+		if ((tp->xt_inp.inp_vflag & (INP_IPV6 | INP_IPV6PROTO | INP_IPV4)) != 0 ) {
+			/*for connection in listen state we have a separate table*/
+			if ( tp->xt_tp.t_state != TCPS_LISTEN ) {
+				tcp46_state_g.all_tcp_total++;
+			}
+		}
 		if (tp->xt_tp.t_state == TCPS_ESTABLISHED ||
 		    tp->xt_tp.t_state == TCPS_CLOSE_WAIT) {
 			tcp46_state_g.tcp_estab_count++;
 		}	
 	}
 
-	TCP46_DPRINTF((stderr, "[%s] Got %d tcp4 connections.\n ", 
+	TCP46_DPRINTF((stderr, "[%s] Got %d tcp4 connections and %d tcp{4,6} connections.\n ", 
 		__func__, 
-		tcp46_state_g.tcp4_total)); 
+		tcp46_state_g.tcp4_total,
+		tcp46_state_g.all_tcp_total)); 
 
-	/*Then reallocate the SNMP holder if needed*/
+	/*Then reallocate the SNMP holder for v4 if needed*/
 	if (tcp46_state_g.tcp4oids_len < tcp46_state_g.tcp4_total) {
 		oid = realloc(tcp46_state_g.tcp4oids, 
 			tcp46_state_g.tcp4_total * sizeof(tcp46_state_g.tcp4oids[0]));
@@ -393,11 +424,29 @@
 		tcp46_state_g.tcp4oids_len = tcp46_state_g.tcp4_total;
 	}
 
-	/*Finally fill in the SNMP index*/
+	/*Then reallocate the SNMP holder for v4 & v6 if needed*/
+	if (tcp46_state_g.all_tcpoids_len < tcp46_state_g.all_tcp_total) {
+		all_oid = realloc(tcp46_state_g.all_tcpoids, 
+			tcp46_state_g.all_tcp_total * sizeof(tcp46_state_g.all_tcpoids[0]));
+		if (all_oid == NULL) {
+			free(tcp46_state_g.all_tcpoids);
+			tcp46_state_g.all_tcpoids_len = 0;
+			return (0);
+		}
+		tcp46_state_g.all_tcpoids = all_oid;
+		tcp46_state_g.all_tcpoids_len = tcp46_state_g.all_tcp_total;
+	}
+
+
+	/*Finally fill in the SNMP indexes*/
         memset(tcp46_state_g.tcp4oids, 0, 
 		tcp46_state_g.tcp4_total * sizeof(tcp46_state_g.tcp4oids[0]) );
-		
+
+        memset(tcp46_state_g.all_tcpoids, 0, 
+		tcp46_state_g.all_tcp_total * sizeof(tcp46_state_g.all_tcpoids[0]) );
+				
 	oid = tcp46_state_g.tcp4oids;
+	all_oid = tcp46_state_g.all_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)) {
@@ -413,6 +462,7 @@
 			continue;
 		}		
 		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);
@@ -428,15 +478,69 @@
 			oid->index.subs[8] = (inaddr >>  0) & 0xff;
 			oid->index.subs[9] = ntohs(tp->xt_inp.inp_fport);
 			oid++;
+			/*END processing for the old/ deprecated v4 only table*/
+			
+			/*for connection in listen state we have a separate table*/
+			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);
+
+				all_oid++;
+				/*END processing for the new v4/v6 table*/
+			}
+
+			
+		} 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);
+				all_oid++;
+				/*END processing for the new v4/v6 table*/
+			}
+
 		}
 	}
 
-	/*Keep the list sorted ins SNMP index ordering*/
+	/*Keep the lists sorted ins SNMP index ordering*/
 	qsort( tcp46_state_g.tcp4oids, 
 		tcp46_state_g.tcp4_total, 
 		sizeof(tcp46_state_g.tcp4oids[0]), 
 		tcp_compare);
 
+	qsort( tcp46_state_g.all_tcpoids, 
+		tcp46_state_g.all_tcp_total, 
+		sizeof(tcp46_state_g.all_tcpoids[0]), 
+		tcp_compare);
+
 	return (0);
 }
 
@@ -667,12 +771,110 @@
 }
 
 int	
-op_tcpConnectionTable( 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_tcpConnectionTable( 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.all_tcp_total; i++)
+			if (index_compare(&value->var, sub, 
+				&tcp46_state_g.all_tcpoids[i].index) < 0)
+				break;
+		if (i == tcp46_state_g.all_tcp_total)
+			return (SNMP_ERR_NOSUCHNAME);
+			
+		index_append(&value->var, sub, 
+			&tcp46_state_g.all_tcpoids[i].index);
+		break;
+
+	  case SNMP_OP_GET:
+		for (i = 0; i < tcp46_state_g.all_tcp_total; i++)
+			if (index_compare(&value->var, sub, 
+				&tcp46_state_g.all_tcpoids[i].index) == 0)
+				break;
+				
+		if (i == tcp46_state_g.all_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.all_tcpoids[i].index.len == 12 || 
+		tcp46_state_g.all_tcpoids[i].index.len == 36);			
+	
+	switch (value->var.subs[sub - 1]) {
+
+	  case LEAF_tcpConnectionState:
+		switch (tcp46_state_g.all_tcpoids[i].tp->xt_tp.t_state) {
+
+		  case TCPS_CLOSED:
+			value->v.integer = TCPS_closed;
+			break;
+		  case TCPS_LISTEN:
+			value->v.integer = TCPS_listen;
+			assert(0);
+			break;
+		  case TCPS_SYN_SENT:
+			value->v.integer = TCPS_synSent;
+			break;
+		  case TCPS_SYN_RECEIVED:
+			value->v.integer = TCPS_synReceived;
+			break;
+		  case TCPS_ESTABLISHED:
+			value->v.integer = TCPS_established;
+			break;
+		  case TCPS_CLOSE_WAIT:
+			value->v.integer = TCPS_closeWait;
+			break;
+		  case TCPS_FIN_WAIT_1:
+			value->v.integer = TCPS_finWait1;
+			break;
+		  case TCPS_CLOSING:
+			value->v.integer = TCPS_closing;
+			break;
+		  case TCPS_LAST_ACK:
+			value->v.integer = TCPS_lastAck;
+			break;
+		  case TCPS_FIN_WAIT_2:
+			value->v.integer = TCPS_finWait2;
+			break;
+		  case TCPS_TIME_WAIT:
+			value->v.integer = TCPS_timeWait;
+			break;
+		  default:
+			value->v.integer = 0;
+			break;
+		}
+		break;
+		
+
+	  
+	  case LEAF_tcpConnectionProcess:
+	  	/*this is from hrSWRunTable, where the index is pid + 1 */
+		/*FIX ME: this doesn't work*/
+		value->v.integer = ( tcp46_state_g.all_tcpoids[i].so_pgid == 0 ? 0 : 
+					tcp46_state_g.all_tcpoids[i].so_pgid + 1 ); 
+		break;
+	  default:
+	  	assert(0);	
+		return (SNMP_ERR_NOSUCHNAME);
+	}
+	return (SNMP_ERR_NOERROR);
+
 }
 
 int	


More information about the p4-projects mailing list