[BACK]Return to inet.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / netstat

Diff for /src/usr.bin/netstat/inet.c between version 1.139 and 1.140

version 1.139, 2015/02/08 04:40:50 version 1.140, 2015/02/12 01:49:02
Line 36 
Line 36 
 #include <sys/domain.h>  #include <sys/domain.h>
 #include <sys/protosw.h>  #include <sys/protosw.h>
 #include <sys/sysctl.h>  #include <sys/sysctl.h>
   #define _KERNEL
   #include <sys/ucred.h>
   #include <sys/file.h>
   #undef _KERNEL
   
 #include <net/route.h>  #include <net/route.h>
 #include <netinet/in.h>  #include <netinet/in.h>
Line 87 
Line 91 
 struct  socket sockb;  struct  socket sockb;
   
 char    *inetname(struct in_addr *);  char    *inetname(struct in_addr *);
 void    inetprint(struct in_addr *, in_port_t, char *, int);  void    inetprint(struct in_addr *, in_port_t, const char *, int);
 char    *inet6name(struct in6_addr *);  char    *inet6name(struct in6_addr *);
 void    inet6print(struct in6_addr *, int, char *);  
 void    sosplice_dump(u_long);  void    sosplice_dump(u_long);
 void    sockbuf_dump(struct sockbuf *, const char *);  void    sockbuf_dump(struct sockbuf *, const char *);
 void    protosw_dump(u_long, u_long);  void    protosw_dump(u_long, u_long);
