PERFORCE change 164178 for review

Gabor Pali pgj at FreeBSD.org
Fri Jun 12 14:55:37 UTC 2009


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

Change 164178 by pgj at petymeg-current on 2009/06/12 14:55:17

	libnetstat:
	netstat:

Affected files ...

.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#23 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/extern.h#5 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/inet.c#13 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#8 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/unix.c#12 edit

Differences ...

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

@@ -370,16 +370,124 @@
 
 #undef KREAD
 
+
+#define NPCB_KVM(proc, family, type, list, kvm, nl, flags) do {		    \
+	if (net_##proc##_pcblist_kvm((family), (type), (list), (kvm), (nl), \
+	    (flags)) != 0) {						    \
+		list->stl_error = NETSTAT_ERROR_UNDEFINED;		    \
+		return (-1);						    \
+	}								    \
+} while (0)
+
+#define NPCB_SCT(proc, family, type, list, flags) do {			    \
+	if (net_##proc##_pcblist_sysctl((family), (type), (list),	    \
+	    (flags)) != 0) {						    \
+		list->stl_error = NETSTAT_ERROR_UNDEFINED;		    \
+		return (-1);						    \
+	}								    \
+} while (0)
+
 int
+netstat_local_sockets(int type, struct socket_type_list *list, kvm_t *kvm,
+    struct nlist *nl, int flags)
+{
+	int use_kvm = flags & NETSTAT_SOCKET_KVM;
+
+	switch (type) {
+	case SOCK_STREAM:
+	case SOCK_DGRAM:
+		if (use_kvm)
+			NPCB_KVM(local, PF_LOCAL, type, list, kvm, nl,
+			    flags);
+		else
+			/* Use sysctl (or something else). */
+			NPCB_SCT(local, PF_LOCAL, type, list, flags);
+		break;
+	/* All PF_LOCAL */
+	case 0:
+		if (use_kvm) {
+			NPCB_KVM(local, PF_LOCAL, SOCK_STREAM, list, kvm,
+			    nl, flags);
+			NPCB_KVM(local, PF_LOCAL, SOCK_DGRAM, list, kvm,
+			    nl, flags);
+		} else {
+			NPCB_SCT(local, PF_LOCAL, SOCK_STREAM, list,
+			    flags);
+			NPCB_SCT(local, PF_LOCAL, SOCK_DGRAM, list,
+			    flags);
+		}
+		break;
+	default:
+		list->stl_error = NETSTAT_ERROR_UNSUPPORTED;
+		return (-1);
+	}
+	return (0);
+}
+
+int
+netstat_inet_sockets(int domain, int protocol, struct socket_type_list *list,
+    kvm_t *kvm, struct nlist *nl, int flags)
+{
+	int use_kvm = flags & NETSTAT_SOCKET_KVM;
+
+	switch (protocol) {
+	case IPPROTO_TCP:
+	case IPPROTO_UDP:
+	case IPPROTO_DIVERT:
+	case IPPROTO_RAW:
+	case IPPROTO_ICMP:
+	case IPPROTO_IGMP:
+	case IPPROTO_PIM:
+	case IPPROTO_ICMPV6:
+		if (use_kvm)
+			NPCB_KVM(inet, domain, protocol, list, kvm, nl,
+			    flags);
+		else
+			NPCB_SCT(inet, domain, protocol, list, flags);
+		break;
+	/* All PF_INET */
+	case 0:
+		/* Errors do not count here. */
+		if (use_kvm) {
+			net_inet_pcblist_kvm(domain, IPPROTO_TCP, list, kvm,
+			    nl, flags);
+			net_inet_pcblist_kvm(domain, IPPROTO_UDP, list, kvm,
+			    nl, flags);
+			net_inet_pcblist_kvm(domain, IPPROTO_DIVERT, list,
+			    kvm, nl, flags);
+			net_inet_pcblist_kvm(domain, IPPROTO_RAW, list, kvm,
+			    nl, flags);
+		} else {
+			net_inet_pcblist_sysctl(domain, IPPROTO_TCP, list,
+			    flags);
+			net_inet_pcblist_sysctl(domain, IPPROTO_UDP, list,
+			    flags);
+			net_inet_pcblist_sysctl(domain, IPPROTO_DIVERT, list,
+			    flags);
+			net_inet_pcblist_sysctl(domain, IPPROTO_RAW, list,
+			    flags);
+		}
+		break;
+	default:
+		list->stl_error = NETSTAT_ERROR_UNSUPPORTED;
+		return (-1);
+	}
+	return (0);
+}
+
+#undef NPCB_KVM
+#undef NPCB_SCT
+
+
+int
 netstat_socket(int domain, int type, int protocol,
     struct socket_type_list *list, int flags, void *kvm_handle)
 {
 	kvm_t	*kvm;
-	int	use_kvm;
+	int	result;
 	struct nlist *nlp = NULL;
 
-	use_kvm = flags & NETSTAT_SOCKET_KVM;
-	if (use_kvm) {
+	if (flags & NETSTAT_SOCKET_KVM) {
 		/* Use KVM to retrieve data. */
 		switch (domain) {
 		case PF_LOCAL:
@@ -398,104 +506,37 @@
 			return (-1);
 		}
 	}
-
-#define NPCB_KVM(proc, family, type, list, kvm, nl, flags) do {		    \
-	if (net_##proc##_pcblist_kvm((family), (type), (list), (kvm), (nl), \
-	    (flags)) != 0) {						    \
-		list->stl_error = NETSTAT_ERROR_UNDEFINED;		    \
-		return (-1);						    \
-	}								    \
-} while (0)
-
-#define NPCB_SCT(proc, family, type, list, flags) do {			    \
-	if (net_##proc##_pcblist_sysctl((family), (type), (list),	    \
-	    (flags)) != 0) {						    \
-		list->stl_error = NETSTAT_ERROR_UNDEFINED;		    \
-		return (-1);						    \
-	}								    \
-} while (0)
-
 	switch (domain) {
+	case PF_UNSPEC:
+		/* "Everything" */
+		result = netstat_local_sockets(0, list, kvm, nl, flags);
+		if (result < 0)
+			return (result);
+#if 1
+		result = netstat_inet_sockets(PF_INET, 0, list, kvm, nl,
+		    flags);
+		if (result < 0)
+			return (result);
+#endif
+#if 0
+		result = netstat_inet_sockets(PF_INET6, 0, list, kvm, nl,
+		    flags);
+		if (result < 0)
+			return (result);
+#endif
+		break;
 	case PF_LOCAL:
-		switch (type) {
-		case SOCK_STREAM:
-		case SOCK_DGRAM:
-			if (use_kvm)
-				NPCB_KVM(local, domain, type, list, kvm, nl,
-				    flags);
-			else
-				/* Use sysctl (or something else). */
-				NPCB_SCT(local, domain, type, list, flags);
-			break;
-		/* All PF_LOCAL */
-		case 0:
-			if (use_kvm) {
-				NPCB_KVM(local, domain, SOCK_STREAM, list, kvm,
-				    nl, flags);
-				NPCB_KVM(local, domain, SOCK_DGRAM, list, kvm,
-				    nl, flags);
-			} else {
-				NPCB_SCT(local, domain, SOCK_STREAM, list,
-				    flags);
-				NPCB_SCT(local, domain, SOCK_DGRAM, list,
-				    flags);
-			}
-			break;
-		default:
-			list->stl_error = NETSTAT_ERROR_UNSUPPORTED;
-			return (-1);
-		}
+		return (netstat_local_sockets(type, list, kvm, nl, flags));
 		break;
 	case PF_INET:
 	case PF_INET6:
-		switch (protocol) {
-		case IPPROTO_TCP:
-		case IPPROTO_UDP:
-		case IPPROTO_DIVERT:
-		case IPPROTO_RAW:
-		case IPPROTO_ICMP:
-		case IPPROTO_IGMP:
-		case IPPROTO_PIM:
-		case IPPROTO_ICMPV6:
-			if (use_kvm)
-				NPCB_KVM(inet, domain, protocol, list, kvm, nl,
-				    flags);
-			else
-				NPCB_SCT(inet, domain, protocol, list, flags);
-			break;
-		/* All PF_INET */
-		case 0:
-			if (use_kvm) {
-				NPCB_KVM(inet, domain, IPPROTO_TCP, list, kvm,
-				    nl, flags);
-				NPCB_KVM(inet, domain, IPPROTO_UDP, list, kvm,
-				    nl, flags);
-				NPCB_KVM(inet, domain, IPPROTO_DIVERT, list,
-				    kvm, nl, flags);
-				NPCB_KVM(inet, domain, IPPROTO_RAW, list, kvm,
-				    nl, flags);
-			} else {
-				NPCB_SCT(inet, domain, IPPROTO_TCP, list,
-				    flags);
-				NPCB_SCT(inet, domain, IPPROTO_UDP, list,
-				    flags);
-				NPCB_SCT(inet, domain, IPPROTO_DIVERT, list,
-				    flags);
-				NPCB_SCT(inet, domain, IPPROTO_RAW, list,
-				    flags);
-			}
-			break;
-		default:
-			list->stl_error = NETSTAT_ERROR_UNSUPPORTED;
-			return (-1);
-		}
+		return (netstat_inet_sockets(domain, protocol, list, kvm, nl,
+		    flags));
 		break;
 	default:
 		list->stl_error = NETSTAT_ERROR_UNSUPPORTED;
 		return (-1);
 	}
