PERFORCE change 163933 for review

Gabor Pali pgj at FreeBSD.org
Tue Jun 9 21:01:20 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=163933

Change 163933 by pgj at petymeg-current on 2009/06/09 21:00:22

	Start to use libnetstat for displaying tcp connections -- needs
	some work, still contains hacks

Affected files ...

.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/Makefile#5 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#9 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#12 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#9 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#11 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/extern.h#2 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/inet.c#3 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#5 edit

Differences ...

==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/Makefile#5 (text+ko) ====

@@ -18,4 +18,8 @@
 
 WITHOUT_MAN=	yes
 
+.if ${MK_INET6_SUPPORT} != "no"
+CFLAGS+=    -DINET6
+.endif
+
 .include <bsd.lib.mk>

==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#9 (text+ko) ====

@@ -9,6 +9,11 @@
 #include <err.h>
 #include <errno.h>
 #include <kvm.h>
+#include <netinet/in.h>
+#include <netinet/in_pcb.h>
+#include <netinet/tcp_var.h>
+#define TCPSTATES
+#include <netinet/tcp_fsm.h>
 #include <nlist.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -17,7 +22,7 @@
 #include "netstat_internal.h"
 
 static struct nlist nl[] = {
-/* UNP_###-related variables. */
+/* UNP_###-related */
 #define X_UNP_COUNT	    0
 	{ .n_name = "_unp_count" },
 #define X_UNP_GENCNT	    1
@@ -27,19 +32,32 @@
 #define X_UNP_SHEAD	    3
 	{ .n_name = "_unp_shead" },
 	{ .n_name = NULL },
+/* INET-related */
+#define X_TCBINFO	    5
+	{ .n_name = "_tcbinfo" },
+#define X_UDBINFO	    6
+	{ .n_name = "_udbinfo" },
+	{ .n_name = NULL },
 };
 
 static void extract_xunpcb_data(struct xunpcb *, struct socket_type *);
+static void extract_inet_data(struct tcpcb *, struct inpcb *,
+    struct xsocket *, struct socket_type *);
 
+/* type names */
 static const char *const socktype[] =
     { "#0", "stream", "dgram", "raw", "rdm", "seqpacket" }; 
 
+static const char *const ipproto[] =
+    { "hopopts", "igmp", "tcp", "ggp", "ipv4", "ipip", "st", "egp", "pgip",
+      "rccmon", "nvpii", "pup", "argus", "emcon", "xnet", "chaos", "udp" };
+
 static int
 net_local_pcblist_sysctl(int type, struct socket_type_list *list)
 {
 	char	*buf;
 	size_t	len;
-	char	mibvar[sizeof "net.local.seqpacket.pcblist"];
+	char	mibvar[64];
 
 	struct	xunpgen	    *xug, *oxug;
 	struct	xunpcb	    *xunp;
@@ -156,6 +174,75 @@
 #undef KREAD
 }
 
+static int
+net_inet_pcblist_sysctl(int protocol, struct socket_type_list *list)
+{
+	char	*buf;
+	size_t	len;
+	char	mibvar[64];
+
+	struct	xinpgen	    *xig, *oxig;
+	struct	tcpcb	    *tp = NULL;
+	struct	inpcb	    *inp;
+	struct	xsocket	    *so;
+
+	struct	socket_type *stp;
+
+	sprintf(mibvar, "net.inet.%s.pcblist", ipproto[protocol]);
+
+	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);
+	}
+
+	oxig = xig = (struct xinpgen *)buf;
+	for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
+	    xig->xig_len > sizeof(struct xinpgen);
+	    xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
+		if (protocol == IPPROTO_TCP) {
+			tp = &((struct xtcpcb *)xig)->xt_tp;
+			inp = &((struct xtcpcb *)xig)->xt_inp;
+			so = &((struct xtcpcb *)xig)->xt_socket;
+		} else {
+			inp = &((struct xinpcb *)xig)->xi_inp;
+			so = &((struct xinpcb *)xig)->xi_socket;
+		}
+
+		/* Ignore sockets for protocols other than the desired one.
+		   XXX: is this needed? */
+		if (so->xso_protocol != protocol)
+			continue;
+
+		if (inp->inp_gencnt <= oxig->xig_gen) {
+			stp = _netstat_st_allocate(list, PF_INET, protocol,
+			    ipproto[protocol]);
+			extract_inet_data(tp, inp, so, stp);
+		}
+	}
+	
+	free(buf);
+	return (0);
+}
+
+static int
+net_inet_pcblist_kvm(int protocol, struct socket_type_list *list,
+    kvm_t *kvm, struct nlist *nlistp)
+{
+	/* XXX: to be filled in. */
+	return (0);
+}
+
 int
 netstat_socket(int domain, int type, int protocol,
     struct socket_type_list *list, int flags, void *kvm_handle)
