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 d...@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");
        }
 }
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to