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

  1. /* $Id: etherread.c,v 2.1 89/10/23 15:42:40 dupuy Exp $ */
  2.  
  3. #include <sys/types.h>            /* iovec (caddr_t) */
  4. #include <sys/uio.h>            /* iovec */
  5.  
  6. #include <errno.h>            /* EWOULDBLOCK/EMSGSIZE */
  7.  
  8. extern int errno;
  9.  
  10. #include "libether.h"
  11.  
  12. #define HEADER    0
  13. #define DATA    1
  14. #define WASTE    2
  15. #define MAXIOV    3
  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.  Reads on the
  21.  * ethernet packet filter device always return one packet.  Streams must be in
  22.  * RMSGD mode for reads to return one packet at a time
  23.  */
  24.  
  25. int
  26. ether_read (fd, packet)
  27. int fd;
  28. ether_packet *packet;
  29. {
  30.     char waste[ETHER_MAX];
  31.     struct iovec iov[MAXIOV];
  32.     int count;
  33.  
  34.     iov[HEADER].iov_len = ETHER_PKT;
  35.     iov[HEADER].iov_base = (char *) packet;
  36.  
  37.     if (packet->pktbuf)
  38.     {
  39.     iov[DATA].iov_len = packet->pktlen;
  40.     iov[DATA].iov_base = packet->pktbuf;
  41.  
  42.     iov[WASTE].iov_len = sizeof (waste);
  43.     iov[WASTE].iov_base = waste;
  44.  
  45.     count = 3;            /* use waste to get all of packet */
  46.     }
  47.     else
  48.     {
  49.     iov[DATA].iov_len = packet->pktlen = ETHER_MAX;
  50.     if ((iov[DATA].iov_base = (char *) malloc ((unsigned) ETHER_MAX)) == 0)
  51.         return (-1);
  52.     packet->pktbuf = iov[DATA].iov_base;
  53.  
  54.     count = 2;            /* no need to use waste */
  55.     }
  56.  
  57.     if ((count = readv (fd, iov, count)) <= 0)
  58.     {
  59. #ifndef EBADMSG                /* a stream will return EAGAIN */
  60.     if (count == 0 || errno == EWOULDBLOCK)
  61.         errno = EAGAIN;
  62. #endif
  63.     return (-1);
  64.     }
  65.  
  66.     if ((count -= ETHER_PKT) < 0)
  67.     {                    /* enet returns EOF (0) */
  68. #ifdef EBADMSG
  69.     errno = EBADMSG;        /* XXX readv() can also return this */
  70. #else
  71.     errno = EMSGSIZE;        /* XXX message isn't really too long */
  72. #endif
  73.     }
  74.     else if (packet->pktlen > count)
  75.     packet->pktlen = count;
  76.  
  77.     return (count);
  78. }
  79.