PERFORCE change 82761 for review

Victor Cruceru soc-victor at FreeBSD.org
Mon Aug 29 13:10:13 GMT 2005


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

Change 82761 by soc-victor at soc-victor_82.76.158.176 on 2005/08/29 13:09:44

	
	SNMP instrumentation (first step) for the new udpEndpointTable
	(combined v4 & v6). MIB semantic is not fully implemented yet.

Affected files ...

.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp_udp46/Makefile#6 edit
.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp_udp46/tcp46_snmp.c#5 edit
.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp_udp46/tcp_udp46.h#3 edit
.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp_udp46/tcp_udp46_common.c#3 edit
.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp_udp46/udp46_snmp.c#4 edit

Differences ...

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

@@ -43,6 +43,8 @@
 	
 DEFS=	${MOD}_tree.def
 
-BMIBS=	TCP-MIB.txt UDP-MIB.txt INET-ADDRESS-MIB.txt
+BMIBS=	TCP-MIB.txt \
+	UDP-MIB.txt \
+	INET-ADDRESS-MIB.txt
 
 .include <bsd.lib.mk>

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

@@ -125,14 +125,6 @@
 	TCPS_deleteTCB =	12
 };		    
 
-enum InetAddressType {
-	IAT_unknown	=	0,
-	IAT_ipv4	=	1,
-	IAT_ipv6	=	2,
-	IAT_ipv4z	=	3,
-	IAT_ipv6z	=	4,
-	IAT_dns		=	16
-};		    
 
 
 
@@ -1360,8 +1352,7 @@
 
 	  case LEAF_tcpListenerProcess:
 	  	/*this is from hrSWRunTable, where the index is pid + 1 */
