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>