home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume20 / etherlib / part01 / src / dliread.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-24  |  1.8 KB  |  69 lines

  1. /* $Id: dliread.c,v 2.1 89/10/23 15:42:04 dupuy Exp $ */
  2.  
  3. #include <sys/param.h>            /* NOFILE */
  4. #include <sys/socket.h>            /* sockaddr_dl (sockaddr) */
  5.  
  6. #include <net/if.h>            /* ifdevea */
  7. #include <netinet/in.h>            /* (ether_header) (in_addr) */
  8. #include <netinet/if_ether.h>        /* sockaddr_dl (ether_header) */
  9. #include <netdnet/dli_var.h>        /* sockaddr_dl */
  10.  
  11. #include <errno.h>            /* EWOULDBLOCK */
  12.  
  13. #include "libether.h"
  14.  
  15. extern ether_addr _ether_multi_addrs[NOFILE];
  16.  
  17. /*
  18.  * Reads and returns a single packet, filling in all fields.  If pktbuf is
  19.  * NULL, a buffer is allocated for it.    If pktbuf is not NULL, the function
  20.  * assumes that pktbuf is large enough to hold pktlen bytes.  Has to do
  21.  * address checking, since we are operating in DLI_EXCLUSIVE mode.
  22.  */
  23.  
  24. int
  25. ether_read (fd, packet)
  26. int fd;
  27. ether_packet *packet;
  28. {
  29.     struct sockaddr_dl from;
  30.     int alen;
  31.     int count;
  32.     char *dest;
  33.  
  34.     if (packet->pktbuf == 0)
  35.     {
  36.     packet->pktlen = ETHER_MAX;
  37.     if ((packet->pktbuf = (char *) malloc ((unsigned) ETHER_MAX)) == 0)
  38.         return (-1);
  39.     }
  40.  
  41.     from.dli_family = AF_DLI;
  42.     alen = sizeof (from);
  43.  
  44.     do                    /* ignore bogus multicast packets */
  45.     {
  46.     if ((count = recvfrom (fd, packet->pktbuf, (int) packet->pktlen, 0,
  47.                    (struct sockaddr *) &from, &alen)) < 0)
  48.     {
  49.         if (errno == EWOULDBLOCK)
  50.         errno = EAGAIN;
  51.         return (-1);
  52.     }
  53.  
  54.     dest = (char *) from.choose_addr.dli_eaddr.dli_dest;
  55.     }
  56.     while (address_check (dest));    /* constant argument to NOT ??? */
  57.  
  58.     bcopy (dest, (char *) &packet->dest, sizeof (ether_addr));
  59.     bcopy ((char *) from.choose_addr.dli_eaddr.dli_target,
  60.        (char *) &packet->src, sizeof (ether_addr));
  61.     packet->type[0] = (from.choose_addr.dli_eaddr.dli_protype & 0xff00) >> 8;
  62.     packet->type[1] = from.choose_addr.dli_eaddr.dli_protype & 0xff;
  63.  
  64.     if (packet->pktlen > count)
  65.     packet->pktlen = count;
  66.  
  67.     return (count);
  68. }
  69.