-#undef NPCB_KVM
-#undef NPCB_SCT
 	return (0);
 }
 
@@ -568,22 +609,28 @@
 	stp->st_conn = (u_long)0;
 	stp->st_refs = (u_long)0;
 	stp->st_reflink = (u_long)0;
-	stp->st_flags = SOCKTYPE_TCP;
+	stp->st_flags = 0;
 	/* XXX: Remove this. */
 	stp->XXX_inpcb = *inp;
 	/* XXX: address is missing. */
 	stp->st_address[0] = '\0';
-	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 (tp != NULL) {
+		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';
+			/* 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) */
 		}
-#endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
+		stp->st_flags |= SOCKTYPE_TCP;
+	} else {
+		/* Has no TCP state. */
+		stp->st_tcpstate[0] = '\0';
 	}
 #ifdef INET6
 	if ((inp->inp_vflag & INP_IPV6) != 0)

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

@@ -35,6 +35,7 @@
  */
 
 #include <sys/cdefs.h>
+#include <netstat.h>
 
 extern int	Aflag;	/* show addresses of protocol control block */
 extern int	aflag;	/* show all sockets (including servers) */
@@ -69,6 +70,8 @@
 
 int	sotoxsocket(struct socket *, struct xsocket *);
 void	inetpr(void *, int, int);