@@ -173,18 +260,18 @@
 		}
 	}
 
-#define NLP_KVM(type, list, kvm, nl) do {				\
-	if (net_local_pcblist_kvm((type), (list), (kvm), (nl)) != 0) {	\
-		list->stl_error = NETSTAT_ERROR_UNDEFINED;		\
-		return (-1);						\
-	}								\
+#define NPCB_KVM(family, type, list, kvm, nl) do {			    \
+	if (net_##family##_pcblist_kvm((type), (list), (kvm), (nl)) != 0) { \
+		list->stl_error = NETSTAT_ERROR_UNDEFINED;		    \
+		return (-1);						    \
+	}								    \
 } while (0)
 
-#define NLP_SCT(type, list) do {					\
-	if (net_local_pcblist_sysctl((type), (list)) != 0) {		\
-		list->stl_error = NETSTAT_ERROR_UNDEFINED;		\
-		return (-1);						\
-	}								\
+#define NPCB_SCT(family, type, list) do {				    \
+	if (net_##family##_pcblist_sysctl((type), (list)) != 0) {	    \
+		list->stl_error = NETSTAT_ERROR_UNDEFINED;		    \
+		return (-1);						    \
+	}								    \
 } while (0)
 
 	switch (domain) {
@@ -193,18 +280,43 @@
 		case SOCK_STREAM:
 		case SOCK_DGRAM:
 			if (use_kvm)
-				NLP_KVM(type, list, kvm, nl);
+				NPCB_KVM(local, type, list, kvm, nl);
 			else
 				/* Use sysctl (or something else). */
-				NLP_SCT(type, list);
+				NPCB_SCT(local, type, list);
+			break;
 		/* All PF_LOCAL */
 		case 0:
 			if (use_kvm) {
-				NLP_KVM(SOCK_STREAM, list, kvm, nl);
-				NLP_KVM(SOCK_DGRAM, list, kvm, nl);
+				NPCB_KVM(local, SOCK_STREAM, list, kvm, nl);
+				NPCB_KVM(local, SOCK_DGRAM, list, kvm, nl);
+			} else {
+				NPCB_SCT(local, SOCK_STREAM, list);
+				NPCB_SCT(local, SOCK_DGRAM, list);
+			}
+			break;
+		default:
+			list->stl_error = NETSTAT_ERROR_UNSUPPORTED;
+			return (-1);
+		}
+		break;
+	case PF_INET:
+		switch (protocol) {
+		case IPPROTO_TCP:
+		case IPPROTO_UDP:
+			if (use_kvm)
+				NPCB_KVM(inet, protocol, list, kvm, nl);
+			else
+				NPCB_SCT(inet, protocol, list);
+			break;
+		/* All PF_INET */
+		case 0:
+			if (use_kvm) {
+				NPCB_KVM(inet, IPPROTO_TCP, list, kvm, nl);
+				NPCB_KVM(inet, IPPROTO_UDP, list, kvm, nl);
 			} else {
-				NLP_SCT(SOCK_STREAM, list);
-				NLP_SCT(SOCK_DGRAM, list);
+				NPCB_SCT(inet, IPPROTO_TCP, list);
+				NPCB_SCT(inet, IPPROTO_UDP, list);
 			}
 			break;
 		default:
@@ -216,8 +328,8 @@
 		list->stl_error = NETSTAT_ERROR_UNSUPPORTED;
 		return (-1);
 	}
-#undef NLP_KVM
-#undef NLP_SCT
+#undef NPCB_KVM
+#undef NPCB_SCT
 	return (0);
 }
 
