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