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

Diff for /src/usr.bin/netstat/route.c between version 1.101 and 1.102

version 1.101, 2016/09/15 01:01:07 version 1.102, 2019/04/28 17:59:51
Line 55 
Line 55 
   
 #include "netstat.h"  #include "netstat.h"
   
 /* alignment constraint for routing socket */  
 #define ROUNDUP(a) \  
         ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))  
 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))  
   
 struct radix_node_head ***rt_head;  
 struct radix_node_head ***rnt;  
 struct radix_node_head *rt_tables[AF_MAX+1];    /* provides enough space */  
 u_int8_t                  af2rtafidx[AF_MAX+1];  
   
 static union {  static union {
         struct          sockaddr u_sa;          struct          sockaddr u_sa;
         u_int32_t       u_data[64];          u_int32_t       u_data[64];
         int             u_dummy;        /* force word-alignment */          int             u_dummy;        /* force word-alignment */
 } pt_u;  } pt_u;
   
 int     do_rtent = 0;  
 struct  rtentry rtentry;  struct  rtentry rtentry;
 struct  radix_node rnode;  
 struct  radix_mask rmask;  
   
 static struct sockaddr *kgetsa(struct sockaddr *);  static struct sockaddr *kgetsa(struct sockaddr *);
 static void p_tree(struct radix_node *);  static struct sockaddr *plentosa(sa_family_t, int, struct sockaddr *);
 static void p_rtnode(void);  static struct art_node *getdefault(struct art_table *);
 static void p_rtflags(u_char);  static void p_table(struct art_table *);
   static void p_artnode(struct art_node *);
 static void p_krtentry(struct rtentry *);  static void p_krtentry(struct rtentry *);
   
 /*  /*
  * Print routing tables.   * Print routing tables.
  */   */
 void  void
 routepr(u_long rtree, u_long mtree, u_long af2idx, u_long rtbl_id_max,  routepr(u_long afmap, u_long af2idx, u_long af2idx_max, u_int tableid)
     u_int tableid)  
 {  {
         struct radix_node_head *rnh, head;          struct art_root ar;
         int i, idxmax = 0;          struct art_node *node;
         u_int rtidxmax;          struct srp *afm_head, *afm;
           struct {
                   unsigned int    limit;
                   void          **tbl;
           } map;
           void **tbl;
           int i;
           uint8_t af2i[AF_MAX+1];
           uint8_t af2i_max;
   
         printf("Routing tables\n");          printf("Routing tables\n");
   
         if (rtree == 0 || af2idx == 0) {          if (afmap == 0 || af2idx == 0 || af2idx_max == 0) {
                 printf("rt_tables: symbol not in namelist\n");                  printf("symbol not in namelist\n");
                 return;                  return;
         }          }
   
         kread((u_long)rtree, &rt_head, sizeof(rt_head));          kread(afmap, &afm_head, sizeof(afm_head));
         kread((u_long)rtbl_id_max, &rtidxmax, sizeof(rtidxmax));          kread(af2idx, af2i, sizeof(af2i));
         kread((long)af2idx, &af2rtafidx, sizeof(af2rtafidx));          kread(af2idx_max, &af2i_max, sizeof(af2i_max));
   
         for (i = 0; i <= AF_MAX; i++) {          if ((afm = calloc(af2i_max + 1, sizeof(*afm))) == NULL)
                 if (af2rtafidx[i] > idxmax)  
                         idxmax = af2rtafidx[i];  
         }  
   
         if ((rnt = calloc(rtidxmax + 1, sizeof(struct radix_node_head **))) ==  
             NULL)  
                 err(1, NULL);                  err(1, NULL);
   
         kread((u_long)rt_head, rnt, (rtidxmax + 1) *          kread((u_long)afm_head, afm, (af2i_max + 1) * sizeof(*afm));
             sizeof(struct radix_node_head **));  
         if (tableid > rtidxmax || rnt[tableid] == NULL) {  
                 printf("Bad table %u\n", tableid);  
                 return;  
         }  
         kread((u_long)rnt[tableid], rt_tables, (idxmax + 1) * sizeof(rnh));  
   
         for (i = 0; i <= AF_MAX; i++) {          for (i = 1; i <= AF_MAX; i++) {
                 if (i == AF_UNSPEC) {                  if (af != AF_UNSPEC && af != i)
                         if (Aflag && (af == AF_UNSPEC || af == 0xff)) {  
                                 kread(mtree, &rnh, sizeof(rnh));  
                                 kread((u_long)rnh, &head, sizeof(head));  
                                 printf("Netmasks:\n");  
                                 p_tree(head.rnh_treetop);  
                         }  
                         continue;                          continue;
                 }                  if (af2i[i] == 0 || afm[af2i[i]].ref == NULL)
                 if (af2rtafidx[i] == 0)  
                         /* no table for this AF */  
                         continue;                          continue;
                 if ((rnh = rt_tables[af2rtafidx[i]]) == NULL)  
                   kread((u_long)afm[af2i[i]].ref, &map, sizeof(map));
                   if (tableid >= map.limit)
                         continue;                          continue;
                 kread((u_long)rnh, &head, sizeof(head));  
                 if (af == AF_UNSPEC || af == i) {                  if ((tbl = calloc(map.limit, sizeof(*tbl))) == NULL)
                         pr_family(i);                          err(1, NULL);
                         do_rtent = 1;  
                         pr_rthdr(i, Aflag);                  kread((u_long)map.tbl, tbl, map.limit * sizeof(*tbl));
                         p_tree(head.rnh_treetop);                  if (tbl[tableid] == NULL)
                 }                          continue;
   
                   kread((u_long)tbl[tableid], &ar, sizeof(ar));
   
                   free(tbl);
   
                   if (ar.ar_root.ref == NULL)
                           continue;
   
                   pr_family(i);
                   pr_rthdr(i, Aflag);
   
                   node = getdefault(ar.ar_root.ref);
                   if (node != NULL)
                           p_artnode(node);
   
                   p_table(ar.ar_root.ref);
         }          }
   
           free(afm);
 }  }
   
 static struct sockaddr *  static struct sockaddr *