@@ -230,12 +342,24 @@
 	stp->st_incqlen = xpcb->xu_socket.so_incqlen;
 	stp->st_qlimit = xpcb->xu_socket.so_qlimit;
 	stp->st_snd_cc = xpcb->xu_socket.so_snd.sb_cc;
+	stp->st_snd_mcnt = xpcb->xu_socket.so_snd.sb_mcnt;
+	stp->st_snd_ccnt = xpcb->xu_socket.so_snd.sb_ccnt;
+	stp->st_snd_hiwat = xpcb->xu_socket.so_snd.sb_hiwat;
+	stp->st_snd_lowat = xpcb->xu_socket.so_snd.sb_lowat;
+	stp->st_snd_mbcnt = xpcb->xu_socket.so_snd.sb_mbcnt;
+	stp->st_snd_mbmax = xpcb->xu_socket.so_snd.sb_mbmax;
 	stp->st_rcv_cc = xpcb->xu_socket.so_rcv.sb_cc;
-	stp->st_pcb = (long)xpcb->xu_socket.so_pcb;
-	stp->st_vnode = (long)xpcb->xu_unp.unp_vnode;
-	stp->st_conn = (long)xpcb->xu_unp.unp_conn;
-	stp->st_refs = (long)LIST_FIRST(&xpcb->xu_unp.unp_refs);
-	stp->st_reflink = (long)LIST_NEXT(&xpcb->xu_unp, unp_reflink);
+	stp->st_rcv_mcnt = xpcb->xu_socket.so_rcv.sb_mcnt;
+	stp->st_rcv_ccnt = xpcb->xu_socket.so_rcv.sb_ccnt;
+	stp->st_rcv_hiwat = xpcb->xu_socket.so_rcv.sb_hiwat;
+	stp->st_rcv_lowat = xpcb->xu_socket.so_rcv.sb_lowat;
+	stp->st_rcv_mbcnt = xpcb->xu_socket.so_rcv.sb_mbcnt;
+	stp->st_rcv_mbmax = xpcb->xu_socket.so_rcv.sb_mbmax;
+	stp->st_pcb = (u_long)xpcb->xu_socket.so_pcb;
+	stp->st_vnode = (u_long)xpcb->xu_unp.unp_vnode;
+	stp->st_conn = (u_long)xpcb->xu_unp.unp_conn;
+	stp->st_refs = (u_long)LIST_FIRST(&xpcb->xu_unp.unp_refs);
+	stp->st_reflink = (u_long)LIST_NEXT(&xpcb->xu_unp, unp_reflink);
 	stp->st_flags = SOCKTYPE_VNODE | SOCKTYPE_CONN | SOCKTYPE_REFS;
 	if (xpcb->xu_unp.unp_addr) {
 		sa = (struct sockaddr_un *)&xpcb->xu_addr;
@@ -245,4 +369,56 @@
 	} else {
 		stp->st_address[0] = '\0';
 	}
+	stp->st_listening = 0;
+	stp->st_tcpstate[0] = '\0';
+}
+
+void
+extract_inet_data(struct tcpcb *tp, struct inpcb *inp, struct xsocket *so,
+    struct socket_type *stp)
+{
+	stp->st_qlen = so->so_qlen;
+	stp->st_incqlen = so->so_incqlen;
+	stp->st_qlimit = so->so_qlimit;
+	stp->st_snd_cc = so->so_snd.sb_cc;
+	stp->st_snd_mcnt = so->so_snd.sb_mcnt;
+	stp->st_snd_ccnt = so->so_snd.sb_ccnt;
+	stp->st_snd_hiwat = so->so_snd.sb_hiwat;
+	stp->st_snd_lowat = so->so_snd.sb_lowat;
+	stp->st_snd_mbcnt = so->so_snd.sb_mbcnt;
+	stp->st_snd_mbmax = so->so_snd.sb_mbmax;
+	stp->st_rcv_cc = so->so_rcv.sb_cc;
+	stp->st_rcv_mcnt = so->so_rcv.sb_mcnt;
+	stp->st_rcv_ccnt = so->so_rcv.sb_ccnt;
+	stp->st_rcv_hiwat = so->so_rcv.sb_hiwat;
+	stp->st_rcv_lowat = so->so_rcv.sb_lowat;
+	stp->st_rcv_mbcnt = so->so_rcv.sb_mbcnt;
+	stp->st_rcv_mbmax = so->so_rcv.sb_mbmax;
+	stp->st_pcb = (tp == NULL) ? (u_long)inp->inp_ppcb :
+	    (u_long)so->so_pcb;
+	stp->st_vnode = (u_long)0;
+	stp->st_conn = (u_long)0;
+	stp->st_refs = (u_long)0;
+	stp->st_reflink = (u_long)0;
+	stp->st_flags = SOCKTYPE_TCP;
+	/* XXX: Remove this. */
+	if (tp != NULL)
+		stp->XXX_tcpcb = *tp;
+	stp->XXX_inpcb = *inp;
+	stp->XXX_xsocket = *so;
+	/* XXX: address is missing. */
+	stp->st_address[0] = '\0';
+	stp->st_listening = (tp->t_state == TCPS_LISTEN);
+	if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
+		sprintf(stp->st_tcpstate, "%d", tp->t_state);
+	else {
+		sprintf(stp->st_tcpstate, "%s", tcpstates[tp->t_state]);
+#if defined(TF_NEEDSYN) && defined(TF_NEEDFIN)
+		/* T/TCP `hidden state' */
+		if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) {
+			stp->st_tcpstate[0] = '*';
+			stp->st_tcpstate[1] = '\0';
+		}
+#endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
+	}
 }

