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

Diff for /src/usr.bin/netstat/main.c between version 1.105 and 1.106

version 1.105, 2015/02/09 12:25:03 version 1.106, 2015/02/12 01:49:02
Line 54 
Line 54 
 #include "netstat.h"  #include "netstat.h"
   
 struct nlist nl[] = {  struct nlist nl[] = {
 #define N_TCBTABLE      0  #define N_RTREE         0
         { "_tcbtable" },  
 #define N_UDBTABLE      1  
         { "_udbtable" },  
   
 #define N_RTREE         7  
         { "_rt_tables"},          { "_rt_tables"},
 #define N_RTMASK        8  #define N_RTMASK        1
         { "_mask_rnhead" },          { "_mask_rnhead" },
 #define N_AF2RTAFIDX    9  #define N_AF2RTAFIDX    2
         { "_af2rtafidx" },          { "_af2rtafidx" },
 #define N_RTBLIDMAX     10  #define N_RTBLIDMAX     3
         { "_rtbl_id_max" },          { "_rtbl_id_max" },
   
 #define N_RAWIPTABLE    11  
         { "_rawcbtable" },  
 #define N_RAWIP6TABLE   12  
         { "_rawin6pcbtable" },  
 #define N_DIVBTABLE     13  
         { "_divbtable" },  
 #define N_DIVB6TABLE    14  
         { "_divb6table" },  
   
         { "" }          { "" }
 };  };
   
 struct protox {  struct protox {
         u_char  pr_index;               /* index into nlist of cb head */  
         void    (*pr_cblocks)(u_long, char *, int, u_int, u_long);  
                                         /* control blocks printing routine */  
         void    (*pr_stats)(char *);    /* statistics printing routine */          void    (*pr_stats)(char *);    /* statistics printing routine */
         char    *pr_name;               /* well-known name */          char    *pr_name;               /* well-known name */
           int     pr_proto;               /* protocol number */
 } protox[] = {  } protox[] = {
         { N_TCBTABLE,   protopr,        tcp_stats,      "tcp" },          { ip_stats,     "ip",   IPPROTO_IPV4 },
         { N_UDBTABLE,   protopr,        udp_stats,      "udp" },          { icmp_stats,   "icmp", 0 },
         { N_RAWIPTABLE, protopr,        ip_stats,       "ip" },          { igmp_stats,   "igmp", 0 },
         { N_DIVBTABLE,  protopr,        div_stats,      "divert" },          { ipip_stats,   "ipencap", 0 },
         { -1,           NULL,           icmp_stats,     "icmp" },          { tcp_stats,    "tcp",  IPPROTO_TCP },
         { -1,           NULL,           igmp_stats,     "igmp" },          { udp_stats,    "udp",  IPPROTO_UDP },
         { -1,           NULL,           ah_stats,       "ah" },          { esp_stats,    "esp", 0 },
         { -1,           NULL,           esp_stats,      "esp" },          { ah_stats,     "ah", 0 },
         { -1,           NULL,           ipip_stats,     "ipencap" },          { etherip_stats,"etherip", 0 },
         { -1,           NULL,           etherip_stats,  "etherip" },          { ipcomp_stats, "ipcomp", 0 },
         { -1,           NULL,           ipcomp_stats,   "ipcomp" },          { carp_stats,   "carp", 0 },
         { -1,           NULL,           carp_stats,     "carp" },          { pfsync_stats, "pfsync", 0 },
         { -1,           NULL,           pfsync_stats,   "pfsync" },          { div_stats,    "divert", IPPROTO_DIVERT },
         { -1,           NULL,           pim_stats,      "pim" },          { pim_stats,    "pim", 0 },
         { -1,           NULL,           pflow_stats,    "pflow" },          { pflow_stats,  "pflow", 0 },
         { -1,           NULL,           NULL,           NULL }          { NULL,         NULL, 0 }
 };  };
   
 struct protox ip6protox[] = {  struct protox ip6protox[] = {
         { N_TCBTABLE,   protopr,        NULL,           "tcp" },          { ip6_stats,    "ip6", IPPROTO_IPV6 },
         { N_UDBTABLE,   protopr,        NULL,           "udp" },          { div6_stats,   "divert6", IPPROTO_DIVERT },
         { N_RAWIP6TABLE,protopr,        ip6_stats,      "ip6" },          { icmp6_stats,  "icmp6", 0 },
         { N_DIVB6TABLE, protopr,        div6_stats,     "divert6" },          { pim6_stats,   "pim6", 0 },
         { -1,           NULL,           icmp6_stats,    "icmp6" },          { rip6_stats,   "rip6", 0 },
         { -1,           NULL,           pim6_stats,     "pim6" },          { NULL,         NULL, 0 }
         { -1,           NULL,           rip6_stats,     "rip6" },  
         { -1,           NULL,           NULL,           NULL }  
 };  };
   
 struct protox *protoprotox[] = {  struct protox *protoprotox[] = {
         protox, ip6protox, NULL          protox, ip6protox, NULL
 };  };
   
 static void printproto(struct protox *, char *, int, u_int, u_long);  
 static void usage(void);  static void usage(void);
 static struct protox *name2protox(char *);  static struct protox *name2protox(char *);
 static struct protox *knownname(char *);  static struct protox *knownname(char *);
 u_int gettable(const char *);  u_int gettable(const char *);
   
 int hideroot;  
   
 kvm_t *kvmd;  kvm_t *kvmd;
   
 int  int
