Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 Sep 2007 01:11:36 +0200 (CEST)
From:      Jeremie Le Hen <jeremie@le-hen.org>
To:        FreeBSD-gnats-submit@FreeBSD.org
Cc:        Jeremie Le Hen <jeremie@le-hen.org>
Subject:   misc/116643: [patch] fstat: add INET/INET6 socket details as in NetBSD and OpenBSD
Message-ID:  <20070925231136.B6515405B@obiwan.tataz.chchile.org>
Resent-Message-ID: <200709252320.l8PNK1rd001751@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         116643
>Category:       misc
>Synopsis:       [patch] fstat: add INET/INET6 socket details as in NetBSD and OpenBSD
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Sep 25 23:20:01 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Jeremie Le Hen <jeremie@le-hen.org>
>Release:        FreeBSD 7.0-CURRENT i386
>Organization:
>Environment:
FreeBSD 7.0-CURRENT

>Description:
This patch adds socket details to AF_INET/AF_INET6 output of fstat.
Currently, we have an output like this:
    root     sshd         721    3* internet stream tcp c3f08e10
    tataz    ssh         1271    3* internet stream tcp c4611870
With this patch, we have:
    root     sshd         721    3* internet stream tcp c3f08e10 *:22
    tataz    ssh         1271    3* internet stream tcp c4611870 192.168.1.3:50995 <-> 192.168.1.2:22
>How-To-Repeat:
>Fix:
The patch below implements this behaviour.  It has been ported from
NetBSD and OpenBSD.  Note that due to lack of inet6 connectivity, I
couldn't test the AF_INET6 case.

