PERFORCE change 163670 for review
Gabor Pali
pgj at FreeBSD.org
Sat Jun 6 21:45:47 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=163670
Change 163670 by pgj at 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);
}
}
More information about the p4-projects
mailing list