Line 97 
Line 100 
 void    inpcb_dump(u_long, short, int);  void    inpcb_dump(u_long, short, int);
 void    tcpcb_dump(u_long);  void    tcpcb_dump(u_long);
   
   int type_map[] = { -1, 2, 3, 1, 4, 5 };
   
   int
   kf_comp(const void *a, const void *b)
   {
           const struct kinfo_file *ka = a, *kb = b;
   
           if (ka->so_family != kb->so_family) {
                   /* AF_INET < AF_INET6 < AF_LOCAL */
                   if (ka->so_family == AF_INET)
                           return (-1);
                   if (ka->so_family == AF_LOCAL)
                           return (1);
                   if (kb->so_family == AF_LOCAL)
                           return (-1);
                   return (1);
           }
           if (ka->so_family == AF_LOCAL) {
                   if (type_map[ka->so_type] < type_map[kb->so_type])
                           return (-1);
                   if (type_map[ka->so_type] > type_map[kb->so_type])
                           return (1);
           } else if (ka->so_family == AF_INET || ka->so_family == AF_INET6) {
                   if (ka->so_protocol < kb->so_protocol)
                           return (-1);
                   if (ka->so_protocol > kb->so_protocol)
                           return (1);
                   if (ka->so_type == SOCK_DGRAM || ka->so_type == SOCK_STREAM) {
                           /* order sockets by remote port desc */
                           if (ka->inp_fport > kb->inp_fport)
                                   return (-1);
                           if (ka->inp_fport < kb->inp_fport)
                                   return (1);
                   } else if (ka->so_type == SOCK_RAW) {
                           if (ka->inp_proto > kb->inp_proto)
                                   return (-1);
                           if (ka->inp_proto < kb->inp_proto)
                                   return (1);
                   }
           }
           return (0);
   }
   
   void
   protopr(kvm_t *kvmd, u_long pcbaddr, u_int tableid, int proto)
   {
           struct kinfo_file *kf;
           int i, fcnt;
   
           kf = kvm_getfiles(kvmd, KERN_FILE_BYFILE, DTYPE_SOCKET,
               sizeof(*kf), &fcnt);
           if (kf == NULL) {
                   printf("Out of memory (file table).\n");
                   return;
           }
   
           /* sort sockets by AF and type */
           qsort(kf, fcnt, sizeof(*kf), kf_comp);
   
           for (i = 0; i < fcnt; i++) {
                   if (Pflag) {
                           switch (kf[i].so_family) {
                           case AF_INET:
                           case AF_INET6:
                                   /*
                                    * XXX at the moment fstat returns the pointer
                                    * to the so_pcb or for tcp sockets the tcpcb
                                    * pointer (inp_ppcb) so check both.
                                    */
                                   if (pcbaddr == kf[i].so_pcb) {
                                           inpcb_dump(pcbaddr, kf[i].so_protocol,
                                               kf[i].so_family);
                                           return;
                                   } else if (pcbaddr == kf[i].inp_ppcb &&
                                       kf[i].so_protocol == IPPROTO_TCP) {
                                           tcpcb_dump(pcbaddr);
                                           return;
                                   }
                                   break;
                           case AF_UNIX:
                                   if (pcbaddr == kf[i].so_pcb) {
                                           unpcb_dump(pcbaddr);
                                           return;
                                   }
                                   break;
                           }
                           continue;
                   }
                   if (kf[i].so_family == AF_LOCAL && (kf[i].so_pcb != 0 ||
                       kf[i].unp_path[0] != '\0'))
                           if ((af == AF_LOCAL || af == AF_UNSPEC) && !proto)
                                   unixdomainpr(&kf[i]);
                   if (kf[i].so_family == AF_INET && kf[i].so_pcb != 0 &&
                       kf[i].inp_rtableid == tableid)
                           if (af == AF_INET || af == AF_UNSPEC)
                                   netdomainpr(&kf[i], proto);
                   if (kf[i].so_family == AF_INET6 && kf[i].so_pcb != 0 &&
                       kf[i].inp_rtableid == tableid)
                           if (af == AF_INET6 || af == AF_UNSPEC)
                                   netdomainpr(&kf[i], proto);
           }
   }
   
 /*  /*
  * Print a summary of connections related to an Internet   * Print a summary of connections related to an Internet
  * protocol.  For TCP, also give state of connection.   * protocol.  For TCP, also give state of connection.
Line 104 
Line 210 
  * -a (all) flag is specified.   * -a (all) flag is specified.
  */   */
 void  void
 protopr(u_long off, char *name, int af, u_int tableid, u_long pcbaddr)  netdomainpr(struct kinfo_file *kf, int proto)
 {  {
         struct inpcbtable table;          static int af = 0, type = 0;
         struct inpcb *prev, *next;          struct in_addr laddr, faddr;
         struct inpcb inpcb, prevpcb;          struct in6_addr laddr6, faddr6;
         int istcp, israw, isany;          const char *name, *name6;
         int addrlen = 22;          int addrlen = 22;
         int first = 1;          int isany = 0;
         char *name0;          int istcp = 0;
         char namebuf[20];          int isip6 = 0;
   
         name0 = name;          /* XXX should fix kinfo_file instead but not now */
         if (off == 0)          if (kf->so_pcb == -1)
                 return;                  kf->so_pcb = 0;
         istcp = strcmp(name, "tcp") == 0;  
         israw = strncmp(name, "ip", 2) == 0;  
         kread(off, &table, sizeof table);  
         prev = NULL;  
         next = TAILQ_FIRST(&table.inpt_queue);  
   
         while (next != NULL) {          switch (proto) {
                 kread((u_long)next, &inpcb, sizeof inpcb);          case IPPROTO_TCP:
                 if (prev != NULL) {          case IPPROTO_UDP:
                         kread((u_long)prev, &prevpcb, sizeof prevpcb);          case IPPROTO_DIVERT:
                         if (TAILQ_NEXT(&prevpcb, inp_queue) != next) {                  if (kf->so_protocol != proto)
                                 printf("PCB list changed\n");                          return;
                                 break;                  break;
                         }          case IPPROTO_IPV4:
                 }                  if (kf->so_type != SOCK_RAW || kf->so_family != AF_INET)
                 prev = next;                          return;
                 next = TAILQ_NEXT(&inpcb, inp_queue);                  break;
           case IPPROTO_IPV6:
                   if (kf->so_type != SOCK_RAW || kf->so_family != AF_INET6)
                           return;
                   break;
           }
   
                 switch (af) {          /* make in_addr6 access a bit easier */
                 case AF_INET:  #define s6_addr32 __u6_addr.__u6_addr32
                         if ((inpcb.inp_flags & INP_IPV6) != 0)          laddr.s_addr = kf->inp_laddru[0];
                                 continue;          laddr6.s6_addr32[0] = kf->inp_laddru[0];
                         isany = inet_lnaof(inpcb.inp_faddr) == INADDR_ANY;          laddr6.s6_addr32[1] = kf->inp_laddru[1];
                         break;          laddr6.s6_addr32[2] = kf->inp_laddru[2];
                 case AF_INET6:          laddr6.s6_addr32[3] = kf->inp_laddru[3];
                         if ((inpcb.inp_flags & INP_IPV6) == 0)  
                                 continue;  
                         isany = IN6_IS_ADDR_UNSPECIFIED(&inpcb.inp_faddr6);  
                         break;  
                 default:  
                         isany = 0;  
                         break;  
                 }  
   
                 if (Pflag) {          faddr.s_addr = kf->inp_faddru[0];
                         if (istcp && pcbaddr == (u_long)inpcb.inp_ppcb) {          faddr6.s6_addr32[0] = kf->inp_faddru[0];
                                 if (vflag)          faddr6.s6_addr32[1] = kf->inp_faddru[1];
                                         socket_dump((u_long)inpcb.inp_socket);          faddr6.s6_addr32[2] = kf->inp_faddru[2];
                                 else          faddr6.s6_addr32[3] = kf->inp_faddru[3];
                                         tcpcb_dump(pcbaddr);  #undef s6_addr32
                         } else if (pcbaddr == (u_long)prev) {  
                                 if (vflag)  
                                         socket_dump((u_long)inpcb.inp_socket);  
                                 else  
                                         inpcb_dump(pcbaddr, 0, af);  
                         }  
                         continue;  
                 }  
   
                 if (inpcb.inp_rtableid != tableid)          switch (kf->so_family) {
                         continue;          case AF_INET:
                   isany = faddr.s_addr == INADDR_ANY;
                   break;
           case AF_INET6:
                   isany = IN6_IS_ADDR_UNSPECIFIED(&faddr6);
                   isip6 = 1;
                   break;
           }
   
                 kread((u_long)inpcb.inp_socket, &sockb, sizeof (sockb));          switch (kf->so_protocol) {
                 if (istcp) {          case IPPROTO_TCP:
                         kread((u_long)inpcb.inp_ppcb, &tcpcb, sizeof (tcpcb));                  name = "tcp";
                         if (!aflag && tcpcb.t_state <= TCPS_LISTEN)                  name6 = "tcp6";
                                 continue;                  istcp = 1;
                 } else if (!aflag && isany)                  break;
                         continue;          case IPPROTO_UDP:
                 if (first) {                  name = "udp";
                         printf("Active Internet connections");                  name6 = "udp6";
                         if (aflag)                  break;
                                 printf(" (including servers)");          case IPPROTO_DIVERT:
                         putchar('\n');                  name = "divert";
                         if (Aflag) {                  name6 = "divert6";
                                 addrlen = 18;                  break;
                                 printf("%-*.*s ", PLEN, PLEN, "PCB");          default:
                         }                  name = "ip";
                         printf("%-7.7s %-6.6s %-6.6s ",                  name6 = "ip6";
                             "Proto", "Recv-Q", "Send-Q");                  break;
                         if (Bflag && istcp)          }
                                 printf("%-6.6s %-6.6s %-6.6s ",  
                                     "Recv-W", "Send-W", "Cgst-W");          /* filter listening sockets out unless -a is set */
                         printf(" %-*.*s %-*.*s %s\n",          if (!aflag && istcp && kf->t_state <= TCPS_LISTEN)
                             addrlen, addrlen, "Local Address",                  return;
                             addrlen, addrlen, "Foreign Address", "(state)");          else if (!aflag && isany)
                         first = 0;                  return;
                 }  
           if (af != kf->so_family || type != kf->so_type) {
                   af = kf->so_family;
                   type = kf->so_type;
                   printf("Active Internet connections");
                   if (aflag)
                           printf(" (including servers)");
                   putchar('\n');
                 if (Aflag) {                  if (Aflag) {
                         if (istcp)                          addrlen = 18;
                                 printf("%*p ", PLEN, hideroot ? 0 : inpcb.inp_ppcb);                          printf("%-*.*s ", PLEN, PLEN, "PCB");
                         else  
                                 printf("%*p ", PLEN, hideroot ? 0 : prev);  
                 }                  }
                 if (inpcb.inp_flags & INP_IPV6 && !israw) {                  printf("%-7.7s %-6.6s %-6.6s ",
                         strlcpy(namebuf, name0, sizeof namebuf);                      "Proto", "Recv-Q", "Send-Q");
                         strlcat(namebuf, "6", sizeof namebuf);  
                         name = namebuf;  
                 } else  
                         name = name0;  
                 printf("%-7.7s %6lu %6lu ",  
                     name, sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc);  
                 if (Bflag && istcp)                  if (Bflag && istcp)
                         printf("%6lu %6lu %6lu ", tcpcb.rcv_wnd, tcpcb.snd_wnd,                          printf("%-6.6s %-6.6s %-6.6s ",
                             (tcpcb.t_state == TCPS_ESTABLISHED) ?                              "Recv-W", "Send-W", "Cgst-W");
                             tcpcb.snd_cwnd : 0);                  printf(" %-*.*s %-*.*s %s\n",
                       addrlen, addrlen, "Local Address",
                       addrlen, addrlen, "Foreign Address", "(state)");
           }
   
                 if (inpcb.inp_flags & INP_IPV6) {          if (Aflag)
                         inet6print(&inpcb.inp_laddr6, (int)inpcb.inp_lport,                  printf("%#*llx%s ", FAKE_PTR(kf->so_pcb));
                             name);  
                         inet6print(&inpcb.inp_faddr6, (int)inpcb.inp_fport,  
                             name);  
                 } else {  
                         inetprint(&inpcb.inp_laddr, (int)inpcb.inp_lport,  
                             name, 1);  
                         inetprint(&inpcb.inp_faddr, (int)inpcb.inp_fport,  
                             name, 0);  
                 }  
                 if (istcp) {  
                         if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)  
                                 printf(" %d", tcpcb.t_state);  
                         else  
                                 printf(" %s", tcpstates[tcpcb.t_state]);  
                 } else if (israw) {  
                         u_int8_t proto;  
   
                         if (inpcb.inp_flags & INP_IPV6)          printf("%-7.7s %6llu %6llu ",
                                 proto = inpcb.inp_ipv6.ip6_nxt;              isip6 ? name6: name, kf->so_rcv_cc, kf->so_snd_cc);
                         else          if (Bflag && istcp)
                                 proto = inpcb.inp_ip.ip_p;                  printf("%6llu %6llu %6llu ", kf->t_rcv_wnd, kf->t_snd_wnd,
                         printf(" %u", proto);                      (kf->t_state == TCPS_ESTABLISHED) ?
                 }                      kf->t_snd_cwnd : 0);
                 putchar('\n');  
           if (isip6) {
                   inet6print(&laddr6, kf->inp_lport, name);
                   inet6print(&faddr6, kf->inp_fport, name);
           } else {
                   inetprint(&laddr, kf->inp_lport, name, 1);
                   inetprint(&faddr, kf->inp_fport, name, 0);
         }          }
           if (istcp) {
                   if (kf->t_state < 0 || kf->t_state >= TCP_NSTATES)
                           printf(" %d", kf->t_state);
                   else
                           printf(" %s", tcpstates[kf->t_state]);
           } else if (kf->so_type == SOCK_RAW) {
                   printf(" %u", kf->inp_proto);
           }
           putchar('\n');
 }  }
   
 /*  /*
Line 767 
Line 865 
  * If the nflag was specified, use numbers instead of names.   * If the nflag was specified, use numbers instead of names.
  */   */
 void  void
 inetprint(struct in_addr *in, in_port_t port, char *proto, int local)  inetprint(struct in_addr *in, in_port_t port, const char *proto, int local)
 {  {
         struct servent *sp = 0;          struct servent *sp = 0;
         char line[80], *cp, *nam;          char line[80], *cp, *nam;
Line 1167 
Line 1265 
         kread(off, &so, sizeof(so));          kread(off, &so, sizeof(so));
   
 #define p(fmt, v, sep) printf(#v " " fmt sep, so.v);  #define p(fmt, v, sep) printf(#v " " fmt sep, so.v);
 #define pp(fmt, v, sep) printf(#v " " fmt sep, hideroot ? 0 : so.v);  #define pp(fmt, v, sep) printf(#v " " fmt sep, so.v);
         printf("socket %#lx\n ", hideroot ? 0 : off);          printf("socket %#lx\n ", off);
         p("%#.4x", so_type, "\n ");          p("%#.4x", so_type, "\n ");
         p("%#.4x", so_options, "\n ");          p("%#.4x", so_options, "\n ");
         p("%d", so_linger, "\n ");          p("%d", so_linger, "\n ");
Line 1197 
Line 1295 
 #undef  p  #undef  p
 #undef  pp  #undef  pp
   
         if (!vflag)  
                 return;  
         protosw_dump((u_long)so.so_proto, (u_long)so.so_pcb);          protosw_dump((u_long)so.so_proto, (u_long)so.so_pcb);
 }  }
   