--- fstat_inetsock_detail.diff begins here ---
Index: fstat.c
===================================================================
RCS file: /mnt/octobre/space/freebsd-cvs/src/usr.bin/fstat/fstat.c,v
retrieving revision 1.64
diff -u -p -r1.64 fstat.c
--- fstat.c	9 Mar 2007 16:21:40 -0000	1.64
+++ fstat.c	25 Sep 2007 23:04:31 -0000
@@ -86,6 +86,8 @@ __FBSDID("$FreeBSD: src/usr.bin/fstat/fs
 #include <netinet/ip.h>
 #include <netinet/in_pcb.h>
 
+#include <arpa/inet.h>
+
 #include <ctype.h>
 #include <err.h>
 #include <fcntl.h>
@@ -151,6 +153,7 @@ int  nfs_filestat(struct vnode *vp, stru
 int  devfs_filestat(struct vnode *vp, struct filestat *fsp);
 char *getmnton(struct mount *m);
 void pipetrans(struct pipe *pi, int i, int flag);
+const char *inet6_addrstr(struct in6_addr *);
 void socktrans(struct socket *sock, int i);
 void getinetproto(int number);
 int  getfname(const char *filename);
@@ -757,6 +760,31 @@ bad:
 	printf("* error\n");
 }
 
+const char *
+inet6_addrstr(struct in6_addr *p)
+{
+	struct sockaddr_in6 sin6;
+	static char hbuf[NI_MAXHOST];
+	const int niflags = NI_NUMERICHOST;
+
+	memset(&sin6, 0, sizeof(sin6));
+	sin6.sin6_family = AF_INET6;
+	sin6.sin6_len = sizeof(struct sockaddr_in6);
+	sin6.sin6_addr = *p;
+	if (IN6_IS_ADDR_LINKLOCAL(p) &&
+	    *(u_int16_t *)&sin6.sin6_addr.s6_addr[2] != 0) {
+		sin6.sin6_scope_id =
+		    ntohs(*(u_int16_t *)&sin6.sin6_addr.s6_addr[2]);
+		sin6.sin6_addr.s6_addr[2] = sin6.sin6_addr.s6_addr[3] = 0;
+	    }
+
+	    if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
+		hbuf, sizeof(hbuf), NULL, 0, niflags))
+		    return "invalid";
+
+	    return hbuf;
+}
+
 void
 socktrans(struct socket *sock, int i)
 {
@@ -776,6 +804,7 @@ socktrans(struct socket *sock, int i)
 	struct unpcb	unpcb;
 	int len;
 	char dname[32];
+	char xaddrbuf[NI_MAXHOST + 2];
 
 	PREFIX(i);
 
@@ -826,19 +855,68 @@ socktrans(struct socket *sock, int i)
 	 */
 	switch(dom.dom_family) {
 	case AF_INET:
+		getinetproto(proto.pr_protocol);
+		if (proto.pr_protocol == IPPROTO_TCP ||
+		    proto.pr_protocol == IPPROTO_UDP) {
+			if (so.so_pcb == NULL)
+				break;
+			if (kvm_read(kd, (u_long)so.so_pcb,
+			    (char *)&inpcb, sizeof(struct inpcb))
+			    != sizeof(struct inpcb)) {
+				dprintf(stderr,
+				    "can't read inpcb at %p\n",
+				    (void *)so.so_pcb);
+				goto bad;
+			}
+			if (proto.pr_protocol == IPPROTO_TCP)
+				printf(" %lx", (u_long)inpcb.inp_ppcb);
+			else
+				printf(" %lx", (u_long)so.so_pcb);
+			printf(" %s:%hu",
+			    inpcb.inp_laddr.s_addr == INADDR_ANY ? "*" :
+			    inet_ntoa(inpcb.inp_laddr),
+			    ntohs(inpcb.inp_lport));
+			if (inpcb.inp_fport) {
+				printf(" <-> %s:%hu",
+				    inpcb.inp_faddr.s_addr == INADDR_ANY ?
+				    "*" : inet_ntoa(inpcb.inp_faddr),
+				    ntohs(inpcb.inp_fport));
+			}
+		}
+		else if (so.so_pcb)
+			printf(" %lx", (u_long)so.so_pcb);
+		break;
 	case AF_INET6:
 		getinetproto(proto.pr_protocol);
-		if (proto.pr_protocol == IPPROTO_TCP ) {
-			if (so.so_pcb) {
-				if (kvm_read(kd, (u_long)so.so_pcb,
-				    (char *)&inpcb, sizeof(struct inpcb))
-				    != sizeof(struct inpcb)) {
-					dprintf(stderr,
-					    "can't read inpcb at %p\n",
-					    (void *)so.so_pcb);
-					goto bad;
-				}
+		if (proto.pr_protocol == IPPROTO_TCP ||
+		    proto.pr_protocol == IPPROTO_UDP) {
+			if (so.so_pcb == NULL)
+				break;
+			if (kvm_read(kd, (u_long)so.so_pcb,
+			    (char *)&inpcb, sizeof(struct inpcb))
+			    != sizeof(struct inpcb)) {
+				dprintf(stderr,
+				    "can't read inpcb at %p\n",
+				    (void *)so.so_pcb);
+				goto bad;
+			}
+			if (proto.pr_protocol == IPPROTO_TCP)
 				printf(" %lx", (u_long)inpcb.inp_ppcb);
+			else
+				printf(" %lx", (u_long)so.so_pcb);
+			snprintf(xaddrbuf, sizeof(xaddrbuf), "[%s]",
+			    inet6_addrstr(&inpcb.in6p_laddr));
+			printf(" %s:%hu",
+			    IN6_IS_ADDR_UNSPECIFIED(&inpcb.in6p_laddr) ?
+			    "*" : xaddrbuf,
+			    ntohs(inpcb.in6p_lport));
+			if (inpcb.in6p_fport) {
+				snprintf(xaddrbuf, sizeof(xaddrbuf),
+				    "[%s]", inet6_addrstr(&inpcb.in6p_faddr));
+				printf(" <-> %s:%hu",
+				    IN6_IS_ADDR_UNSPECIFIED(&inpcb.in6p_faddr)?
+				    "*" : xaddrbuf,
+				    ntohs(inpcb.in6p_fport));
 			}
 		}
 		else if (so.so_pcb)
--- fstat_inetsock_detail.diff ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:



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