The following reply was made to PR bin/116643; it has been noted by GNATS.

From: Jeremie Le Hen <jere...@le-hen.org>
To: bug-follo...@freebsd.org
Cc: b...@freebsd.org, freebsd-net@FreeBSD.org, jere...@le-hen.org
Subject: Re: bin/116643: [patch] [request] fstat(1): add INET/INET6 socket
 details as in NetBSD and OpenBSD
Date: Wed, 5 May 2010 18:40:34 +0200

 --XOIedfhf+7KOe/yw
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 Hi,
 
 I've updated the patch so it compiles with -CURRENT.  Also the proposed
 behaviour is opt-in through the -i option.
 
 This PR has been waiting for two years and a half.  I propose that we
 try to find a consensus whether it is useful or not and then close it,
 no matter if it has been accepted or not.
 
 Regards,
 -- 
 Jeremie Le Hen
 
 Humans are born free and equal.  But some are more equal than others.
                                            Coluche
 
 --XOIedfhf+7KOe/yw
 Content-Type: text/x-diff; charset=us-ascii
 Content-Disposition: attachment; filename="fstat-i.diff"
 
 Index: fstat.1
 ===================================================================
 RCS file: /mnt/repos/freebsd-cvsroot/src/usr.bin/fstat/fstat.1,v
 retrieving revision 1.28
 diff -u -p -u -p -r1.28 fstat.1
 --- fstat.1    9 Jul 2009 16:40:00 -0000       1.28
 +++ fstat.1    5 May 2010 16:39:49 -0000
 @@ -40,7 +40,7 @@
  .Nd identify active files
  .Sh SYNOPSIS
  .Nm
 -.Op Fl fmnv
 +.Op Fl fimnv
  .Op Fl M Ar core
  .Op Fl N Ar system
  .Op Fl p Ar pid
 @@ -68,6 +68,8 @@ directory
  .Pa /usr/src
  resides, type
  .Dq Li fstat -f /usr/src .
 +.It Fl i
 +Print extended socket informations for internet sockets.
  .It Fl M
  Extract values associated with the name list from the specified core
  instead of the default
 @@ -213,6 +215,16 @@ connected unix domain stream socket.
  A unidirectional unix domain socket indicates the direction of flow with
  an arrow (``<-'' or ``->''), and a full duplex socket shows a double arrow
  (``<->'').
 +.Pp
 +For internet sockets,
 +the
 +.Fl i
 +flag will make
 +.Nm
 +mimic other BSDs behaviour that is attempt to print the internet address and
 +port for the local connection.
 +If a socket is connected it also prints the remote internet address and port.
 +An asterisk (``*'') is used to indicate an INADDR_ANY binding.
  .Sh SEE ALSO
  .Xr netstat 1 ,
  .Xr nfsstat 1 ,
 Index: fstat.c
 ===================================================================
 RCS file: /mnt/repos/freebsd-cvsroot/src/usr.bin/fstat/fstat.c,v
 retrieving revision 1.72
 diff -u -p -u -p -r1.72 fstat.c
 --- fstat.c    20 Aug 2009 10:57:14 -0000      1.72
 +++ fstat.c    5 May 2010 16:26:45 -0000
 @@ -87,6 +87,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>
 @@ -126,6 +128,7 @@ int        checkfile; /* true if restricting t
  int   nflg;   /* (numerical) display f.s. and rdev as dev_t */
  int   vflg;   /* display errors in locating kernel data objects etc... */
  int   mflg;   /* include memory-mapped files */
 +int   iflg;   /* display inet socket details */
  
  
  struct file **ofiles; /* buffer of pointers to file structures */
 @@ -153,6 +156,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 ptstrans(struct tty *tp, int i, int flag);
  void getinetproto(int number);
 @@ -169,11 +173,14 @@ main(int argc, char **argv)
        arg = 0;
        what = KERN_PROC_PROC;
        nlistf = memf = NULL;
 -      while ((ch = getopt(argc, argv, "fmnp:u:vN:M:")) != -1)
 +      while ((ch = getopt(argc, argv, "fimnp:u:vN:M:")) != -1)
                switch((char)ch) {
                case 'f':
                        fsflg = 1;
                        break;
 +              case 'i':
 +                      iflg = 1;
 +                      break;
                case 'M':
                        memf = optarg;
                        break;
 @@ -772,6 +779,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)
  {
 @@ -791,6 +823,7 @@ socktrans(struct socket *sock, int i)
        struct unpcb    unpcb;
        int len;
        char dname[32];
 +      char xaddrbuf[NI_MAXHOST + 2];
  
        PREFIX(i);
  
 @@ -841,19 +874,72 @@ 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);
 +                      if (!iflg)
 +                              break;
 +                      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);
 +                      if (!iflg)
 +                              break;
 +                      snprintf(xaddrbuf, sizeof(xaddrbuf), "[%s]",
 +                          inet6_addrstr(&inpcb.in6p_laddr));
 +                      printf(" %s:%hu",
 +                          IN6_IS_ADDR_UNSPECIFIED(&inpcb.in6p_laddr) ?
 +                          "*" : xaddrbuf,
 +                          ntohs(inpcb.inp_lport));
 +                      if (inpcb.inp_fport) {
 +                              snprintf(xaddrbuf, sizeof(xaddrbuf),
 +                                  "[%s]", inet6_addrstr(&inpcb.in6p_faddr));
 +                              printf(" <-> %s:%hu",
 +                                  IN6_IS_ADDR_UNSPECIFIED(&inpcb.in6p_faddr)?
 +                                  "*" : xaddrbuf,
 +                                  ntohs(inpcb.inp_fport));
                        }
                }
                else if (so.so_pcb)
 
 --XOIedfhf+7KOe/yw--
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to