Line 1216 
Line 1312 
   
 #define p(fmt, v, sep) printf(#v " " fmt sep, ssp.v);  #define p(fmt, v, sep) printf(#v " " fmt sep, ssp.v);
 #define pll(fmt, v, sep) printf(#v " " fmt sep, (long long) ssp.v);  #define pll(fmt, v, sep) printf(#v " " fmt sep, (long long) ssp.v);
 #define pp(fmt, v, sep) printf(#v " " fmt sep, hideroot ? 0 : ssp.v);  #define pp(fmt, v, sep) printf(#v " " fmt sep, ssp.v);
         pp("%p", ssp_socket, ", ");          pp("%p", ssp_socket, ", ");
         pp("%p", ssp_soback, "\n ");          pp("%p", ssp_soback, "\n ");
         p("%lld", ssp_len, ", ");          p("%lld", ssp_len, ", ");
Line 1264 
Line 1360 
         kread(off, &proto, sizeof(proto));          kread(off, &proto, sizeof(proto));
   
 #define p(fmt, v, sep) printf(#v " " fmt sep, proto.v);  #define p(fmt, v, sep) printf(#v " " fmt sep, proto.v);
 #define pp(fmt, v, sep) printf(#v " " fmt sep, hideroot ? 0 : proto.v);  #define pp(fmt, v, sep) printf(#v " " fmt sep, proto.v);
         printf("protosw %#lx\n ", hideroot ? 0 : off);          printf("protosw %#lx\n ", off);
         p("%#.4x", pr_type, "\n ");          p("%#.4x", pr_type, "\n ");
         pp("%p", pr_domain, "\n ");          pp("%p", pr_domain, "\n ");
         p("%d", pr_protocol, "\n ");          p("%d", pr_protocol, "\n ");