==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#12 (text+ko) ====

@@ -56,17 +56,36 @@
 int		netstat_st_get_family(const struct socket_type *stp);
 int		netstat_st_get_protocol(const struct socket_type *stp);
 const char	*netstat_st_get_name(const struct socket_type *stp);
+/* XXX: move snd/rcv-related properties into a new abstract type? */
 u_int		netstat_st_get_snd_cc(const struct socket_type *stp);
+u_int		netstat_st_get_snd_hiwat(const struct socket_type *stp);
+u_int		netstat_st_get_snd_lowat(const struct socket_type *stp);
+u_int		netstat_st_get_snd_mbcnt(const struct socket_type *stp);
+u_int		netstat_st_get_snd_mcnt(const struct socket_type *stp);
+u_int		netstat_st_get_snd_ccnt(const struct socket_type *stp);
+u_int		netstat_st_get_snd_mbmax(const struct socket_type *stp);
 u_int		netstat_st_get_rcv_cc(const struct socket_type *stp);
+u_int		netstat_st_get_rcv_hiwat(const struct socket_type *stp);
+u_int		netstat_st_get_rcv_lowat(const struct socket_type *stp);
+u_int		netstat_st_get_rcv_mbcnt(const struct socket_type *stp);
+u_int		netstat_st_get_rcv_mcnt(const struct socket_type *stp);
+u_int		netstat_st_get_rcv_ccnt(const struct socket_type *stp);
+u_int		netstat_st_get_rcv_mbmax(const struct socket_type *stp);
 u_short		netstat_st_get_qlen(const struct socket_type *stp);
 u_short		netstat_st_get_incqlen(const struct socket_type *stp);
 u_short		netstat_st_get_qlimit(const struct socket_type *stp);
-long		netstat_st_get_pcb(const struct socket_type *stp);
-long		netstat_st_get_vnode(const struct socket_type *stp);
-long		netstat_st_get_conn(const struct socket_type *stp);
-long		netstat_st_get_refs(const struct socket_type *stp);
-long		netstat_st_get_reflink(const struct socket_type *stp);
+u_long		netstat_st_get_pcb(const struct socket_type *stp);
+u_long		netstat_st_get_vnode(const struct socket_type *stp);
+u_long		netstat_st_get_conn(const struct socket_type *stp);
+u_long		netstat_st_get_refs(const struct socket_type *stp);
+u_long		netstat_st_get_reflink(const struct socket_type *stp);
 const char	*netstat_st_get_address(const struct socket_type *stp);
+int		netstat_st_get_listening(const struct socket_type *stp);
+const char	*netstat_st_get_tcpstate(const struct socket_type *stp);
+/* XXX: Remove this hacks. */
+struct tcpcb	XXX_netstat_st_get_tcpcb(const struct socket_type *stp);
+struct inpcb	XXX_netstat_st_get_inpcb(const struct socket_type *stp);
+struct xsocket	XXX_netstat_st_get_xsocket(const struct socket_type *stp);
 __END_DECLS
 
 #endif /* !_NETSTAT_H_ */

