home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / kboot22.zoo / kboot22.1 / nitlib.c < prev   
C/C++ Source or Header  |  1991-02-22  |  6KB  |  270 lines

  1. #ifndef lint
  2. static char    *RCSid="$Header: /tmp_mnt/home/src/rand/etc/kboot/RCS/nitlib.c,v 1.2 91/02/12 19:38:10 root Exp $";
  3. #endif lint
  4.  
  5. /*
  6.  * $Log:    nitlib.c,v $
  7.  * Revision 1.2  91/02/12  19:38:10  root
  8.  * Don't call fdfunc() if NULL.
  9.  * 
  10.  * Revision 1.1  91/01/29  17:37:28  root
  11.  * Initial revision
  12.  * 
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <syslog.h>
  17. #include <sys/types.h>
  18. #include <sys/time.h>
  19. #include <sys/socket.h>
  20. #include <sys/file.h>
  21. #include <sys/signal.h>
  22. #include <netdb.h>
  23. #include <net/if.h>
  24. #include <sys/ioctl.h>
  25. #include <sys/stropts.h>
  26. #include <net/nit_if.h>
  27. #include <net/nit_pf.h>
  28. #include <netinet/in.h>
  29. #include <netinet/in_systm.h>
  30. #include <netinet/if_ether.h>
  31. #include <net/packetfilt.h>
  32. #include "config.h"
  33.  
  34. #define MAXPKT        1500
  35. #define OFFSET(t,f)    ((int) &(((t *) NULL)->f))
  36.  
  37. extern char    *malloc ();
  38. extern char    *strdup ();
  39.  
  40. extern int    debug;
  41. extern int    detached;
  42. extern int    errno;
  43. extern char    *sys_errlist[];
  44.  
  45. /*
  46.  * Globals.
  47.  */
  48. struct ether_addr    myether;
  49. int            nit_fd;
  50. char            nitbuf[MAXPKT];
  51. int            numfds;
  52. char            *interface;
  53.  
  54. /*
  55.  * nit_init - Initialize nit library.
  56.  */
  57. nit_init (dev)
  58.  
  59. char    *dev;
  60.  
  61. {
  62.   struct ifconf        ifc;
  63.   int            s;
  64.   char            buf[BUFSIZ];
  65.  
  66.   numfds = getdtablesize ();
  67.   if (dev == NULL) {
  68.       if ((s = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {
  69.             logerr ("nit_init: socket - %s\n", sys_errlist[errno]);
  70.             exit(1);
  71.       }
  72.       ifc.ifc_len = BUFSIZ;
  73.       ifc.ifc_buf = buf;
  74.       if (ioctl (s, SIOCGIFCONF, (caddr_t) &ifc) < 0) {
  75.           logerr ("nit_init: ioctl(SIOCGIFCONF) - %s\n", sys_errlist[errno]);
  76.           exit(1);
  77.       }
  78.       close(s);
  79.       interface = strdup (ifc.ifc_req->ifr_name);
  80.   } else
  81.       interface = dev;
  82.   if (debug)
  83.       fprintf (stderr, "nit_init: Using interface %s\n", interface);
  84. }
  85.  
  86. /*
  87.  * nit_open - Open NIT device and bind to an interface.
  88.  *   Prints an error and exits if there's a problem.
  89.  */
  90. nit_open (snaplen, pkttype)
  91.  
  92. int    snaplen;
  93. int    pkttype;
  94.  
  95. {
  96.   int            s;
  97.   struct packetfilt    pf;
  98.   u_short        *pfp;
  99.   struct ifreq        ifr;
  100.  
  101.   if ((nit_fd = open ("/dev/nit", O_RDWR)) < 0) {    /* Open NIT dev    */
  102.       logerr ("nit_open: open(/dev/nit) - %s\n", sys_errlist[errno]);
  103.       exit (1);
  104.   }
  105.   if (ioctl (nit_fd, I_SRDOPT, (caddr_t) RMSGD) < 0) {    /* Discrete msgs*/
  106.       logerr ("nit_open: ioctl(I_SRDOPT) - %s\n", sys_errlist[errno]);
  107.       exit (1);
  108.   }
  109.   if (pkttype) {
  110.       if (ioctl (nit_fd, I_PUSH, "pf") < 0) {    /* Setup packet filter    */
  111.           logerr ("nit_open: ioctl(I_PUSH: pf) - %s\n", sys_errlist[errno]);
  112.           exit (1);
  113.       }
  114.       pfp = pf.Pf_Filter;
  115.       *pfp++ = ENF_PUSHWORD +
  116.     OFFSET (struct ether_header, ether_type) / sizeof (u_short);
  117.       *pfp++ = ENF_PUSHLIT | ENF_EQ;
  118.       *pfp++ = htons (pkttype);
  119.       pf.Pf_FilterLen = ((int) pfp - (int) pf.Pf_Filter) / sizeof (u_short);
  120.       if (ioctl (nit_fd, NIOCSETF, (caddr_t) &pf) < 0) {
  121.           logerr ("nit_open: ioctl(NIOCSETF) - %s\n", sys_errlist[errno]);
  122.           exit (1);
  123.       }
  124.   }
  125.   strncpy (ifr.ifr_name, interface, sizeof ifr.ifr_name);
  126.   ifr.ifr_name[sizeof ifr.ifr_name - 1] = '\0';
  127.   if (ioctl (nit_fd, NIOCBIND, &ifr) < 0) {
  128.       logerr ("nit_open: ioctl(NIOCBIND) - %s\n", sys_errlist[errno]);
  129.       exit(1);
  130.   }
  131.                         /* Get ethernet address    */
  132.   if (ioctl (nit_fd, SIOCGIFADDR, (caddr_t) &ifr) < 0) {
  133.       logerr ("nit_open: ioctl(SIOCGIFADDR) - %s\n", sys_errlist[errno]);
  134.       exit (1);
  135.   }
  136.   ether_copy (ifr.ifr_addr.sa_data, &myether);
  137.   if (snaplen > 0) {                            /* Set snapshot length  */
  138.       if (ioctl (nit_fd, NIOCSSNAP, (caddr_t) &snaplen) < 0) {
  139.           logerr ("nit_open: ioctl (NIOCSSNAP) - %s\n", sys_errlist[errno]);
  140.           exit (1);
  141.       }
  142.   }
  143. }
  144.  
  145. /*
  146.  * nit_close - Close nit file descriptor.
  147.  */
  148. nit_close ()
  149.  
  150. {
  151.   close (nit_fd);
  152. }
  153.  
  154. /*
  155.  * timeout - Return timeval structure for timeout specified in ticks for
  156.  *   reads from nit device.  Ticks are 1/60 of a second.  A timeout of 0
  157.  *   means reads will not timeout.
  158.  */
  159. nit_timeout (ticks, tv)
  160.  
  161. int        ticks;
  162. struct timeval    *tv;
  163.  
  164. {
  165.   tv->tv_sec = ticks / 60;            /* Set timeout        */
  166.   tv->tv_usec = ((ticks * 1000000) / 60) % 1000000;
  167. }
  168.  
  169. /*
  170.  * nit_write - Send a raw ethernet packet.
  171.  */
  172. nit_write (eh, pkt, len)
  173.  
  174. struct ether_header    *eh;
  175. caddr_t            pkt;
  176. int            len;
  177.  
  178. {
  179.   struct sockaddr    sa;
  180.   struct strbuf        cbuf;
  181.   struct strbuf        dbuf;
  182.  
  183.   sa.sa_family = AF_UNSPEC;
  184.   bcopy (eh, sa.sa_data, sizeof (*eh));
  185.   cbuf.len = sizeof sa;
  186.   cbuf.buf = (caddr_t) &sa;
  187.   dbuf.len = len;
  188.   dbuf.buf = pkt;
  189.   if (putmsg (nit_fd, &cbuf, &dbuf, 0) < 0) {
  190.       logerr ("nit_write: putmsg - %s\n", sys_errlist[errno]);
  191.       exit (1);
  192.   }
  193. }
  194.  
  195. /*
  196.  * nit_dispatch - Read and process n packets.  If n is 0 read forever.
  197.  *   Calls "func" for each packet with the arguments:
  198.  *
  199.  *    (*func) (pp, pl)
  200.  *      pp = packet pointer
  201.  *      pl = length of packet
  202.  *
  203.  *   If an application is waiting for input on other file descriptors
  204.  *   they can be specified in "fds".  "fdfunc" will be called with
  205.  *   the set of descriptors that have input waiting before the current
  206.  *   packet is processed.  Returns 0 on timeout, 1 otherwise.
  207.  */
  208. int nit_dispatch (func, n, fds, fdfunc, timeout)
  209.  
  210. int        (*func)();
  211. int        n;
  212. fd_set        *fds;
  213. int        (*fdfunc)();
  214. struct timeval    *timeout;
  215.  
  216. {
  217.   int        i;
  218.   int        numpkts;
  219.   fd_set    fdset;
  220.   fd_set    rfds;
  221.  
  222.   numpkts = 0;
  223.   if (fds)
  224.       fdset = *fds;
  225.   else
  226.       FD_ZERO (&fdset);
  227.   FD_SET (nit_fd, &fdset);
  228.   while (n == 0 || numpkts < n) {
  229.       rfds = fdset;
  230.       i = select (numfds, &rfds, NULL, NULL, timeout);
  231.       if (i == 0)
  232.       return (0);            /* Timeout            */
  233.       if (FD_ISSET (nit_fd, &rfds)) {
  234.       numpkts++;
  235.       FD_CLR (nit_fd, &rfds);
  236.       if (i > 1)
  237.           (*fdfunc) (&rfds);
  238.       } else if (fdfunc) {
  239.       (*fdfunc) (&rfds);
  240.       continue;
  241.       }
  242.       if ((i = read (nit_fd, nitbuf, MAXPKT)) < 0) {
  243.           lseek (nit_fd, 0, 0);        /* File pointer may've wrapped    */
  244.           if ((i = read (nit_fd, nitbuf, MAXPKT)) < 0) {
  245.           logerr ("nit_dispatch: read - %s\n", sys_errlist[errno]);
  246.           exit (1);
  247.           }
  248.       }
  249.       (*func) (nitbuf, i);
  250.   }
  251.   return (1);
  252. }
  253.  
  254. /*
  255.  * logerr - Log error to stderr (if debug) or syslog.
  256.  */
  257. logerr (fmt, a1, a2, a3)
  258.  
  259. char    *fmt;
  260. char    *a1;
  261. char    *a2;
  262. char    *a3;
  263.  
  264. {
  265.   if (detached)
  266.       syslog (LOG_ERR, fmt, a1, a2, a3);
  267.   else
  268.       fprintf (stderr, fmt, a1, a2, a3);
  269. }
  270.