-		/*FIX ME: this doesn't work*/
-		value->v.integer = ( tcp_udp46_state_g.listen_tcpoids[i].so_pgid == 0 ? 0 : 
+		value->v.uint32 = ( tcp_udp46_state_g.listen_tcpoids[i].so_pgid == 0 ? 0 : 
 					tcp_udp46_state_g.listen_tcpoids[i].so_pgid + 1 ); 
 		break;
 	  default:

==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp_udp46/tcp_udp46.h#3 (text+ko) ====

@@ -57,8 +57,19 @@
 #define TCP46_DPRINTF(ARGS)
 #endif /*NDEBUG*/
 
+enum InetAddressType {
+	IAT_unknown	=	0,
+	IAT_ipv4	=	1,
+	IAT_ipv6	=	2,
+	IAT_ipv4z	=	3,
+	IAT_ipv6z	=	4,
+	IAT_dns		=	16
+};		    
+
+
+
 /*
- * Structure used to hold info about one tcp[4,6} connection
+ * Structure used to hold info about one tcp{4,6} connection
  * for both active and passive entries
  */
 struct tcp_index {
@@ -68,33 +79,40 @@
 };
 
 /*
- * Structure used to hold info about one udp[4,6} 
+ * Structure used to hold info about one udp{4,6} 
  * endpoint
  */
 struct udp_index {
 	struct asn_oid	index;
 	struct xinpcb	*inp;
+	pid_t		so_pgid;
 };
 
 
 struct tcp_udp46_state {
 	struct clockinfo clock_info;
-	uint64_t	tcp_tick;		/*agent tick when this struct was last updated*/
+	uint64_t	tcp_tick;		/*agent tick when this struct was 
+							last updated*/
 	struct tcpstat	tcpstat;		/*holder for tcp stats*/
-	struct xinpgen	*tcp_xinpgen;		/*holder for data get via sysctl; malloc'd*/
+	struct xinpgen	*tcp_xinpgen;		/*holder for data get via sysctl; 
+							malloc'd*/
 	size_t		tcp_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 (without listeners)*/
-	u_int		listen_tcp_total;	/*the number of tcp4 and tcp6 entries in listen state*/
+	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 unified 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*/
+	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 */
 	
 	uint64_t	udp_tick;
@@ -102,11 +120,13 @@
 	struct xinpgen	*udp_xinpgen;
 	size_t		udp_xinpgen_len;
 	u_int		udp4_total;
-	
+	u_int		all_udp_total;
 
 	struct udp_index *udp4oids;
 	size_t		udp4oids_len;
 
+	struct udp_index *all_udpoids;
+	size_t		  all_udpoids_len;
 	
 	
 	struct xfile 	*xfiles;

==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp_udp46/tcp_udp46_common.c#3 (text+ko) ====

@@ -130,7 +130,14 @@
 		tcp_udp46_state_g.udp4oids_len = 0;
 	}
 
+	if (tcp_udp46_state_g.all_udpoids != NULL && tcp_udp46_state_g.all_udpoids_len > 0) {
+		free(tcp_udp46_state_g.all_udpoids);
+		tcp_udp46_state_g.all_udpoids = NULL;
+		tcp_udp46_state_g.all_udpoids_len = 0;
+	}
 
+
+	/*XFILES zone*/
 	if (tcp_udp46_state_g.xfiles != NULL && tcp_udp46_state_g.xfiles_len > 0 ) {
 		free(tcp_udp46_state_g.xfiles);
 		tcp_udp46_state_g.xfiles = NULL;
@@ -212,7 +219,7 @@
 			
 
 	if (fetch_udp() == -1) {
-		syslog(LOG_ERR, "Failed to fetch the UDP data in tcp-udp46 module." );
+		syslog(LOG_ERR, "Failed to fetch the UDP data in tcp_udp46 module." );
 	}		
 
         TCP46_DPRINTF((stderr, "[%s] done.\n ", __func__));       

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

@@ -92,6 +92,24 @@
 	return result;
 }
 
+static
+pid_t 
+get_endpoint_pid(const struct xinpcb *inp) {
+	struct xfile *xf = NULL;
+	u_int n = 0;
+	assert(inp != NULL);
+	
+	for (xf =  tcp_udp46_state_g.xfiles, n = 0; n < tcp_udp46_state_g.xfiles_total; ++n, ++xf) {
+		if (xf->xf_data == NULL) {
+			continue;
+		}	
+		if (xf->xf_data == (void *)inp->xi_socket.xso_so) {
+			return (xf->xf_pid);
+		}	
+	}
+	return ((pid_t)0);		
+}
+
 /*
  * Used to check if the enpoint is already in the oid list
  * (for the deprecated table - it doesn't have the capability
@@ -103,7 +121,12 @@
 int check_duplicate_endpoint4(const struct xinpcb *inp) {
 	struct udp_index *_oid = NULL;
 	u_int i = 0;
+	
+
 	assert(inp != NULL);
+	
+
+	
 	for (i = 0, _oid = tcp_udp46_state_g.udp4oids; 
 		i < tcp_udp46_state_g.udp4_total; 
 		i++, _oid++) {
@@ -119,6 +142,117 @@
 		
 }
 
+static
+int 
+handle_new_endpoint4(struct udp_index *all_oid, const struct xinpcb *inp) {
+	struct udp_index *_oid = NULL;
+	u_int i = 0;
+	pid_t  pid_owner = 0;
+	in_addr_t inaddr;
+	u_int instance = 1;
+
+	assert(inp != NULL);
+	
+	pid_owner = get_endpoint_pid(inp); 
+	
+	for (i = 0, _oid = tcp_udp46_state_g.all_udpoids; 
+		i < tcp_udp46_state_g.all_udp_total; 
+		i++, _oid++) {
+		if ( _oid->inp == NULL) {
+			continue;
+		}
+		if ( 	_oid->index.subs[0] == IAT_ipv4 
+			&& inp->xi_inp.inp_laddr.s_addr == _oid->inp->xi_inp.inp_laddr.s_addr 
+			&& inp->xi_inp.inp_lport == _oid->inp->xi_inp.inp_lport
+			&& inp->xi_inp.inp_faddr.s_addr == _oid->inp->xi_inp.inp_faddr.s_addr
+			&& inp->xi_inp.inp_fport == _oid->inp->xi_inp.inp_fport) {
+			
+			if ( pid_owner	!= _oid->so_pgid ) {
+				instance++;
+			} else {
+				return (1); /*duplicate endpoint found*/	
+			}
+		} 
+	}
+	all_oid->index.len = 13;
+	all_oid->index.subs[0] = IAT_ipv4;
+	inaddr = ntohl(inp->xi_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(inp->xi_inp.inp_lport);
+	all_oid->index.subs[6] = IAT_ipv4;
+	inaddr = ntohl(inp->xi_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(inp->xi_inp.inp_fport);
+	all_oid->index.subs[12] = instance;
+	all_oid->so_pgid = pid_owner;
+	
+		
+	return (0);
+	
+}
+
+
+static
+int 
+handle_new_endpoint6(struct udp_index *all_oid, const struct xinpcb *inp) {
+	struct udp_index *_oid = NULL;
+	u_int i = 0;
+	pid_t  pid_owner = 0;
+	u_int instance = 1;
+
+	assert(inp != NULL);
+	
+	pid_owner = get_endpoint_pid(inp); 
+	
+	for (i = 0, _oid = tcp_udp46_state_g.all_udpoids; 
+		i < tcp_udp46_state_g.all_udp_total; 
+		i++, _oid++) {
+		if ( _oid->inp == NULL) {
+			continue;
+		}
+		if ( _oid->index.subs[0] == IAT_ipv6 
+		  && IN6_ARE_ADDR_EQUAL(&inp->xi_inp.in6p_laddr,  
+		  	&_oid->inp->xi_inp.in6p_laddr) == 0 
+		  && inp->xi_inp.in6p_lport == _oid->inp->xi_inp.in6p_lport
+		  && IN6_ARE_ADDR_EQUAL(&inp->xi_inp.in6p_faddr,  
+		  	&_oid->inp->xi_inp.in6p_faddr) == 0
+		  && inp->xi_inp.inp_fport == _oid->inp->xi_inp.inp_fport) {
+			
+		  if ( pid_owner != _oid->so_pgid ) {
+			instance++;
+		  } else {
+			return (1); /*duplicate endpoint found*/	
+		  }
+		} 
+	}
+	all_oid->index.len = 37;
+
+	all_oid->index.subs[0] = IAT_ipv6;
+	for (i=0; i<16; i++) {
+		all_oid->index.subs[1+i] = inp->xi_inp.in6p_laddr.s6_addr[i];
+		all_oid->index.subs[19+i] = inp->xi_inp.in6p_faddr.s6_addr[i];
+	}
+	all_oid->index.subs[17] = ntohs(inp->xi_inp.in6p_lport);
+	all_oid->index.subs[18] = IAT_ipv6;
+	all_oid->index.subs[35] = ntohs(inp->xi_inp.in6p_fport);
+	all_oid->index.subs[36] = instance;
+		
+	
+	all_oid->so_pgid = pid_owner;
+	
+		
+	return (0);
+	
+}
+
+
+
 int
 fetch_udp(void)
 {
@@ -126,6 +260,7 @@
 	struct xinpgen *ptr = NULL;
 	struct xinpcb *inp = NULL;
 	struct udp_index *oid = NULL;
+	struct udp_index *all_oid = NULL;
 	in_addr_t inaddr;
 
 	len = sizeof(tcp_udp46_state_g.udpstat);
@@ -166,6 +301,13 @@
 
 	tcp_udp46_state_g.udp4_total = 0;
 	
+	tcp_udp46_state_g.all_udp_total = 0;
+	
+	if (fetch_xfiles() != 0) {
+		TCP46_DPRINTF((stderr, "[%s] Failed to fetch the xfiles\n ", __func__ ));
+	}
+
+		
 	ptr = (struct xinpgen *)tcp_udp46_state_g.udp_xinpgen;
 	for (ptr = (struct xinpgen *)((char *)ptr + ptr->xig_len);
 	     ptr->xig_len > sizeof(struct xinpgen);
@@ -180,10 +322,19 @@
 		if (inp->xi_inp.inp_gencnt > tcp_udp46_state_g.udp_xinpgen->xig_gen) {
 			continue;
 		}
+
+		if ( inp->xi_inp.inp_lport == 0 ) {
+			continue;
+		}
+				
+		if ((inp->xi_inp.inp_vflag & INP_IPV4) == INP_IPV4 ) {
+			tcp_udp46_state_g.udp4_total++;
+		}
 		
-		if ((inp->xi_inp.inp_vflag & INP_IPV4) == INP_IPV4 && inp->xi_inp.inp_lport != 0){
-			tcp_udp46_state_g.udp4_total++;
+		if ((inp->xi_inp.inp_vflag & (INP_IPV6 | INP_IPV6PROTO | INP_IPV4)) != 0) {
+			tcp_udp46_state_g.all_udp_total++;
 		}
+		
 	}
 
 	if (tcp_udp46_state_g.udp4oids_len < tcp_udp46_state_g.udp4_total) {
@@ -198,16 +349,36 @@
 		tcp_udp46_state_g.udp4oids_len = tcp_udp46_state_g.udp4_total;
 	}
 
-	TCP46_DPRINTF((stderr, "[%s] Got %d udp4 endpoints, %d udp{4,6} endpoints.\n ", 
+	if (tcp_udp46_state_g.all_udpoids_len < tcp_udp46_state_g.all_udp_total) {
+		all_oid = realloc(tcp_udp46_state_g.all_udpoids, 
+			tcp_udp46_state_g.all_udp_total * sizeof(struct udp_index));
+		if (all_oid == NULL) {
+			free(tcp_udp46_state_g.all_udpoids);
+			tcp_udp46_state_g.all_udpoids_len = 0;
+			return (0);
+		}
+		tcp_udp46_state_g.all_udpoids = all_oid;
+		tcp_udp46_state_g.all_udpoids_len = tcp_udp46_state_g.all_udp_total;
+	}
+
+
+	TCP46_DPRINTF((stderr, 
+		"[%s] Got %d udp4 endpoints, %d udp{4,6} endpoints.\n", 
 		__func__, 
 		tcp_udp46_state_g.udp4_total,
-		0)); 
+		tcp_udp46_state_g.all_udp_total)); 
 
 	/*Finally fill in the SNMP indexes*/
         memset(tcp_udp46_state_g.udp4oids, 0, 
 		tcp_udp46_state_g.udp4_total * sizeof(struct udp_index) );
 
+        memset(tcp_udp46_state_g.all_udpoids, 0, 
+		tcp_udp46_state_g.all_udp_total * sizeof(struct udp_index) );
+
+
 	oid = tcp_udp46_state_g.udp4oids;
+	all_oid  = tcp_udp46_state_g.all_udpoids;
+	
 	ptr = (struct xinpgen *)tcp_udp46_state_g.udp_xinpgen;
 	for (ptr = (struct xinpgen *)((char *)ptr + ptr->xig_len);
 	     ptr->xig_len > sizeof(struct xinpgen);
@@ -223,7 +394,12 @@
 		if (inp->xi_inp.inp_gencnt > tcp_udp46_state_g.udp_xinpgen->xig_gen) {
 			continue;
 		} 
-		if ((inp->xi_inp.inp_vflag & INP_IPV4) == INP_IPV4 && inp->xi_inp.inp_lport != 0) {
+		
+		if ( inp->xi_inp.inp_lport == 0 ) {
+			continue;
+		}
+		
+		if ((inp->xi_inp.inp_vflag & INP_IPV4) == INP_IPV4 ) {
 			if (check_duplicate_endpoint4(inp) == 1) {
 				assert(tcp_udp46_state_g.udp4_total > 1);
 				tcp_udp46_state_g.udp4_total--;
@@ -238,13 +414,41 @@
 				oid->index.subs[4] = ntohs(inp->xi_inp.inp_lport);
 				oid++;
 			}
+			
+			if (handle_new_endpoint4(all_oid, inp) == 0){
+				all_oid->inp = inp;
+				all_oid++;
+			} else {
+				assert(tcp_udp46_state_g.all_udp_total > 1);
+				tcp_udp46_state_g.all_udp_total--;
+			}
+			
 		}
+		
+		if ((inp->xi_inp.inp_vflag & (INP_IPV6 | INP_IPV6PROTO )) != 0 )	{
+			if (handle_new_endpoint6(all_oid, inp) == 0){
+				all_oid->inp = inp;
+				all_oid++;
+			} else {
+				assert(tcp_udp46_state_g.all_udp_total > 1);
+				tcp_udp46_state_g.all_udp_total--;
+			}
+			
+		}
+		
+
+		
 	}
 
 	qsort(tcp_udp46_state_g.udp4oids, 
 		tcp_udp46_state_g.udp4_total, 
 		sizeof(struct udp_index), udp_compare);
 
+	qsort(tcp_udp46_state_g.all_udpoids, 
+		tcp_udp46_state_g.all_udp_total, 
+		sizeof(struct udp_index), udp_compare);
+
+
 	return (0);
 }
 
@@ -297,10 +501,12 @@
 		value->v.uint32 = tcp_udp46_state_g.udpstat.udps_opackets;
 		break;
 	  case LEAF_udpHCInDatagrams:
-	  	value->v.counter64 = tcp_udp46_state_g.udpstat.udps_ipackets; /*FIX ME: need 64-bit stats*/
+	  	/*FIX ME: need 64-bit stats*/
+	  	value->v.counter64 = tcp_udp46_state_g.udpstat.udps_ipackets; 
 	  	break;
 	  case LEAF_udpHCOutDatagrams:
-	  	value->v.counter64 = tcp_udp46_state_g.udpstat.udps_opackets; /*FIX ME: need 64-bit stats*/
+	  	/*FIX ME: need 64-bit stats*/
+	  	value->v.counter64 = tcp_udp46_state_g.udpstat.udps_opackets; 
 	  	break;
 	  		
 	}
@@ -322,7 +528,8 @@
 
 	  case SNMP_OP_GETNEXT:
 		for (i = 0; i < tcp_udp46_state_g.udp4_total; i++)
-			if (index_compare(&value->var, sub, &tcp_udp46_state_g.udp4oids[i].index) < 0)
+			if (index_compare(&value->var, sub, 
+				&tcp_udp46_state_g.udp4oids[i].index) < 0)
 				break;
 		if (i == tcp_udp46_state_g.udp4_total)
 			return (SNMP_ERR_NOSUCHNAME);
@@ -331,7 +538,8 @@
 
 	  case SNMP_OP_GET:
 		for (i = 0; i < tcp_udp46_state_g.udp4_total; i++)
-			if (index_compare(&value->var, sub, &tcp_udp46_state_g.udp4oids[i].index) == 0)
+			if (index_compare(&value->var, sub, 
+				&tcp_udp46_state_g.udp4oids[i].index) == 0)
 				break;
 		if (i == tcp_udp46_state_g.udp4_total)
 			return (SNMP_ERR_NOSUCHNAME);
@@ -364,8 +572,59 @@
 }
 
 int	
-op_udpEndpointTable(struct snmp_context *ctx __unused, struct snmp_value *value __unused,
-    u_int sub __unused, u_int iidx __unused, enum snmp_op op __unused) {
-	return (SNMP_ERR_NOSUCHNAME);
+op_udpEndpointTable(struct snmp_context *ctx __unused, struct snmp_value *value,
+    u_int sub, u_int iidx __unused, enum snmp_op op)
+{
+	u_int i;
+
+	if (tcp_udp46_state_g.udp_tick < this_tick)
+		if (fetch_udp() == -1)
+			return (SNMP_ERR_GENERR);
+
+	switch (op) {
+
+	  case SNMP_OP_GETNEXT:
+		for (i = 0; i < tcp_udp46_state_g.all_udp_total; i++)
+			if (index_compare(&value->var, sub, 
+				&tcp_udp46_state_g.all_udpoids[i].index) < 0)
+				break;
+		if (i == tcp_udp46_state_g.all_udp_total)
+			return (SNMP_ERR_NOSUCHNAME);
+		index_append(&value->var, sub, &tcp_udp46_state_g.all_udpoids[i].index);
+		break;
+
+	  case SNMP_OP_GET:
+		for (i = 0; i < tcp_udp46_state_g.all_udp_total; i++)
+			if (index_compare(&value->var, sub, 
+				&tcp_udp46_state_g.all_udpoids[i].index) == 0)
+				break;
+		if (i == tcp_udp46_state_g.all_udp_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();
+	}
+
+	switch (value->var.subs[sub - 1]) {
+
+	  case LEAF_udpEndpointProcess:
+  	  	/*this is from hrSWRunTable, where the index is pid + 1 */
+		value->v.uint32 = (tcp_udp46_state_g.all_udpoids[i].so_pgid == 0 ? 0 : 
+				tcp_udp46_state_g.all_udpoids[i].so_pgid + 1);
+		break;
+
+	  default:
+		return (SNMP_ERR_NOSUCHNAME);
+		
+
+	}
+	return (SNMP_ERR_NOERROR);
+
 }
 


More information about the p4-projects mailing list