==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#9 (text+ko) ====

@@ -9,6 +9,9 @@
 #include <sys/un.h>
 #include <sys/unpcb.h>
 #include <kvm.h>
+#include <netinet/in.h>
+#include <netinet/in_pcb.h>
+#include <netinet/tcp_var.h>
 
 /* XXX: not used yet */
 /* Address type:
@@ -34,17 +37,36 @@
 #endif
 
 	u_int		st_snd_cc;  /* actual chars in the send buffer */
+	u_int		st_snd_mcnt;
+	u_int		st_snd_ccnt;
+	u_int		st_snd_hiwat;
+	u_int		st_snd_lowat;
+	u_int		st_snd_mbcnt;
+	u_int		st_snd_mbmax;
 	u_int		st_rcv_cc;  /* actual chars in the receive buffer */
+	u_int		st_rcv_mcnt;
+	u_int		st_rcv_ccnt;
+	u_int		st_rcv_hiwat;
+	u_int		st_rcv_lowat;
+	u_int		st_rcv_mbcnt;
+	u_int		st_rcv_mbmax;
 	u_short		st_qlen;    /* number of unaccepted connections */
 	u_short		st_incqlen; /* number of unaccepted incomplete
 				       connections */
 	u_short		st_qlimit;  /* max number queued connections */
-	long		st_pcb;	    /* protocol control block */
-	long		st_vnode;   /* if associated with file */
-	long		st_conn;    /* control block of connected socket */
-	long		st_refs;    /* referencing socket linked list */
-	long		st_reflink; /* link in references list */
+	u_long		st_pcb;	    /* protocol control block */
+	u_long		st_vnode;   /* if associated with file */
+	u_long		st_conn;    /* control block of connected socket */
+	u_long		st_refs;    /* referencing socket linked list */
+	u_long		st_reflink; /* link in references list */
 	char		st_address[SOCKTYPE_MAXADDR];
+	char		st_tcpstate[16];
+	int		st_listening;
+
+	/* XXX: Removables. */
+	struct tcpcb	XXX_tcpcb;
+	struct inpcb	XXX_inpcb;
+	struct xsocket	XXX_xsocket;
 
 	/* list of types */
 	LIST_ENTRY(socket_type) st_list;
@@ -54,6 +76,7 @@
 #define	SOCKTYPE_VNODE		0x01	/* Associated with a file. */
 #define SOCKTYPE_CONN		0x02	/* Has a control block connected. */
 #define SOCKTYPE_REFS		0x04	/* Has socket references. */
+#define SOCKTYPE_TCP		0x08	/* A TCP socket, has states. */
 
 struct socket_type_list {
 	LIST_HEAD(, socket_type)    stl_list;

==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#11 (text+ko) ====

@@ -259,11 +259,83 @@
 }
 
 u_int
+netstat_st_get_rcv_hiwat(const struct socket_type *stp)
+{
+	return (stp->st_rcv_hiwat);
+}
+
+u_int
+netstat_st_get_rcv_lowat(const struct socket_type *stp)
+{
+	return (stp->st_rcv_lowat);
+}
+
+u_int
+netstat_st_get_rcv_mbcnt(const struct socket_type *stp)
+{
+	return (stp->st_rcv_mbcnt);
+}
+
+u_int
+netstat_st_get_rcv_mcnt(const struct socket_type *stp)
+{
+	return (stp->st_rcv_mcnt);
+}
+
+u_int
+netstat_st_get_rcv_ccnt(const struct socket_type *stp)
+{
+	return (stp->st_rcv_ccnt);
+}
+
+u_int
+netstat_st_get_rcv_mbmax(const struct socket_type *stp)
+{
+	return (stp->st_rcv_mbmax);
+}
+
+u_int
 netstat_st_get_snd_cc(const struct socket_type *stp)
 {
 	return (stp->st_snd_cc);
 }
 
