PERFORCE change 82724 for review
Victor Cruceru
soc-victor at FreeBSD.org
Sun Aug 28 22:48:29 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=82724
Change 82724 by soc-victor at soc-victor_82.76.158.176 on 2005/08/28 22:47:35
Added the SNMP instrumentation fro UDP scalars and for the deprecated table
udpTable (based on Harti's work).
Also a lot of cleanup.
Affected files ...
.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp_udp46/Makefile#4 edit
.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp_udp46/tcp46_snmp.c#4 edit
.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp_udp46/tcp_udp46.h#2 edit
.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp_udp46/tcp_udp46_common.c#2 edit
.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp_udp46/udp46_snmp.c#2 edit
Differences ...
==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp_udp46/Makefile#4 (text+ko) ====
@@ -37,7 +37,7 @@
WARNS?= 6
#Not having NDEBUG defined will enable assertions and a lot of output on stderr
-CFLAGS+= -DNDEBUG
+#CFLAGS+= -DNDEBUG
XSYM= tcpMIB udpMIB
==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp_udp46/tcp46_snmp.c#4 (text+ko) ====
@@ -497,15 +497,15 @@
syslog(LOG_ERR, "sysctlbyname(net.inet.tcp.pcblist) failed: %m");
return (-1);
}
- if (len > tcp_udp46_state_g.xinpgen_len) {
- if ((ptr = realloc(tcp_udp46_state_g.xinpgen, len)) == NULL) {
+ if (len > tcp_udp46_state_g.tcp_xinpgen_len) {
+ if ((ptr = realloc(tcp_udp46_state_g.tcp_xinpgen, len)) == NULL) {
syslog(LOG_ERR, "%zu: %m", len);
return (-1);
}
- tcp_udp46_state_g.xinpgen = ptr;
- tcp_udp46_state_g.xinpgen_len = len;
+ tcp_udp46_state_g.tcp_xinpgen = ptr;
+ tcp_udp46_state_g.tcp_xinpgen_len = len;
}
- if (sysctlbyname("net.inet.tcp.pcblist", tcp_udp46_state_g.xinpgen, &len, NULL, 0) == -1) {
+ if (sysctlbyname("net.inet.tcp.pcblist", tcp_udp46_state_g.tcp_xinpgen, &len, NULL, 0) == -1) {
syslog(LOG_ERR, "sysctlbyname(net.inet.tcp.pcblist) failed: %m");
return (-1);
}
@@ -522,7 +522,7 @@
}
/*First count the endpoints*/
- for (ptr = (struct xinpgen *)(void *)((char *)tcp_udp46_state_g.xinpgen + tcp_udp46_state_g.xinpgen->xig_len);
+ for (ptr = (struct xinpgen *)(void *)((char *)tcp_udp46_state_g.tcp_xinpgen + tcp_udp46_state_g.tcp_xinpgen->xig_len);
ptr->xig_len > sizeof(struct xinpgen);
ptr = (struct xinpgen *)(void *)((char *)ptr + ptr->xig_len)) {
tp = (struct xtcpcb *)ptr;
@@ -539,7 +539,7 @@
}
/* Ignore PCBs which were freed during copyout. */
- if (tp->xt_inp.inp_gencnt > tcp_udp46_state_g.xinpgen->xig_gen ) {
+ if (tp->xt_inp.inp_gencnt > tcp_udp46_state_g.tcp_xinpgen->xig_gen ) {
TCP46_DPRINTF((stderr, "[%s] One tcp4 conn. ignored (freed during copyout)\n ",
__func__
));
@@ -626,7 +626,7 @@
all_oid = tcp_udp46_state_g.all_tcpoids;
listen_oid = tcp_udp46_state_g.listen_tcpoids;
- for (ptr = (struct xinpgen *)(void *)((char *)tcp_udp46_state_g.xinpgen + tcp_udp46_state_g.xinpgen->xig_len);
+ for (ptr = (struct xinpgen *)(void *)((char *)tcp_udp46_state_g.tcp_xinpgen + tcp_udp46_state_g.tcp_xinpgen->xig_len);
ptr->xig_len > sizeof(struct xinpgen);
ptr = (struct xinpgen *)(void *)((char *)ptr + ptr->xig_len)) {
tp = (struct xtcpcb *)ptr;
@@ -637,7 +637,7 @@
}
/* Ignore PCBs which were freed during copyout. */
- if (tp->xt_inp.inp_gencnt > tcp_udp46_state_g.xinpgen->xig_gen ) {
+ if (tp->xt_inp.inp_gencnt > tcp_udp46_state_g.tcp_xinpgen->xig_gen ) {
continue;
}
if ( (tp->xt_inp.inp_vflag & INP_IPV4) == INP_IPV4) {
==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp_udp46/tcp_udp46.h#2 (text+ko) ====
@@ -42,7 +42,11 @@
#include <sys/file.h> /*for struct xfile*/
#include <stdio.h> /*for fprintf*/
#include <sys/types.h> /*for pid_t*/
+#include <netinet/udp.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp_var.h>
+
/*a debug macro*/
#ifndef NDEBUG
#define TCP46_DPRINTF(ARGS) do { \
@@ -63,13 +67,22 @@
pid_t so_pgid;
};
+/*
+ * Structure used to hold info about one udp[4,6}
+ * endpoint
+ */
+struct udp_index {
+ struct asn_oid index;
+ struct xinpcb *inp;
+};
+
struct tcp_udp46_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 */
+ 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)*/
@@ -84,6 +97,18 @@
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;
+ struct udpstat udpstat;
+ struct xinpgen *udp_xinpgen;
+ size_t udp_xinpgen_len;
+ u_int udp4_total;
+
+
+ struct udp_index *udp4oids;
+ size_t udp4oids_len;
+
+
+
struct xfile *xfiles;
size_t xfiles_len;
u_int xfiles_total;
@@ -111,4 +136,10 @@
int
fetch_xfiles(void);
+/*
+ * Get all the UDP{4,6} info from the O/S
+ */
+int
+fetch_udp(void);
+
#endif /*__TCP_UDP46_H_INCLUDED__*/
==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp_udp46/tcp_udp46_common.c#2 (text+ko) ====
@@ -91,6 +91,7 @@
*/
static
int tcp_udp46_fini(void) {
+ /*TCP zone*/
if (tcp_udp46_state_g.tcp4oids != NULL && tcp_udp46_state_g.tcp4oids_len > 0) {
free(tcp_udp46_state_g.tcp4oids);
tcp_udp46_state_g.tcp4oids = NULL;
@@ -109,12 +110,27 @@
tcp_udp46_state_g.listen_tcpoids_len = 0;
}
- if (tcp_udp46_state_g.xinpgen != NULL && tcp_udp46_state_g.xinpgen_len > 0) {
- free(tcp_udp46_state_g.xinpgen);
- tcp_udp46_state_g.xinpgen = NULL;
- tcp_udp46_state_g.xinpgen_len = 0;
+ if (tcp_udp46_state_g.tcp_xinpgen != NULL && tcp_udp46_state_g.tcp_xinpgen_len > 0) {
+ free(tcp_udp46_state_g.tcp_xinpgen);
+ tcp_udp46_state_g.tcp_xinpgen = NULL;
+ tcp_udp46_state_g.tcp_xinpgen_len = 0;
+ }
+
+ /*UDP zone*/
+ if (tcp_udp46_state_g.udp_xinpgen != NULL && tcp_udp46_state_g.udp_xinpgen_len > 0) {
+ free(tcp_udp46_state_g.udp_xinpgen);
+ tcp_udp46_state_g.udp_xinpgen = NULL;
+ tcp_udp46_state_g.udp_xinpgen_len = 0;
+ }
+
+
+ if (tcp_udp46_state_g.udp4oids != NULL && tcp_udp46_state_g.udp4oids_len > 0) {
+ free(tcp_udp46_state_g.udp4oids);
+ tcp_udp46_state_g.udp4oids = NULL;
+ tcp_udp46_state_g.udp4oids_len = 0;
}
+
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;
@@ -125,7 +141,11 @@
or_unregister(tcp46_registration_id);
}
-
+ if (udp46_registration_id > 0) {
+ or_unregister(udp46_registration_id);
+ }
+
+
TCP46_DPRINTF((stderr, "[%s] done.\n", __func__));
return (0);
@@ -187,7 +207,12 @@
}
if (fetch_tcp() == -1) {
- syslog(LOG_ERR, "Failed to fetch the TCP data in tcp46 module." );
+ syslog(LOG_ERR, "Failed to fetch the TCP data in tcp_udp46 module." );
+ }
+
+
+ if (fetch_udp() == -1) {
+ 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#2 (text+ko) ====
@@ -29,22 +29,306 @@
* UDP-MIB implementation for SNMPd: instrumentation for RFC 4113 covering
* both IPv4 and IPv6 objects
*/
+/*
+ * Copyright (c) 2001-2003
+ * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
+ * All rights reserved.
+ *
+ * Author: Harti Brandt <harti at freebsd.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Begemot: bsnmp/snmp_mibII/mibII_udp.c,v 1.7 2005/05/23 09:03:42 brandt_h Exp $
+ *
+ * udp
+ */
+
#include "tcp_udp46.h"
#include "tcp_udp46.h"
#include "tcp_udp46_oid.h"
#include "tcp_udp46_tree.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <syslog.h>
+
+static int
+udp_compare(const void *p1, const void *p2)
+{
+ int result = 0;
+ const struct udp_index *t1 = p1;
+ const struct udp_index *t2 = p2;
+ assert(t1 != NULL);
+ assert(t2 != NULL);
+ if (t1 == NULL || t2 == NULL) {
+ return 0;
+ }
+ result = asn_compare_oid(&t1->index, &t2->index);
+ if ( result == 0 ) {
+ syslog(LOG_ERR, "udp malfunction: two equal oids.");
+ assert(0);
+ }
+ return result;
+}
+
+int
+fetch_udp(void)
+{
+ size_t len = 0;
+ struct xinpgen *ptr = NULL;
+ struct xinpcb *inp = NULL;
+ struct udp_index *oid = NULL;
+ in_addr_t inaddr;
+
+ len = sizeof(tcp_udp46_state_g.udpstat);
+ if (sysctlbyname("net.inet.udp.stats", &tcp_udp46_state_g.udpstat,
+ &len, NULL, 0) == -1) {
+ syslog(LOG_ERR, "net.inet.udp.stats: %m");
+ return (-1);
+ }
+ if (len != sizeof(tcp_udp46_state_g.udpstat)) {
+ syslog(LOG_ERR, "net.inet.udp.stats: wrong size");
+ return (-1);
+ }
+
+ tcp_udp46_state_g.udp_tick = get_ticks();
+
+ len = 0;
+ if (sysctlbyname("net.inet.udp.pcblist", NULL, &len, NULL, 0) == -1) {
+ syslog(LOG_ERR, "net.inet.udp.pcblist: %m");
+ return (-1);
+ }
+
+ TCP46_DPRINTF((stderr, "[%s] Got %d len at net.inet.udp.pcblist .\n", __func__, len));
+
+ if (len > tcp_udp46_state_g.udp_xinpgen_len) {
+ if ((ptr = realloc(tcp_udp46_state_g.udp_xinpgen, len)) == NULL) {
+ syslog(LOG_ERR, "%zu: %m", len);
+ return (-1);
+ }
+ tcp_udp46_state_g.udp_xinpgen = ptr;
+ tcp_udp46_state_g.udp_xinpgen_len = len;
+ memset(tcp_udp46_state_g.udp_xinpgen, 0, len);
+ }
+ if (sysctlbyname("net.inet.udp.pcblist", tcp_udp46_state_g.udp_xinpgen,
+ &len, NULL, 0) == -1) {
+ syslog(LOG_ERR, "net.inet.udp.pcblist: %m");
+ return (-1);
+ }
+
+ tcp_udp46_state_g.udp4_total = 0;
+
+ ptr = (struct xinpgen *)tcp_udp46_state_g.udp_xinpgen;
+ for (ptr = (struct xinpgen *)((char *)ptr + ptr->xig_len);
+ ptr->xig_len > sizeof(struct xinpgen);
+ ptr = (struct xinpgen *)((char *)ptr + ptr->xig_len)) {
+ inp = (struct xinpcb *)ptr;
+
+ /* Ignore sockets for protocols other than the desired one. */
+ if (inp->xi_socket.xso_protocol != IPPROTO_UDP) {
+ continue;
+ }
+
+ 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){
+ tcp_udp46_state_g.udp4_total++;
+ }
+ }
+
+ if (tcp_udp46_state_g.udp4oids_len < tcp_udp46_state_g.udp4_total) {
+ oid = realloc(tcp_udp46_state_g.udp4oids,
+ tcp_udp46_state_g.udp4_total * sizeof(struct udp_index));
+ if (oid == NULL) {
+ free(tcp_udp46_state_g.udp4oids);
+ tcp_udp46_state_g.udp4oids_len = 0;
+ return (0);
+ }
+ tcp_udp46_state_g.udp4oids = oid;
+ 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 ",
+ __func__,
+ tcp_udp46_state_g.udp4_total,
+ 0));
+
+ /*Finally fill in the SNMP indexes*/
+ memset(tcp_udp46_state_g.udp4oids, 0,
+ tcp_udp46_state_g.udp4_total * sizeof(struct udp_index) );
+
+ oid = tcp_udp46_state_g.udp4oids;
+ ptr = (struct xinpgen *)tcp_udp46_state_g.udp_xinpgen;
+ for (ptr = (struct xinpgen *)((char *)ptr + ptr->xig_len);
+ ptr->xig_len > sizeof(struct xinpgen);
+ ptr = (struct xinpgen *)((char *)ptr + ptr->xig_len)) {
+ inp = (struct xinpcb *)ptr;
+ /* Ignore sockets for protocols other than the desired one. */
+ if (inp->xi_socket.xso_protocol != IPPROTO_UDP) {
+ continue;
+ }
+
+ 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) {
+ oid->inp = inp;
+ oid->index.len = 5;
+ inaddr = ntohl(inp->xi_inp.inp_laddr.s_addr);
+ oid->index.subs[0] = (inaddr >> 24) & 0xff;
+ oid->index.subs[1] = (inaddr >> 16) & 0xff;
+ oid->index.subs[2] = (inaddr >> 8) & 0xff;
+ oid->index.subs[3] = (inaddr >> 0) & 0xff;
+ oid->index.subs[4] = ntohs(inp->xi_inp.inp_lport);
+ oid++;
+ }
+ }
+
+ qsort(tcp_udp46_state_g.udp4oids,
+ tcp_udp46_state_g.udp4_total,
+ sizeof(struct udp_index), udp_compare);
+
+ return (0);
+}
+
+
int
-op_udp( 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_udp(struct snmp_context *ctx __unused, struct snmp_value *value,
+ u_int sub, u_int iidx __unused, enum snmp_op op)
+{
+ switch (op) {
+
+ case SNMP_OP_GETNEXT:
+ abort();
+
+ case SNMP_OP_GET:
+ break;
+
+ case SNMP_OP_SET:
+ return (SNMP_ERR_NOT_WRITEABLE);
+
+ case SNMP_OP_ROLLBACK:
+ case SNMP_OP_COMMIT:
+ assert(0);
+ return (SNMP_ERR_GENERR);
+ }
+
+ if (tcp_udp46_state_g.udp_tick < this_tick)
+ if (fetch_udp() == -1)
+ return (SNMP_ERR_GENERR);
+
+ switch (value->var.subs[sub - 1]) {
+
+ case LEAF_udpInDatagrams:
+ value->v.uint32 = tcp_udp46_state_g.udpstat.udps_ipackets;
+ break;
+
+ case LEAF_udpNoPorts:
+ value->v.uint32 = tcp_udp46_state_g.udpstat.udps_noport +
+ tcp_udp46_state_g.udpstat.udps_noportbcast +
+ tcp_udp46_state_g.udpstat.udps_noportmcast;
+ break;
+
+ case LEAF_udpInErrors:
+ value->v.uint32 = tcp_udp46_state_g.udpstat.udps_hdrops +
+ tcp_udp46_state_g.udpstat.udps_badsum +
+ tcp_udp46_state_g.udpstat.udps_badlen +
+ tcp_udp46_state_g.udpstat.udps_fullsock;
+ break;
+
+ case LEAF_udpOutDatagrams:
+ 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*/
+ break;
+ case LEAF_udpHCOutDatagrams:
+ value->v.counter64 = tcp_udp46_state_g.udpstat.udps_opackets; /*FIX ME: need 64-bit stats*/
+ break;
+
+ }
+ return (SNMP_ERR_NOERROR);
+
}
int
-op_udpTable(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_udpTable(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.udp4_total; i++)
+ 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);
+ index_append(&value->var, sub, &tcp_udp46_state_g.udp4oids[i].index);
+ break;
+
+ 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)
+ break;
+ if (i == tcp_udp46_state_g.udp4_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_udpLocalAddress:
+ value->v.ipaddress[0] = tcp_udp46_state_g.udp4oids[i].index.subs[0];
+ value->v.ipaddress[1] = tcp_udp46_state_g.udp4oids[i].index.subs[1];
+ value->v.ipaddress[2] = tcp_udp46_state_g.udp4oids[i].index.subs[2];
+ value->v.ipaddress[3] = tcp_udp46_state_g.udp4oids[i].index.subs[3];
+ break;
+
+ case LEAF_udpLocalPort:
+ value->v.integer = tcp_udp46_state_g.udp4oids[i].index.subs[4];
+ break;
+
+ }
+ return (SNMP_ERR_NOERROR);
}
int
More information about the p4-projects
mailing list