+void	inetppr(struct socket_type *);
+void	unixdomainpr(struct socket_type *);
 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#13 (text+ko) ====

@@ -95,7 +95,6 @@
 #ifdef INET6
 static int udp_done, tcp_done;
 #endif /* INET6 */
-static void inetppr(struct socket_type *);
 
 /*
  * Print a summary of connections related to an Internet
@@ -146,6 +145,8 @@
 		inetppr(stp);
 		netstat_st_free(stp);
 	}
+	netstat_sti_free(stip);
+	netstat_stl_free(stlp);
 #else
 	netstat_stl_iterate(stlp, inetppr);
 #endif

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

@@ -73,6 +73,9 @@
 #include <unistd.h>
 #include "extern.h"
 
+#include <netstat.h>
+
+
 static struct nlist nl[] = {
 #define	N_IFNET		0
 	{ .n_name = "_ifnet" },
@@ -294,6 +297,7 @@
 #endif
 					 atalkprotox, NULL };
 
+static void connpr(struct socket_type *);
 static void printproto(struct protox *, const char *);
 static void usage(void);
 static struct protox *name2protox(const char *);
@@ -336,6 +340,11 @@
 	struct protox *tp = NULL;  /* for printing cblocks & stats */
 	int ch;
 
+	struct socket_type_list *stlp;
+	int error, st_flags;
+	struct socket_type_iterator *stip;
+	struct socket_type	    *stp;
+
 	af = AF_UNSPEC;
 
 	while ((ch = getopt(argc, argv, "AaBbdf:ghI:iLlM:mN:np:rSstuWw:xz")) != -1)