+u_int
+netstat_st_get_snd_hiwat(const struct socket_type *stp)
+{
+	return (stp->st_snd_hiwat);
+}
+
+u_int
+netstat_st_get_snd_lowat(const struct socket_type *stp)
+{
+	return (stp->st_snd_lowat);
+}
+
+u_int
+netstat_st_get_snd_mbcnt(const struct socket_type *stp)
+{
+	return (stp->st_snd_mbcnt);
+}
+
+u_int
+netstat_st_get_snd_mcnt(const struct socket_type *stp)
+{
+	return (stp->st_snd_mcnt);
+}
+
+u_int
+netstat_st_get_snd_ccnt(const struct socket_type *stp)
+{
+	return (stp->st_snd_ccnt);
+}
+
+u_int
+netstat_st_get_snd_mbmax(const struct socket_type *stp)
+{
+	return (stp->st_snd_mbmax);
+}
+
 u_short
 netstat_st_get_qlen(const struct socket_type *stp)
 {
@@ -282,31 +354,31 @@
 	return (stp->st_qlimit);
 }
 
-long
+u_long
 netstat_st_get_pcb(const struct socket_type *stp)
 {
 	return (stp->st_pcb);
 }
 
-long
+u_long
 netstat_st_get_vnode(const struct socket_type *stp)
 {
 	return (stp->st_vnode);
 }
 
-long
+u_long
 netstat_st_get_conn(const struct socket_type *stp)
 {
 	return (stp->st_conn);
 }
 
-long
+u_long
 netstat_st_get_refs(const struct socket_type *stp)
 {
 	return (stp->st_refs); 
 }
 
-long
+u_long
 netstat_st_get_reflink(const struct socket_type *stp)
 {
 	return (stp->st_reflink);
@@ -317,3 +389,34 @@
 {
 	return (stp->st_address);
 }
+
+int
+netstat_st_get_listening(const struct socket_type *stp)
+{
+	return (stp->st_listening);
+}
+
+const char *
+netstat_st_get_tcpstate(const struct socket_type *stp)
+{
+	return (stp->st_tcpstate);
+}
+
+/* XXX: Remove this hacks. */
+struct tcpcb
+XXX_netstat_st_get_tcpcb(const struct socket_type *stp)
+{
+	return (stp->XXX_tcpcb);
+}
+
+struct inpcb 
+XXX_netstat_st_get_inpcb(const struct socket_type *stp)
+{
+	return (stp->XXX_inpcb);
+}
+
+struct xsocket
+XXX_netstat_st_get_xsocket(const struct socket_type *stp)
+{
+	return (stp->XXX_xsocket);
+}

==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/extern.h#2 (text+ko) ====

@@ -69,6 +69,7 @@
 
 int	sotoxsocket(struct socket *, struct xsocket *);
 void	protopr(u_long, const char *, int, int);
+void	inetpr(void *, int);
 void	tcp_stats(u_long, const char *, int, int);
 void	udp_stats(u_long, const char *, int, int);
 #ifdef SCTP

==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/inet.c#3 (text+ko) ====

@@ -83,13 +83,19 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+
+#include <kvm.h>
+#include <netstat.h>
 #include "extern.h"
 
+#define USE_ITERATOR_TYPE
+
 char	*inetname(struct in_addr *);
 void	inetprint(struct in_addr *, int, const char *, int);
 #ifdef INET6
 static int udp_done, tcp_done;
 #endif /* INET6 */
+static void inetppr(struct socket_type *);
 
 static int
 pcblist_sysctl(int proto, char **bufp, int istcp)
@@ -554,6 +560,225 @@
 	free(buf);
 }
 
