svn commit: r296882 - head/usr.bin/netstat

Gleb Smirnoff glebius at FreeBSD.org
Tue Mar 15 00:19:32 UTC 2016


Author: glebius
Date: Tue Mar 15 00:19:30 2016
New Revision: 296882
URL: https://svnweb.freebsd.org/changeset/base/296882

Log:
  Print running TCP connection counts with TCP statistics.

Modified:
  head/usr.bin/netstat/inet.c
  head/usr.bin/netstat/main.c
  head/usr.bin/netstat/netstat.h
  head/usr.bin/netstat/nlist_symbols

Modified: head/usr.bin/netstat/inet.c
==============================================================================
--- head/usr.bin/netstat/inet.c	Tue Mar 15 00:15:10 2016	(r296881)
+++ head/usr.bin/netstat/inet.c	Tue Mar 15 00:19:30 2016	(r296882)
@@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$");
 #include <unistd.h>
 #include <libxo/xo.h>
 #include "netstat.h"
+#include "nl_defs.h"
 
 char	*inetname(struct in_addr *);
 void	inetprint(const char *, struct in_addr *, int, const char *, int,
@@ -638,6 +639,7 @@ void
 tcp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
 {
 	struct tcpstat tcpstat;
+	uint64_t tcps_states[TCP_NSTATES];
 
 #ifdef INET6
 	if (tcp_done != 0)
@@ -650,6 +652,10 @@ tcp_stats(u_long off, const char *name, 
 	    sizeof(tcpstat), kread_counters) != 0)
 		return;
 
+	if (fetch_stats_ro("net.inet.tcp.states", nl[N_TCPS_STATES].n_value,
+	    &tcps_states, sizeof(tcps_states), kread_counters) != 0)
+		return;
+
 	xo_open_container("tcp");
 	xo_emit("{T:/%s}:\n", name);
 
@@ -853,6 +859,28 @@ tcp_stats(u_long off, const char *name, 
  #undef p2a
  #undef p3
 	xo_close_container("ecn");
+
+	xo_open_container("TCP connection count by state");
+	xo_emit("{T:/TCP connection count by state}:\n");
+	for (int i = 0; i < TCP_NSTATES; i++) {
+		/*
+		 * XXXGL: is there a way in libxo to use %s
+		 * in the "content string" of a format
+		 * string? I failed to do that, that's why
+		 * a temporary buffer is used to construct
+		 * format string for xo_emit().
+		 */
+		char fmtbuf[80];
+
+		if (sflag > 1 && tcps_states[i] == 0)
+			continue;
+		snprintf(fmtbuf, sizeof(fmtbuf), "\t{:%s/%%ju} "
+                    "{Np:/connection ,connections} in %s state\n",
+		    tcpstates[i], tcpstates[i]);
+		xo_emit(fmtbuf, (uintmax_t )tcps_states[i]);
+	}
+	xo_close_container("TCP connection count by state");
+
 	xo_close_container("tcp");
 }
 

Modified: head/usr.bin/netstat/main.c
==============================================================================
--- head/usr.bin/netstat/main.c	Tue Mar 15 00:15:10 2016	(r296881)
+++ head/usr.bin/netstat/main.c	Tue Mar 15 00:19:30 2016	(r296882)
@@ -551,15 +551,15 @@ main(int argc, char *argv[])
 	exit(0);
 }
 
-int
-fetch_stats(const char *sysctlname, u_long off, void *stats, size_t len,
-    int (*kreadfn)(u_long, void *, size_t))
+static int
+fetch_stats_internal(const char *sysctlname, u_long off, void *stats,
+    size_t len, kreadfn_t kreadfn, int zero)
 {
 	int error;
 
 	if (live) {
 		memset(stats, 0, len);
-		if (zflag)
+		if (zero)
 			error = sysctlbyname(sysctlname, NULL, NULL, stats,
 			    len);
 		else
@@ -574,6 +574,23 @@ fetch_stats(const char *sysctlname, u_lo
 	return (error);
 }
 
+int
+fetch_stats(const char *sysctlname, u_long off, void *stats,
+    size_t len, kreadfn_t kreadfn)
+{
+
+	return (fetch_stats_internal(sysctlname, off, stats, len, kreadfn,
+    zflag));
+}
+
+int
+fetch_stats_ro(const char *sysctlname, u_long off, void *stats,
+    size_t len, kreadfn_t kreadfn)
+{
+
+	return (fetch_stats_internal(sysctlname, off, stats, len, kreadfn, 0));
+}
+
 /*
  * Print out protocol statistics or control blocks (per sflag).
  * If the interface was not specifically requested, and the symbol

Modified: head/usr.bin/netstat/netstat.h
==============================================================================
--- head/usr.bin/netstat/netstat.h	Tue Mar 15 00:15:10 2016	(r296881)
+++ head/usr.bin/netstat/netstat.h	Tue Mar 15 00:19:30 2016	(r296882)
@@ -63,8 +63,10 @@ extern int	unit;	/* unit number for abov
 
 extern int	live;	/* true if we are examining a live system */
 
-int	fetch_stats(const char *sysctlname, u_long addr, void *stats,
-	    size_t len, int (*kreadfn)(u_long, void *, size_t));
+typedef	int kreadfn_t(u_long, void *, size_t);
+int	fetch_stats(const char *, u_long, void *, size_t, kreadfn_t);
+int	fetch_stats_ro(const char *, u_long, void *, size_t, kreadfn_t);
+
 int	kread(u_long addr, void *buf, size_t size);
 uint64_t kread_counter(u_long addr);
 int	kread_counters(u_long addr, void *buf, size_t size);

Modified: head/usr.bin/netstat/nlist_symbols
==============================================================================
--- head/usr.bin/netstat/nlist_symbols	Tue Mar 15 00:15:10 2016	(r296881)
+++ head/usr.bin/netstat/nlist_symbols	Tue Mar 15 00:19:30 2016	(r296882)
@@ -44,6 +44,7 @@ all	_sctpstat
 all	_sfstat
 all	_tcbinfo
 all	_tcpstat
+all	_tcps_states
 all	_udbinfo
 all	_udpstat
 all	_unp_count


More information about the svn-src-head mailing list