From owner-p4-projects@FreeBSD.ORG Mon Aug 29 13:10:12 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 2C15716A421; Mon, 29 Aug 2005 13:10:12 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id DF1C716A41F for ; Mon, 29 Aug 2005 13:10:11 +0000 (GMT) (envelope-from soc-victor@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8550043D45 for ; Mon, 29 Aug 2005 13:10:11 +0000 (GMT) (envelope-from soc-victor@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j7TDABpW051120 for ; Mon, 29 Aug 2005 13:10:11 GMT (envelope-from soc-victor@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j7TDABRs051117 for perforce@freebsd.org; Mon, 29 Aug 2005 13:10:11 GMT (envelope-from soc-victor@freebsd.org) Date: Mon, 29 Aug 2005 13:10:11 GMT Message-Id: <200508291310.j7TDABRs051117@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to soc-victor@freebsd.org using -f From: Victor Cruceru To: Perforce Change Reviews Cc: Subject: PERFORCE change 82761 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 29 Aug 2005 13:10:13 -0000 http://perforce.freebsd.org/chv.cgi?CH=82761 Change 82761 by soc-victor@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 ==== //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); + }