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