Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Jan 2012 21:33:34 +0000 (UTC)
From:      Jilles Tjoelker <jilles@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r230512 - head/usr.bin/sockstat
Message-ID:  <201201242133.q0OLXYTx093359@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jilles
Date: Tue Jan 24 21:33:34 2012
New Revision: 230512
URL: http://svn.freebsd.org/changeset/base/230512

Log:
  sockstat: Also show sockets not associated with a file descriptor.
  
  Sockets not associated with a file descriptor include TCP TIME_WAIT states
  and sockets created via the socket(9) API such as from rpc.lockd and the NFS
  client.
  
  PR:		bin/164081
  MFC after:	2 weeks
  No objection:	des

Modified:
  head/usr.bin/sockstat/sockstat.1
  head/usr.bin/sockstat/sockstat.c

Modified: head/usr.bin/sockstat/sockstat.1
==============================================================================
--- head/usr.bin/sockstat/sockstat.1	Tue Jan 24 17:31:27 2012	(r230511)
+++ head/usr.bin/sockstat/sockstat.1	Tue Jan 24 21:33:34 2012	(r230512)
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd July 9, 2009
+.Dd January 24, 2012
 .Dt SOCKSTAT 1
 .Os
 .Sh NAME
@@ -137,19 +137,10 @@ The address the foreign end of the socke
 .Xr getpeername 2 ) .
 .El
 .Pp
-Note that TCP sockets in the
-.Dv AF_INET
-or
-.Dv AF_INET6
-domains that are not in one of the
-.Dv LISTEN , SYN_SENT ,
-or
-.Dv ESTABLISHED
-states may not be shown by
-.Nm ;
-use
-.Xr netstat 1
-to examine them instead.
+If a socket is associated with more than one file descriptor,
+it is shown multiple times.
+If a socket is not associated with any file descriptor,
+the first four columns have no meaning.
 .Sh SEE ALSO
 .Xr fstat 1 ,
 .Xr netstat 1 ,
@@ -167,10 +158,3 @@ The
 .Nm
 command and this manual page were written by
 .An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org .
-.Sh BUGS
-Unlike
-.Xr netstat 1 ,
-.Nm
-lists sockets by walking file descriptor tables and will not output
-the ones owned by the kernel, e.g. NLM sockets created by
-.Xr rpc.lockd 8 .

Modified: head/usr.bin/sockstat/sockstat.c
==============================================================================
--- head/usr.bin/sockstat/sockstat.c	Tue Jan 24 17:31:27 2012	(r230511)
+++ head/usr.bin/sockstat/sockstat.c	Tue Jan 24 21:33:34 2012	(r230512)
@@ -86,6 +86,7 @@ static int	*ports;
 struct sock {
 	void *socket;
 	void *pcb;
+	int shown;
 	int vflag;
 	int family;
 	int proto;
@@ -571,12 +572,67 @@ check_ports(struct sock *s)
 }
 
 static void
+displaysock(struct sock *s, int pos)
+{
+	void *p;
+	int hash;
+
+	while (pos < 29)
+		pos += xprintf(" ");
+	pos += xprintf("%s", s->protoname);
+	if (s->vflag & INP_IPV4)
+		pos += xprintf("4 ");
+	if (s->vflag & INP_IPV6)
+		pos += xprintf("6 ");
+	while (pos < 36)
+		pos += xprintf(" ");
+	switch (s->family) {
+	case AF_INET:
+	case AF_INET6:
+		pos += printaddr(s->family, &s->laddr);
+		if (s->family == AF_INET6 && pos >= 58)
+			pos += xprintf(" ");
+		while (pos < 58)
+			pos += xprintf(" ");
+		pos += printaddr(s->family, &s->faddr);
+		break;
+	case AF_UNIX:
+		/* server */
+		if (s->laddr.ss_len > 0) {
+			pos += printaddr(s->family, &s->laddr);
+			break;
+		}
+		/* client */
+		p = *(void **)&s->faddr;
+		if (p == NULL) {
+			pos += xprintf("(not connected)");
+			break;
+		}
+		pos += xprintf("-> ");
+		for (hash = 0; hash < HASHSIZE; ++hash) {
+			for (s = sockhash[hash]; s != NULL; s = s->next)
+				if (s->pcb == p)
+					break;
+			if (s != NULL)
+				break;
+		}
+		if (s == NULL || s->laddr.ss_len == 0)
+			pos += xprintf("??");
+		else
+			pos += printaddr(s->family, &s->laddr);
+		break;
+	default:
+		abort();
+	}
+	xprintf("\n");
+}
+
+static void
 display(void)
 {
 	struct passwd *pwd;
 	struct xfile *xf;
 	struct sock *s;
-	void *p;
 	int hash, n, pos;
 
 	printf("%-8s %-10s %-5s %-2s %-6s %-21s %-21s\n",
@@ -594,6 +650,7 @@ display(void)
 			continue;
 		if (!check_ports(s))
 			continue;
+		s->shown = 1;
 		pos = 0;
 		if ((pwd = getpwuid(xf->xf_uid)) == NULL)
 			pos += xprintf("%lu ", (u_long)xf->xf_uid);
@@ -608,54 +665,19 @@ display(void)
 		while (pos < 26)
 			pos += xprintf(" ");
 		pos += xprintf("%d ", xf->xf_fd);
-		while (pos < 29)
-			pos += xprintf(" ");
-		pos += xprintf("%s", s->protoname);
-		if (s->vflag & INP_IPV4)
-			pos += xprintf("4 ");
-		if (s->vflag & INP_IPV6)
-			pos += xprintf("6 ");
-		while (pos < 36)
-			pos += xprintf(" ");
-		switch (s->family) {
-		case AF_INET:
-		case AF_INET6:
-			pos += printaddr(s->family, &s->laddr);
-			if (s->family == AF_INET6 && pos >= 58)
-				pos += xprintf(" ");
-			while (pos < 58)
-				pos += xprintf(" ");
-			pos += printaddr(s->family, &s->faddr);
-			break;
-		case AF_UNIX:
-			/* server */
-			if (s->laddr.ss_len > 0) {
-				pos += printaddr(s->family, &s->laddr);
-				break;
-			}
-			/* client */
-			p = *(void **)&s->faddr;
-			if (p == NULL) {
-				pos += xprintf("(not connected)");
-				break;
-			}
-			pos += xprintf("-> ");
-			for (hash = 0; hash < HASHSIZE; ++hash) {
-				for (s = sockhash[hash]; s != NULL; s = s->next)
-					if (s->pcb == p)
-						break;
-				if (s != NULL)
-					break;
-			}
-			if (s == NULL || s->laddr.ss_len == 0)
-				pos += xprintf("??");
-			else
-				pos += printaddr(s->family, &s->laddr);
-			break;
-		default:
-			abort();
+		displaysock(s, pos);
+	}
+	for (hash = 0; hash < HASHSIZE; hash++) {
+		for (s = sockhash[hash]; s != NULL; s = s->next) {
+			if (s->shown)
+				continue;
+			if (!check_ports(s))
+				continue;
+			pos = 0;
+			pos += xprintf("%-8s %-10s %-5s %-2s ",
+			    "?", "?", "?", "?");
+			displaysock(s, pos);
 		}
-		xprintf("\n");
 	}
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201201242133.q0OLXYTx093359>