rsalz@uunet.uu.net (Rich Salz) (10/26/89)
Submitted-by: Alexander Dupuy <dupuy@cs.columbia.edu> Posting-number: Volume 20, Issue 58 Archive-name: etherlib/part01 This ethernet access library is a part of the Columbia Netmate project which is being released as a useful component in its own right. These functions provide access to the raw ethernet for user-level programs. On Suns, they are implemented using NIT(4p) (network interface tap). While they do not provide the full functionality of NIT, these functions do run on both the socket- and streams-based NIT implementations. On Ultrix systems, they are implemented using DLI (data link interface). On Berkeley systems, they are implemented using the Stanford enetfilter available as user-contributed software in the 4.3 BSD release. These functions are not designed to be used for ethernet monitoring, but rather for programs implementing ethernet protocols such as RARP, or the Ethernet configuration test protocol. It comes with a manual page, and both a GNU makefile and a regular one. If you are on a BSD system with the enetfilter, you will have to create some new device files before you can build or use this library. Because there is no way to map between the interface names ("il0", "de0", etc.) used by most programs and the old enetfilter device names (/dev/enet0, /dev/eneta0, etc.), this library uses a different convention for enetfilter device names, using device files in the /dev/enet/ directory. #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 3)." # Contents: ./GNUmake.config ./GNUmakefile ./ReadMe # ./src ./src/ReadMe ./src/dliaddr.c ./src/dliintaddr.c # ./src/dliread.c ./src/dlireadv.c ./src/dliself.c ./src/dliwrite.c # ./src/dliwritev.c ./src/enetaddr.c ./src/enetblock.c # ./src/enetintaddr.c ./src/enetself.c ./src/enetwrite.c # ./src/enetwritev.c ./src/ethera2e.c ./src/etheraddr.c # ./src/etherblock.c ./src/ethere2a.c ./src/etherlocal.c # ./src/etherread.c ./src/etherreadv.c ./src/libether.h # ./src/nit3intaddr.c ./src/nit3read.c ./src/nit3readv.c # ./src/nit3self.c ./src/nit3write.c ./src/nit3writev.c # ./src/nit4intaddr.c ./src/nit4self.c ./src/nit4write.c # ./src/nit4writev.c ./src/nitaddr.c ./system ./tests MANIFEST # Wrapped by rsalz@papaya.bbn.com on Wed Oct 25 16:37:29 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f './GNUmake.config' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./GNUmake.config'\" else echo shar: Extracting \"'./GNUmake.config'\" \(1799 characters\) sed "s/^X//" >'./GNUmake.config' <<'END_OF_FILE' X# X# Build flags which are used by various components X# X Xifeq ($(SYSTEM),) X XSYSTEM := $(strip $(shell PATH=$$PATH:.:..:../..:../../.. system )) X X X# Compilation parameters X# (don't try to use gcc if the machine isn't supported yet) X# don't use gcc on Sun-4 until we resolve structure pass/return incompatibility X Xifneq ($(findstring ibmrt,$(SYSTEM)),ibmrt) Xifneq ($(findstring mipsel,$(SYSTEM)),mipsel) Xifneq ($(findstring sun4,$(SYSTEM)),sun4) XCC := gcc Xendif Xendif Xendif X X# X# Sun-3 floating-point options; replace 68881 with soft or fpa as appropriate X# X Xifeq ($(findstring sun3,$(SYSTEM)),sun3) X XFLOAT_OPTION = f68881 X Xifeq ($(findstring os4,$(SYSTEM)),os4) X XFLIB = /usr/lib/$(FLOAT_OPTION).il X Xelse X XFLIB = /usr/lib/$(FLOAT_OPTION)/libm.il X Xendif X Xendif X XOPT = -g XOPTG = -g -W X Xifeq ($(findstring os4,$(SYSTEM)),os4) Xifeq ($(findstring -g,$(OPTG)),-g) Xifeq ($(findstring gcc,$(CC)),gcc) Xoverride LDFLAGS := -g -static Xelse Xoverride LDFLAGS := -g -Bstatic Xendif Xendif Xendif X XDEFINES = X X X# Listing variables and flags X XTROFF = ptroff XVGRIND = vgrind X XGRIND = $(VGRIND) -d vgrindefs X X X# Installation tools X XINSTALL=install -c X Xifeq ($(findstring os4,$(SYSTEM)),os4) XRANLIB=ranlib -t Xelse XRANLIB=ranlib Xendif X X X# Installation locations X XMANDIR = /usr/local/man XBINDIR = /usr/local/bin XLIBDIR = /usr/local/lib XINCDIR = /usr/local/include X Xendif X X X# Pattern rules X X%.ps: %.c X $(VGRIND) -lC -t $< > $@ X X%.ps: %.h X $(VGRIND) -lC -t $< > $@ X X# Installation pattern rules X X%/bin: % X mkdir $@ X X$(BINDIR)/%: % X $(INSTALL) $< $@ X X%/lib: % X mkdir $@ X X$(LIBDIR)/%: % X $(INSTALL) $< $@ X $(RANLIB) $@ X @chmod -x $@ X X%/include: % X mkdir $@ X X$(INCDIR)/%: % X $(INSTALL) $< $@ X @chmod -x $@ X X%/man: % X mkdir $@ X X$(MANDIR)/man1/%: % X $(INSTALL) $< $@ X @chmod -x $@ X X$(MANDIR)/man3/%: % X $(INSTALL) $< $@ X @chmod -x $@ END_OF_FILE if test 1799 -ne `wc -c <'./GNUmake.config'`; then echo shar: \"'./GNUmake.config'\" unpacked with wrong size! fi # end of './GNUmake.config' fi if test -f './GNUmakefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./GNUmakefile'\" else echo shar: Extracting \"'./GNUmakefile'\" \(621 characters\) sed "s/^X//" >'./GNUmakefile' <<'END_OF_FILE' X# X# GNU makefile for ethernet library X# X Xinclude GNUmake.config X XOPTG := -O $(OPTG) XOPT := -O XDEFINES = X X# This doesn't do anything - it just hands it off to the subdirectory X X.PHONY: all install lint noise listing clean cleanlists realclean X Xall install ethertest ctp: $(SYSTEM) X $(MAKE) -C $(SYSTEM) -f ../GNUmake.mk $@ X Xlint noise listing: X $(MAKE) -C src -f ../GNUmake.mk $@ X Xclean: $(SYSTEM) X $(MAKE) -C $(SYSTEM) -f ../GNUmake.mk $@ X Xrealclean: $(SYSTEM) X $(MAKE) -C $(SYSTEM) -f ../GNUmake.mk $@ X $(MAKE) -C src -f ../GNUmake.mk $@ X X$(SYSTEM): X mkdir $(SYSTEM) X X.DEFAULT: X $(MAKE) -C $(SYSTEM) -f ../GNUmake.mk $@ END_OF_FILE if test 621 -ne `wc -c <'./GNUmakefile'`; then echo shar: \"'./GNUmakefile'\" unpacked with wrong size! fi # end of './GNUmakefile' fi if test -f './ReadMe' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./ReadMe'\" else echo shar: Extracting \"'./ReadMe'\" \(644 characters\) sed "s/^X//" >'./ReadMe' <<'END_OF_FILE' X XThis is the source tree for the ethernet interface library. X XGNUmakefile X X is the master makefile for the ethernet interface library. X XGNUmake.mk X X is used as a common makefile for the architecture-specific X subdirectories. X Xether.3n X X manual page describing the library routines X XInstructions X X are instructions for building this library. X XSunBugs X X describes several bugs in the Sun 4.0 NIT interface X XThere are the following subdirectories X X src contains the sources X tests contains the source for test programs X enet contains sources for Stanford enetfilter X X sun3 have object files for various architectures X sun3-os4 X sun4-os4 X etc. END_OF_FILE if test 644 -ne `wc -c <'./ReadMe'`; then echo shar: \"'./ReadMe'\" unpacked with wrong size! fi # end of './ReadMe' fi if test ! -d './src' ; then echo shar: Creating directory \"'./src'\" mkdir './src' fi if test -f './src/ReadMe' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/ReadMe'\" else echo shar: Extracting \"'./src/ReadMe'\" \(1021 characters\) sed "s/^X//" >'./src/ReadMe' <<'END_OF_FILE' X XThis is the source subtree for the ethernet interface library. X XMakefile X X is a no-frills makefile for the ethernet interface library, so that it X can be distributed separately, and used with any make. If you have GNU X make, you should be using the GNUmakefile in the parent directory. X Xether.h X X is the external interface header file for installation in /usr/include. X Xlibether.h X X is the internal header file, for use by the library only. X Xetherblock.c Xetherints.c X X are generic, and should work on any system with Berkeley sockets. X Xetherread.c X X is somewhat generic, and works on SunOS 4.x and BSD+enetfilter systems. X Xnitaddr.c X X has generic NIT code, and should work on any system with NIT. X Xnit4open.c X X has streams-based NIT code, and works only on SunOS 4.x systems. X Xnit3open.c X X has socket-based NIT code, and works only on SunOS 3.x systems. X Xdliopen.c X X has Ultrix DLI code, and works only on Ultrix systems. X Xenetaddr.c Xenetopen.c X X have Stanford enetfilter code, and work only on BSD+enetfilter systems. END_OF_FILE if test 1021 -ne `wc -c <'./src/ReadMe'`; then echo shar: \"'./src/ReadMe'\" unpacked with wrong size! fi # end of './src/ReadMe' fi if test -f './src/dliaddr.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/dliaddr.c'\" else echo shar: Extracting \"'./src/dliaddr.c'\" \(1468 characters\) sed "s/^X//" >'./src/dliaddr.c' <<'END_OF_FILE' X/* $Id: dliaddr.c,v 2.0 89/10/20 19:01:26 dupuy Exp $ */ X X#include <sys/param.h> /* NOFILE */ X#include <sys/ioctl.h> /* ioctl */ X#include <sys/socket.h> /* sockaddr_dl (sockaddr) */ X X#include <net/if.h> /* ifdevea */ X#include <netinet/in.h> /* (ether_header) (in_addr) */ X#include <netinet/if_ether.h> /* sockaddr_dl (ether_header) */ X#include <netdnet/dli_var.h> /* sockaddr_dl */ X X#include "libether.h" X Xextern struct sockaddr_dl _ether_sockaddrs[NOFILE]; X X#define sad (_ether_sockaddrs[fd]) X X Xstatic void Xdevid_to_name (name, devid) Xchar *name; Xstruct dli_devid *devid; X{ X register int i; X X for (i = 0; devid->dli_devname[i]; i++) X name[i] = devid->dli_devname[i]; X X name[i++] = '0' + devid->dli_devnumber; X X name[i] = '\0'; X} X X X/* X * Returns the local ethernet address for the ethernet interface on the file X * descriptor fd. The result is stored in the structure given by address; if X * none is given, malloc is used to allocate space. X */ X Xether_addr * Xether_address (fd, address) Xint fd; Xether_addr *address; X{ X struct ifdevea ifd; X X devid_to_name (ifd.ifr_name, &sad.dli_device); X X if (ioctl (fd, SIOCRPHYSADDR, (char *) &ifd) < 0) X { X#ifdef DEBUG X perror ("ether_address: ioctl SIOCRPHYSADDR"); X#endif X return (0); X } X X if (address == 0) X address = (ether_addr *) malloc (sizeof (ether_addr)); X X if (address != 0) X bcopy ((char *) ifd.current_pa, (char *) address, sizeof (ether_addr)); X X return (address); X} END_OF_FILE if test 1468 -ne `wc -c <'./src/dliaddr.c'`; then echo shar: \"'./src/dliaddr.c'\" unpacked with wrong size! fi # end of './src/dliaddr.c' fi if test -f './src/dliintaddr.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/dliintaddr.c'\" else echo shar: Extracting \"'./src/dliintaddr.c'\" \(821 characters\) sed "s/^X//" >'./src/dliintaddr.c' <<'END_OF_FILE' X/* $Id: dliintaddr.c,v 2.1 89/10/23 15:41:58 dupuy Exp $ */ X X#include <errno.h> X Xextern int errno; X X#include "libether.h" X X/* X * Returns the local ethernet address for the ethernet interface. The result X * is stored in the structure given by address; if none is given, malloc is X * used to allocate space. X */ X Xether_addr * Xether_intfaddr (intf, address) Xchar *intf; Xether_addr *address; X{ X int fd; X unsigned short proto = 0xffff; X int saved_errno; X X do X if ((fd = ether_open (intf, proto--, (ether_addr *) 0)) < 0) X { X if (errno == EADDRINUSE) X continue; X return (0); X } /* constant argument to NOT ??? */ X while (fd < 0 && proto >= ETHER_MINTYPE); X X address = ether_address (fd, address); X X saved_errno = errno; X (void) close (fd); X errno = saved_errno; X X return (address); X} END_OF_FILE if test 821 -ne `wc -c <'./src/dliintaddr.c'`; then echo shar: \"'./src/dliintaddr.c'\" unpacked with wrong size! fi # end of './src/dliintaddr.c' fi if test -f './src/dliread.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/dliread.c'\" else echo shar: Extracting \"'./src/dliread.c'\" \(1891 characters\) sed "s/^X//" >'./src/dliread.c' <<'END_OF_FILE' X/* $Id: dliread.c,v 2.1 89/10/23 15:42:04 dupuy Exp $ */ X X#include <sys/param.h> /* NOFILE */ X#include <sys/socket.h> /* sockaddr_dl (sockaddr) */ X X#include <net/if.h> /* ifdevea */ X#include <netinet/in.h> /* (ether_header) (in_addr) */ X#include <netinet/if_ether.h> /* sockaddr_dl (ether_header) */ X#include <netdnet/dli_var.h> /* sockaddr_dl */ X X#include <errno.h> /* EWOULDBLOCK */ X X#include "libether.h" X Xextern ether_addr _ether_multi_addrs[NOFILE]; X X/* X * Reads and returns a single packet, filling in all fields. If pktbuf is X * NULL, a buffer is allocated for it. If pktbuf is not NULL, the function X * assumes that pktbuf is large enough to hold pktlen bytes. Has to do X * address checking, since we are operating in DLI_EXCLUSIVE mode. X */ X Xint Xether_read (fd, packet) Xint fd; Xether_packet *packet; X{ X struct sockaddr_dl from; X int alen; X int count; X char *dest; X X if (packet->pktbuf == 0) X { X packet->pktlen = ETHER_MAX; X if ((packet->pktbuf = (char *) malloc ((unsigned) ETHER_MAX)) == 0) X return (-1); X } X X from.dli_family = AF_DLI; X alen = sizeof (from); X X do /* ignore bogus multicast packets */ X { X if ((count = recvfrom (fd, packet->pktbuf, (int) packet->pktlen, 0, X (struct sockaddr *) &from, &alen)) < 0) X { X if (errno == EWOULDBLOCK) X errno = EAGAIN; X return (-1); X } X X dest = (char *) from.choose_addr.dli_eaddr.dli_dest; X } X while (address_check (dest)); /* constant argument to NOT ??? */ X X bcopy (dest, (char *) &packet->dest, sizeof (ether_addr)); X bcopy ((char *) from.choose_addr.dli_eaddr.dli_target, X (char *) &packet->src, sizeof (ether_addr)); X packet->type[0] = (from.choose_addr.dli_eaddr.dli_protype & 0xff00) >> 8; X packet->type[1] = from.choose_addr.dli_eaddr.dli_protype & 0xff; X X if (packet->pktlen > count) X packet->pktlen = count; X X return (count); X} END_OF_FILE if test 1891 -ne `wc -c <'./src/dliread.c'`; then echo shar: \"'./src/dliread.c'\" unpacked with wrong size! fi # end of './src/dliread.c' fi if test -f './src/dlireadv.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/dlireadv.c'\" else echo shar: Extracting \"'./src/dlireadv.c'\" \(1664 characters\) sed "s/^X//" >'./src/dlireadv.c' <<'END_OF_FILE' X/* $Id: dlireadv.c,v 2.1 89/10/23 15:42:06 dupuy Exp $ */ X X#include <sys/param.h> /* NOFILE */ X#include <sys/socket.h> /* sockaddr_dl (sockaddr) */ X#include <sys/uio.h> /* iovec */ X X#include <net/if.h> /* ifdevea */ X#include <netinet/in.h> /* (ether_header) (in_addr) */ X#include <netinet/if_ether.h> /* sockaddr_dl (ether_header) */ X#include <netdnet/dli_var.h> /* sockaddr_dl */ X X#include <errno.h> /* EWOULDBLOCK */ X X#include "libether.h" X Xextern ether_addr _ether_multi_addrs[NOFILE]; X X X/* X * Reads and returns a single packet, filling in all fields. Has to do X * address checking, since we are operating in DLI_EXCLUSIVE mode. X */ X Xint Xether_readv (fd, packet) Xint fd; Xether_vec *packet; X{ X struct sockaddr_dl from; X struct msghdr msg; X int count; X char *dest; X X from.dli_family = AF_DLI; X msg.msg_iov = packet->iov; X msg.msg_iovlen = packet->iovcnt; X msg.msg_name = (caddr_t) &from; X msg.msg_namelen = sizeof (from); X msg.msg_accrights = 0; X msg.msg_accrightslen = 0; X X do /* ignore bogus multicast packets */ X { X if ((count = recvmsg (fd, &msg, 0)) < 0) X { X if (errno == EWOULDBLOCK) X errno = EAGAIN; X return (-1); X } X X dest = (char *) from.choose_addr.dli_eaddr.dli_dest; X } X while (address_check (dest)); /* constant argument to NOT ??? */ X X bcopy (dest, (char *) &packet->dest, sizeof (ether_addr)); X bcopy ((char *) from.choose_addr.dli_eaddr.dli_target, X (char *) &packet->src, sizeof (ether_addr)); X packet->type[0] = (from.choose_addr.dli_eaddr.dli_protype & 0xff00) >> 8; X packet->type[1] = from.choose_addr.dli_eaddr.dli_protype & 0xff; X X return (count); X} END_OF_FILE if test 1664 -ne `wc -c <'./src/dlireadv.c'`; then echo shar: \"'./src/dlireadv.c'\" unpacked with wrong size! fi # end of './src/dlireadv.c' fi if test -f './src/dliself.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/dliself.c'\" else echo shar: Extracting \"'./src/dliself.c'\" \(1415 characters\) sed "s/^X//" >'./src/dliself.c' <<'END_OF_FILE' X/* $Id: dliself.c,v 2.0 89/10/20 19:01:55 dupuy Exp $ */ X X#include <sys/param.h> /* NOFILE */ X#include <sys/socket.h> /* sockaddr_dl (sockaddr) */ X X#include <net/if.h> /* (ether_header) (ifnet) */ X#include <netinet/in.h> /* (ether_header) (in_addr) */ X#include <netinet/if_ether.h> /* sockaddr_dl (ether_header) */ X#include <netdnet/dli_var.h> /* sockaddr_dl */ X Xextern struct sockaddr_dl _ether_sockaddrs[NOFILE]; X X#define sad (_ether_sockaddrs[fd]) X X/* X * Most, but not all, VAX interfaces, loopback packets. The Ultrix drivers X * for the rest try (with varying degrees of success) to compensate for that X * as far as broadcast packets go. The ec (3com) driver does it only for IP X * packets, and does not support multicast, and seems to be unsupported by X * DEC. X */ X Xstatic char *softloops[] = {"ec", "qe", "se"}; X Xint Xether_send_self (fd) Xint fd; X{ X unsigned char *devname = sad.dli_device.dli_devname; X int i; X X for (i = 0; i < sizeof (softloops) / sizeof (softloops[0]); i++) X if (!strcmp ((char *) devname, softloops[i])) X return (0); X X return (1); /* default to true */ X} X Xint Xether_mcast_self (fd) Xint fd; X{ X return (ether_send_self (fd)); X} X Xint Xether_bcast_self (fd) Xint fd; X{ X unsigned char *devname = sad.dli_device.dli_devname; X X if (!strcmp ((char *) devname, "ec")) X return (0); /* the ec driver is broken... */ X X return (1); /* default to true */ X} END_OF_FILE if test 1415 -ne `wc -c <'./src/dliself.c'`; then echo shar: \"'./src/dliself.c'\" unpacked with wrong size! fi # end of './src/dliself.c' fi if test -f './src/dliwrite.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/dliwrite.c'\" else echo shar: Extracting \"'./src/dliwrite.c'\" \(971 characters\) sed "s/^X//" >'./src/dliwrite.c' <<'END_OF_FILE' X/* $Id: dliwrite.c,v 2.1 89/10/23 15:42:09 dupuy Exp $ */ X X#include <sys/param.h> /* NOFILE */ X#include <sys/socket.h> /* sockaddr_dl (sockaddr) */ X X#include <net/if.h> /* ifdevea */ X#include <netinet/in.h> /* (ether_header) (in_addr) */ X#include <netinet/if_ether.h> /* sockaddr_dl (ether_header) */ X#include <netdnet/dli_var.h> /* sockaddr_dl */ X X#include <errno.h> /* EWOULDBLOCK */ X X#include "libether.h" X Xextern struct sockaddr_dl _ether_sockaddrs[NOFILE]; X X#define sad (_ether_sockaddrs[fd]) X X/* X * Writes a single packet, filling src and type fields. X */ X Xint Xether_write (fd, packet) Xint fd; Xether_packet *packet; X{ X int result; X X bcopy ((char *) &packet->dest, X (char *) sad.choose_addr.dli_eaddr.dli_target, DLI_EADDRSIZE); X X result = sendto (fd, packet->pktbuf, (int) packet->pktlen, 0, X (struct sockaddr *) &sad, sizeof (struct sockaddr_dl)); X X if (result < 0 && errno == EWOULDBLOCK) X errno = EAGAIN; X X return (result); X} END_OF_FILE if test 971 -ne `wc -c <'./src/dliwrite.c'`; then echo shar: \"'./src/dliwrite.c'\" unpacked with wrong size! fi # end of './src/dliwrite.c' fi if test -f './src/dliwritev.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/dliwritev.c'\" else echo shar: Extracting \"'./src/dliwritev.c'\" \(1132 characters\) sed "s/^X//" >'./src/dliwritev.c' <<'END_OF_FILE' X/* $Id: dliwritev.c,v 2.1 89/10/23 15:42:10 dupuy Exp $ */ X X#include <sys/param.h> /* NOFILE */ X#include <sys/socket.h> /* sockaddr_dl (sockaddr) */ X#include <sys/uio.h> /* iovec */ X X#include <net/if.h> /* ifdevea */ X#include <netinet/in.h> /* (ether_header) (in_addr) */ X#include <netinet/if_ether.h> /* sockaddr_dl (ether_header) */ X#include <netdnet/dli_var.h> /* sockaddr_dl */ X X#include <errno.h> /* EWOULDBLOCK */ X X#include "libether.h" X Xextern struct sockaddr_dl _ether_sockaddrs[NOFILE]; X X#define sad (_ether_sockaddrs[fd]) X X/* X * Writes a single packet, filling src and type fields. X */ X Xint Xether_writev (fd, packet) Xint fd; Xether_vec *packet; X{ X struct msghdr msg; X int result; X X bcopy ((char *) &packet->dest, X (char *) sad.choose_addr.dli_eaddr.dli_target, DLI_EADDRSIZE); X X msg.msg_iov = packet->iov; X msg.msg_iovlen = packet->iovcnt; X msg.msg_name = (caddr_t) &sad; X msg.msg_namelen = sizeof (sad); X msg.msg_accrights = 0; X msg.msg_accrightslen = 0; X X result = sendmsg (fd, &msg, 0); X X if (result < 0 && errno == EWOULDBLOCK) X errno = EAGAIN; X X return (result); X} END_OF_FILE if test 1132 -ne `wc -c <'./src/dliwritev.c'`; then echo shar: \"'./src/dliwritev.c'\" unpacked with wrong size! fi # end of './src/dliwritev.c' fi if test -f './src/enetaddr.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/enetaddr.c'\" else echo shar: Extracting \"'./src/enetaddr.c'\" \(1415 characters\) sed "s/^X//" >'./src/enetaddr.c' <<'END_OF_FILE' X/* $Id: enetaddr.c,v 2.0 89/10/20 19:01:58 dupuy Exp $ */ X X#include <sys/types.h> /* FD_ISSET */ X#include <sys/ioctl.h> /* ioctl */ X X#include <net/enet.h> /* endevp */ X X#include "libether.h" X Xstatic fd_set addrcachevalid; X Xstatic ether_addr ifaddrs[FD_SETSIZE]; X X#define ifaddr (ifaddrs[fd]) X X/* X * Returns the local ethernet address for the ethernet interface on the file X * descriptor fd. The result is stored in the structure given by address; if X * none is given, malloc is used to allocate space. We cache results here X * because this function is called every time we send a packet. X */ X Xether_addr * Xether_address (fd, address) Xint fd; Xether_addr *address; X{ X if (!FD_ISSET (fd, &addrcachevalid)) X { X struct endevp edev; X X if (ioctl (fd, EIOCDEVP, (char *) &edev) < 0) X { X#ifdef DEBUG X perror ("ether_address: ioctl EIOCDEVP"); X#endif X return (0); X } X X bcopy ((char *) edev.end_addr, (char *) &ifaddr, sizeof (ether_addr)); X X FD_SET (fd, &addrcachevalid); X } X X X if (address == 0) X address = (ether_addr *) malloc (sizeof (ether_addr)); X X if (address != 0) X bcopy ((char *) &ifaddr, (char *) address, sizeof (ether_addr)); X X return (address); X} X X/* X * This function is called by ether_open to invalidate the local address X * cache, since the file descriptor may be attached to a different interface. X */ X Xvoid X_ether_newaddr (fd) Xint fd; X{ X FD_CLR (fd, &addrcachevalid); X} END_OF_FILE if test 1415 -ne `wc -c <'./src/enetaddr.c'`; then echo shar: \"'./src/enetaddr.c'\" unpacked with wrong size! fi # end of './src/enetaddr.c' fi if test -f './src/enetblock.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/enetblock.c'\" else echo shar: Extracting \"'./src/enetblock.c'\" \(980 characters\) sed "s/^X//" >'./src/enetblock.c' <<'END_OF_FILE' X/* $Id: enetblock.c,v 2.0 89/10/20 19:02:00 dupuy Exp $ */ X X#include <sys/types.h> /* eniocb (u_char) */ X#include <net/enet.h> /* eniocb */ X X#define ERR (-1) X X/* X * If state is false (0), set ethernet file descriptor fd to be non-blocking, X * else set fd to be blocking. If there is an error, ether_blocking() returns X * (-1) and the appropriate value is left in errno. Normal return status X * zero. X * X * We _ought_ to be able to use fcntl like SunOS and Ultrix, but since the enet X * special device doesn't support the FIONBIO ioctl, we can't. This is a bug X * in the enet device driver which should be fixed. Furthermore, this only X * prevents blocking on reads (the most common case, admittedly). Writes to X * ethernet devices can still block waiting for queue resources. X */ X Xint Xether_blocking (fd, state) Xint fd; Xint state; X{ X struct eniocb eni; X X if (state) X eni.en_rtout = 0; X else X eni.en_rtout = -1; X X return (ioctl (fd, EIOCSETP, (char *) &eni)); X} END_OF_FILE if test 980 -ne `wc -c <'./src/enetblock.c'`; then echo shar: \"'./src/enetblock.c'\" unpacked with wrong size! fi # end of './src/enetblock.c' fi if test -f './src/enetintaddr.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/enetintaddr.c'\" else echo shar: Extracting \"'./src/enetintaddr.c'\" \(1076 characters\) sed "s/^X//" >'./src/enetintaddr.c' <<'END_OF_FILE' X/* $Id: enetintaddr.c,v 2.0 89/10/20 19:02:02 dupuy Exp $ */ X X#include <strings.h> /* strcpy */ X#include <sys/types.h> /* (sockaddr) (u_short) */ X#include <sys/socket.h> /* IFNAMSIZ (sockaddr) */ X#include <sys/file.h> /* O_RDWR */ X#include <net/if.h> /* IFNAMSIZ */ X Xextern int errno; X X#include "libether.h" X X#ifndef ENET_DEVDIR X#define ENET_DEVDIR "/dev/enet/" X#endif X X/* X * Returns the local ethernet address for an ethernet interface. The result X * is stored in the structure given by address; if none is given, malloc is X * used to allocate space. X */ X Xether_addr * Xether_intfaddr (intf, address) Xchar *intf; Xether_addr *address; X{ X char pathname[sizeof (ENET_DEVDIR) + IFNAMSIZ]; X int fd; X int saved_errno; X X (void) strcpy (pathname, ENET_DEVDIR); X (void) strncat (pathname, intf, IFNAMSIZ); X X if ((fd = open (pathname, O_RDWR)) < 0) X { X#ifdef DEBUG X perror (pathname); X#endif X return (0); X } X X address = ether_address (fd, address); X X saved_errno = errno; X (void) close (fd); X errno = saved_errno; X X return (address); X} END_OF_FILE if test 1076 -ne `wc -c <'./src/enetintaddr.c'`; then echo shar: \"'./src/enetintaddr.c'\" unpacked with wrong size! fi # end of './src/enetintaddr.c' fi if test -f './src/enetself.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/enetself.c'\" else echo shar: Extracting \"'./src/enetself.c'\" \(601 characters\) sed "s/^X//" >'./src/enetself.c' <<'END_OF_FILE' X/* $Id: enetself.c,v 2.0 89/10/20 19:02:05 dupuy Exp $ */ X X/* X * Most, but not all, VAX interfaces, loopback packets. The enetfilter X * drivers for the ec (3com) interface loops back packets in software, except X * for multicast packets. Since the enetfilter currently has no way to X * receive multicast packets, that makes little difference. X */ X X/* ARGSUSED */ X Xint Xether_send_self (fd) Xint fd; X{ X return (1); X} X X/* ARGSUSED */ X Xint Xether_mcast_self (fd) Xint fd; X{ X return (0); /* can't receive multicast packets */ X} X X/* ARGSUSED */ X Xint Xether_bcast_self (fd) Xint fd; X{ X return (1); X} END_OF_FILE if test 601 -ne `wc -c <'./src/enetself.c'`; then echo shar: \"'./src/enetself.c'\" unpacked with wrong size! fi # end of './src/enetself.c' fi if test -f './src/enetwrite.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/enetwrite.c'\" else echo shar: Extracting \"'./src/enetwrite.c'\" \(1012 characters\) sed "s/^X//" >'./src/enetwrite.c' <<'END_OF_FILE' X/* $Id: enetwrite.c,v 2.1 89/10/24 17:53:05 dupuy Exp $ */ X X#include <sys/types.h> /* iovec (caddr_t) */ X#include <sys/uio.h> /* iovec */ X X#include "libether.h" X Xextern unsigned _ether_types[FD_SETSIZE]; X X#define ether_type (_ether_types[fd]) X X#define HEADER 0 X#define DATA 1 X#define MAXIOV 2 X X/* X * Writes a single packet, filling src and type fields. We have to fill in X * the src field in user space, since the enetfilter doesn't do it for us, and X * at least some VAX interface devices don't do it either. X */ X Xint Xether_write (fd, packet) Xint fd; Xether_packet *packet; X{ X struct iovec iov[MAXIOV]; X X iov[HEADER].iov_len = ETHER_PKT; X iov[HEADER].iov_base = (char *) packet; X X iov[DATA].iov_len = packet->pktlen; X iov[DATA].iov_base = packet->pktbuf; X X if (ether_type != ETHER_ALLTYPES) X { X packet->type[0] = (ether_type >> 8) & 0xff; X packet->type[1] = ether_type & 0xff; X } X X (void) ether_address (fd, (ether_addr *) &packet->src); X X return (writev (fd, iov, MAXIOV)); X} END_OF_FILE if test 1012 -ne `wc -c <'./src/enetwrite.c'`; then echo shar: \"'./src/enetwrite.c'\" unpacked with wrong size! fi # end of './src/enetwrite.c' fi if test -f './src/enetwritev.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/enetwritev.c'\" else echo shar: Extracting \"'./src/enetwritev.c'\" \(1313 characters\) sed "s/^X//" >'./src/enetwritev.c' <<'END_OF_FILE' X/* $Id: enetwritev.c,v 2.2 89/10/24 17:53:10 dupuy Exp $ */ X X#include <sys/types.h> /* iovec (caddr_t) */ X#include <sys/uio.h> /* iovec */ X X#include "libether.h" X X#ifdef __GNUC__ X#define alloca __builtin_alloca X#else X#ifdef lint Xextern double *dalloca (); X#define alloca dalloca X#else X#ifdef sparc X#include <alloca.h> X#endif Xextern char *alloca (); X#endif X#endif X Xextern unsigned _ether_types[FD_SETSIZE]; X X#define ether_type (_ether_types[fd]) X X#define HEADER 0 X#define USER 1 X X/* X * Writes a single packet, filling src and type fields. We have to fill in X * the src field in user space, since the enetfilter doesn't do it for us, and X * at least some VAX interface devices don't do it either. X */ X Xint Xether_writev (fd, packet) Xint fd; Xether_vec *packet; X{ X int count = 1 + packet->iovcnt; X struct iovec *iov = X (struct iovec *) alloca (sizeof (struct iovec) * count); X X iov[HEADER].iov_len = ETHER_PKT; X iov[HEADER].iov_base = (char *) packet; X X (void) bcopy ((char *) packet->iov, (char *) &iov[USER], X (int) packet->iovcnt * sizeof (struct iovec)); X X if (ether_type != ETHER_ALLTYPES) X { X packet->type[0] = (ether_type >> 8) & 0xff; X packet->type[1] = ether_type & 0xff; X } X X (void) ether_address (fd, (ether_addr *) &packet->src); X X return (writev (fd, iov, count)); X} END_OF_FILE if test 1313 -ne `wc -c <'./src/enetwritev.c'`; then echo shar: \"'./src/enetwritev.c'\" unpacked with wrong size! fi # end of './src/enetwritev.c' fi if test -f './src/ethera2e.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/ethera2e.c'\" else echo shar: Extracting \"'./src/ethera2e.c'\" \(995 characters\) sed "s/^X//" >'./src/ethera2e.c' <<'END_OF_FILE' X/* $Id: ethera2e.c,v 2.1 89/10/23 15:42:22 dupuy Exp $ */ X X#include <stdio.h> /* sscanf */ X X#include "libether.h" X X#define EBYTES 6 X Xether_addr * Xether_a2e (estring, addr) Xchar *estring; Xether_addr *addr; X{ X unsigned bytes[EBYTES]; X int allocated = 0; X int i; X X if (addr == NULL) X { X addr = (ether_addr *) malloc (sizeof (ether_addr)); X allocated++; X } X X if (addr != NULL) X if (sscanf (estring, " %2x:%2x:%2x:%2x:%2x:%2x", &bytes[0], &bytes[1], X &bytes[2], &bytes[3], &bytes[4], &bytes[5]) X == EBYTES || X sscanf (estring, " %2x-%2x-%2x-%2x-%2x-%2x", &bytes[0], &bytes[1], X &bytes[2], &bytes[3], &bytes[4], &bytes[5]) X == EBYTES) X { X for (i = 0; i < EBYTES; i++) X addr->bytes[i] = bytes[i]; X } X else X { X if (allocated) X (void) free ((char *) addr); X addr = NULL; X } X X return (addr); X} X X#ifndef ETHERDB X Xether_addr * Xether_aton (estring) Xchar *estring; X{ X static ether_addr addr; X X return (ether_a2e (estring, &addr)); X} X X#endif END_OF_FILE if test 995 -ne `wc -c <'./src/ethera2e.c'`; then echo shar: \"'./src/ethera2e.c'\" unpacked with wrong size! fi # end of './src/ethera2e.c' fi if test -f './src/etheraddr.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/etheraddr.c'\" else echo shar: Extracting \"'./src/etheraddr.c'\" \(755 characters\) sed "s/^X//" >'./src/etheraddr.c' <<'END_OF_FILE' X/* $Id: etheraddr.c,v 2.1 89/10/23 15:44:44 dupuy Exp $ */ X X/* X * Static initialization of ethernet broadcast address. We do it in a separate X * file so that it can be compiled with -R (read-only), but more importatntly, X * so that we can get around the restriction on initializing unions if needed. X */ X X#ifdef __STDC__ X X#include "ether.h" X Xether_addr ether_bcast_addr = {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}; X X#else X X#ifdef lint X X#include "ether.h" X Xether_addr ether_bcast_addr; /* a little white lie */ X X#else X X#define __ETHER_BCAST_ADDR__ /* avoid conflict with ether.h */ X X#include "ether.h" X Xstruct ether_addr X{ X unsigned short shorts[3]; /* must have short alignment */ X} Xether_bcast_addr = {{ 0xffff, 0xffff, 0xffff }}; X X#endif X X#endif END_OF_FILE if test 755 -ne `wc -c <'./src/etheraddr.c'`; then echo shar: \"'./src/etheraddr.c'\" unpacked with wrong size! fi # end of './src/etheraddr.c' fi if test -f './src/etherblock.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/etherblock.c'\" else echo shar: Extracting \"'./src/etherblock.c'\" \(890 characters\) sed "s/^X//" >'./src/etherblock.c' <<'END_OF_FILE' X/* $Id: etherblock.c,v 2.1 89/10/23 15:42:26 dupuy Exp $ */ X X#include <sys/file.h> /* FNBIO/FNDELAY */ X X#ifdef __STDC__ Xextern int fcntl (int f, int c, int a); X#else Xextern int fcntl (); X#endif X X#ifdef FNBIO X#define FNOBLOCK FNBIO X#else X#define FNOBLOCK FNDELAY X#endif X X#define ERR (-1) X X/* X * If state is false (0), set ethernet file descriptor fd to be non-blocking, X * else set fd to be blocking. If there is an error, ether_blocking() returns X * (-1) and the appropriate value is left in errno. Normal return status X * zero. X */ X Xint Xether_blocking (fd, state) Xint fd; Xint state; X{ X int flags; X X if ((flags = fcntl (fd, F_GETFL, -1)) < 0) X return (ERR); X X if (state) X if (flags & FNOBLOCK) X state = fcntl (fd, F_SETFL, flags & ~FNOBLOCK); X else X state = 0; X else if ((flags & FNOBLOCK) == 0) X state = fcntl (fd, F_SETFL, flags | FNOBLOCK); X X return (state); X} END_OF_FILE if test 890 -ne `wc -c <'./src/etherblock.c'`; then echo shar: \"'./src/etherblock.c'\" unpacked with wrong size! fi # end of './src/etherblock.c' fi if test -f './src/ethere2a.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/ethere2a.c'\" else echo shar: Extracting \"'./src/ethere2a.c'\" \(630 characters\) sed "s/^X//" >'./src/ethere2a.c' <<'END_OF_FILE' X/* $Id: ethere2a.c,v 2.1 89/10/23 15:42:28 dupuy Exp $ */ X X#include <stdio.h> X X#include "libether.h" X Xchar * Xether_e2a (addr, estring) Xether_addr *addr; Xchar *estring; X{ X#ifdef lint X char *sprintf (); X#endif X if (estring == NULL) X estring = (char *) malloc (ETHERSTRLEN); X X if (estring != NULL) X (void) sprintf (estring, "%x:%x:%x:%x:%x:%x", X addr->bytes[0], addr->bytes[1], addr->bytes[2], X addr->bytes[3], addr->bytes[4], addr->bytes[5]); X return (estring); X} X X#ifndef ETHERDB X Xchar * Xether_ntoa (addr) Xether_addr *addr; X{ X static char estring[ETHERSTRLEN]; X X return (ether_e2a (addr, estring)); X} X X#endif END_OF_FILE if test 630 -ne `wc -c <'./src/ethere2a.c'`; then echo shar: \"'./src/ethere2a.c'\" unpacked with wrong size! fi # end of './src/ethere2a.c' fi if test -f './src/etherlocal.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/etherlocal.c'\" else echo shar: Extracting \"'./src/etherlocal.c'\" \(1143 characters\) sed "s/^X//" >'./src/etherlocal.c' <<'END_OF_FILE' X/* $Id: etherlocal.c,v 2.1 89/10/23 15:42:38 dupuy Exp $ */ X X#include <sys/types.h> /* (u_char) */ X#include <sys/socket.h> /* sockaddr_in (sockaddr) */ X#include <net/if.h> /* ifconf */ X#include <netinet/in.h> /* sockaddr_in */ X#include <errno.h> X Xextern int errno; X X#include "libether.h" X Xextern short _ether_ifindex[MAXNUMIF]; /* from ether_interfaces() */ Xextern struct ifconf _ether_ifconf; /* from ether_interfaces() */ X X Xint X_ether_localif (addr, ipaddr) Xether_addr *addr; Xstruct in_addr *ipaddr; X{ X char **intfs; X int i; X X if ((intfs = ether_interfaces ()) == 0) X return (0); X X for (i = 0; *intfs; intfs++, i++) X { X ether_addr eaddr; X X if (_ether_ifindex[i] < 0) X continue; /* not an AF_INET interface */ X X if (ether_intfaddr (*intfs, &eaddr) == 0) X return (0); X X if (ether_cmp (addr, &eaddr) == 0) X { X struct sockaddr_in *inaddr; X X inaddr = (struct sockaddr_in *) X &_ether_ifconf.ifc_req[_ether_ifindex[i]].ifr_addr; X X (void) bcopy ((char *) &inaddr->sin_addr, (char *) ipaddr, X sizeof (*ipaddr)); X return (1); X } X } X X return (0); /* doesn't match any local interface */ X} END_OF_FILE if test 1143 -ne `wc -c <'./src/etherlocal.c'`; then echo shar: \"'./src/etherlocal.c'\" unpacked with wrong size! fi # end of './src/etherlocal.c' fi if test -f './src/etherread.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/etherread.c'\" else echo shar: Extracting \"'./src/etherread.c'\" \(1860 characters\) sed "s/^X//" >'./src/etherread.c' <<'END_OF_FILE' X/* $Id: etherread.c,v 2.1 89/10/23 15:42:40 dupuy Exp $ */ X X#include <sys/types.h> /* iovec (caddr_t) */ X#include <sys/uio.h> /* iovec */ X X#include <errno.h> /* EWOULDBLOCK/EMSGSIZE */ X Xextern int errno; X X#include "libether.h" X X#define HEADER 0 X#define DATA 1 X#define WASTE 2 X#define MAXIOV 3 X X/* X * Reads and returns a single packet, filling in all fields. If pktbuf is X * NULL, a buffer is allocated for it. If pktbuf is not NULL, the function X * assumes that pktbuf is large enough to hold pktlen bytes. Reads on the X * ethernet packet filter device always return one packet. Streams must be in X * RMSGD mode for reads to return one packet at a time X */ X Xint Xether_read (fd, packet) Xint fd; Xether_packet *packet; X{ X char waste[ETHER_MAX]; X struct iovec iov[MAXIOV]; X int count; X X iov[HEADER].iov_len = ETHER_PKT; X iov[HEADER].iov_base = (char *) packet; X X if (packet->pktbuf) X { X iov[DATA].iov_len = packet->pktlen; X iov[DATA].iov_base = packet->pktbuf; X X iov[WASTE].iov_len = sizeof (waste); X iov[WASTE].iov_base = waste; X X count = 3; /* use waste to get all of packet */ X } X else X { X iov[DATA].iov_len = packet->pktlen = ETHER_MAX; X if ((iov[DATA].iov_base = (char *) malloc ((unsigned) ETHER_MAX)) == 0) X return (-1); X packet->pktbuf = iov[DATA].iov_base; X X count = 2; /* no need to use waste */ X } X X if ((count = readv (fd, iov, count)) <= 0) X { X#ifndef EBADMSG /* a stream will return EAGAIN */ X if (count == 0 || errno == EWOULDBLOCK) X errno = EAGAIN; X#endif X return (-1); X } X X if ((count -= ETHER_PKT) < 0) X { /* enet returns EOF (0) */ X#ifdef EBADMSG X errno = EBADMSG; /* XXX readv() can also return this */ X#else X errno = EMSGSIZE; /* XXX message isn't really too long */ X#endif X } X else if (packet->pktlen > count) X packet->pktlen = count; X X return (count); X} END_OF_FILE if test 1860 -ne `wc -c <'./src/etherread.c'`; then echo shar: \"'./src/etherread.c'\" unpacked with wrong size! fi # end of './src/etherread.c' fi if test -f './src/etherreadv.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/etherreadv.c'\" else echo shar: Extracting \"'./src/etherreadv.c'\" \(1628 characters\) sed "s/^X//" >'./src/etherreadv.c' <<'END_OF_FILE' X/* $Id: etherreadv.c,v 2.1 89/10/23 15:42:42 dupuy Exp $ */ X X#include <sys/types.h> /* iovec (caddr_t) */ X#include <sys/uio.h> /* iovec */ X X#include <errno.h> /* EWOULDBLOCK/EMSGSIZE */ X Xextern int errno; X X#include "libether.h" X X#ifdef __GNUC__ X#define alloca __builtin_alloca X#else X#ifdef lint Xextern double *dalloca (); X#define alloca dalloca X#else X#ifdef sparc X#include <alloca.h> X#endif Xextern char *alloca (); X#endif X#endif X X#define HEADER 0 X#define USER 1 X#define WASTE (count - 1) X X/* X * Reads and returns a single packet, filling in all fields. Reads on the X * ethernet packet filter device always return one packet. Streams must be in X * RMSGD mode for reads to return one packet at a time X */ X Xint Xether_readv (fd, packet) Xint fd; Xether_vec *packet; X{ X char waste[ETHER_MAX]; X int count = 2 + packet->iovcnt; X struct iovec *iov = X (struct iovec *) alloca (sizeof (struct iovec) * count); X X iov[HEADER].iov_len = ETHER_PKT; X iov[HEADER].iov_base = (char *) packet; X X (void) bcopy ((char *) packet->iov, (char *) &iov[USER], X (int) packet->iovcnt * sizeof (struct iovec)); X X iov[WASTE].iov_len = sizeof (waste); X iov[WASTE].iov_base = waste; X X if ((count = readv (fd, iov, count)) <= 0) X { /* enet returns EOF (0) */ X#ifndef EBADMSG /* a stream will return EAGAIN */ X if (count == 0 || errno == EWOULDBLOCK) X errno = EAGAIN; X#endif X return (-1); X } X X if ((count -= ETHER_PKT) < 0) X { X#ifdef EBADMSG X errno = EBADMSG; /* XXX readv() can also return this */ X#else X errno = EMSGSIZE; /* XXX message isn't really too long */ X#endif X } X X return (count); X} END_OF_FILE if test 1628 -ne `wc -c <'./src/etherreadv.c'`; then echo shar: \"'./src/etherreadv.c'\" unpacked with wrong size! fi # end of './src/etherreadv.c' fi if test -f './src/libether.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/libether.h'\" else echo shar: Extracting \"'./src/libether.h'\" \(1312 characters\) sed "s/^X//" >'./src/libether.h' <<'END_OF_FILE' X/* $Id: libether.h,v 2.1 89/10/23 15:42:44 dupuy Exp $ */ X X/* Internal definitions for ethernet access library */ X X#include "ether.h" /* get interface definitions */ X X#define MAXNUMIF 16 /* maximum number of interfaces */ X X#define ETHER_BUFFERS 5 /* for socket based NIT interface */ X#define ETHER_BUFSIZ \ X (ETHER_BUFFERS * (ETHER_PKT + ETHER_MAX + (2 * sizeof (struct nit_hdr)))) X X#define ALIGNSIZE (sizeof (int)) X#define pad(x) ((ALIGNSIZE - ((unsigned)(x)) % ALIGNSIZE) % ALIGNSIZE) X X#define address_check(dest) \ X (ETHER_MCAST (dest) \ X && bcmp ((char *)(dest), (char *) ðer_bcast_addr, sizeof (ether_addr)) \ X && bcmp ((char *)(dest), (char *) &_ether_multi_addrs[fd], \ X sizeof (ether_addr))) X X#ifdef __STDC__ X Xextern char *malloc (unsigned size); X Xextern int _ether_arpscan (ether_addr *addr, struct in_addr *ipaddr); Xextern int _ether_localif (ether_addr *addr, struct in_addr *ipaddr); X#ifdef RARP Xextern int _ether_rarpprobe (ether_addr *addr, struct in_addr *ipaddr); X#endif X X#else X X#ifdef lint X X#ifndef htons X Xextern unsigned short htons (); X X#endif X X#ifdef ultrix X Xextern void bzero (); Xextern void bcopy (); Xextern void free (); Xextern void perror (); X X#endif X Xextern double *dalloc (); X#define malloc dalloc X X#else X Xextern char *malloc (); X X#endif /* lint */ X X#endif /* __STDC__ */ END_OF_FILE if test 1312 -ne `wc -c <'./src/libether.h'`; then echo shar: \"'./src/libether.h'\" unpacked with wrong size! fi # end of './src/libether.h' fi if test -f './src/nit3intaddr.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/nit3intaddr.c'\" else echo shar: Extracting \"'./src/nit3intaddr.c'\" \(1250 characters\) sed "s/^X//" >'./src/nit3intaddr.c' <<'END_OF_FILE' X/* $Id: nit3intaddr.c,v 2.1 89/10/23 15:42:47 dupuy Exp $ */ X X#include <sys/types.h> /* AF_NIT (u_short) */ X#include <sys/socket.h> /* AF_NIT */ X Xextern int errno; X X#include "libether.h" X Xether_addr _ether_localaddr; /* shared with ether_address() */ Xint _ether_haveaddress; /* shared with ether_address() */ X X/* X * Returns the local ethernet address for an ethernet interface. The result X * is stored in the structure given by address; if none is given, malloc is X * used to allocate space. Sun systems have the "feature" that all ethernet X * interfaces are set to the same address (taken from the ID PROM). So we can X * get the answer once, and use it forever. X */ X X/* ARGSUSED */ X Xether_addr * Xether_intfaddr (intf, address) Xchar *intf; Xether_addr *address; X{ X if (!_ether_haveaddress) X { X int fd; X int saved_errno; X X if ((fd = socket (AF_NIT, SOCK_RAW, 0)) < 0) X { X#ifdef DEBUG X perror ("ether_open: socket"); X#endif X return (0); X } X X address = ether_address (fd, address); X X saved_errno = errno; X (void) close (fd); X errno = saved_errno; X X return (address); X } X X if (address == 0) X address = (ether_addr *) malloc (sizeof (ether_addr)); X X if (address != 0) X *address = _ether_localaddr; X X return (address); X} END_OF_FILE if test 1250 -ne `wc -c <'./src/nit3intaddr.c'`; then echo shar: \"'./src/nit3intaddr.c'\" unpacked with wrong size! fi # end of './src/nit3intaddr.c' fi if test -f './src/nit3read.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/nit3read.c'\" else echo shar: Extracting \"'./src/nit3read.c'\" \(1151 characters\) sed "s/^X//" >'./src/nit3read.c' <<'END_OF_FILE' X/* $Id: nit3read.c,v 2.1 89/10/23 15:42:53 dupuy Exp $ */ X X#include "libether.h" X X/* X * Reads and returns a single packet, filling in all fields. If pktbuf is X * NULL, a buffer is allocated for it. If pktbuf is not NULL, the function X * assumes that pktbuf is large enough to hold pktlen bytes. Since read() may X * return several packets at a time, we have to buffer them as well. Since X * socket based nit doesn't handle multicast addresses, we have to check them X * at the user level. X * X * NOTE - the buffering code is not re-entrant, although different fd's will X * not conflict. X */ X Xint Xether_read (fd, packet) Xint fd; Xether_packet *packet; X{ X char *pbuf; X int bytes; X X if ((bytes = _ether_next_packet (fd, &pbuf)) < 0) X return (-1); X X bcopy (pbuf, (char *) packet, ETHER_PKT); X pbuf += ETHER_PKT; X X if (packet->pktbuf == 0) X { X packet->pktlen = bytes; X if ((packet->pktbuf = (char *) malloc ((unsigned) bytes)) == 0) X return (-1); X } X X bcopy (pbuf, packet->pktbuf, X (int) ((packet->pktlen > bytes) ? bytes : packet->pktlen)); X X if (packet->pktlen > bytes) X packet->pktlen = bytes; X X return (bytes); X} END_OF_FILE if test 1151 -ne `wc -c <'./src/nit3read.c'`; then echo shar: \"'./src/nit3read.c'\" unpacked with wrong size! fi # end of './src/nit3read.c' fi if test -f './src/nit3readv.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/nit3readv.c'\" else echo shar: Extracting \"'./src/nit3readv.c'\" \(1251 characters\) sed "s/^X//" >'./src/nit3readv.c' <<'END_OF_FILE' X/* $Id: nit3readv.c,v 2.0 89/10/20 19:02:38 dupuy Exp $ */ X X#include <sys/types.h> /* iovec (caddr_t) */ X#include <sys/uio.h> /* iovec */ X X#include "libether.h" X X/* X * Reads and returns a single packet, filling in all fields. Since read() may X * return several packets at a time, we have to buffer them as well. Since X * socket based nit doesn't handle multicast addresses, we have to check them X * at the user level. X * X * NOTE - the buffering code is not re-entrant, although different fd's will X * not conflict. X */ X Xint Xether_readv (fd, packet) Xint fd; Xether_vec *packet; X{ X char *pbuf; X int index = 0; X int count; X int bytes; X X if ((bytes = _ether_next_packet (fd, &pbuf)) < 0) X return (-1); X X bcopy (pbuf, (char *) packet, ETHER_PKT); X pbuf += ETHER_PKT; X X for (count = 0; count < packet->iovcnt && index < bytes; count++) X if (packet->iov[count].iov_len) X { X if (bytes - index < packet->iov[count].iov_len) X { X bcopy (&pbuf[index], (char *) packet->iov[count].iov_base, X bytes - index); X break; X } X else X { X bcopy (&pbuf[index], (char *) packet->iov[count].iov_base, X (int) packet->iov[count].iov_len); X index += packet->iov[count].iov_len; X } X } X X return (bytes); X} END_OF_FILE if test 1251 -ne `wc -c <'./src/nit3readv.c'`; then echo shar: \"'./src/nit3readv.c'\" unpacked with wrong size! fi # end of './src/nit3readv.c' fi if test -f './src/nit3self.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/nit3self.c'\" else echo shar: Extracting \"'./src/nit3self.c'\" \(396 characters\) sed "s/^X//" >'./src/nit3self.c' <<'END_OF_FILE' X/* $Id: nit3self.c,v 2.0 89/10/20 19:02:40 dupuy Exp $ */ X X/* X * No standard sun ethernet interface loops back packets. The socket-based Sun X * NIT interface doesn't do it either. X */ X X/* ARGSUSED */ X Xint Xether_send_self (fd) Xint fd; X{ X return (0); X} X X/* ARGSUSED */ X Xint Xether_mcast_self (fd) Xint fd; X{ X return (0); X} X X/* ARGSUSED */ X Xint Xether_bcast_self (fd) Xint fd; X{ X return (0); X} END_OF_FILE if test 396 -ne `wc -c <'./src/nit3self.c'`; then echo shar: \"'./src/nit3self.c'\" unpacked with wrong size! fi # end of './src/nit3self.c' fi if test -f './src/nit3write.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/nit3write.c'\" else echo shar: Extracting \"'./src/nit3write.c'\" \(681 characters\) sed "s/^X//" >'./src/nit3write.c' <<'END_OF_FILE' X/* $Id: nit3write.c,v 2.0 89/10/20 19:02:41 dupuy Exp $ */ X X#include <sys/param.h> X#include <sys/socket.h> X X#include "libether.h" X Xextern unsigned _ether_types[NOFILE]; X X#define ether_type (_ether_types[fd]) X X/* X * Writes a single packet, filling src and type fields. X */ X Xint Xether_write (fd, packet) Xint fd; Xether_packet *packet; X{ X struct sockaddr sa; X X sa.sa_family = AF_UNSPEC; X bcopy ((char *) packet, sa.sa_data, ETHER_TYPE); X X if (ether_type != ETHER_ALLTYPES) X { X sa.sa_data[12] = (ether_type >> 8) & 0xff; X sa.sa_data[13] = ether_type & 0xff; X } X X return (sendto (fd, packet->pktbuf, (int) packet->pktlen, 0, &sa, X sizeof (sa)) < 0 ? -1 : 0); X} END_OF_FILE if test 681 -ne `wc -c <'./src/nit3write.c'`; then echo shar: \"'./src/nit3write.c'\" unpacked with wrong size! fi # end of './src/nit3write.c' fi if test -f './src/nit3writev.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/nit3writev.c'\" else echo shar: Extracting \"'./src/nit3writev.c'\" \(844 characters\) sed "s/^X//" >'./src/nit3writev.c' <<'END_OF_FILE' X/* $Id: nit3writev.c,v 2.0 89/10/20 19:02:42 dupuy Exp $ */ X X#include <sys/param.h> X#include <sys/socket.h> X X#include "libether.h" X Xextern unsigned _ether_types[NOFILE]; X X#define ether_type (_ether_types[fd]) X X/* X * Writes a single packet, filling src and type fields. X */ X Xint Xether_writev (fd, packet) Xint fd; Xether_vec *packet; X{ X struct sockaddr sa; X struct msghdr msg; X X sa.sa_family = AF_UNSPEC; X bcopy ((char *) packet, sa.sa_data, ETHER_TYPE); X X if (ether_type != ETHER_ALLTYPES) X { X sa.sa_data[12] = (ether_type >> 8) & 0xff; X sa.sa_data[13] = ether_type & 0xff; X } X X msg.msg_iov = packet->iov; X msg.msg_iovlen = packet->iovcnt; X msg.msg_name = (caddr_t) & sa; X msg.msg_namelen = sizeof (sa); X msg.msg_accrights = 0; X msg.msg_accrightslen = 0; X X return (sendmsg (fd, &msg, 0) < 0 ? -1 : 0); X} END_OF_FILE if test 844 -ne `wc -c <'./src/nit3writev.c'`; then echo shar: \"'./src/nit3writev.c'\" unpacked with wrong size! fi # end of './src/nit3writev.c' fi if test -f './src/nit4intaddr.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/nit4intaddr.c'\" else echo shar: Extracting \"'./src/nit4intaddr.c'\" \(1809 characters\) sed "s/^X//" >'./src/nit4intaddr.c' <<'END_OF_FILE' X/* $Id: nit4intaddr.c,v 2.1 89/10/23 15:42:56 dupuy Exp $ */ X X#include <strings.h> /* strncpy */ X#include <sys/file.h> /* O_RDWR */ X#include <sys/types.h> /* NIOCBIND (u_long) */ X#include <sys/time.h> /* NIOCBIND (timeval) */ X#include <sys/ioccom.h> /* ioctl */ X#include <sys/socket.h> /* ifreq (sockaddr) */ X X#include <net/if.h> /* ifreq */ X#include <net/nit_if.h> /* NIOCBIND */ X X#include "libether.h" X Xextern int errno; X X#ifndef NIT_DEV X#define NIT_DEV "/dev/nit" X#endif X Xether_addr _ether_localaddr; /* shared with ether_address() */ Xint _ether_haveaddress; /* shared with ether_address() */ X X/* X * Returns the local ethernet address for an ethernet interface. The result X * is stored in the structure given by address; if none is given, malloc is X * used to allocate space. Sun systems have the "feature" that all ethernet X * interfaces are set to the same address (taken from the ID PROM). So we can X * get the answer once, and use it forever. X */ X Xether_addr * Xether_intfaddr (intf, address) Xchar *intf; Xether_addr *address; X{ X if (!_ether_haveaddress) X { X int fd; X struct ifreq ifr; X int saved_errno; X X if ((fd = open (NIT_DEV, O_RDWR)) < 0) X { X#ifdef DEBUG X perror (NIT_DEV); X#endif X return (0); X } X X (void) strncpy (ifr.ifr_name, intf, sizeof (ifr.ifr_name)); X X if (ioctl (fd, NIOCBIND, (char *) &ifr) < 0) X { X saved_errno = errno; X#ifdef DEBUG X perror ("ether_intfaddr: ioctl NIOCBIND"); X#endif X (void) close (fd); X errno = saved_errno; X return (0); X } X X address = ether_address (fd, address); X X saved_errno = errno; X (void) close (fd); X errno = saved_errno; X X return (address); X } X X if (address == 0) X address = (ether_addr *) malloc (sizeof (ether_addr)); X X if (address != 0) X *address = _ether_localaddr; X X return (address); X} END_OF_FILE if test 1809 -ne `wc -c <'./src/nit4intaddr.c'`; then echo shar: \"'./src/nit4intaddr.c'\" unpacked with wrong size! fi # end of './src/nit4intaddr.c' fi if test -f './src/nit4self.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/nit4self.c'\" else echo shar: Extracting \"'./src/nit4self.c'\" \(894 characters\) sed "s/^X//" >'./src/nit4self.c' <<'END_OF_FILE' X/* $Id: nit4self.c,v 2.0 89/10/20 19:02:46 dupuy Exp $ */ X X#include <sys/sockio.h> /* SIOCGETFDSTAT */ X X/* X * No standard sun ethernet interface loops back packets. Early versions of X * the streams-based Sun NIT interface don't loopback broadcast packets, but X * 4.0.3 and later appear to (although 4.0.3 has bugs). Since a 4.0 compiled X * binary will run on a 4.0.3 system, we can't determine the answer correctly X * at compile time. Since there doesn't seem to be any kernel feature present X * in 4.0.3 and absent in earlier versions that we can test for, we use a X * compile-time check. It's the best we can do for now. X */ X X/* ARGSUSED */ X Xint Xether_send_self (fd) Xint fd; X{ X return (0); X} X X/* ARGSUSED */ X Xint Xether_mcast_self (fd) Xint fd; X{ X return (0); X} X X/* ARGSUSED */ X Xint Xether_bcast_self (fd) Xint fd; X{ X#ifdef SIOCGETFDSTAT X return (1); X#else X return (0); X#endif X} END_OF_FILE if test 894 -ne `wc -c <'./src/nit4self.c'`; then echo shar: \"'./src/nit4self.c'\" unpacked with wrong size! fi # end of './src/nit4self.c' fi if test -f './src/nit4write.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/nit4write.c'\" else echo shar: Extracting \"'./src/nit4write.c'\" \(956 characters\) sed "s/^X//" >'./src/nit4write.c' <<'END_OF_FILE' X/* $Id: nit4write.c,v 2.0 89/10/20 19:02:47 dupuy Exp $ */ X X#include <sys/types.h> X#include <sys/socket.h> X#include <sys/stropts.h> X X#include "libether.h" X Xextern unsigned _ether_types[FD_SETSIZE]; X X#define ether_type (_ether_types[fd]) X X/* X * Writes a single packet, filling src and type fields. X */ X Xint Xether_write (fd, packet) Xint fd; Xether_packet *packet; X{ X struct sockaddr sa; X struct strbuf cbuf; X struct strbuf dbuf; X X sa.sa_family = AF_UNSPEC; X bcopy ((char *) packet, sa.sa_data, ETHER_TYPE); X X if (ether_type != ETHER_ALLTYPES) X { X sa.sa_data[12] = (ether_type >> 8) & 0xff; X sa.sa_data[13] = ether_type & 0xff; X } X X cbuf.maxlen = cbuf.len = sizeof (sa); X cbuf.buf = (char *) &sa; X X /* X * The interface output routines will paste the ether header back onto the X * front of the message. X */ X X dbuf.len = packet->pktlen; X dbuf.buf = packet->pktbuf; X X return (putmsg (fd, &cbuf, &dbuf, 0)); X} END_OF_FILE if test 956 -ne `wc -c <'./src/nit4write.c'`; then echo shar: \"'./src/nit4write.c'\" unpacked with wrong size! fi # end of './src/nit4write.c' fi if test -f './src/nit4writev.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/nit4writev.c'\" else echo shar: Extracting \"'./src/nit4writev.c'\" \(1172 characters\) sed "s/^X//" >'./src/nit4writev.c' <<'END_OF_FILE' X/* $Id: nit4writev.c,v 2.0 89/10/20 19:02:48 dupuy Exp $ */ X X#include <sys/types.h> X#include <sys/socket.h> X#include <sys/stropts.h> X#include <sys/uio.h> X X#include "libether.h" X Xextern unsigned _ether_types[FD_SETSIZE]; X X#define ether_type (_ether_types[fd]) X X/* X * Writes a single packet, filling src and type fields. X */ X Xint Xether_writev (fd, packet) Xint fd; Xether_vec *packet; X{ X struct sockaddr sa; X struct strbuf cbuf; X struct strbuf dbuf; X char buffer[ETHER_MAX]; X char *bufp = buffer; X int count; X X sa.sa_family = AF_UNSPEC; X bcopy ((char *) packet, sa.sa_data, ETHER_TYPE); X X if (ether_type != ETHER_ALLTYPES) X { X sa.sa_data[12] = (ether_type >> 8) & 0xff; X sa.sa_data[13] = ether_type & 0xff; X } X X cbuf.maxlen = cbuf.len = sizeof (sa); X cbuf.buf = (char *) &sa; X X dbuf.len = 0; X dbuf.buf = bufp; X X for (count = 0; count < packet->iovcnt; count++) X if (packet->iov[count].iov_len) X { X bcopy ((char *) packet->iov[count].iov_base, bufp, X (int) packet->iov[count].iov_len); X bufp += packet->iov[count].iov_len; X dbuf.len += packet->iov[count].iov_len; X } X X return (putmsg (fd, &cbuf, &dbuf, 0)); X} END_OF_FILE if test 1172 -ne `wc -c <'./src/nit4writev.c'`; then echo shar: \"'./src/nit4writev.c'\" unpacked with wrong size! fi # end of './src/nit4writev.c' fi if test -f './src/nitaddr.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./src/nitaddr.c'\" else echo shar: Extracting \"'./src/nitaddr.c'\" \(1351 characters\) sed "s/^X//" >'./src/nitaddr.c' <<'END_OF_FILE' X/* $Id: nitaddr.c,v 2.1 89/10/23 15:43:02 dupuy Exp $ */ X X#include <sys/types.h> /* ifreq (u_short) */ X#include <sys/socket.h> /* ifreq (sockaddr) */ X#include <net/if.h> /* ifreq */ X#include <sys/ioctl.h> /* SIOCGIFADDR */ X X#include "libether.h" X Xether_addr _ether_localaddr; /* shared with ether_intfaddr() */ Xint _ether_haveaddress; /* shared with ether_intfaddr() */ X X/* X * Returns the local ethernet address for the ethernet interface on the file X * descriptor fd. The result is stored in the structure given by address; if X * none is given, malloc is used to allocate space. Sun systems have the X * "feature" that all ethernet interfaces are set to the same address (taken X * from the ID PROM). So we can get the answer once, and use it forever. X */ X Xether_addr * Xether_address (fd, address) Xint fd; Xether_addr *address; X{ X if (!_ether_haveaddress) X { X struct ifreq ifr; X X ifr.ifr_addr.sa_family = AF_NIT; X if (ioctl (fd, SIOCGIFADDR, (char *) &ifr) < 0) X { X#ifdef DEBUG X perror ("ether_address: ioctl SIOCGIFADDR"); X#endif X return (0); X } X X bcopy (ifr.ifr_addr.sa_data, (char *) &_ether_localaddr, X sizeof (ether_addr)); X X _ether_haveaddress = 1; X } X X if (address == 0) X address = (ether_addr *) malloc (sizeof (ether_addr)); X X if (address != 0) X *address = _ether_localaddr; X X return (address); X} END_OF_FILE if test 1351 -ne `wc -c <'./src/nitaddr.c'`; then echo shar: \"'./src/nitaddr.c'\" unpacked with wrong size! fi # end of './src/nitaddr.c' fi if test -f './system' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./system'\" else echo shar: Extracting \"'./system'\" \(1175 characters\) sed "s/^X//" >'./system' <<'END_OF_FILE' X#!/bin/sh X# X# Determine the current system platform X# Xif [ -s /bin/arch -a -s /bin/sun ]; then # Sun's arch X ARCH=`/bin/arch` X Xelif [ -s /bin/machine ]; then # MIPS' machine X ARCH=`/bin/machine` X Xelif [ -f /bin/vax ] && /bin/vax; then X ARCH=vax X Xelif [ "`echo /bin/hp*`" != '/bin/hp*' ]; then # HP's way X { /bin/hp9000s800 && ARCH=hp800; } || \ X { /bin/hp9000s500 && ARCH=hp500; } || \ X { /bin/hp9000s300 && ARCH=hp300; } || \ X { /bin/hp9000s200 && ARCH=hp200; } || \ X { /bin/hp300 && ARCH=hp300; } || \ X { /bin/hp800 && ARCH=hp800; } # Utah HP 4.3 X Xelif [ -d /usr/ibm -o -d /vrm ]; then # IBM AIX or ACIS X ARCH=ibmrt X Xelif [ -d /NextLibrary ]; then # Unique to NeXT cubes X ARCH=next X Xelif [ -d /usr/ucb ]; then # desperation time X ARCH=vax Xfi X Xcase $ARCH in X X hp*) X if [ -f /hp-ux ]; then X OS=hpux X fi;; X X ibmrt) X if [ -d /vrm ]; then X OS=aix X fi;; X X mips*) X if [ -f /ultrixboot ]; then X ARCH=mipsel X OS=ultrix X fi;; X X sun[234]) X if [ -f /usr/ucb/logger ]; then X OS=os4 X elif [ -d /usr/suntools ]; then X OS=os2 X fi;; X X next) OS=mach;; X X vax) X if [ -f /ultrixboot ]; then X OS=ultrix X fi;; X X *) ARCH=unknown;; X Xesac X Xexec echo $ARCH${OS+-$OS} END_OF_FILE if test 1175 -ne `wc -c <'./system'`; then echo shar: \"'./system'\" unpacked with wrong size! fi # end of './system' fi if test ! -d './tests' ; then echo shar: Creating directory \"'./tests'\" mkdir './tests' fi echo shar: End of archive 1 \(of 3\). cp /dev/null ark1isdone MISSING="" for I in 1 2 3 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 3 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.