Date: Wed, 24 Aug 2005 22:31:11 GMT From: Victor Cruceru <soc-victor@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 82514 for review Message-ID: <200508242231.j7OMVBHA081630@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=82514 Change 82514 by soc-victor@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508242231.j7OMVBHA081630>