home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / nfs / nfswatch4.0 / snoop.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-01  |  3.5 KB  |  192 lines

  1. #ifndef lint
  2. static char *RCSid = "$Header: /home/harbor/davy/system/nfswatch/RCS/snoop.c,v 4.0 1993/03/01 19:59:00 davy Exp $";
  3. #endif
  4.  
  5. #include "os.h"
  6.  
  7. #ifdef USE_SNOOP
  8. /*
  9.  * snoop.c - routines for snooping on network traffic via the SGI
  10.  *         provided snoop(7p) network monitoring protocol
  11.  *         -- works under IRIX 3.2.* and IRIX 3.3.[12]
  12.  *
  13.  * NOTE: must be "root" to use this
  14.  *
  15.  * Tim Hudson
  16.  * Mincom Pty Ltd
  17.  * Mincom Centre
  18.  * Juliette Street
  19.  * Greenslopes 4120
  20.  * Brisbane Australia
  21.  * tjh@mincom.oz.au
  22.  *
  23.  */
  24. #include <sys/param.h>
  25. #include <sys/stropts.h>
  26. #include <sys/socket.h>
  27. #include <sys/ioctl.h>
  28. #include <sys/time.h>
  29. #include <sys/file.h>
  30. #include <net/if.h>
  31. #include <signal.h>
  32. #include <stdio.h>
  33.  
  34. #include <net/soioctl.h>
  35. #include <net/raw.h>
  36. #include <netinet/if_ether.h>
  37.  
  38. #include "nfswatch.h"
  39. #include "externs.h"
  40.  
  41. /*
  42.  * setup_snoop_dev - set up the network interface tap.
  43.  */
  44. int
  45. setup_snoop_dev(device)
  46. char **device;
  47. {
  48.     int n, s;
  49.     int i, res;
  50.     u_int chunksz;
  51.     u_long if_flags;
  52.     char buf[BUFSIZ];
  53.     struct ifconf ifc;
  54.     struct snoopfilter sf;
  55.     struct timeval timeout;
  56.     struct ifreq ifr, *ifrp;
  57.     struct sockaddr_raw sr, sn;
  58.  
  59.     /*
  60.      * If the interface device was not specified,
  61.      * get the default one.
  62.      */
  63.     if (*device == NULL) {
  64.         /*
  65.          * Grab a socket.
  66.          */
  67.         if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  68.             error("socket");
  69.             finish(-1);
  70.         }
  71.  
  72.         ifc.ifc_buf = buf;
  73.         ifc.ifc_len = sizeof(buf);
  74.  
  75.         /*
  76.          * See what devices we've got.
  77.          */
  78.         if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0) {
  79.             error("ioctl: SIOCGIFCONF");
  80.             finish(-1);
  81.         }
  82.  
  83.         /*
  84.          * Take the first device we encounter.
  85.          */
  86.         ifrp = ifc.ifc_req;
  87.         for (n = ifc.ifc_len/sizeof(struct ifreq); n > 0; n--,ifrp++) {
  88.             /*
  89.              * Skip the loopback interface.
  90.              */
  91.             if (strcmp(ifrp->ifr_name, "lo0") == 0)
  92.                 continue;
  93.  
  94.             *device = savestr(ifrp->ifr_name);
  95.             break;
  96.         }
  97.  
  98.         (void) close(s);
  99.     }
  100.  
  101.     /*
  102.      * Make the raw socket.
  103.      */
  104.     if ((s = socket(PF_RAW,SOCK_RAW,RAWPROTO_SNOOP)) < 0) {
  105.         error("snoop: socket");
  106.         finish(-1);
  107.     }
  108.  
  109.     /*
  110.      * Set it up for the chosen interface.
  111.      */
  112.     bzero((char *)&sr, sizeof(sr));
  113.     sr.sr_family = AF_RAW;    
  114.     sr.sr_port = 0;
  115.     strncpy(sr.sr_ifname, *device, sizeof(sr.sr_ifname));
  116.  
  117.     /*
  118.      * If the bind fails, there's no such device.
  119.      */
  120.     if (bind(s, &sr, sizeof(sr)) < 0) {
  121.         close(s);
  122.         return(-1);
  123.     }
  124.  
  125.     /*
  126.      * Set up NULL filter - this is not necessary ...
  127.      */
  128.     bzero((char *)&sf, sizeof(sf));
  129.  
  130.     if (ioctl(s, SIOCADDSNOOP, &sf) < 0) {
  131.         error("snoop: add filter");
  132.         finish(-1);
  133.     }
  134.  
  135.     /*
  136.      * Beef up the socket buffer to minimise packet losses
  137.      */
  138.     i = SNOOP_BUFFER_SIZE;
  139.     if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&i, sizeof(i)) < 0) {
  140.         error("snoop: set rcvbuf");
  141.         finish(-1);
  142.     }
  143.  
  144.     return(s);
  145. }
  146.  
  147. /*
  148.  * flush_snoop - flush data from the snoop.
  149.  */
  150. void
  151. flush_snoop(fd)
  152. int fd;
  153. {
  154.     int on = 1;
  155.     int off = 0;
  156.  
  157.     /*
  158.      * Off then on should do a flush methinks
  159.      */
  160.     ioctl(fd, SIOCSNOOPING, &off);
  161.  
  162.     if (ioctl(fd, SIOCSNOOPING, &on) < 0) {
  163.         error("snoop: snoop on");
  164.         finish(-1);
  165.     }
  166. }
  167.  
  168. /*
  169.  * snoop_devtype - determine the type of device we're looking at.
  170.  */
  171. int
  172. snoop_devtype(device)
  173. char *device;
  174. {
  175.     /*
  176.      * This whole routine is a kludge.  Ultrix does it the
  177.      * right way; see pfilt.c.
  178.      */
  179.  
  180.     if (strncmp(device, "et", 2) == 0 || strncmp(device, "ec", 2) == 0 ||
  181.         strncmp(device, "fxp", 3) == 0 || strncmp(device, "enp", 3) == 0)
  182.         return(DLT_EN10MB);
  183.     
  184.     if (strncmp(device, "ipg", 4) == 0)
  185.         return(DLT_FDDI);
  186.  
  187.     fprintf(stderr, "Unknown device type: %s -- assuming ethernet.\n",
  188.         device);
  189.     return(DLT_EN10MB);
  190. }
  191. #endif /* USE_SNOOP */
  192.