summaryrefslogtreecommitdiffstats
path: root/usr.bin/sockstat
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2012-01-24 21:33:34 +0000
committerjilles <jilles@FreeBSD.org>2012-01-24 21:33:34 +0000
commita5b724067f61f946eb7f0a03ea81fd8b11dbd57d (patch)
tree3115e8a61ae111109e0fca902eef016ddd13e6d0 /usr.bin/sockstat
parentc44964e7d0b7676037c964221ecd6159e8da2ece (diff)
downloadFreeBSD-src-a5b724067f61f946eb7f0a03ea81fd8b11dbd57d.zip
FreeBSD-src-a5b724067f61f946eb7f0a03ea81fd8b11dbd57d.tar.gz
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
Diffstat (limited to 'usr.bin/sockstat')
-rw-r--r--usr.bin/sockstat/sockstat.126
-rw-r--r--usr.bin/sockstat/sockstat.c118
2 files changed, 75 insertions, 69 deletions
diff --git a/usr.bin/sockstat/sockstat.1 b/usr.bin/sockstat/sockstat.1
index 02cf568..f38d9d7 100644
--- a/usr.bin/sockstat/sockstat.1
+++ b/usr.bin/sockstat/sockstat.1
@@ -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 socket is bound to (see
.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 .
diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c
index 7235ba9..dff7761 100644
--- a/usr.bin/sockstat/sockstat.c
+++ b/usr.bin/sockstat/sockstat.c
@@ -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");
}
}
OpenPOWER on IntegriCloud