BSD 4_3_Net_2 release
[unix-history] / usr / src / usr.bin / netstat / route.c
index 4b3de9c..c1ddec9 100644 (file)
@@ -2,23 +2,37 @@
  * Copyright (c) 1983, 1988 Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1983, 1988 Regents of the University of California.
  * All rights reserved.
  *
- * Redistribution and use in source and binary forms are permitted provided
- * that: (1) source distributions retain this entire copyright notice and
- * comment, and (2) distributions including binaries display the following
- * acknowledgement:  ``This product includes software developed by the
- * University of California, Berkeley and its contributors'' in the
- * documentation or other materials provided with the distribution and in
- * all advertising materials mentioning features or use of this software.
- * Neither the name of the University nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)route.c    5.19 (Berkeley) 6/18/90";
+static char sccsid[] = "@(#)route.c    5.20 (Berkeley) 11/29/90";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -39,7 +53,8 @@ static char sccsid[] = "@(#)route.c   5.19 (Berkeley) 6/18/90";
 #include <stdio.h>
 #include <string.h>
 
 #include <stdio.h>
 #include <string.h>
 
-extern int nflag;
+extern int nflag, aflag, Aflag, af;
+int do_rtent;
 extern char *routename(), *netname(), *ns_print(), *plural();
 extern char *malloc();
 #define kget(p, d) \
 extern char *routename(), *netname(), *ns_print(), *plural();
 extern char *malloc();
 #define kget(p, d) \
@@ -58,8 +73,9 @@ struct bits {
        { RTF_DYNAMIC,  'D' },
        { RTF_MODIFIED, 'M' },
        { RTF_CLONING,  'C' },
        { RTF_DYNAMIC,  'D' },
        { RTF_MODIFIED, 'M' },
        { RTF_CLONING,  'C' },
-       { RTF_XRESOLVE, 'R' },
+       { RTF_XRESOLVE, 'X' },
        { RTF_LLINFO,   'L' },
        { RTF_LLINFO,   'L' },
+       { RTF_REJECT,   'R' },
        { 0 }
 };
 
        { 0 }
 };
 
@@ -78,6 +94,8 @@ routepr(hostaddr, netaddr, hashsizeaddr, treeaddr)
        int i, doinghost = 1;
 
        printf("Routing tables\n");
        int i, doinghost = 1;
 
        printf("Routing tables\n");
+       if (Aflag)
+               printf("%-8.8s ","Address");
        printf("%-16.16s %-18.18s %-6.6s  %6.6s%8.8s  %s\n",
                "Destination", "Gateway",
                "Flags", "Refs", "Use", "Interface");
        printf("%-16.16s %-18.18s %-6.6s  %6.6s%8.8s  %s\n",
                "Destination", "Gateway",
                "Flags", "Refs", "Use", "Interface");
@@ -105,7 +123,9 @@ again:
                m = routehash[i];
                while (m) {
                        kget(m, mb);
                m = routehash[i];
                while (m) {
                        kget(m, mb);
-                       p_rtentry((struct rtentry *)(mb.m_dat));
+                       if (Aflag)
+                               printf("%8.8x ", m);
+                       p_ortentry((struct ortentry *)(mb.m_dat));
                        m = mb.m_next;
                }
        }
                        m = mb.m_next;
                }
        }
@@ -123,7 +143,10 @@ static union {
        struct  sockaddr u_sa;
        u_short u_data[128];
 } pt_u;
        struct  sockaddr u_sa;
        u_short u_data[128];
 } pt_u;
-static struct rtentry rtentry;
+int do_rtent = 0;
+struct rtentry rtentry;
+struct radix_node rnode;
+struct radix_mask rmask;
 
 int NewTree = 0;
 treestuff(rtree)
 
 int NewTree = 0;
 treestuff(rtree)
@@ -131,17 +154,20 @@ off_t rtree;
 {
        struct radix_node_head *rnh, head;
 
 {
        struct radix_node_head *rnh, head;
 
-       if (NewTree)
+       if (Aflag == 0 && NewTree)
                return(ntreestuff());
        for (kget(rtree, rnh); rnh; rnh = head.rnh_next) {
                kget(rnh, head);
                if (head.rnh_af == 0) {
                return(ntreestuff());
        for (kget(rtree, rnh); rnh; rnh = head.rnh_next) {
                kget(rnh, head);
                if (head.rnh_af == 0) {
-                       printf("Netmasks:\n");
-                       p_tree(head.rnh_treetop, 0);
-               } else {
+                       if (Aflag || af == AF_UNSPEC) { 
+                               printf("Netmasks:\n");
+                               p_tree(head.rnh_treetop);
+                       }
+               } else if (af == AF_UNSPEC || af == head.rnh_af) {
                        printf("\nRoute Tree for Protocol Family %d:\n",
                                                                head.rnh_af);
                        printf("\nRoute Tree for Protocol Family %d:\n",
                                                                head.rnh_af);
-                       p_tree(head.rnh_treetop, 1);
+                       do_rtent = 1;
+                       p_tree(head.rnh_treetop);
                }
        }
 }
                }
        }
 }
