Date: Sat, 6 Jun 2009 21:45:45 GMT From: Gabor Pali <pgj@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 163670 for review Message-ID: <200906062145.n56Ljjj7077028@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=163670 Change 163670 by pgj@petymeg-current on 2009/06/06 21:45:37 Theoretically, unixpr() now uses libnetstat for getting information on active UNIX domain sockets :) Practically, it needs some testing and further refinements. Affected files ... .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/Makefile#2 edit .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#2 edit .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/netstat.h#2 edit .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/unix.c#2 edit Differences ... ==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/Makefile#2 (text+ko) ==== @@ -20,8 +20,12 @@ BINGRP= kmem BINMODE=2555 -DPADD= ${LIBKVM} ${LIBMEMSTAT} ${LIBUTIL} -LDADD= -lkvm -lmemstat -lutil +DPADD= ${LIBKVM} ${LIBMEMSTAT} ${LIBUTIL} ${LIBNETSTAT} +LDADD= -lkvm -lmemstat -lutil -lnetstat + +# XXX: temp. solution +CFLAGS+= -I../../lib/libnetstat +LDFLAGS+= -L../../lib/libnetstat .if ${MK_NETGRAPH_SUPPORT} != "no" SRCS+= netgraph.c ==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#2 (text+ko) ==== @@ -596,8 +596,7 @@ printproto(tp, tp->pr_name); #endif /* NETGRAPH */ if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag) - unixpr(nl[N_UNP_COUNT].n_value, nl[N_UNP_GENCNT].n_value, - nl[N_UNP_DHEAD].n_value, nl[N_UNP_SHEAD].n_value); + unixpr(kvmd); exit(0); } ==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/netstat.h#2 (text+ko) ==== @@ -149,7 +149,7 @@ void netgraphprotopr(u_long, const char *, int, int); #endif -void unixpr(u_long, u_long, u_long, u_long); +void unixpr(void *); void esis_stats(u_long, const char *, int, int); void clnp_stats(u_long, const char *, int, int); ==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/unix.c#2 (text+ko) ==== @@ -63,6 +63,7 @@ #include <stdlib.h> #include <strings.h> #include <kvm.h> +#include <netstat.h> /* libnetstat */ #include "netstat.h" static void unixdomainpr(struct xunpcb *, struct xsocket *); @@ -70,174 +71,51 @@ static const char *const socktype[] = { "#0", "stream", "dgram", "raw", "rdm", "seqpacket" }; -static int -pcblist_sysctl(int type, char **bufp) +void +unixpr(void *kvmd) { - char *buf; - size_t len; - char mibvar[sizeof "net.local.seqpacket.pcblist"]; + int ret, type; + struct xsocket *so; + struct socket_type_list *stlp; + struct socket_type *stp; + struct xunpcb *xunp; + int error; + kvm_t *kvm; - sprintf(mibvar, "net.local.%s.pcblist", socktype[type]); - - len = 0; - if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) { - if (errno != ENOENT) - warn("sysctl: %s", mibvar); - return (-1); - } - if ((buf = malloc(len)) == 0) { - warnx("malloc %lu bytes", (u_long)len); - return (-2); - } - if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) { - warn("sysctl: %s", mibvar); - free(buf); - return (-2); - } - *bufp = buf; - return (0); -} - -static int -pcblist_kvm(u_long count_off, u_long gencnt_off, u_long head_off, char **bufp) -{ - struct unp_head head; - struct unpcb *unp, unp_conn; - u_char sun_len; - struct socket so; - struct xunpgen xug; - struct xunpcb xu; - unp_gen_t unp_gencnt; - u_int unp_count; - char *buf, *p; - size_t len; - - if (count_off == 0 || gencnt_off == 0) - return (-2); - if (head_off == 0) - return (-1); - kread(count_off, &unp_count, sizeof(unp_count)); - len = 2 * sizeof(xug) + (unp_count + unp_count / 8) * sizeof(xu); - if ((buf = malloc(len)) == 0) { - warnx("malloc %lu bytes", (u_long)len); - return (-2); - } - p = buf; - -#define COPYOUT(obj, size) do { \ - if (len < (size)) { \ - warnx("buffer size exceeded"); \ - goto fail; \ - } \ - bcopy((obj), p, (size)); \ - len -= (size); \ - p += (size); \ -} while (0) - -#define KREAD(off, buf, len) do { \ - if (kread((uintptr_t)(off), (buf), (len)) != 0) \ - goto fail; \ -} while (0) - - /* Write out header. */ - kread(gencnt_off, &unp_gencnt, sizeof(unp_gencnt)); - xug.xug_len = sizeof xug; - xug.xug_count = unp_count; - xug.xug_gen = unp_gencnt; - xug.xug_sogen = 0; - COPYOUT(&xug, sizeof xug); - - /* Walk the PCB list. */ - xu.xu_len = sizeof xu; - KREAD(head_off, &head, sizeof(head)); - LIST_FOREACH(unp, &head, unp_link) { - xu.xu_unpp = unp; - KREAD(unp, &xu.xu_unp, sizeof (*unp)); - unp = &xu.xu_unp; - - if (unp->unp_gencnt > unp_gencnt) - continue; - if (unp->unp_addr != NULL) { - KREAD(unp->unp_addr, &sun_len, sizeof(sun_len)); - KREAD(unp->unp_addr, &xu.xu_addr, sun_len); - } - if (unp->unp_conn != NULL) { - KREAD(unp->unp_conn, &unp_conn, sizeof(unp_conn)); - if (unp_conn.unp_addr != NULL) { - KREAD(unp_conn.unp_addr, &sun_len, - sizeof(sun_len)); - KREAD(unp_conn.unp_addr, &xu.xu_caddr, sun_len); - } - } - KREAD(unp->unp_socket, &so, sizeof(so)); - if (sotoxsocket(&so, &xu.xu_socket) != 0) - goto fail; - COPYOUT(&xu, sizeof(xu)); + kvm = (kvm_t *)kvmd; + stlp = netstat_stl_alloc(); + if (stlp == NULL) { + warn("netstat_stl_alloc"); + return; } - /* Reread the counts and write the footer. */ - kread(count_off, &unp_count, sizeof(unp_count)); - kread(gencnt_off, &unp_gencnt, sizeof(unp_gencnt)); - xug.xug_count = unp_count; - xug.xug_gen = unp_gencnt; - COPYOUT(&xug, sizeof xug); - - *bufp = buf; - return (0); - -fail: - free(buf); - return (-1); -#undef COPYOUT -#undef KREAD -} - -void -unixpr(u_long count_off, u_long gencnt_off, u_long dhead_off, u_long shead_off) -{ - char *buf; - int ret, type; - struct xsocket *so; - struct xunpgen *xug, *oxug; - struct xunpcb *xunp; - for (type = SOCK_STREAM; type <= SOCK_SEQPACKET; type++) { - if (live) - ret = pcblist_sysctl(type, &buf); - else - ret = pcblist_kvm(count_off, gencnt_off, - type == SOCK_STREAM ? shead_off : - (type == SOCK_DGRAM ? dhead_off : 0), &buf); - if (ret == -1) + ret = netstat_socket(PF_LOCAL, type, 0, stlp, + live ? 0 : NETSTAT_SOCKET_KVM, kvm); + if (ret < 0 && + netstat_stl_geterror(stlp) == NETSTAT_ERROR_UNSUPPORTED) continue; - if (ret < 0) + if (ret < 0) { + error = netstat_stl_geterror(stlp); + if (error == NETSTAT_ERROR_KVM) + warnx("netstat_socket: %s", kvm_geterr(kvm)); + else + warnx("netstat_socket: %s", + netstat_strerror(error)); return; + } - oxug = xug = (struct xunpgen *)buf; - for (xug = (struct xunpgen *)((char *)xug + xug->xug_len); - xug->xug_len > sizeof(struct xunpgen); - xug = (struct xunpgen *)((char *)xug + xug->xug_len)) { - xunp = (struct xunpcb *)xug; - so = &xunp->xu_socket; - - /* Ignore PCBs which were freed during copyout. */ - if (xunp->xu_unp.unp_gencnt > oxug->xug_gen) - continue; - unixdomainpr(xunp, so); - } - if (xug != oxug && xug->xug_gen != oxug->xug_gen) { - if (oxug->xug_count > xug->xug_count) { - printf("Some %s sockets may have been deleted.\n", - socktype[type]); - } else if (oxug->xug_count < xug->xug_count) { - printf("Some %s sockets may have been created.\n", - socktype[type]); - } else { - printf("Some %s sockets may have been created or deleted", - socktype[type]); - } + /* + * It should be guaranteed that only active PCBs are + * returned. + */ + for (stp = netstat_stl_first(stlp); + stp != NULL; + stp = netstat_stl_next(stp)) { + xunp = (struct xunpcb *)netstat_st_get_pcb(stp); + so = &xunp->xu_socket; + unixdomainpr(xunp, so); } - free(buf); } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906062145.n56Ljjj7077028>