home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / E-zine / Magazines / crh / freebsd / rootkit / netstat / if.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-05-27  |  12.6 KB  |  495 lines

  1. /*
  2.  * Copyright (c) 1983, 1988, 1993
  3.  *    The Regents of the University of California.  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    8.3 (Berkeley) 4/28/95";
  36. #endif /* not lint */
  37.  
  38. #include <sys/types.h>
  39. #include <sys/protosw.h>
  40. #include <sys/socket.h>
  41.  
  42. #include <net/if.h>
  43. #include <net/if_dl.h>
  44. #include <net/if_types.h>
  45. #include <netinet/in.h>
  46. #include <netinet/in_var.h>
  47. #define KERNEL 1
  48. #include <netinet/if_ether.h>
  49. #undef KERNEL
  50. #include <netipx/ipx.h>
  51. #include <netipx/ipx_if.h>
  52. #ifdef NS
  53. #include <netns/ns.h>
  54. #include <netns/ns_if.h>
  55. #endif
  56. #ifdef ISO
  57. #include <netiso/iso.h>
  58. #include <netiso/iso_var.h>
  59. #endif
  60. #include <arpa/inet.h>
  61.  
  62. #include <signal.h>
  63. #include <stdio.h>
  64. #include <string.h>
  65. #include <unistd.h>
  66.  
  67. #include "netstat.h"
  68.  
  69. #define    YES    1
  70. #define    NO    0
  71.  
  72. static void sidewaysintpr __P((u_int, u_long));
  73. static void catchalarm __P((int));
  74.  
  75. /*
  76.  * Print a description of the network interfaces.
  77.  */
  78. void
  79. intpr(interval, ifnetaddr)
  80.     int interval;
  81.     u_long ifnetaddr;
  82. {
  83.     struct ifnet ifnet;
  84.     union {
  85.         struct ifaddr ifa;
  86.         struct in_ifaddr in;
  87.         struct ipx_ifaddr ipx;
  88. #ifdef NS
  89.         struct ns_ifaddr ns;
  90. #endif
  91. #ifdef ISO
  92.         struct iso_ifaddr iso;
  93. #endif
  94.     } ifaddr;
  95.     u_long ifaddraddr;
  96.     u_long ifaddrfound;
  97.     u_long ifnetfound;
  98.     struct sockaddr *sa;
  99.     char name[32], tname[16];
  100.  
  101.     if (ifnetaddr == 0) {
  102.         printf("ifnet: symbol not defined\n");
  103.         return;
  104.     }
  105.     if (interval) {
  106.         sidewaysintpr((unsigned)interval, ifnetaddr);
  107.         return;
  108.     }
  109.     if (kread(ifnetaddr, (char *)&ifnetaddr, sizeof ifnetaddr))
  110.         return;
  111.     printf("%-5.5s %-5.5s %-13.13s %-15.15s %8.8s %5.5s",
  112.         "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs");
  113.     if (bflag)
  114.         printf(" %10.10s","Ibytes");
  115.     printf(" %8.8s %5.5s", "Opkts", "Oerrs");
  116.     if (bflag)
  117.         printf(" %10.10s","Obytes");
  118.     printf(" %5s", "Coll");
  119.     if (tflag)
  120.         printf(" %s", "Time");
  121.     if (dflag)
  122.         printf(" %s", "Drop");
  123.     putchar('\n');
  124.     ifaddraddr = 0;
  125.     while (ifnetaddr || ifaddraddr) {
  126.         struct sockaddr_in *sin;
  127.         register char *cp;
  128.         int n, m;
  129.  
  130.         if (ifaddraddr == 0) {
  131.             ifnetfound = ifnetaddr;
  132.             if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) ||
  133.                 kread((u_long)ifnet.if_name, tname, 16))
  134.                 return;
  135.             tname[15] = '\0';
  136.             ifnetaddr = (u_long)ifnet.if_next;
  137.             snprintf(name, 32, "%s%d", tname, ifnet.if_unit);
  138.             if (interface != 0 && (strcmp(name, interface) != 0))
  139.                 continue;
  140.             cp = index(name, '\0');
  141.             if ((ifnet.if_flags&IFF_UP) == 0)
  142.                 *cp++ = '*';
  143.             *cp = '\0';
  144.             ifaddraddr = (u_long)ifnet.if_addrlist;
  145.         }
  146.         printf("%-5.5s %-5lu ", name, ifnet.if_mtu);
  147.         ifaddrfound = ifaddraddr;
  148.         if (ifaddraddr == 0) {
  149.             printf("%-13.13s ", "none");
  150.             printf("%-15.15s ", "none");
  151.         } else {
  152.             if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) {
  153.                 ifaddraddr = 0;
  154.                 continue;
  155.             }
  156. #define CP(x) ((char *)(x))
  157.             cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) +
  158.                 CP(&ifaddr); sa = (struct sockaddr *)cp;
  159.             switch (sa->sa_family) {
  160.             case AF_UNSPEC:
  161.                 printf("%-13.13s ", "none");
  162.                 printf("%-15.15s ", "none");
  163.                 break;
  164.             case AF_INET:
  165.                 sin = (struct sockaddr_in *)sa;
  166. #ifdef notdef
  167.                 /* can't use inet_makeaddr because kernel
  168.                  * keeps nets unshifted.
  169.                  */
  170.                 in = inet_makeaddr(ifaddr.in.ia_subnet,
  171.                     INADDR_ANY);
  172.                 printf("%-13.13s ", netname(in.s_addr,
  173.                     ifaddr.in.ia_subnetmask));
  174. #else
  175.                 printf("%-13.13s ",
  176.                     netname(htonl(ifaddr.in.ia_subnet),
  177.                     ifaddr.in.ia_subnetmask));
  178. #endif
  179.                 printf("%-15.15s ",
  180.                     routename(sin->sin_addr.s_addr));
  181.                 break;
  182.             case AF_IPX:
  183.                 {
  184.                 struct sockaddr_ipx *sipx =
  185.                     (struct sockaddr_ipx *)sa;
  186.                 u_long net;
  187.                 char netnum[10];
  188.  
  189.                 *(union ipx_net *) &net = sipx->sipx_addr.x_net;
  190.                 sprintf(netnum, "%lx", ntohl(net));
  191.                 printf("ipx:%-8s ", netnum);
  192. /*                printf("ipx:%-8s ", netname(net, 0L)); */
  193.                 printf("%-15s ",
  194.                     ipx_phost((struct sockaddr *)sipx));
  195.                 }
  196.                 break;
  197.  
  198.             case AF_APPLETALK:
  199.                 printf("atalk:%-12.12s ",atalk_print(sa,0x10) );
  200.                 printf("%-9.9s  ",atalk_print(sa,0x0b) );
  201.                 break;
  202. #ifdef NS
  203.             case AF_NS:
  204.                 {
  205.                 struct sockaddr_ns *sns =
  206.                     (struct sockaddr_ns *)sa;
  207.                 u_long net;
  208.                 char netnum[10];
  209.  
  210.                 *(union ns_net *) &net = sns->sns_addr.x_net;
  211.                 sprintf(netnum, "%lxH", ntohl(net));
  212.                 upHex(netnum);
  213.                 printf("ns:%-8s ", netnum);
  214.                 printf("%-15s ",
  215.                     ns_phost((struct sockaddr *)sns));
  216.                 }
  217.                 break;
  218. #endif
  219.             case AF_LINK:
  220.                 {
  221.                 struct sockaddr_dl *sdl =
  222.                     (struct sockaddr_dl *)sa;
  223.                     cp = (char *)LLADDR(sdl);
  224.                     n = sdl->sdl_alen;
  225.                 }
  226.                 m = printf("%-11.11s ", "<Link>");
  227.                 goto hexprint;
  228.             default:
  229.                 m = printf("(%d)", sa->sa_family);
  230.                 for (cp = sa->sa_len + (char *)sa;
  231.                     --cp > sa->sa_data && (*cp == 0);) {}
  232.                 n = cp - sa->sa_data + 1;
  233.                 cp = sa->sa_data;
  234.             hexprint:
  235.                 while (--n >= 0)
  236.                     m += printf("%02x%c", *cp++ & 0xff,
  237.                             n > 0 ? '.' : ' ');
  238.                 m = 30 - m;
  239.                 while (m-- > 0)
  240.                     putchar(' ');
  241.                 break;
  242.             }
  243.             ifaddraddr = (u_long)ifaddr.ifa.ifa_next;
  244.         }
  245.         printf("%8lu %5lu ",
  246.             ifnet.if_ipackets, ifnet.if_ierrors);
  247.         if (bflag)
  248.             printf("%10lu ", ifnet.if_ibytes);
  249.         printf("%8lu %5lu ",
  250.             ifnet.if_opackets, ifnet.if_oerrors);
  251.         if (bflag)
  252.             printf("%10lu ", ifnet.if_obytes);
  253.         printf("%5lu", ifnet.if_collisions);
  254.         if (tflag)
  255.             printf(" %3d", ifnet.if_timer);
  256.         if (dflag)
  257.             printf(" %3d", ifnet.if_snd.ifq_drops);
  258.         putchar('\n');
  259.         if (aflag && ifaddrfound) {
  260.             /*
  261.              * Print family's multicast addresses
  262.              */
  263.             switch (sa->sa_family) {
  264.             case AF_INET:
  265.             {
  266.                 u_long multiaddr;
  267.                 struct in_multi inm;
  268.  
  269.                 multiaddr = (u_long)ifaddr.in.ia_multiaddrs.lh_first;
  270.                 while (multiaddr != 0) {
  271.                     kread(multiaddr, (char *)&inm,
  272.                             sizeof inm);
  273.                     multiaddr = (u_long)inm.inm_entry.le_next;
  274.                     printf("%23s %s\n", "",
  275.                         routename(inm.inm_addr.s_addr));
  276.                 }
  277.                 break;
  278.             }
  279.             case AF_LINK:
  280.                 switch (ifnet.if_type) {
  281.                 case IFT_ETHER:
  282.                 case IFT_FDDI:    /*XXX*/
  283.                 {
  284.                     off_t multiaddr;
  285.                     struct arpcom ac;
  286.                     struct ether_multi enm;
  287.  
  288.                     kread(ifnetfound, (char *)&ac, sizeof ac);
  289.                     multiaddr = (u_long)ac.ac_multiaddrs;
  290.                     while (multiaddr != 0) {
  291.                         kread(multiaddr, (char *)&enm,
  292.                             sizeof enm);
  293.                         multiaddr = (u_long)enm.enm_next;
  294.                         printf("%23s %s", "",
  295.                         ether_ntoa(&enm.enm_addrlo));
  296.                         if (bcmp(&enm.enm_addrlo,
  297.                              &enm.enm_addrhi, 6) != 0)
  298.                         printf(" to %s",
  299.                             ether_ntoa(&enm.enm_addrhi));
  300.                         printf("\n");
  301.                     }
  302.                     break;
  303.                 }
  304.                 default:
  305.                     break;
  306.                 }
  307.             default:
  308.                 break;
  309.             }
  310.         }
  311.     }
  312. }
  313.  
  314. #define    MAXIF    10
  315. struct    iftot {
  316.     char    ift_name[16];        /* interface name */
  317.     u_int    ift_ip;            /* input packets */
  318.     u_int    ift_ie;            /* input errors */
  319.     u_int    ift_op;            /* output packets */
  320.     u_int    ift_oe;            /* output errors */
  321.     u_int    ift_co;            /* collisions */
  322.     u_int    ift_dr;            /* drops */
  323.     u_int    ift_ib;            /* input bytes */
  324.     u_int    ift_ob;            /* output bytes */
  325. } iftot[MAXIF];
  326.  
  327. u_char    signalled;            /* set if alarm goes off "early" */
  328.  
  329. /*
  330.  * Print a running summary of interface statistics.
  331.  * Repeat display every interval seconds, showing statistics
  332.  * collected over that interval.  Assumes that interval is non-zero.
  333.  * First line printed at top of screen is always cumulative.
  334.  */
  335. static void
  336. sidewaysintpr(interval, off)
  337.     unsigned interval;
  338.     u_long off;
  339. {
  340.     struct ifnet ifnet;
  341.     u_long firstifnet;
  342.     register struct iftot *ip, *total;
  343.     register int line;
  344.     struct iftot *lastif, *sum, *interesting;
  345.     int oldmask, first;
  346.     u_long interesting_off;
  347.  
  348.     if (kread(off, (char *)&firstifnet, sizeof (u_long)))
  349.         return;
  350.     lastif = iftot;
  351.     sum = iftot + MAXIF - 1;
  352.     total = sum - 1;
  353.     interesting = NULL;
  354.     interesting_off = 0;
  355.     for (off = firstifnet, ip = iftot; off;) {
  356.         char name[16], tname[16];
  357.  
  358.         if (kread(off, (char *)&ifnet, sizeof ifnet))
  359.             break;
  360.         if (kread((u_long)ifnet.if_name, tname, 16))
  361.             break;
  362.         tname[15] = '\0';
  363.         snprintf(name, 16, "%s%d", tname, ifnet.if_unit);
  364.         if (interface && strcmp(name, interface) == 0) {
  365.             interesting = ip;
  366.             interesting_off = off;
  367.         }
  368.         snprintf(ip->ift_name, 16, "(%s)", name);;
  369.         ip++;
  370.         if (ip >= iftot + MAXIF - 2)
  371.             break;
  372.         off = (u_long) ifnet.if_next;
  373.     }
  374.     lastif = ip;
  375.  
  376.     (void)signal(SIGALRM, catchalarm);
  377.     signalled = NO;
  378.     (void)alarm(interval);
  379.     for (ip = iftot; ip < iftot + MAXIF; ip++) {
  380.         ip->ift_ip = 0;
  381.         ip->ift_ie = 0;
  382.         ip->ift_ib = 0;
  383.         ip->ift_op = 0;
  384.         ip->ift_oe = 0;
  385.         ip->ift_ob = 0;
  386.         ip->ift_co = 0;
  387.         ip->ift_dr = 0;
  388.     }
  389.     first = 1;
  390. banner:
  391.     printf("%17s %14s %16s", "input",
  392.         interesting ? interesting->ift_name : "(Total)", "output");
  393.     putchar('\n');
  394.     printf("%10s %5s %10s %10s %5s %10s %5s",
  395.         "packets", "errs", "bytes", "packets", "errs", "bytes", "colls");
  396.     if (dflag)
  397.         printf(" %5.5s", "drops");
  398.     putchar('\n');
  399.     fflush(stdout);
  400.     line = 0;
  401. loop:
  402.     if (interesting != NULL) {
  403.         ip = interesting;
  404.         if (kread(interesting_off, (char *)&ifnet, sizeof ifnet)) {
  405.             printf("???\n");
  406.             exit(1);
  407.         };
  408.         if (!first) {
  409.             printf("%10lu %5lu %10lu %10lu %5lu %10lu %5lu",
  410.                 ifnet.if_ipackets - ip->ift_ip,
  411.                 ifnet.if_ierrors - ip->ift_ie,
  412.                 ifnet.if_ibytes - ip->ift_ib,
  413.                 ifnet.if_opackets - ip->ift_op,
  414.                 ifnet.if_oerrors - ip->ift_oe,
  415.                 ifnet.if_obytes - ip->ift_ob,
  416.                 ifnet.if_collisions - ip->ift_co);
  417.             if (dflag)
  418.                 printf(" %5u", ifnet.if_snd.ifq_drops - ip->ift_dr);
  419.         }
  420.         ip->ift_ip = ifnet.if_ipackets;
  421.         ip->ift_ie = ifnet.if_ierrors;
  422.         ip->ift_ib = ifnet.if_ibytes;
  423.         ip->ift_op = ifnet.if_opackets;
  424.         ip->ift_oe = ifnet.if_oerrors;
  425.         ip->ift_ob = ifnet.if_obytes;
  426.         ip->ift_co = ifnet.if_collisions;
  427.         ip->ift_dr = ifnet.if_snd.ifq_drops;
  428.     } else {
  429.         sum->ift_ip = 0;
  430.         sum->ift_ie = 0;
  431.         sum->ift_ib = 0;
  432.         sum->ift_op = 0;
  433.         sum->ift_oe = 0;
  434.         sum->ift_ob = 0;
  435.         sum->ift_co = 0;
  436.         sum->ift_dr = 0;
  437.         for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) {
  438.             if (kread(off, (char *)&ifnet, sizeof ifnet)) {
  439.                 off = 0;
  440.                 continue;
  441.             }
  442.             sum->ift_ip += ifnet.if_ipackets;
  443.             sum->ift_ie += ifnet.if_ierrors;
  444.             sum->ift_ib += ifnet.if_ibytes;
  445.             sum->ift_op += ifnet.if_opackets;
  446.             sum->ift_oe += ifnet.if_oerrors;
  447.             sum->ift_ob += ifnet.if_obytes;
  448.             sum->ift_co += ifnet.if_collisions;
  449.             sum->ift_dr += ifnet.if_snd.ifq_drops;
  450.             off = (u_long) ifnet.if_next;
  451.         }
  452.         if (!first) {
  453.             printf("%10u %5u %10u %10u %5u %10u %5u",
  454.                 sum->ift_ip - total->ift_ip,
  455.                 sum->ift_ie - total->ift_ie,
  456.                 sum->ift_ib - total->ift_ib,
  457.                 sum->ift_op - total->ift_op,
  458.                 sum->ift_oe - total->ift_oe,
  459.                 sum->ift_ob - total->ift_ob,
  460.                 sum->ift_co - total->ift_co);
  461.             if (dflag)
  462.                 printf(" %5u", sum->ift_dr - total->ift_dr);
  463.         }
  464.         *total = *sum;
  465.     }
  466.     if (!first)
  467.         putchar('\n');
  468.     fflush(stdout);
  469.     oldmask = sigblock(sigmask(SIGALRM));
  470.     if (! signalled) {
  471.         sigpause(0);
  472.     }
  473.     sigsetmask(oldmask);
  474.     signalled = NO;
  475.     (void)alarm(interval);
  476.     line++;
  477.     first = 0;
  478.     if (line == 21)
  479.         goto banner;
  480.     else
  481.         goto loop;
  482.     /*NOTREACHED*/
  483. }
  484.  
  485. /*
  486.  * Called if an interval expires before sidewaysintpr has completed a loop.
  487.  * Sets a flag to not wait for the alarm.
  488.  */
  489. static void
  490. catchalarm(signo)
  491.     int signo;
  492. {
  493.     signalled = YES;
  494. }
  495.