subnet fixes
[unix-history] / usr / src / usr.bin / netstat / route.c
index 1cc721c..b7140dc 100644 (file)
@@ -1,14 +1,16 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)route.c    4.3 82/10/06";
+static char sccsid[] = "@(#)route.c    4.8 84/05/17";
 #endif
 
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/mbuf.h>
 #endif
 
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/mbuf.h>
+
 #include <net/if.h>
 #include <net/if.h>
-#include <net/in.h>
 #define        KERNEL          /* to get routehash and RTHASHSIZ */
 #include <net/route.h>
 #define        KERNEL          /* to get routehash and RTHASHSIZ */
 #include <net/route.h>
+#include <netinet/in.h>
+
 #include <netdb.h>
 
 extern int kmem;
 #include <netdb.h>
 
 extern int kmem;
@@ -71,7 +73,9 @@ again:
                        read(kmem, &mb, sizeof (mb));
                        rt = mtod(&mb, struct rtentry *);
                        sin = (struct sockaddr_in *)&rt->rt_dst;
                        read(kmem, &mb, sizeof (mb));
                        rt = mtod(&mb, struct rtentry *);
                        sin = (struct sockaddr_in *)&rt->rt_dst;
-                       printf("%-15.15s ", routename(sin->sin_addr));
+                       printf("%-15.15s ",
+                           sin->sin_addr.s_addr ?
+                               routename(sin->sin_addr) : "default");
                        sin = (struct sockaddr_in *)&rt->rt_gateway;
                        printf("%-15.15s ", routename(sin->sin_addr));
                        for (flags = name, p = bits; p->b_mask; p++)
                        sin = (struct sockaddr_in *)&rt->rt_gateway;
                        printf("%-15.15s ", routename(sin->sin_addr));
                        for (flags = name, p = bits; p->b_mask; p++)
@@ -107,19 +111,30 @@ routename(in)
 {
        char *cp = 0;
        static char line[50];
 {
        char *cp = 0;
        static char line[50];
-       int lna, net;
+       struct hostent *hp;
+       struct netent *np;
+       int lna, net, subnet;
 
 
-       net = in_netof(in);
-       lna = in_lnaof(in);
+       net = inet_netof(in);
+       subnet = inet_subnetof(in);
+       lna = inet_lnaof(in);
        if (!nflag) {
                if (lna == INADDR_ANY) {
        if (!nflag) {
                if (lna == INADDR_ANY) {
-                       struct netent *np = getnetbyaddr(net, AF_INET);
-
+                       np = getnetbyaddr(net, AF_INET);
                        if (np)
                                cp = np->n_name;
                        if (np)
                                cp = np->n_name;
+                       else if (net == 0)
+                               cp = "default";
+               } else if ((subnet != net) && ((lna & 0xff) == 0) &&
+                   (np = getnetbyaddr(subnet, AF_INET))) {
+                       struct in_addr subnaddr, inet_makeaddr();
+                       subnaddr = inet_makeaddr(subnet, INADDR_ANY);
+                       if (bcmp(&in, &subnaddr, sizeof(in)) == 0)
+                               cp = np->n_name;
+                       else
+                               goto host;
                } else {
                } else {
-                       struct hostent *hp;
-
+host:
                        hp = gethostbyaddr(&in, sizeof (struct in_addr),
                                AF_INET);
                        if (hp)
                        hp = gethostbyaddr(&in, sizeof (struct in_addr),
                                AF_INET);
                        if (hp)
@@ -138,3 +153,57 @@ routename(in)
        }
        return (line);
 }
        }
        return (line);
 }
+/*
+ * Print routing statistics
+ */
+rt_stats(off)
+       off_t off;
+{
+       struct rtstat rtstat;
+
+       if (off == 0) {
+               printf("rtstat: symbol not in namelist\n");
+               return;
+       }
+       klseek(kmem, off, 0);
+       read(kmem, (char *)&rtstat, sizeof (rtstat));
+       printf("routing:\n");
+       printf("\t%d bad routing redirect%s\n",
+               rtstat.rts_badredirect, plural(rtstat.rts_badredirect));
+       printf("\t%d dynamically created route%s\n",
+               rtstat.rts_dynamic, plural(rtstat.rts_dynamic));
+       printf("\t%d new gateway%s due to redirects\n",
+               rtstat.rts_newgateway, plural(rtstat.rts_newgateway));
+       printf("\t%d destination%s found unreachable\n",
+               rtstat.rts_unreach, plural(rtstat.rts_unreach));
+       printf("\t%d use%s of a wildcard route\n",
+               rtstat.rts_wildcard, plural(rtstat.rts_wildcard));
+}
+
+/*
+ * Return the possible subnetwork number from an internet address.
+ * If the address is of the form of a subnet address (most significant
+ * bit of the host part is set), believe the subnet exists.
+ * Otherwise, return the network number.
+ * SHOULD FIND OUT WHETHER THIS IS A LOCAL NETWORK BEFORE LOOKING
+ * INSIDE OF THE HOST PART.  We can only believe this if we have other
+ * information (e.g., we can find a name for this number).
+ */
+inet_subnetof(in)
+       struct in_addr in;
+{
+       register u_long i = ntohl(in.s_addr);
+
+       if (IN_CLASSA(i)) {
+               if (IN_SUBNETA(i))
+                       return ((i & IN_CLASSA_SUBNET) >> IN_CLASSA_SUBNSHIFT);
+               else
+                       return ((i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
+       } else if (IN_CLASSB(i)) {
+               if (IN_SUBNETB(i))
+                       return ((i & IN_CLASSB_SUBNET) >> IN_CLASSB_SUBNSHIFT);
+               else
+                       return ((i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
+       } else
+               return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
+}