home *** CD-ROM | disk | FTP | other *** search
- /* $Id: dliread.c,v 2.1 89/10/23 15:42:04 dupuy Exp $ */
-
- #include <sys/param.h> /* NOFILE */
- #include <sys/socket.h> /* sockaddr_dl (sockaddr) */
-
- #include <net/if.h> /* ifdevea */
- #include <netinet/in.h> /* (ether_header) (in_addr) */
- #include <netinet/if_ether.h> /* sockaddr_dl (ether_header) */
- #include <netdnet/dli_var.h> /* sockaddr_dl */
-
- #include <errno.h> /* EWOULDBLOCK */
-
- #include "libether.h"
-
- extern ether_addr _ether_multi_addrs[NOFILE];
-
- /*
- * Reads and returns a single packet, filling in all fields. If pktbuf is
- * NULL, a buffer is allocated for it. If pktbuf is not NULL, the function
- * assumes that pktbuf is large enough to hold pktlen bytes. Has to do
- * address checking, since we are operating in DLI_EXCLUSIVE mode.
- */
-
- int
- ether_read (fd, packet)
- int fd;
- ether_packet *packet;
- {
- struct sockaddr_dl from;
- int alen;
- int count;
- char *dest;
-
- if (packet->pktbuf == 0)
- {
- packet->pktlen = ETHER_MAX;
- if ((packet->pktbuf = (char *) malloc ((unsigned) ETHER_MAX)) == 0)
- return (-1);
- }
-
- from.dli_family = AF_DLI;
- alen = sizeof (from);
-
- do /* ignore bogus multicast packets */
- {
- if ((count = recvfrom (fd, packet->pktbuf, (int) packet->pktlen, 0,
- (struct sockaddr *) &from, &alen)) < 0)
- {
- if (errno == EWOULDBLOCK)
- errno = EAGAIN;
- return (-1);
- }
-
- dest = (char *) from.choose_addr.dli_eaddr.dli_dest;
- }
- while (address_check (dest)); /* constant argument to NOT ??? */
-
- bcopy (dest, (char *) &packet->dest, sizeof (ether_addr));
- bcopy ((char *) from.choose_addr.dli_eaddr.dli_target,
- (char *) &packet->src, sizeof (ether_addr));
- packet->type[0] = (from.choose_addr.dli_eaddr.dli_protype & 0xff00) >> 8;
- packet->type[1] = from.choose_addr.dli_eaddr.dli_protype & 0xff;
-
- if (packet->pktlen > count)
- packet->pktlen = count;
-
- return (count);
- }
-