@@ -157,21 +183,23 @@ register struct sockaddr *dst;
        return (&pt_u.u_sa);
 }
 
        return (&pt_u.u_sa);
 }
 
-p_tree(rn, do_rtent)
+p_tree(rn)
 struct radix_node *rn;
 {
 struct radix_node *rn;
 {
-       struct radix_node rnode;
-       register u_short *s, *slim;
-       int len;
 
 again:
        kget(rn, rnode);
        if (rnode.rn_b < 0) {
 
 again:
        kget(rn, rnode);
        if (rnode.rn_b < 0) {
+               if (Aflag)
+                       printf("%-8.8x ", rn);
                if (rnode.rn_flags & RNF_ROOT)
                if (rnode.rn_flags & RNF_ROOT)
-                       printf("(root node)\n");
+                       printf("(root node)%s",
+                                   rnode.rn_dupedkey ? " =>\n" : "\n");
                else if (do_rtent) {
                        kget(rn, rtentry);
                        p_rtentry(&rtentry);
                else if (do_rtent) {
                        kget(rn, rtentry);
                        p_rtentry(&rtentry);
+                       if (Aflag)
+                               p_rtnode();
                } else {
                        p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_key),
                                    0, 44);
                } else {
                        p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_key),
                                    0, 44);
@@ -180,9 +208,43 @@ again:
                if (rn = rnode.rn_dupedkey)
                        goto again;
        } else {
                if (rn = rnode.rn_dupedkey)
                        goto again;
        } else {
-               p_tree(rnode.rn_l, do_rtent);
-               p_tree(rnode.rn_r, do_rtent);
+               if (Aflag && do_rtent) {
+                       printf("%-8.8x ", rn);
+                       p_rtnode();
+               }
+               rn = rnode.rn_r;
+               p_tree(rnode.rn_l);
+               p_tree(rn);
+       }
+}
+char nbuf[20];
+
+p_rtnode()
+{
+
+       struct radix_mask *rm = rnode.rn_mklist;
+       if (rnode.rn_b < 0) {
+               if (rnode.rn_mask) {
+                       printf("\t  mask ");
+                       p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_mask),
+                                   0, -1);
+               } else if (rm == 0)
+                       return;
+       } else {
+               sprintf(nbuf, "(%d)", rnode.rn_b);
+               printf("%6.6s %8.8x : %8.8x", nbuf, rnode.rn_l, rnode.rn_r);
+       }
+       while (rm) {
+               kget(rm, rmask);
+               sprintf(nbuf, " %d refs, ", rmask.rm_refs);
+               printf(" mk = %8.8x {(%d),%s",
+                       rm, -1 - rmask.rm_b, rmask.rm_refs ? nbuf : " ");
+               p_sockaddr(kgetsa((struct sockaddr *)rmask.rm_mask), 0, -1);
+               putchar('}');
+               if (rm = rmask.rm_mklist)
+                       printf(" ->");
        }
        }
+       putchar('\n');
 }
 
 ntreestuff()
 }
 
 ntreestuff()
@@ -266,21 +328,26 @@ int flags, width;
 
        default:
            {
 
        default:
            {
-               register u_short *s = ((u_short *)sa->sa_data),
-                               *slim = ((sa->sa_len + 1)/2) + s;
+               register u_short *s = ((u_short *)sa->sa_data), *slim;
 
 
+               slim = (u_short *) sa + ((sa->sa_len + sizeof(u_short) - 1) /
+                   sizeof(u_short));
                cp = workbuf;
                cplim = cp + sizeof(workbuf) - 6;
                cp += sprintf(cp, "(%d)", sa->sa_family);
                while (s < slim && cp < cplim)
                cp = workbuf;
                cplim = cp + sizeof(workbuf) - 6;
                cp += sprintf(cp, "(%d)", sa->sa_family);
                while (s < slim && cp < cplim)
-                       cp += sprintf(cp, "%x ", *s++);
+                       cp += sprintf(cp, " %x", *s++);
                cp = workbuf;
            }
        }
                cp = workbuf;
            }
        }
-       if (nflag)
-               printf("%-*s ", width, cp);
-       else
-               printf("%-*.*s ", width, width, cp);
+       if (width < 0 )
+               printf("%s ", cp);
+       else {
+               if (nflag)
+                       printf("%-*s ", width, cp);
+               else
+                       printf("%-*.*s ", width, width, cp);
+       }
 }
 
 p_flags(f, format)
 }
 
 p_flags(f, format)
@@ -313,7 +380,8 @@ register struct rtentry *rt;
        }
        kget(rt->rt_ifp, ifnet);
        kvm_read((off_t)ifnet.if_name, name, 16);
        }
        kget(rt->rt_ifp, ifnet);
        kvm_read((off_t)ifnet.if_name, name, 16);
-       printf(" %.15s%d\n", name, ifnet.if_unit);
+       printf(" %.15s%d%s", name, ifnet.if_unit,
+               rt->rt_nodes[0].rn_dupedkey ? " =>\n" : "\n");
 }
 
 p_ortentry(rt)
 }
 
 p_ortentry(rt)