Line 1291 
Line 1387 
         kread((u_long)dom.dom_name, name, sizeof(name));          kread((u_long)dom.dom_name, name, sizeof(name));
   
 #define p(fmt, v, sep) printf(#v " " fmt sep, dom.v);  #define p(fmt, v, sep) printf(#v " " fmt sep, dom.v);
         printf("domain %#lx\n ", hideroot ? 0 : off);          printf("domain %#lx\n ", off);
         p("%d", dom_family, "\n ");          p("%d", dom_family, "\n ");
         printf("dom_name %.*s\n", (int)sizeof(name), name);          printf("dom_name %.*s\n", (int)sizeof(name), name);
 #undef  p  #undef  p
   
         switch (dom.dom_family) {  
         case AF_INET:  
         case AF_INET6:  
                 inpcb_dump(pcb, protocol, dom.dom_family);  
                 break;  
         case AF_UNIX:  
                 unpcb_dump(pcb);  
                 break;  
         }  
 }  }
   
 /*  /*
Line 1319 
Line 1405 
         if (off == 0)          if (off == 0)
                 return;                  return;
         kread(off, &inp, sizeof(inp));          kread(off, &inp, sizeof(inp));
   
           if (vflag)
                   socket_dump((u_long)inp.inp_socket);
   
         switch (af) {          switch (af) {
         case AF_INET:          case AF_INET:
                 inet_ntop(af, &inp.inp_faddr, faddr, sizeof(faddr));                  inet_ntop(af, &inp.inp_faddr, faddr, sizeof(faddr));
Line 1333 
Line 1423 
         }          }
   
 #define p(fmt, v, sep) printf(#v " " fmt sep, inp.v);  #define p(fmt, v, sep) printf(#v " " fmt sep, inp.v);
 #define pp(fmt, v, sep) printf(#v " " fmt sep, hideroot ? 0 : inp.v);  #define pp(fmt, v, sep) printf(#v " " fmt sep, inp.v);
         printf("inpcb %#lx\n ", hideroot ? 0 : off);          printf("inpcb %#lx\n ", off);
         pp("%p", inp_table, "\n ");          pp("%p", inp_table, "\n ");
         printf("inp_faddru %s, inp_laddru %s\n ", faddr, laddr);          printf("inp_faddru %s, inp_laddru %s\n ", faddr, laddr);
         HTONS(inp.inp_fport);          HTONS(inp.inp_fport);
Line 1385 
Line 1475 
         kread(off, (char *)&tcpcb, sizeof (tcpcb));          kread(off, (char *)&tcpcb, sizeof (tcpcb));
   
 #define p(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v);  #define p(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v);
 #define pp(fmt, v, sep) printf(#v " " fmt sep, hideroot ? 0 : tcpcb.v);  #define pp(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v);
         printf("tcpcb %#lx\n ", hideroot ? 0 : off);          printf("tcpcb %#lx\n ", off);
         pp("%p", t_inpcb, "\n ");          pp("%p", t_inpcb, "\n ");
         p("%d", t_state, "");          p("%d", t_state, "");
         if (tcpcb.t_state >= 0 && tcpcb.t_state < TCP_NSTATES)          if (tcpcb.t_state >= 0 && tcpcb.t_state < TCP_NSTATES)

Legend:
Removed from v.1.139  
changed lines
  Added in v.1.140