+void
+inetpr(void *kvmd, int proto)
+{
+	struct socket_type_list *stlp;
+	int error, st_flags;
+	kvm_t *kvm;
+#ifdef USE_ITERATOR_TYPE
+	struct socket_type_iterator *stip;
+	struct socket_type	    *stp;
+#endif
+
+	kvm = (kvm_t *)kvmd;
+	stlp = netstat_stl_alloc();
+	if (stlp == NULL) {
+		warn("netstat_stl_alloc");
+		return;
+	}
+
+	st_flags = 0;
+	if (live)
+		st_flags |= NETSTAT_SOCKET_KVM;
+	
+	if (netstat_socket(PF_INET, 0, proto, stlp, st_flags, kvm) < 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;
+	}
+
+#ifdef USE_ITERATOR_TYPE
+	if (netstat_sti_alloc(stlp, &stip) < 0) {
+		warnx("netstat_sti_alloc");
+		return;
+	}
+	for (stp = netstat_sti_first(stip); stp != NULL;
+	    stp = netstat_sti_next(stip)) {
+		inetppr(stp);
+		netstat_st_free(stp);
+	}
+#else
+	netstat_stl_iterate(stlp, inetppr);
+#endif
+}
+
+void
+inetppr(struct socket_type *stp)
+{
+	static int first = 1;
+	char buf1[15];
+	const char *vchar;
+	struct tcpcb tp;
+	struct inpcb inp;
+	struct xsocket so;
+	int istcp;
+
+	istcp = 0;
+	inp = XXX_netstat_st_get_inpcb(stp);
+	so = XXX_netstat_st_get_xsocket(stp);
+	if (netstat_st_get_protocol(stp) == IPPROTO_TCP) {
+		tp = XXX_netstat_st_get_tcpcb(stp);
+		istcp = 1;
+	}
+/* XXX: af1 */
+#if 0
+	if ((af1 == AF_INET && (inp.inp_vflag & INP_IPV4) == 0)
+#ifdef INET6
+	    || (af1 == AF_INET6 && (inp.inp_vflag & INP_IPV6) == 0)
+#endif /* INET6 */
+	    || (af1 == AF_UNSPEC && ((inp.inp_vflag & INP_IPV4) == 0
+#ifdef INET6
+				&& (inp.inp_vflag & INP_IPV6) == 0
+#endif /* INET6 */
+		))
+	    )
+		continue;
+	if (!aflag &&
+	    (
+	     (istcp && netstat_st_get_listening(stp))
+	     || (af1 == AF_INET &&
+	      inet_lnaof(inp.inp_laddr) == INADDR_ANY)
+#ifdef INET6
+	     || (af1 == AF_INET6 &&
+		IN6_IS_ADDR_UNSPECIFIED(&inp.in6p_laddr))
+#endif /* INET6 */
+	     || (af1 == AF_UNSPEC &&
+		 (((inp.inp_vflag & INP_IPV4) != 0 &&
+		   inet_lnaof(inp.inp_laddr) == INADDR_ANY)
+#ifdef INET6
+		   || ((inp.inp_vflag & INP_IPV6) != 0 &&
+		       IN6_IS_ADDR_UNSPECIFIED(&inp.in6p_laddr))
+#endif
+		   ))
+	     ))
+		return;
+#endif
+	if (first) {
+		if (!Lflag) {
+			printf("Active Internet connections");
+			if (aflag)
+				printf(" (including servers)");
+		} else
+			printf(
+    "Current listen queue sizes (qlen/incqlen/maxqlen)");
+		putchar('\n');
+		if (Aflag)
+			printf("%-8.8s ", "Tcpcb");
+		if (Lflag)
+			printf("%-5.5s %-14.14s %-22.22s\n",
+			    "Proto", "Listen", "Local Address");
+		else {
+			printf((Aflag && !Wflag) ?
+			    "%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s" :
+			    "%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s",
+			    "Proto", "Recv-Q", "Send-Q",
+			    "Local Address", "Foreign Address");
+			if (xflag)
+				printf(
+    "%-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s\n",
+				    "R-MBUF", "S-MBUF", "R-CLUS",
+				    "S-CLUS", "R-HIWA", "S-HIWA",
+				    "R-LOWA", "S-LOWA", "R-BCNT",
+				    "S-BCNT", "R-BMAX", "S-BMAX");
+			else
+				printf("(state)\n");
+		}
+		first = 0;
+	}
+	if (Lflag && so.so_qlimit == 0)
+		return;
+	if (Aflag)
+		printf("%8lx ", netstat_st_get_pcb(stp));
+#ifdef INET6
+	if ((inp.inp_vflag & INP_IPV6) != 0)
+		vchar = ((inp.inp_vflag & INP_IPV4) != 0) ?
+		    "46" : "6 ";
+	else
+#endif
+	vchar = ((inp.inp_vflag & INP_IPV4) != 0) ?
+	    "4 " : "  ";
+	printf("%-3.3s%-2.2s", netstat_st_get_name(stp), vchar);
+	if (Lflag) {
+		snprintf(buf1, 15, "%d/%d/%d", netstat_st_get_qlen(stp),
+		    netstat_st_get_incqlen(stp), netstat_st_get_qlimit(stp));
+		printf("%-14.14s", buf1);
+	} else {
+		printf("%6u %6u", netstat_st_get_rcv_cc(stp),
+		    netstat_st_get_snd_cc(stp));
+	}
+	if (numeric_port) {
+		if (inp.inp_vflag & INP_IPV4) {
+			inetprint(&inp.inp_laddr, (int)inp.inp_lport,
+			    netstat_st_get_name(stp), 1);
+			if (!Lflag)
+				inetprint(&inp.inp_faddr,
+				    (int)inp.inp_fport,
+				    netstat_st_get_name(stp), 1);
+		}
+#ifdef INET6
+		else if (inp.inp_vflag & INP_IPV6) {
+			inet6print(&inp.in6p_laddr,
+			    (int)inp.inp_lport, netstat_st_get_name(stp), 1);
+			if (!Lflag)
+				inet6print(&inp.in6p_faddr,
+				    (int)inp.inp_fport,
+				    netstat_st_get_name(stp), 1);
+		} /* else nothing printed now */
+#endif /* INET6 */
+	} else if (inp.inp_flags & INP_ANONPORT) {
+		if (inp.inp_vflag & INP_IPV4) {
+			inetprint(&inp.inp_laddr, (int)inp.inp_lport,
+			    netstat_st_get_name(stp), 1);
+			if (!Lflag)
+				inetprint(&inp.inp_faddr,
+				    (int)inp.inp_fport,
+				    netstat_st_get_name(stp), 0);
+		}
+#ifdef INET6
+		else if (inp.inp_vflag & INP_IPV6) {
+			inet6print(&inp.in6p_laddr,
+			    (int)inp.inp_lport, netstat_st_get_name(stp), 1);
+			if (!Lflag)
+				inet6print(&inp.in6p_faddr,
+				    (int)inp.inp_fport,
+				    netstat_st_get_name(stp), 0);
+		} /* else nothing printed now */
+#endif /* INET6 */
+		else if (inp.inp_vflag & INP_IPV6) {
+			inet6print(&inp.in6p_laddr,
+			    (int)inp.inp_lport, netstat_st_get_name(stp), 0);
+			if (!Lflag)
+				inet6print(&inp.in6p_faddr,
+				    (int)inp.inp_fport,
+				    netstat_st_get_name(stp),
+				    inp.inp_lport != inp.inp_fport);
+		} /* else nothing printed now */
+	}
+	if (xflag) {
+		if (Lflag)
+			printf("%21s", " ");
+		printf("%6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u",
+		    netstat_st_get_rcv_mcnt(stp), netstat_st_get_snd_mcnt(stp),
+		    netstat_st_get_rcv_ccnt(stp), netstat_st_get_snd_ccnt(stp),
+		    netstat_st_get_rcv_hiwat(stp),
+		    netstat_st_get_snd_hiwat(stp),
+		    netstat_st_get_rcv_lowat(stp),
+		    netstat_st_get_snd_lowat(stp),
+		    netstat_st_get_rcv_mbcnt(stp),
+		    netstat_st_get_snd_mbcnt(stp),
+		    netstat_st_get_rcv_mbmax(stp),
+		    netstat_st_get_snd_mbmax(stp));
+	}
+	if (istcp && !Lflag) {
+		printf("%s", netstat_st_get_tcpstate(stp));
+	}
+	putchar('\n');
+}
+
 /*
  * Dump TCP statistics structure.
  */

==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#5 (text+ko) ====

@@ -652,8 +652,13 @@
 			off = nl[tp->pr_index].n_value;
 	}
 	if (pr != NULL && (off || (live && tp->pr_usesysctl) ||
-	    af != AF_UNSPEC))
-		(*pr)(off, name, af, tp->pr_protocol);
+	    af != AF_UNSPEC)) {
+		/* XXX: temp. hack */
+		if (tp->pr_index == N_TCBINFO)
+			inetpr(kvmd, IPPROTO_TCP);
+		else
+			(*pr)(off, name, af, tp->pr_protocol);
+	}
 }
 
 /*


More information about the p4-projects mailing list