added depend label
[unix-history] / usr / src / usr.bin / netstat / if.c
index 9c062d9..e03a86d 100644 (file)
@@ -1,21 +1,33 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)if.c       4.6 84/11/20";
-#endif
+static char sccsid[] = "@(#)if.c       5.4 (Berkeley) %G%";
+#endif not lint
 
 #include <sys/types.h>
 #include <sys/socket.h>
 
 #include <net/if.h>
 #include <netinet/in.h>
 
 #include <sys/types.h>
 #include <sys/socket.h>
 
 #include <net/if.h>
 #include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netns/ns.h>
 
 #include <stdio.h>
 
 #include <stdio.h>
+#include <signal.h>
+
+#define        YES     1
+#define        NO      0
 
 extern int kmem;
 extern int tflag;
 extern int nflag;
 extern char *interface;
 extern int unit;
 
 extern int kmem;
 extern int tflag;
 extern int nflag;
 extern char *interface;
 extern int unit;
-extern char *routename();
+extern char *routename(), *netname(), *ns_phost();
 
 /*
  * Print a description of the network interfaces.
 
 /*
  * Print a description of the network interfaces.
@@ -25,6 +37,11 @@ intpr(interval, ifnetaddr)
        off_t ifnetaddr;
 {
        struct ifnet ifnet;
        off_t ifnetaddr;
 {
        struct ifnet ifnet;
+       union {
+               struct ifaddr ifa;
+               struct in_ifaddr in;
+       } ifaddr;
+       off_t ifaddraddr;
        char name[16];
 
        if (ifnetaddr == 0) {
        char name[16];
 
        if (ifnetaddr == 0) {
@@ -32,11 +49,11 @@ intpr(interval, ifnetaddr)
                return;
        }
        if (interval) {
                return;
        }
        if (interval) {
-               sidewaysintpr(interval, ifnetaddr);
+               sidewaysintpr((unsigned)interval, ifnetaddr);
                return;
        }
        klseek(kmem, ifnetaddr, 0);
                return;
        }
        klseek(kmem, ifnetaddr, 0);
-       read(kmem, &ifnetaddr, sizeof ifnetaddr);
+       read(kmem, (char *)&ifnetaddr, sizeof ifnetaddr);
        printf("%-5.5s %-5.5s %-10.10s  %-12.12s %-7.7s %-5.5s %-7.7s %-5.5s",
                "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs",
                "Opkts", "Oerrs");
        printf("%-5.5s %-5.5s %-10.10s  %-12.12s %-7.7s %-5.5s %-7.7s %-5.5s",
                "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs",
                "Opkts", "Oerrs");
@@ -44,32 +61,95 @@ intpr(interval, ifnetaddr)
        if (tflag)
                printf(" %-6.6s", "Timer");
        putchar('\n');
        if (tflag)
                printf(" %-6.6s", "Timer");
        putchar('\n');
-       while (ifnetaddr) {
+       ifaddraddr = 0;
+       while (ifnetaddr || ifaddraddr) {
                struct sockaddr_in *sin;
                register char *cp;
                struct sockaddr_in *sin;
                register char *cp;
+               int n;
                char *index();
                char *index();
-               struct in_addr in, inet_makeaddr();
-
-               klseek(kmem, ifnetaddr, 0);
-               read(kmem, &ifnet, sizeof ifnet);
-               klseek(kmem, (int)ifnet.if_name, 0);
-               read(kmem, name, 16);
-               name[15] = '\0';
-               ifnetaddr = (off_t) ifnet.if_next;
-               if (interface != 0 &&
-                   (strcmp(name, interface) != 0 || unit != ifnet.if_unit))
-                       continue;
-               cp = index(name, '\0');
-               *cp++ = ifnet.if_unit + '0';
-               if ((ifnet.if_flags&IFF_UP) == 0)
-                       *cp++ = '*';
-               *cp = '\0';
+               struct in_addr inet_makeaddr();
+
+               if (ifaddraddr == 0) {
+                       klseek(kmem, ifnetaddr, 0);
+                       read(kmem, (char *)&ifnet, sizeof ifnet);
+                       klseek(kmem, (off_t)ifnet.if_name, 0);
+                       read(kmem, name, 16);
+                       name[15] = '\0';
+                       ifnetaddr = (off_t) ifnet.if_next;
+                       if (interface != 0 &&
+                           (strcmp(name, interface) != 0 || unit != ifnet.if_unit))
+                               continue;
+                       cp = index(name, '\0');
+                       *cp++ = ifnet.if_unit + '0';
+                       if ((ifnet.if_flags&IFF_UP) == 0)
+                               *cp++ = '*';
+                       *cp = '\0';
+                       ifaddraddr = (off_t)ifnet.if_addrlist;
+               }
                printf("%-5.5s %-5d ", name, ifnet.if_mtu);
                printf("%-5.5s %-5d ", name, ifnet.if_mtu);
-               sin = (struct sockaddr_in *)&ifnet.if_addr;
-               in = inet_makeaddr(ifnet.if_net, INADDR_ANY);
-               printf("%-10.10s  ", routename(in));
-               printf("%-12.12s %-7d %-5d %-7d %-5d %-6d",
-                   routename(sin->sin_addr),
+               if (ifaddraddr == 0) {
+                       printf("%-10.10s  ", "none");
+                       printf("%-12.12s ", "none");
+               } else {
+                       klseek(kmem, ifaddraddr, 0);
+                       read(kmem, (char *)&ifaddr, sizeof ifaddr);
+                       ifaddraddr = (off_t)ifaddr.ifa.ifa_next;
+                       switch (ifaddr.ifa.ifa_addr.sa_family) {
+                       case AF_UNSPEC:
+                               printf("%-10.10s  ", "none");
+                               printf("%-12.12s ", "none");
+                               break;
+                       case AF_INET:
+                               sin = (struct sockaddr_in *)&ifaddr.in.ia_addr;
+#ifdef notdef
+                               /* can't use inet_makeaddr because kernel
+                                * keeps nets unshifted.
+                                */
+                               in = inet_makeaddr(ifaddr.in.ia_subnet,
+                                       INADDR_ANY);
+                               printf("%-10.10s  ", netname(in));
+#else
+                               printf("%-10.10s  ",
+                                       netname(htonl(ifaddr.in.ia_subnet),
+                                               ifaddr.in.ia_subnetmask));
+#endif
+                               printf("%-12.12s ", routename(sin->sin_addr));
+                               break;
+                       case AF_NS:
+                               {
+                               struct sockaddr_ns *sns =
+                               (struct sockaddr_ns *)&ifaddr.in.ia_addr;
+                               u_long net;
+                               char host[8];
+                               char *ns_phost();
+
+                               *(union ns_net *) &net = sns->sns_addr.x_net;
+                               sprintf(host, "%lxH", ntohl(net));
+                               upHex(host);
+                               printf("ns:%-8s ", host);
+                               printf("%-12s ", ns_phost(sns));
+                               }
+                               break;
+                       default:
+                               printf("af%2d: ", ifaddr.ifa.ifa_addr.sa_family);
+                               for (cp = (char *)&ifaddr.ifa.ifa_addr +
+                                   sizeof(struct sockaddr) - 1;
+                                   cp >= ifaddr.ifa.ifa_addr.sa_data; --cp)
+                                       if (*cp != 0)
+                                               break;
+                               n = cp - (char *)ifaddr.ifa.ifa_addr.sa_data + 1;
+                               cp = (char *)ifaddr.ifa.ifa_addr.sa_data;
+                               if (n <= 6)
+                                       while (--n)
+                                               printf("%02d.", *cp++ & 0xff);
+                               else
+                                       while (--n)
+                                               printf("%02d", *cp++ & 0xff);
+                               printf("%02d ", *cp & 0xff);
+                               break;
+                       }
+               }
+               printf("%-7d %-5d %-7d %-5d %-6d",
                    ifnet.if_ipackets, ifnet.if_ierrors,
                    ifnet.if_opackets, ifnet.if_oerrors,
                    ifnet.if_collisions);
                    ifnet.if_ipackets, ifnet.if_ierrors,
                    ifnet.if_opackets, ifnet.if_oerrors,
                    ifnet.if_collisions);
