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