@@ -552,11 +561,11 @@
 		printproto(tp, tp->pr_name);
 		exit(0);
 	}
-	if (af == AF_INET || af == AF_UNSPEC)
+	if (af == AF_INET)
 		for (tp = protox; tp->pr_name; tp++)
 			printproto(tp, tp->pr_name);
 #ifdef INET6
-	if (af == AF_INET6 || af == AF_UNSPEC)
+	if (af == AF_INET6)
 		for (tp = ip6protox; tp->pr_name; tp++)
 			printproto(tp, tp->pr_name);
 #endif /*INET6*/
@@ -579,11 +588,64 @@
 		for (tp = netgraphprotox; tp->pr_name; tp++)
 			printproto(tp, tp->pr_name);
 #endif /* NETGRAPH */
-	if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)
+	if (af == AF_UNIX && !sflag)
 		unixpr(kvmd);
+	if (af == AF_UNSPEC) {
+		stlp = netstat_stl_alloc();
+		if (stlp == NULL) {
+			warn("netstat_stl_alloc");
+			exit(-1);
+		}
+		st_flags = 0;
+		if (!live)
+			st_flags |= NETSTAT_SOCKET_KVM;
+		if (aflag)
+			st_flags |= NETSTAT_SOCKET_ALL;
+		/* 
+		 * There should be guaranteed that sockets are not mixed (i.e.
+		 * they are coming ordered by family/protocol).
+		 */
+		if (netstat_socket(PF_UNSPEC, 0, 0, stlp, st_flags,
+		    kvmd) < 0) {
+			error = netstat_stl_geterror(stlp);
+			if (error == NETSTAT_ERROR_KVM)
+				warnx("netstat_socket: %s", kvm_geterr(kvmd));
+			else
+				warnx("netstat_socket: %s",
+				    netstat_strerror(error));
+			exit(-1);
+		}
+		if (netstat_sti_alloc(stlp, &stip) < 0) {
+			warnx("netstat_sti_alloc");
+			exit(-1);
+		}
+		for (stp = netstat_sti_first(stip); stp != NULL;
+		    stp = netstat_sti_next(stip)) {
+			connpr(stp);
+			netstat_st_free(stp);
+		}
+		netstat_sti_free(stip);
+		netstat_stl_free(stlp);
+	}
 	exit(0);
 }
 
+static void
+connpr(struct socket_type *stp)
+{
+	switch (netstat_st_get_family(stp)) {
+	case PF_INET:
+	case PF_INET6:
+		inetppr(stp);
+		break;
+	case PF_LOCAL:
+		unixdomainpr(stp);
+		break;
+	default:
+		break;
+	}
+}
+
 /*
  * Print out protocol statistics or control blocks (per sflag).
  * If the interface was not specifically requested, and the symbol
@@ -650,7 +712,8 @@
 		case IPPROTO_IGMP:
 		case IPPROTO_PIM:
 		case IPPROTO_ICMPV6:
-			inetpr(kvmd, af, tp->pr_protocol);
+			inetpr(kvmd, (af == PF_INET6) ? af : PF_INET,
+			    tp->pr_protocol);
 			break;
 		default:
 			if (pr != NULL)

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

@@ -55,8 +55,6 @@
 
 #define USE_ITERATOR_TYPE
 
-static	void unixdomainpr(struct socket_type *);
-
 void
 unixpr(void *kvmd)
 {
@@ -105,12 +103,14 @@
 		unixdomainpr(stp);
 		netstat_st_free(stp);
 	}
+	netstat_sti_free(stip);
+	netstat_stl_free(stlp);
 #else
 	netstat_stl_iterate(stlp, unixdomainpr);
 #endif
 }
 
-static void
+void
 unixdomainpr(struct socket_type *stp)
 {
 	static int first = 1;


More information about the p4-projects mailing list