Line 136 
Line 115 
         extern char *optarg;          extern char *optarg;
         extern int optind;          extern int optind;
         const char *errstr;          const char *errstr;
         struct protoent *p;  
         struct protox *tp = NULL; /* for printing cblocks & stats */          struct protox *tp = NULL; /* for printing cblocks & stats */
         int ch;          int ch;
         char *nlistf = NULL, *memf = NULL, *ep;          char *nlistf = NULL, *memf = NULL, *ep;
         char buf[_POSIX2_LINE_MAX];          char buf[_POSIX2_LINE_MAX];
         gid_t gid;  
         u_long pcbaddr = 0;          u_long pcbaddr = 0;
         u_int tableid;          u_int tableid;
         int Tflag = 0;          int Tflag = 0;
         int repeatcount = 0;          int repeatcount = 0;
           int proto = 0;
         int need_nlist;          int need_nlist;
   
         hideroot = getuid();  
   
         af = AF_UNSPEC;          af = AF_UNSPEC;
         tableid = getrtable();          tableid = getrtable();
   
Line 190 
Line 166 
                                 af = AF_UNIX;                                  af = AF_UNIX;
                         else if (strcmp(optarg, "mpls") == 0)                          else if (strcmp(optarg, "mpls") == 0)
                                 af = AF_MPLS;                                  af = AF_MPLS;
                         else if (strcmp(optarg, "pflow") == 0)  
                                 af = PF_PFLOW;  
                         else if (strcmp(optarg, "mask") == 0)                          else if (strcmp(optarg, "mask") == 0)
                                 af = 0xff;                                  af = 0xff;
                         else {                          else {
Line 289 
Line 263 
         argv += optind;          argv += optind;
         argc -= optind;          argc -= optind;
   
         /*  
          * Show per-interface statistics which don't need access to  
          * kernel memory (they're using IOCTLs)  
          */  
         if (Wflag) {  
                 if (interface == NULL)  
                         usage();  
                 net80211_ifstats(interface);  
                 exit(0);  
         }  
   
 #define BACKWARD_COMPATIBILITY  #define BACKWARD_COMPATIBILITY
 #ifdef  BACKWARD_COMPATIBILITY  #ifdef  BACKWARD_COMPATIBILITY
         if (*argv) {          if (*argv) {
Line 318 
Line 281 
         }          }
 #endif  #endif
   
         need_nlist = !mflag && (pflag || nlistf != NULL || memf != NULL ||  
             (!iflag && !sflag && !gflag && (rflag ? Aflag :  
             (af != AF_UNIX || Pflag))));  
   
         /*          /*
          * Discard setgid privileges if not the running kernel so that bad           * Show per-interface statistics which don't need access to
          * guys can't print interesting stuff from kernel memory.           * kernel memory (they're using IOCTLs)
          * Dumping PCB info is also restricted.  
          */           */
         gid = getgid();          if (Wflag) {
         if (nlistf != NULL || memf != NULL || Pflag)                  if (interface == NULL)
                 if (setresgid(gid, gid, gid) == -1)                          usage();
                         err(1, "setresgid");                  net80211_ifstats(interface);
                   exit(0);
         if ((kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY |  
             (need_nlist ? 0 : KVM_NO_FILES), buf)) == NULL) {  
                 fprintf(stderr, "%s: kvm_openfiles: %s\n", __progname, buf);  
                 exit(1);  
         }          }
   
         if (nlistf == NULL && memf == NULL && !Pflag)  
                 if (setresgid(gid, gid, gid) == -1)  
                         err(1, "setresgid");  
   
         if (need_nlist && (kvm_nlist(kvmd, nl) < 0 || nl[0].n_type == 0)) {  
                 if (nlistf)  
                         fprintf(stderr, "%s: %s: no namelist\n", __progname,  
                             nlistf);  
                 else  
                         fprintf(stderr, "%s: no namelist\n", __progname);  
                 exit(1);  
         }  
         if (mflag) {          if (mflag) {
                 mbpr();                  mbpr();
                 exit(0);                  exit(0);
         }          }
         if (pflag) {  
                 printproto(tp, tp->pr_name, af, tableid, pcbaddr);  
                 exit(0);  
         }  
         if (iflag) {          if (iflag) {
                 intpr(interval, repeatcount);                  intpr(interval, repeatcount);
                 exit(0);                  exit(0);
         }          }
         if (rflag) {          if (sflag) {
                 if (sflag)                  if (rflag) {
                         rt_stats();                          rt_stats();
                 else if (Aflag || nlistf != NULL || memf != NULL)                  } else if (gflag) {
                         routepr(nl[N_RTREE].n_value, nl[N_RTMASK].n_value,  
                             nl[N_AF2RTAFIDX].n_value, nl[N_RTBLIDMAX].n_value,  
                             tableid);  
                 else  
                         p_rttables(af, tableid);  
                 exit(0);  
         }  
         if (gflag) {  
                 if (sflag) {  
                         if (af == AF_INET || af == AF_UNSPEC)                          if (af == AF_INET || af == AF_UNSPEC)
                                 mrt_stats();                                  mrt_stats();
                         if (af == AF_INET6 || af == AF_UNSPEC)                          if (af == AF_INET6 || af == AF_UNSPEC)
                                 mrt6_stats();                                  mrt6_stats();
                   } else if (pflag && tp->pr_name) {
                           (*tp->pr_stats)(tp->pr_name);
                 } else {                  } else {
                         if (af == AF_INET || af == AF_UNSPEC)                          if (af == AF_INET || af == AF_UNSPEC)
                                 mroutepr();                                  for (tp = protox; tp->pr_name; tp++)
                                           (*tp->pr_stats)(tp->pr_name);
                         if (af == AF_INET6 || af == AF_UNSPEC)                          if (af == AF_INET6 || af == AF_UNSPEC)
                                 mroute6pr();                                  for (tp = ip6protox; tp->pr_name; tp++)
                                           (*tp->pr_stats)(tp->pr_name);
                 }                  }
                 exit(0);                  exit(0);
         }          }
         if (af == AF_INET || af == AF_UNSPEC) {          if (gflag) {
                 setprotoent(1);                  if (af == AF_INET || af == AF_UNSPEC)
                 setservent(1);                          mroutepr();
                 /* ugh, this is O(MN) ... why do we do this? */                  if (af == AF_INET6 || af == AF_UNSPEC)
                 while ((p = getprotoent())) {                          mroute6pr();
                         for (tp = protox; tp->pr_name; tp++)                  exit(0);
                                 if (strcmp(tp->pr_name, p->p_name) == 0)  
                                         break;  
                         if (tp->pr_name == 0)  
                                 continue;  
                         printproto(tp, p->p_name, AF_INET, tableid, pcbaddr);  
                 }  
                 endprotoent();  
         }          }
         if (af == PF_PFLOW || af == AF_UNSPEC) {  
                 tp = name2protox("pflow");          /*
                 printproto(tp, tp->pr_name, af, tableid, pcbaddr);           * The remaining code may need kvm so lets try to open it.
            * -r and -P are the only bits left that actually can use this.
            */
           need_nlist = nlistf != NULL || memf != NULL || Pflag || (Aflag && rflag);
   
           if ((kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY |
               (need_nlist ? 0 : KVM_NO_FILES), buf)) == NULL)
                   errx(1, "kvm_openfiles: %s", buf);
   
           if (need_nlist && (kvm_nlist(kvmd, nl) < 0 || nl[0].n_type == 0)) {
                   if (nlistf)
                           errx(1, "%s: no namelist", nlistf);
                   else
                           errx(1, "no namelist");
         }          }
         if (af == AF_INET6 || af == AF_UNSPEC)  
                 for (tp = ip6protox; tp->pr_name; tp++)  
                         printproto(tp, tp->pr_name, AF_INET6, tableid,  
                             pcbaddr);  
         if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)  
                 unixpr(kvmd, pcbaddr);  
         exit(0);  
 }  
   
 /*          if (rflag) {
  * Print out protocol statistics or control blocks (per sflag).                  if (Aflag || nlistf != NULL || memf != NULL)
  * If the interface was not specifically requested, and the symbol                          routepr(nl[N_RTREE].n_value, nl[N_RTMASK].n_value,
  * is not in the namelist, ignore this one.                              nl[N_AF2RTAFIDX].n_value, nl[N_RTBLIDMAX].n_value,
  */                              tableid);
 static void                  else
 printproto(struct protox *tp, char *name, int af, u_int tableid,                          p_rttables(af, tableid);
     u_long pcbaddr)                  exit(0);
 {  
         if (sflag) {  
                 if (tp->pr_stats != NULL)  
                         (*tp->pr_stats)(name);  
         } else {  
                 u_char i = tp->pr_index;  
                 if (tp->pr_cblocks != NULL &&  
                     i < sizeof(nl) / sizeof(nl[0]) &&  
                     (nl[i].n_value || af != AF_UNSPEC))  
                         (*tp->pr_cblocks)(nl[i].n_value, name, af, tableid,  
                             pcbaddr);  
         }          }
   
           if (pflag) {
                   if (tp->pr_proto == 0)
                           errx(1, "no protocol handler for protocol %s",
                               tp->pr_name);
                   else
                           proto = tp->pr_proto;
           }
   
           protopr(kvmd, pcbaddr, tableid, proto);
           exit(0);
 }  }
   
 /*  /*

Legend:
Removed from v.1.105  
changed lines
  Added in v.1.106