Line 156 
Line 151 
         return (&pt_u.u_sa);          return (&pt_u.u_sa);
 }  }
   
 static void  static struct sockaddr *
 p_tree(struct radix_node *rn)  plentosa(sa_family_t af, int plen, struct sockaddr *sa_mask)
 {  {
           struct sockaddr_in *sin = (struct sockaddr_in *)sa_mask;
           struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa_mask;
           uint8_t *p;
           int i;
   
 again:          if (plen < 0)
         kread((u_long)rn, &rnode, sizeof(rnode));                  return (NULL);
         if (rnode.rn_b < 0) {  
                 if (Aflag)          memset(sa_mask, 0, sizeof(struct sockaddr_storage));
                         printf("%-16p ", rn);  
                 if (rnode.rn_flags & RNF_ROOT) {          switch (af) {
                         if (Aflag)          case AF_INET:
                                 printf("(root node)%s",                  if (plen > 32)
                                     rnode.rn_dupedkey ? " =>\n" : "\n");                          return (NULL);
                 } else if (do_rtent) {                  sin->sin_family = AF_INET;
                         kread((u_long)rn, &rtentry, sizeof(rtentry));                  sin->sin_len = sizeof(struct sockaddr_in);
                         p_krtentry(&rtentry);                  memset(&sin->sin_addr, 0, sizeof(sin->sin_addr));
                         if (Aflag)                  p = (uint8_t *)&sin->sin_addr;
                                 p_rtnode();                  break;
                 } else {          case AF_INET6:
                         p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_key),                  if (plen > 128)
                             0, 0, 44);                          return (NULL);
                         putchar('\n');                  sin6->sin6_family = AF_INET6;
                 }                  sin6->sin6_len = sizeof(struct sockaddr_in6);
                 if ((rn = rnode.rn_dupedkey))                  memset(&sin6->sin6_addr.s6_addr, 0, sizeof(sin6->sin6_addr.s6_addr));
                         goto again;                  p = sin6->sin6_addr.s6_addr;
         } else {                  break;
                 if (Aflag && do_rtent) {          default:
                         printf("%-16p ", rn);                  return (NULL);
                         p_rtnode();  
                 }  
                 rn = rnode.rn_r;  
                 p_tree(rnode.rn_l);  
                 p_tree(rn);  
         }          }
   
           for (i = 0; i < plen / 8; i++)
                   p[i] = 0xff;
           if (plen % 8)
                   p[i] = (0xff00 >> (plen % 8)) & 0xff;
   
           return (sa_mask);
 }  }
   
 static void  static struct art_node *
 p_rtflags(u_char flags)  getdefault(struct art_table *at)
 {  {
         putchar('<');          struct art_node *node;
         if (flags & RNF_NORMAL)          struct art_table table;
                 putchar('N');          union {
         if (flags & RNF_ROOT)                  struct srp               node;
                 putchar('R');                  unsigned long            count;
         if (flags & RNF_ACTIVE)          } *heap;
                 putchar('A');  
         if (flags & ~(RNF_NORMAL | RNF_ROOT | RNF_ACTIVE))  
                 printf("/0x%02x", flags);  
         putchar('>');  
 }  
   
 char    nbuf[25];          kread((u_long)at, &table, sizeof(table));
           heap = calloc(1, AT_HEAPSIZE(table.at_bits));
           kread((u_long)table.at_heap, heap, AT_HEAPSIZE(table.at_bits));
   
           node = heap[1].node.ref;
   
           free(heap);
   
           return (node);
   }
   
 static void  static void
 p_rtnode(void)  p_table(struct art_table *at)
 {  {
         struct radix_mask *rm = rnode.rn_mklist;          struct art_node *next, *node;
           struct art_table *nat, table;
           union {
                   struct srp               node;
                   unsigned long            count;
           } *heap;
           int i, j;
   
         if (rnode.rn_b < 0) {          kread((u_long)at, &table, sizeof(table));
                 snprintf(nbuf, sizeof nbuf, " => %p", rnode.rn_dupedkey);          heap = calloc(1, AT_HEAPSIZE(table.at_bits));
                 printf("\t  (%p)%s", rnode.rn_p, rnode.rn_dupedkey ? nbuf : "");          kread((u_long)table.at_heap, heap, AT_HEAPSIZE(table.at_bits));
                 if (rnode.rn_mask) {  
                         printf(" mask ");          for (j = 1; j < table.at_minfringe; j += 2) {
                         p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_mask),                  for (i = (j > 2) ? j : 2; i < table.at_minfringe; i <<= 1) {
                             0, 0, -1);                          next = heap[i >> 1].node.ref;
                 } else if (rm == NULL) {                          node = heap[i].node.ref;
                         putchar('\n');                          if (node != NULL && node != next)
                         return;                                  p_artnode(node);
                 }                  }
         } else {  
                 snprintf(nbuf, sizeof nbuf, "(%d)", rnode.rn_b);  
                 printf("%6.6s (%p) %16p : %16p", nbuf,  
                     rnode.rn_p, rnode.rn_l, rnode.rn_r);  
         }          }
   
         putchar(' ');          for (i = table.at_minfringe; i < table.at_minfringe << 1; i++) {
         p_rtflags(rnode.rn_flags);                  next = heap[i >> 1].node.ref;
                   node = heap[i].node.ref;
                   if (!ISLEAF(node)) {
                           nat = SUBTABLE(node);
                           node = getdefault(nat);
                   } else
                           nat = NULL;
   
         while (rm) {                  if (node != NULL && node != next)
                 kread((u_long)rm, &rmask, sizeof(rmask));                          p_artnode(node);
                 snprintf(nbuf, sizeof nbuf, " %d refs, ", rmask.rm_refs);  
                 printf("\n\tmk = %p {(%d),%s", rm, -1 - rmask.rm_b,  
                     rmask.rm_refs ? nbuf : " ");  
                 p_rtflags(rmask.rm_flags);  
                 printf(", ");  
                 if (rmask.rm_flags & RNF_NORMAL) {  
                         struct radix_node rnode_aux;  
   
                         printf("leaf = %p ", rmask.rm_leaf);                  if (nat != NULL)
                         kread((u_long)rmask.rm_leaf, &rnode_aux, sizeof(rnode_aux));                          p_table(nat);
                         p_sockaddr(kgetsa((struct sockaddr *)rnode_aux.rn_mask),  
                             0, 0, -1);  
                 } else  
                         p_sockaddr(kgetsa((struct sockaddr *)rmask.rm_mask),  
                             0, 0, -1);  
                 putchar('}');  
                 if ((rm = rmask.rm_mklist))  
                         printf(" ->");  
         }          }
         putchar('\n');  
           free(heap);
 }  }
   
 static void  static void
   p_artnode(struct art_node *an)
   {
           struct art_node node;
           struct rtentry *rt;
   
           kread((u_long)an, &node, sizeof(node));
           rt = node.an_rtlist.sl_head.ref;
   
           while (rt != NULL) {
                   kread((u_long)rt, &rtentry, sizeof(rtentry));
                   if (Aflag)
                           printf("%-16p ", rt);
                   p_krtentry(&rtentry);
                   rt = rtentry.rt_next.se_next.ref;
           }
   }
   
   static void
 p_krtentry(struct rtentry *rt)  p_krtentry(struct rtentry *rt)
 {  {
         struct sockaddr_storage sock1, sock2;          struct sockaddr_storage sock1, sock2;
Line 274 
Line 291 
                 return;                  return;
         }          }
   
         if (rt_mask(rt)) {          mask = plentosa(sa->sa_family, rt_plen(rt), mask);
                 bcopy(kgetsa(rt_mask(rt)), mask, sizeof(struct sockaddr));  
                 if (sa->sa_len > sizeof(struct sockaddr))  
                         bcopy(kgetsa(rt_mask(rt)), mask, sa->sa_len);  
         } else  
                 mask = 0;  
   
         p_addr(sa, mask, rt->rt_flags);          p_addr(sa, mask, rt->rt_flags);
         p_gwaddr(kgetsa(rt->rt_gateway), sa->sa_family);          p_gwaddr(kgetsa(rt->rt_gateway), sa->sa_family);
         p_flags(rt->rt_flags, "%-6.6s ");          p_flags(rt->rt_flags, "%-6.6s ");
         printf("%5u %8lld ", rt->rt_refcnt, rt->rt_use);          printf("%5u %8lld ", rt->rt_refcnt - 1, rt->rt_use);
         if (rt->rt_rmx.rmx_mtu)          if (rt->rt_rmx.rmx_mtu)
                 printf("%5u ", rt->rt_rmx.rmx_mtu);                  printf("%5u ", rt->rt_rmx.rmx_mtu);
         else          else
                 printf("%5s ", "-");                  printf("%5s ", "-");
         putchar((rt->rt_rmx.rmx_locks & RTV_MTU) ? 'L' : ' ');          putchar((rt->rt_rmx.rmx_locks & RTV_MTU) ? 'L' : ' ');
         printf("  %2d", rt->rt_priority);          printf("  %2d", rt->rt_priority & RTP_MASK);
   
         if (rt->rt_ifidx != 0) {          if (rt->rt_ifidx != 0)
                 printf(" if%d%s", rt->rt_ifidx,                  printf(" if%d", rt->rt_ifidx);
                     rt->rt_nodes[0].rn_dupedkey ? " =>" : "");  
         }  
         putchar('\n');          putchar('\n');
         if (vflag)          if (vflag)
                 printf("\texpire   %10lld%c\n",                  printf("\texpire   %10lld%c\n",

Legend:
Removed from v.1.101  
changed lines
  Added in v.1.102