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

  1. #ifndef lint
  2. static char *RCSid = "$Header: /home/harbor/davy/system/nfswatch/RCS/nit.c,v 4.0 1993/03/01 19:59:00 davy Exp $";
  3. #endif
  4.  
  5. #include "os.h"
  6.  
  7. #ifdef USE_NIT
  8. /*
  9.  * nit.c - routines for messing with the network interface tap.
  10.  *
  11.  * David A. Curry
  12.  * Purdue University
  13.  * Engineering Computer Network
  14.  * 1285 Electrical Engineering Building
  15.  * West Lafayette, IN 47907-1285
  16.  * davy@ecn.purdue.edu
  17.  *
  18.  * $Log: nit.c,v $
  19.  * Revision 4.0  1993/03/01  19:59:00  davy
  20.  * NFSWATCH Version 4.0.
  21.  *
  22.  * Revision 3.6  1993/02/24  17:44:45  davy
  23.  * Added -auth mode, changes to -proc mode, -map option, -server option.
  24.  *
  25.  * Revision 3.5  1993/01/15  19:33:39  davy
  26.  * Miscellaneous cleanups.
  27.  *
  28.  * Revision 3.4  1993/01/15  14:34:33  davy
  29.  * Changed to handle the default network interface even if the loopback
  30.  * was ifconfig'd first.
  31.  *
  32.  * Revision 3.3  1993/01/14  15:51:16  davy
  33.  * Added FDDI code and device type calculation to NIT and SNOOP.  The FDDI
  34.  * stuff almost definitely won't work without modification on the SNOOP
  35.  * side; it still needs to be tested on the NIT side.
  36.  *
  37.  * Revision 3.2  1993/01/13  20:18:17  davy
  38.  * Put in OS-specific define scheme, and merged in Tim Hudson's code for
  39.  * SGI systems (as yet untested).
  40.  *
  41.  * Revision 3.1  1993/01/13  13:03:01  davy
  42.  * Fixed the SUNOS40 calculation, and also fixed to only use promiscuous
  43.  * mode when needed.
  44.  *
  45.  * Revision 3.0  1991/01/23  08:23:14  davy
  46.  * NFSWATCH Version 3.0.
  47.  *
  48.  * Revision 1.4  90/12/04  08:25:22  davy
  49.  * Fixed to automatically define SUNOS40.
  50.  * 
  51.  * Revision 1.3  90/12/04  08:11:40  davy
  52.  * Changed ifdef for SunOS 4.0.x.
  53.  * 
  54.  * Revision 1.2  90/08/17  15:47:32  davy
  55.  * NFSWATCH Version 2.0.
  56.  * 
  57.  * Revision 1.1  88/11/29  11:20:47  davy
  58.  * NFSWATCH Release 1.0
  59.  * 
  60.  */
  61. #include <sys/param.h>
  62. #include <sys/stropts.h>
  63. #include <sys/socket.h>
  64. #include <sys/ioctl.h>
  65. #include <sys/time.h>
  66. #include <sys/file.h>
  67. #include <net/if.h>
  68. #include <signal.h>
  69. #include <stdio.h>
  70.  
  71. #include <net/nit_if.h>
  72. #include <net/nit_buf.h>
  73.  
  74. #include "nfswatch.h"
  75. #include "externs.h"
  76.  
  77. #if NOFILE <= 64
  78. #define SUNOS40 1
  79. #endif
  80.  
  81. /*
  82.  * setup_nit_dev - set up the network interface tap.
  83.  */
  84. int
  85. setup_nit_dev(device)
  86. char **device;
  87. {
  88.     int n, s, fd;
  89.     u_int chunksz;
  90.     u_long if_flags;
  91.     char buf[BUFSIZ];
  92.     struct ifconf ifc;
  93.     struct strioctl si;
  94.     struct timeval timeout;
  95.     struct ifreq ifr, *ifrp;
  96.  
  97.     /*
  98.      * If the interface device was not specified,
  99.      * get the default one.
  100.      */
  101.     if (*device == NULL) {
  102.         /*
  103.          * Grab a socket.
  104.          */
  105.         if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  106.             error("socket");
  107.             finish(-1);
  108.         }
  109.  
  110.         ifc.ifc_buf = buf;
  111.         ifc.ifc_len = sizeof(buf);
  112.  
  113.         /*
  114.          * See what devices we've got.
  115.          */
  116.         if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0) {
  117.             error("ioctl: SIOCGIFCONF");
  118.             finish(-1);
  119.         }
  120.  
  121.         /*
  122.          * Take the first device we encounter.
  123.          */
  124.         ifrp = ifc.ifc_req;
  125.         for (n = ifc.ifc_len/sizeof(struct ifreq); n > 0; n--,ifrp++) {
  126.             /*
  127.              * Skip the loopback interface.
  128.              */
  129.             if (strcmp(ifrp->ifr_name, "lo0") == 0)
  130.                 continue;
  131.  
  132.             *device = savestr(ifrp->ifr_name);
  133.             break;
  134.         }
  135.  
  136.         (void) close(s);
  137.     }
  138.  
  139.     /*
  140.      * We want the ethernet in promiscuous mode if we're looking
  141.      * at nodes other than ourselves, and we want to know about 
  142.      * dropped packets.
  143.      */
  144.     if (allflag || dstflag)
  145.         if_flags = NI_DROPS | NI_PROMISC | NI_TIMESTAMP;
  146.     else
  147.         if_flags = NI_DROPS | NI_TIMESTAMP;
  148.  
  149.     /*
  150.      * Open the network interface tap.
  151.      */
  152.     if ((fd = open(NIT_DEV, O_RDONLY)) < 0) {
  153.         error("nit: open");
  154.         finish(-1);
  155.     }
  156.  
  157.     /*
  158.      * Arrange to get discrete messages.
  159.      */
  160.     if (ioctl(fd, I_SRDOPT, (char *) RMSGD) < 0) {
  161.         error("ioctl: I_SRDOPT");
  162.         finish(-1);
  163.     }
  164.  
  165.     /*
  166.      * Push and configure the nit buffering module.
  167.      */
  168.     if (ioctl(fd, I_PUSH, NIT_BUF) < 0) {
  169.         error("ioctl: I_PUSH NIT_BUF");
  170.         finish(-1);
  171.     }
  172.  
  173.     /*
  174.      * Set the read timeout.
  175.      */
  176.     timeout.tv_sec = 1;
  177.     timeout.tv_usec = 0;
  178.  
  179.     si.ic_cmd = NIOCSTIME;
  180.     si.ic_timout = INFTIM;
  181.     si.ic_len = sizeof(timeout);
  182.     si.ic_dp = (char *) &timeout;
  183.  
  184.     if (ioctl(fd, I_STR, (char *) &si) < 0) {
  185.         error("ioctl: I_STR NIOCSTIME");
  186.         finish(-1);
  187.     }
  188.  
  189.     /*
  190.      * Set the chunk size.
  191.      */
  192.     chunksz = NIT_CHUNKSIZE;
  193.  
  194.     si.ic_cmd = NIOCSCHUNK;
  195.     si.ic_len = sizeof(chunksz);
  196.     si.ic_dp = (char *) &chunksz;
  197.  
  198.     if (ioctl(fd, I_STR, (char *) &si) < 0) {
  199.         error("ioctl: I_STR NIOCSCHUNK");
  200.         finish(-1);
  201.     }
  202.  
  203.     /*
  204.      * Configure the network interface tap by binding it
  205.      * to the underlying interface, setting the snapshot
  206.      * length, and setting the flags.
  207.      */
  208.     (void) strncpy(ifr.ifr_name, *device, sizeof(ifr.ifr_name));
  209.     ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
  210.  
  211.     si.ic_cmd = NIOCBIND;
  212.     si.ic_len = sizeof(ifr);
  213.     si.ic_dp = (char *) 𝔦
  214.  
  215.     /*
  216.      * If the bind fails, there's no such device.
  217.      */
  218.     if (ioctl(fd, I_STR, (char *) &si) < 0) {
  219.         close(fd);
  220.         return(-1);
  221.     }
  222.  
  223.     /*
  224.      * SNAP is buggy on SunOS 4.0.x
  225.      */
  226. #ifndef SUNOS40
  227.     si.ic_cmd = NIOCSSNAP;
  228.     si.ic_len = sizeof(truncation);
  229.     si.ic_dp = (char *) &truncation;
  230.  
  231.     if (ioctl(fd, I_STR, (char *) &si) < 0) {
  232.         error("ioctl: I_STR NIOCSSNAP");
  233.         finish(-1);
  234.     }
  235. #endif
  236.  
  237.     si.ic_cmd = NIOCSFLAGS;
  238.     si.ic_len = sizeof(if_flags);
  239.     si.ic_dp = (char *) &if_flags;
  240.  
  241.     if (ioctl(fd, I_STR, (char *) &si) < 0) {
  242.         error("ioctl: I_STR NIOCSFLAGS");
  243.         finish(-1);
  244.     }
  245.  
  246.     return(fd);
  247. }
  248.  
  249. /*
  250.  * flush_nit - flush data from the nit.
  251.  */
  252. void
  253. flush_nit(fd)
  254. int fd;
  255. {
  256.     if (ioctl(fd, I_FLUSH, (char *) FLUSHR) < 0) {
  257.         error("ioctl: I_FLUSH");
  258.         finish(-1);
  259.     }
  260. }
  261.  
  262. /*
  263.  * nit_devtype - determine the type of device we're looking at.
  264.  */
  265. int
  266. nit_devtype(device)
  267. char *device;
  268. {
  269.     /*
  270.      * This whole routine is a kludge.  Ultrix does it the
  271.      * right way; see pfilt.c.
  272.      */
  273.  
  274.     if (strncmp(device, "le", 2) == 0 || strncmp(device, "ie", 2) == 0)
  275.         return(DLT_EN10MB);
  276.     
  277.     if (strncmp(device, "fddi", 4) == 0)
  278.         return(DLT_FDDI);
  279.  
  280.     fprintf(stderr, "Unknown device type: %s -- assuming ethernet.\n",
  281.         device);
  282.     return(DLT_EN10MB);
  283. }
  284. #endif /* USE_NIT */
  285.