@@ -89,14 +169,16 @@ struct     iftot {
        int     ift_co;                 /* collisions */
 } iftot[MAXIF];
 
        int     ift_co;                 /* collisions */
 } iftot[MAXIF];
 
+u_char signalled;                      /* set if alarm goes off "early" */
+
 /*
  * Print a running summary of interface statistics.
 /*
  * Print a running summary of interface statistics.
- * Repeat display every interval seconds, showing
- * statistics collected over that interval.  First
- * line printed at top of screen is always cumulative.
+ * Repeat display every interval seconds, showing statistics
+ * collected over that interval.  Assumes that interval is non-zero.
+ * First line printed at top of screen is always cumulative.
  */
 sidewaysintpr(interval, off)
  */
 sidewaysintpr(interval, off)
-       int interval;
+       unsigned interval;
        off_t off;
 {
        struct ifnet ifnet;
        off_t off;
 {
        struct ifnet ifnet;
@@ -104,10 +186,11 @@ sidewaysintpr(interval, off)
        register struct iftot *ip, *total;
        register int line;
        struct iftot *lastif, *sum, *interesting;
        register struct iftot *ip, *total;
        register int line;
        struct iftot *lastif, *sum, *interesting;
-       int maxtraffic;
+       int oldmask;
+       int catchalarm();
 
        klseek(kmem, off, 0);
 
        klseek(kmem, off, 0);
-       read(kmem, &firstifnet, sizeof (off_t));
+       read(kmem, (char *)&firstifnet, sizeof (off_t));
        lastif = iftot;
        sum = iftot + MAXIF - 1;
        total = sum - 1;
        lastif = iftot;
        sum = iftot + MAXIF - 1;
        total = sum - 1;
@@ -116,8 +199,8 @@ sidewaysintpr(interval, off)
                char *cp;
 
                klseek(kmem, off, 0);
                char *cp;
 
                klseek(kmem, off, 0);
-               read(kmem, &ifnet, sizeof ifnet);
-               klseek(kmem, (int)ifnet.if_name, 0);
+               read(kmem, (char *)&ifnet, sizeof ifnet);
+               klseek(kmem, (off_t)ifnet.if_name, 0);
                ip->ift_name[0] = '(';
                read(kmem, ip->ift_name + 1, 15);
                if (interface && strcmp(ip->ift_name + 1, interface) == 0 &&
                ip->ift_name[0] = '(';
                read(kmem, ip->ift_name + 1, 15);
                if (interface && strcmp(ip->ift_name + 1, interface) == 0 &&
@@ -132,6 +215,10 @@ sidewaysintpr(interval, off)
                off = (off_t) ifnet.if_next;
        }
        lastif = ip;
                off = (off_t) ifnet.if_next;
        }
        lastif = ip;
+
+       (void)signal(SIGALRM, catchalarm);
+       signalled = NO;
+       (void)alarm(interval);
 banner:
        printf("    input   %-6.6s    output       ", interesting->ift_name);
        if (lastif - iftot > 0)
 banner:
        printf("    input   %-6.6s    output       ", interesting->ift_name);
        if (lastif - iftot > 0)
@@ -160,7 +247,7 @@ loop:
        sum->ift_co = 0;
        for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) {
                klseek(kmem, off, 0);
        sum->ift_co = 0;
        for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) {
                klseek(kmem, off, 0);
-               read(kmem, &ifnet, sizeof ifnet);
+               read(kmem, (char *)&ifnet, sizeof ifnet);
                if (ip == interesting)
                        printf("%-7d %-5d %-7d %-5d %-5d ",
                                ifnet.if_ipackets - ip->ift_ip,
                if (ip == interesting)
                        printf("%-7d %-5d %-7d %-5d %-5d ",
                                ifnet.if_ipackets - ip->ift_ip,
@@ -190,10 +277,24 @@ loop:
        *total = *sum;
        fflush(stdout);
        line++;
        *total = *sum;
        fflush(stdout);
        line++;
-       if (interval)
-               sleep(interval);
+       oldmask = sigblock(sigmask(SIGALRM));
+       if (! signalled) {
+               sigpause(0);
+       }
+       sigsetmask(oldmask);
+       signalled = NO;
+       (void)alarm(interval);
        if (line == 21)
                goto banner;
        goto loop;
        /*NOTREACHED*/
 }
        if (line == 21)
                goto banner;
        goto loop;
        /*NOTREACHED*/
 }
+
+/*
+ * Called if an interval expires before sidewaysintpr has completed a loop.
+ * Sets a flag to not wait for the alarm.
+ */
+catchalarm()
+{
+       signalled = YES;
+}