home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / netstat / if.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-18  |  9.6 KB  |  361 lines

  1. /*
  2.  * Copyright (c) 1983, 1988 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)if.c    5.15 (Berkeley) 3/1/91";
  36. #endif /* not lint */
  37.  
  38. #include <sys/types.h>
  39. #include <sys/socket.h>
  40.  
  41. #include <net/if.h>
  42. #include <net/if_dl.h>
  43. #include <netinet/in.h>
  44. #include <netinet/in_var.h>
  45. #include <netns/ns.h>
  46. #include <netns/ns_if.h>
  47. #include <netiso/iso.h>
  48. #include <netiso/iso_var.h>
  49.  
  50. #include <stdio.h>
  51. #include <signal.h>
  52.  
  53. #define    YES    1
  54. #define    NO    0
  55.  
  56. extern    int tflag;
  57. extern    int dflag;
  58. extern    int nflag;
  59. extern    char *interface;
  60. extern    int unit;
  61. extern    char *routename(), *netname(), *ns_phost();
  62. char *index();
  63.  
  64. /*
  65.  * Print a description of the network interfaces.
  66.  */
  67. intpr(interval, ifnetaddr)
  68.     int interval;
  69.     off_t ifnetaddr;
  70. {
  71.     struct ifnet ifnet;
  72.     union {
  73.         struct ifaddr ifa;
  74.         struct in_ifaddr in;
  75.         struct ns_ifaddr ns;
  76.         struct iso_ifaddr iso;
  77.     } ifaddr;
  78.     off_t ifaddraddr;
  79.     struct sockaddr *sa;
  80.     char name[16];
  81.  
  82.     if (ifnetaddr == 0) {
  83.         printf("ifnet: symbol not defined\n");
  84.         return;
  85.     }
  86.     if (interval) {
  87.         sidewaysintpr((unsigned)interval, ifnetaddr);
  88.         return;
  89.     }
  90.     kvm_read(ifnetaddr, (char *)&ifnetaddr, sizeof ifnetaddr);
  91.     printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s %8.8s %5.5s",
  92.         "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs",
  93.         "Opkts", "Oerrs");
  94.     printf(" %5s", "Coll");
  95.     if (tflag)
  96.         printf(" %s", "Time");
  97.     if (dflag)
  98.         printf(" %s", "Drop");
  99.     putchar('\n');
  100.     ifaddraddr = 0;
  101.     while (ifnetaddr || ifaddraddr) {
  102.         struct sockaddr_in *sin;
  103.         register char *cp;
  104.         int n, m;
  105.         struct in_addr inet_makeaddr();
  106.  
  107.         if (ifaddraddr == 0) {
  108.             kvm_read(ifnetaddr, (char *)&ifnet, sizeof ifnet);
  109.             kvm_read((off_t)ifnet.if_name, name, 16);
  110.             name[15] = '\0';
  111.             ifnetaddr = (off_t) ifnet.if_next;
  112.             if (interface != 0 &&
  113.                 (strcmp(name, interface) != 0 || unit != ifnet.if_unit))
  114.                 continue;
  115.             cp = index(name, '\0');
  116.             *cp++ = ifnet.if_unit + '0';
  117.             if ((ifnet.if_flags&IFF_UP) == 0)
  118.                 *cp++ = '*';
  119.             *cp = '\0';
  120.             ifaddraddr = (off_t)ifnet.if_addrlist;
  121.         }
  122.         printf("%-5.5s %-5d ", name, ifnet.if_mtu);
  123.         if (ifaddraddr == 0) {
  124.             printf("%-11.11s ", "none");
  125.             printf("%-15.15s ", "none");
  126.         } else {
  127.             kvm_read(ifaddraddr, (char *)&ifaddr, sizeof ifaddr);
  128. #define CP(x) ((char *)(x))
  129.             cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) +
  130.                 CP(&ifaddr); sa = (struct sockaddr *)cp;
  131.             switch (sa->sa_family) {
  132.             case AF_UNSPEC:
  133.                 printf("%-11.11s ", "none");
  134.                 printf("%-15.15s ", "none");
  135.                 break;
  136.             case AF_INET:
  137.                 sin = (struct sockaddr_in *)sa;
  138. #ifdef notdef
  139.                 /* can't use inet_makeaddr because kernel
  140.                  * keeps nets unshifted.
  141.                  */
  142.                 in = inet_makeaddr(ifaddr.in.ia_subnet,
  143.                     INADDR_ANY);
  144.                 printf("%-11.11s ", netname(in));
  145. #else
  146.                 printf("%-11.11s ",
  147.                     netname(htonl(ifaddr.in.ia_subnet),
  148.                         ifaddr.in.ia_subnetmask));
  149. #endif
  150.                 printf("%-15.15s ", routename(sin->sin_addr));
  151.                 break;
  152.             case AF_NS:
  153.                 {
  154.                 struct sockaddr_ns *sns =
  155.                     (struct sockaddr_ns *)sa;
  156.                 u_long net;
  157.                 char netnum[8];
  158.                 char *ns_phost();
  159.  
  160.                 *(union ns_net *) &net = sns->sns_addr.x_net;
  161.         sprintf(netnum, "%lxH", ntohl(net));
  162.                 upHex(netnum);
  163.                 printf("ns:%-8s ", netnum);
  164.                 printf("%-15s ", ns_phost(sns));
  165.                 }
  166.                 break;
  167.             case AF_LINK:
  168.                 {
  169.                 struct sockaddr_dl *sdl =
  170.                     (struct sockaddr_dl *)sa;
  171.                     cp = (char *)LLADDR(sdl);
  172.                     n = sdl->sdl_alen;
  173.                 }
  174.                 m = printf("<Link>");
  175.                 goto hexprint;
  176.             default:
  177.                 m = printf("(%d)", sa->sa_family);
  178.                 for (cp = sa->sa_len + (char *)sa;
  179.                     --cp > sa->sa_data && (*cp == 0);) {}
  180.                 n = cp - sa->sa_data + 1;
  181.                 cp = sa->sa_data;
  182.             hexprint:
  183.                 while (--n >= 0)
  184.                     m += printf("%x%c", *cp++ & 0xff,
  185.                             n > 0 ? '.' : ' ');
  186.                 m = 28 - m;
  187.                 while (m-- > 0)
  188.                     putchar(' ');
  189.                 break;
  190.             }
  191.             ifaddraddr = (off_t)ifaddr.ifa.ifa_next;
  192.         }
  193.         printf("%8d %5d %8d %5d %5d",
  194.             ifnet.if_ipackets, ifnet.if_ierrors,
  195.             ifnet.if_opackets, ifnet.if_oerrors,
  196.             ifnet.if_collisions);
  197.         if (tflag)
  198.             printf(" %3d", ifnet.if_timer);
  199.         if (dflag)
  200.             printf(" %3d", ifnet.if_snd.ifq_drops);
  201.         putchar('\n');
  202.     }
  203. }
  204.  
  205. #define    MAXIF    10
  206. struct    iftot {
  207.     char    ift_name[16];        /* interface name */
  208.     int    ift_ip;            /* input packets */
  209.     int    ift_ie;            /* input errors */
  210.     int    ift_op;            /* output packets */
  211.     int    ift_oe;            /* output errors */
  212.     int    ift_co;            /* collisions */
  213.     int    ift_dr;            /* drops */
  214. } iftot[MAXIF];
  215.  
  216. u_char    signalled;            /* set if alarm goes off "early" */
  217.  
  218. /*
  219.  * Print a running summary of interface statistics.
  220.  * Repeat display every interval seconds, showing statistics
  221.  * collected over that interval.  Assumes that interval is non-zero.
  222.  * First line printed at top of screen is always cumulative.
  223.  */
  224. sidewaysintpr(interval, off)
  225.     unsigned interval;
  226.     off_t off;
  227. {
  228.     struct ifnet ifnet;
  229.     off_t firstifnet;
  230.     register struct iftot *ip, *total;
  231.     register int line;
  232.     struct iftot *lastif, *sum, *interesting;
  233.     int oldmask;
  234.     void catchalarm();
  235.  
  236.     kvm_read(off, (char *)&firstifnet, sizeof (off_t));
  237.     lastif = iftot;
  238.     sum = iftot + MAXIF - 1;
  239.     total = sum - 1;
  240.     interesting = iftot;
  241.     for (off = firstifnet, ip = iftot; off;) {
  242.         char *cp;
  243.  
  244.         kvm_read(off, (char *)&ifnet, sizeof ifnet);
  245.         ip->ift_name[0] = '(';
  246.         kvm_read((off_t)ifnet.if_name, ip->ift_name + 1, 15);
  247.         if (interface && strcmp(ip->ift_name + 1, interface) == 0 &&
  248.             unit == ifnet.if_unit)
  249.             interesting = ip;
  250.         ip->ift_name[15] = '\0';
  251.         cp = index(ip->ift_name, '\0');
  252.         sprintf(cp, "%d)", ifnet.if_unit);
  253.         ip++;
  254.         if (ip >= iftot + MAXIF - 2)
  255.             break;
  256.         off = (off_t) ifnet.if_next;
  257.     }
  258.     lastif = ip;
  259.  
  260.     (void)signal(SIGALRM, catchalarm);
  261.     signalled = NO;
  262.     (void)alarm(interval);
  263. banner:
  264.     printf("   input    %-6.6s    output       ", interesting->ift_name);
  265.     if (lastif - iftot > 0) {
  266.         if (dflag)
  267.             printf("      ");
  268.         printf("     input   (Total)    output");
  269.     }
  270.     for (ip = iftot; ip < iftot + MAXIF; ip++) {
  271.         ip->ift_ip = 0;
  272.         ip->ift_ie = 0;
  273.         ip->ift_op = 0;
  274.         ip->ift_oe = 0;
  275.         ip->ift_co = 0;
  276.         ip->ift_dr = 0;
  277.     }
  278.     putchar('\n');
  279.     printf("%8.8s %5.5s %8.8s %5.5s %5.5s ",
  280.         "packets", "errs", "packets", "errs", "colls");
  281.     if (dflag)
  282.         printf("%5.5s ", "drops");
  283.     if (lastif - iftot > 0)
  284.         printf(" %8.8s %5.5s %8.8s %5.5s %5.5s",
  285.             "packets", "errs", "packets", "errs", "colls");
  286.     if (dflag)
  287.         printf(" %5.5s", "drops");
  288.     putchar('\n');
  289.     fflush(stdout);
  290.     line = 0;
  291. loop:
  292.     sum->ift_ip = 0;
  293.     sum->ift_ie = 0;
  294.     sum->ift_op = 0;
  295.     sum->ift_oe = 0;
  296.     sum->ift_co = 0;
  297.     sum->ift_dr = 0;
  298.     for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) {
  299.         kvm_read(off, (char *)&ifnet, sizeof ifnet);
  300.         if (ip == interesting) {
  301.             printf("%8d %5d %8d %5d %5d",
  302.                 ifnet.if_ipackets - ip->ift_ip,
  303.                 ifnet.if_ierrors - ip->ift_ie,
  304.                 ifnet.if_opackets - ip->ift_op,
  305.                 ifnet.if_oerrors - ip->ift_oe,
  306.                 ifnet.if_collisions - ip->ift_co);
  307.             if (dflag)
  308.                 printf(" %5d",
  309.                     ifnet.if_snd.ifq_drops - ip->ift_dr);
  310.         }
  311.         ip->ift_ip = ifnet.if_ipackets;
  312.         ip->ift_ie = ifnet.if_ierrors;
  313.         ip->ift_op = ifnet.if_opackets;
  314.         ip->ift_oe = ifnet.if_oerrors;
  315.         ip->ift_co = ifnet.if_collisions;
  316.         ip->ift_dr = ifnet.if_snd.ifq_drops;
  317.         sum->ift_ip += ip->ift_ip;
  318.         sum->ift_ie += ip->ift_ie;
  319.         sum->ift_op += ip->ift_op;
  320.         sum->ift_oe += ip->ift_oe;
  321.         sum->ift_co += ip->ift_co;
  322.         sum->ift_dr += ip->ift_dr;
  323.         off = (off_t) ifnet.if_next;
  324.     }
  325.     if (lastif - iftot > 0) {
  326.         printf("  %8d %5d %8d %5d %5d",
  327.             sum->ift_ip - total->ift_ip,
  328.             sum->ift_ie - total->ift_ie,
  329.             sum->ift_op - total->ift_op,
  330.             sum->ift_oe - total->ift_oe,
  331.             sum->ift_co - total->ift_co);
  332.         if (dflag)
  333.             printf(" %5d", sum->ift_dr - total->ift_dr);
  334.     }
  335.     *total = *sum;
  336.     putchar('\n');
  337.     fflush(stdout);
  338.     line++;
  339.     oldmask = sigblock(sigmask(SIGALRM));
  340.     if (! signalled) {
  341.         sigpause(0);
  342.     }
  343.     sigsetmask(oldmask);
  344.     signalled = NO;
  345.     (void)alarm(interval);
  346.     if (line == 21)
  347.         goto banner;
  348.     goto loop;
  349.     /*NOTREACHED*/
  350. }
  351.  
  352. /*
  353.  * Called if an interval expires before sidewaysintpr has completed a loop.
  354.  * Sets a flag to not wait for the alarm.
  355.  */
  356. void
  357. catchalarm()
  358. {
  359.     signalled = YES;
  360. }
  361.