Subject: diffs for arp, bootpd, netboot, pppd, rarpd
To: None <current-users@sun-lamp.cs.berkeley.edu>
From: Christos Zoulas <christos@deshaw.com>
List: current-users
Date: 05/29/1994 15:46:44
The following is a set of diffs that should help to get the whole
source tree to compile. Except for the netboot diff [double inclusion of
<sys/exec.h>], all the rest are related to the deletion of SIOCGARP,
SIOCSARP. I guess someone should delete 'struct arpreq' , since it is
not used anywhere.

Since it is not very simple anymore to set and delete arp addresses
(it takes a almost 100 lines of code!), I broke out the parts that
do this from arp.c into arplib.c and arplib.h. All the programs now
use those two files.

I only tested the changes in arp.c, and I will be testing the pppd
and rarpd changes as soon as I ftp a new binary distribution to my
home machine.

While I was at it, I cleaned up arp.c a bit and fixed the documented -f
flag which was missing from the getopt parsing.

Enjoy,

christos

PS: Theo I want a cookie!

#! /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 shell archive."
# Contents:  arp.diff bootpd.diff netboot.diff pppd.diff rarpd.diff
# Wrapped by christos@cs4 on Sun May 29 15:37:14 1994
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'arp.diff' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'arp.diff'\"
else
echo shar: Extracting \"'arp.diff'\" \(25133 characters\)
sed "s/^X//" >'arp.diff' <<'END_OF_FILE'
X*** Makefile.dist	Tue May 17 06:56:12 1994
X***************
X*** 4,9 ****
X--- 4,10 ----
X  PROG=	arp
X  MAN8=	arp.0
X  CLEANFILES=arp4.0
X+ SRCS=	arp.c arplib.c
X  
X  .if !defined(NOMAN)
X  all: ${PROG} arp4.0 ${MAN8}
X*** arp.c.dist	Fri May 13 07:54:34 1994
X***************
X*** 66,119 ****
X  #include <arpa/inet.h>
X  
X  #include <netdb.h>
X- #include <errno.h>
X- #include <nlist.h>
X  #include <stdio.h>
X  #include <paths.h>
X  
X- extern int errno;
X- static int pid;
X- static int kflag;
X  static int nflag;
X! static int s = -1;
X  
X  main(argc, argv)
X  	int argc;
X  	char **argv;
X  {
X  	int ch;
X  
X! 	pid = getpid();
X! 	while ((ch = getopt(argc, argv, "ands")) != EOF)
X! 		switch((char)ch) {
X  		case 'a':
X! 			dump(0);
X! 			exit(0);
X  		case 'd':
X  			if (argc < 3 || argc > 4)
X! 				usage();
X! 			delete(argv[2], argv[3]);
X! 			exit(0);
X  		case 'n':
X  			nflag = 1;
X  			continue;
X  		case 's':
X  			if (argc < 4 || argc > 7)
X! 				usage();
X! 			exit(set(argc-2, &argv[2]) ? 1 : 0);
X  		case '?':
X  		default:
X! 			usage();
X  		}
X  	if (argc != 2)
X! 		usage();
X! 	get(argv[1]);
X! 	exit(0);
X  }
X  
X  /*
X   * Process a file to set standard arp entries
X   */
X  file(name)
X  	char *name;
X  {
X--- 66,141 ----
X  #include <arpa/inet.h>
X  
X  #include <netdb.h>
X  #include <stdio.h>
X+ #include <string.h>
X  #include <paths.h>
X+ #include <errno.h>
X+ #include <stdlib.h>
X+ #include <unistd.h>
X+ #include <err.h>
X+ #include "arplib.h"
X+ 
X+ extern const char *__progname;
X  
X  static int nflag;
X! static void *ap = NULL;
X! 
X! static int dump __P((u_long));
X! static int usage __P((void));
X! static int delete __P((char *, char *));
X! static int set __P((int argc, char **));
X! static int get __P((char *));
X! static int file __P((char *));
X! static void ether_print __P((u_char *));
X! 
X  
X+ int
X  main(argc, argv)
X  	int argc;
X  	char **argv;
X  {
X  	int ch;
X  
X! 	while ((ch = getopt(argc, argv, "andsf:")) != EOF)
X! 		switch(ch) {
X  		case 'a':
X! 			return dump(0);
X! 
X  		case 'd':
X  			if (argc < 3 || argc > 4)
X! 				return usage();
X! 			return delete(argv[2], argv[3]);
X! 
X  		case 'n':
X  			nflag = 1;
X  			continue;
X+ 
X  		case 's':
X  			if (argc < 4 || argc > 7)
X! 				return usage();
X! 			return set(argc-2, &argv[2]) ? 1 : 0;
X! 
X! 		case 'f':
X! 			return file(optarg);
X! 
X  		case '?':
X  		default:
X! 			return usage();
X  		}
X+ 
X  	if (argc != 2)
X! 		return usage();
X! 
X! 	if (ap != NULL)
X! 		arp_close(ap);
X! 
X! 	return get(argv[1]);
X  }
X  
X  /*
X   * Process a file to set standard arp entries
X   */
X+ static int
X  file(name)
X  	char *name;
X  {
X***************
X*** 122,129 ****
X  	char line[100], arg[5][50], *args[5];
X  
X  	if ((fp = fopen(name, "r")) == NULL) {
X! 		fprintf(stderr, "arp: cannot open %s\n", name);
X! 		exit(1);
X  	}
X  	args[0] = &arg[0][0];
X  	args[1] = &arg[1][0];
X--- 144,151 ----
X  	char line[100], arg[5][50], *args[5];
X  
X  	if ((fp = fopen(name, "r")) == NULL) {
X! 		fprintf(stderr, "%s: cannot open %s\n", __progname, name);
X! 		return -1;
X  	}
X  	args[0] = &arg[0][0];
X  	args[1] = &arg[1][0];
X***************
X*** 135,358 ****
X  		i = sscanf(line, "%s %s %s %s %s", arg[0], arg[1], arg[2],
X  		    arg[3], arg[4]);
X  		if (i < 2) {
X! 			fprintf(stderr, "arp: bad line: %s\n", line);
X! 			retval = 1;
X  			continue;
X  		}
X  		if (set(i, args))
X! 			retval = 1;
X  	}
X  	fclose(fp);
X  	return (retval);
X  }
X  
X! getsocket() {
X! 	if (s < 0) {
X! 		s = socket(PF_ROUTE, SOCK_RAW, 0);
X! 		if (s < 0) {
X! 			perror("arp: socket");
X! 			exit(1);
X  		}
X  	}
X  }
X  
X- struct	sockaddr_in so_mask = {8, 0, 0, { 0xffffffff}};
X- struct	sockaddr_inarp blank_sin = {sizeof(blank_sin), AF_INET }, sin_m;
X- struct	sockaddr_dl blank_sdl = {sizeof(blank_sdl), AF_LINK }, sdl_m;
X- int	expire_time, flags, export_only, doing_proxy, found_entry;
X- struct	{
X- 	struct	rt_msghdr m_rtm;
X- 	char	m_space[512];
X- }	m_rtmsg;
X  
X  /*
X   * Set an individual arp entry 
X   */
X  set(argc, argv)
X  	int argc;
X  	char **argv;
X  {
X! 	struct hostent *hp;
X! 	register struct sockaddr_inarp *sin = &sin_m;
X! 	register struct sockaddr_dl *sdl;
X! 	register struct rt_msghdr *rtm = &(m_rtmsg.m_rtm);
X! 	u_char *ea;
X  	char *host = argv[0], *eaddr = argv[1];
X  
X- 	getsocket();
X  	argc -= 2;
X  	argv += 2;
X! 	sdl_m = blank_sdl;
X! 	sin_m = blank_sin;
X! 	sin->sin_addr.s_addr = inet_addr(host);
X! 	if (sin->sin_addr.s_addr == -1) {
X! 		if (!(hp = gethostbyname(host))) {
X! 			fprintf(stderr, "arp: %s: ", host);
X! 			herror((char *)NULL);
X! 			return (1);
X! 		}
X! 		bcopy((char *)hp->h_addr, (char *)&sin->sin_addr,
X! 		    sizeof sin->sin_addr);
X  	}
X! 	ea = (u_char *)LLADDR(&sdl_m);
X! 	if (ether_aton(eaddr, ea) == 0)
X! 		sdl_m.sdl_alen = 6;
X! 	doing_proxy = flags = export_only = expire_time = 0;
X  	while (argc-- > 0) {
X  		if (strncmp(argv[0], "temp", 4) == 0) {
X! 			struct timeval time;
X! 			gettimeofday(&time, 0);
X! 			expire_time = time.tv_sec + 20 * 60;
X  		}
X  		else if (strncmp(argv[0], "pub", 3) == 0) {
X! 			flags |= RTF_ANNOUNCE;
X! 			doing_proxy = SIN_PROXY;
X  		} else if (strncmp(argv[0], "trail", 5) == 0) {
X  			printf("%s: Sending trailers is no longer supported\n",
X  				host);
X  		}
X  		argv++;
X  	}
X! tryagain:
X! 	if (rtmsg(RTM_GET) < 0) {
X! 		perror(host);
X! 		return (1);
X! 	}
X! 	sin = (struct sockaddr_inarp *)(rtm + 1);
X! 	sdl = (struct sockaddr_dl *)(sin->sin_len + (char *)sin);
X! 	if (sin->sin_addr.s_addr == sin_m.sin_addr.s_addr) {
X! 		if (sdl->sdl_family == AF_LINK &&
X! 		    (rtm->rtm_flags & RTF_LLINFO) &&
X! 		    !(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) {
X! 		case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023:
X! 		case IFT_ISO88024: case IFT_ISO88025:
X! 			goto overwrite;
X! 		}
X! 		if (doing_proxy == 0) {
X! 			printf("set: can only proxy for %s\n", host);
X! 			return (1);
X! 		}
X! 		if (sin_m.sin_other & SIN_PROXY) {
X! 			printf("set: proxy entry exists for non 802 device\n");
X! 			return(1);
X  		}
X! 		sin_m.sin_other = SIN_PROXY;
X! 		export_only = 1;
X! 		goto tryagain;
X! 	}
X! overwrite:
X! 	if (sdl->sdl_family != AF_LINK) {
X! 		printf("cannot intuit interface index and type for %s\n", host);
X! 		return (1);
X! 	}
X! 	sdl_m.sdl_type = sdl->sdl_type;
X! 	sdl_m.sdl_index = sdl->sdl_index;
X! 	return (rtmsg(RTM_ADD));
X  }
X  
X  /*
X   * Display an individual arp entry
X   */
X  get(host)
X  	char *host;
X  {
X! 	struct hostent *hp;
X! 	struct sockaddr_inarp *sin = &sin_m;
X! 	u_char *ea;
X  
X! 	sin_m = blank_sin;
X! 	sin->sin_addr.s_addr = inet_addr(host);
X! 	if (sin->sin_addr.s_addr == -1) {
X! 		if (!(hp = gethostbyname(host))) {
X! 			fprintf(stderr, "arp: %s: ", host);
X! 			herror((char *)NULL);
X! 			exit(1);
X! 		}
X! 		bcopy((char *)hp->h_addr, (char *)&sin->sin_addr,
X! 		    sizeof sin->sin_addr);
X! 	}
X! 	dump(sin->sin_addr.s_addr);
X! 	if (found_entry == 0) {
X! 		printf("%s (%s) -- no entry\n",
X! 		    host, inet_ntoa(sin->sin_addr));
X! 		exit(1);
X  	}
X  }
X  
X  /*
X   * Delete an arp entry 
X   */
X  delete(host, info)
X  	char *host;
X  	char *info;
X  {
X! 	struct hostent *hp;
X! 	register struct sockaddr_inarp *sin = &sin_m;
X! 	register struct rt_msghdr *rtm = &m_rtmsg.m_rtm;
X! 	struct sockaddr_dl *sdl;
X! 	u_char *ea;
X! 	char *eaddr;
X  
X  	if (info && strncmp(info, "pro", 3) )
X! 		export_only = 1;
X! 	getsocket();
X! 	sin_m = blank_sin;
X! 	sin->sin_addr.s_addr = inet_addr(host);
X! 	if (sin->sin_addr.s_addr == -1) {
X! 		if (!(hp = gethostbyname(host))) {
X! 			fprintf(stderr, "arp: %s: ", host);
X! 			herror((char *)NULL);
X! 			return (1);
X! 		}
X! 		bcopy((char *)hp->h_addr, (char *)&sin->sin_addr,
X! 		    sizeof sin->sin_addr);
X! 	}
X! tryagain:
X! 	if (rtmsg(RTM_GET) < 0) {
X! 		perror(host);
X! 		return (1);
X! 	}
X! 	sin = (struct sockaddr_inarp *)(rtm + 1);
X! 	sdl = (struct sockaddr_dl *)(sin->sin_len + (char *)sin);
X! 	if (sin->sin_addr.s_addr == sin_m.sin_addr.s_addr) {
X! 		if (sdl->sdl_family == AF_LINK &&
X! 		    (rtm->rtm_flags & RTF_LLINFO) &&
X! 		    !(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) {
X! 		case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023:
X! 		case IFT_ISO88024: case IFT_ISO88025:
X! 			goto delete;
X  		}
X  	}
X! 	if (sin_m.sin_other & SIN_PROXY) {
X! 		fprintf(stderr, "delete: can't locate %s\n",host);
X! 		return (1);
X! 	} else {
X! 		sin_m.sin_other = SIN_PROXY;
X! 		goto tryagain;
X! 	}
X! delete:
X! 	if (sdl->sdl_family != AF_LINK) {
X! 		printf("cannot locate %s\n", host);
X! 		return (1);
X  	}
X! 	if (rtmsg(RTM_DELETE) == 0)
X! 		printf("%s (%s) deleted\n", host, inet_ntoa(sin->sin_addr));
X  }
X  
X  /*
X   * Dump the entire arp table
X   */
X  dump(addr)
X  u_long addr;
X  {
X  	int mib[6];
X  	size_t needed;
X! 	char *host, *malloc(), *lim, *buf, *next;
X  	struct rt_msghdr *rtm;
X  	struct sockaddr_inarp *sin;
X  	struct sockaddr_dl *sdl;
X  	extern int h_errno;
X  	struct hostent *hp;
X  
X  	mib[0] = CTL_NET;
X  	mib[1] = PF_ROUTE;
X--- 157,321 ----
X  		i = sscanf(line, "%s %s %s %s %s", arg[0], arg[1], arg[2],
X  		    arg[3], arg[4]);
X  		if (i < 2) {
X! 			fprintf(stderr, "%s: bad line: %s\n", __progname, line);
X! 			retval = -1;
X  			continue;
X  		}
X  		if (set(i, args))
X! 			retval = -1;
X  	}
X  	fclose(fp);
X  	return (retval);
X  }
X  
X! 
X! /*
X!  * get a host name or address
X!  */
X! static int
X! gethost(host, ia)
X! 	const char* host;
X! 	struct in_addr *ia;
X! {
X! 
X! 	struct hostent *hp;
X! 
X! 	ia->s_addr = inet_addr(host);
X! 
X! 	if (ia->s_addr == -1) {
X! 		if (!(hp = gethostbyname(host))) {
X! 			fprintf(stderr, "%s: %s: ", __progname, host);
X! 			herror((char *)NULL);
X! 			return -1;
X  		}
X+ 		memcpy(ia, hp->h_addr, sizeof *ia);
X  	}
X+ 	return 0;
X  }
X  
X  
X  /*
X   * Set an individual arp entry 
X   */
X+ static int
X  set(argc, argv)
X  	int argc;
X  	char **argv;
X  {
X! 	struct in_addr ia;
X! 	int flags = ARP_NONE;
X  	char *host = argv[0], *eaddr = argv[1];
X+ 	u_char ea[6];
X  
X  	argc -= 2;
X  	argv += 2;
X! 
X! 	if (gethost(host, &ia) == -1)
X! 		return -1;
X! 
X! 	if (arp_atoe(eaddr, ea) == -1) {
X! 		(void) fprintf(stderr, "%s: Bad ethernet address `%s'\n",
X! 			       __progname, eaddr);
X! 		return -1;
X  	}
X! 
X  	while (argc-- > 0) {
X  		if (strncmp(argv[0], "temp", 4) == 0) {
X! 			flags |= ARP_TEMP;
X  		}
X  		else if (strncmp(argv[0], "pub", 3) == 0) {
X! 			flags |= ARP_PROXY;
X  		} else if (strncmp(argv[0], "trail", 5) == 0) {
X  			printf("%s: Sending trailers is no longer supported\n",
X  				host);
X  		}
X  		argv++;
X  	}
X! 
X! 	if (ap == NULL) {
X! 		if ((ap = arp_open()) == NULL) {
X! 			fprintf(stderr, "%s: %s\n", __progname, arp_error(ap));
X! 			return -1;
X  		}
X! 	}
X! 
X! 	if (arp_set(ap, &ia, ea, flags) == -1) {
X! 		fprintf(stderr, "%s: set(%s, %s): %s\n", __progname,
X! 			host, eaddr, arp_error(ap));
X! 		return -1;
X! 	}
X! 	return 0;
X  }
X  
X  /*
X   * Display an individual arp entry
X   */
X+ static int
X  get(host)
X  	char *host;
X  {
X! 	struct in_addr ia;
X  
X! 	if (gethost(host, &ia) == -1)
X! 		return -1;
X! 
X! 	if (dump(ia.s_addr) == -1) {
X! 		printf("%s (%s) -- no entry\n", host, inet_ntoa(ia));
X! 		return -1;
X  	}
X+ 	return 0;
X  }
X  
X  /*
X   * Delete an arp entry 
X   */
X+ static int
X  delete(host, info)
X  	char *host;
X  	char *info;
X  {
X! 	struct in_addr ia;
X! 	int flags = ARP_NONE;
X  
X  	if (info && strncmp(info, "pro", 3) )
X! 		flags |= ARP_PROXY;
X! 
X! 	if (gethost(host, &ia) == -1)
X! 		return -1;
X! 
X! 	if (ap == NULL) {
X! 		if ((ap = arp_open()) == NULL) {
X! 			fprintf(stderr, "%s: %s\n", __progname, arp_error(ap));
X! 			return -1;
X  		}
X  	}
X! 
X! 	if (arp_delete(ap, &ia, flags) == -1) {
X! 		fprintf(stderr, "%s: delete(%s): %s\n", __progname,
X! 			host, arp_error(ap));
X! 		return -1;
X  	}
X! 
X! 	printf("%s (%s) deleted\n", host, inet_ntoa(ia));
X! 	return 0;
X  }
X  
X  /*
X   * Dump the entire arp table
X   */
X+ static int
X  dump(addr)
X  u_long addr;
X  {
X  	int mib[6];
X  	size_t needed;
X! 	char *host, *lim, *buf, *next;
X  	struct rt_msghdr *rtm;
X  	struct sockaddr_inarp *sin;
X  	struct sockaddr_dl *sdl;
X  	extern int h_errno;
X  	struct hostent *hp;
X+ 	int found = addr == 0 ? 0 : -1;
X  
X  	mib[0] = CTL_NET;
X  	mib[1] = PF_ROUTE;
X***************
X*** 361,371 ****
X  	mib[4] = NET_RT_FLAGS;
X  	mib[5] = RTF_LLINFO;
X  	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
X! 		quit("route-sysctl-estimate");
X  	if ((buf = malloc(needed)) == NULL)
X! 		quit("malloc");
X  	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
X! 		quit("actual retrieval of routing table");
X  	lim = buf + needed;
X  	for (next = buf; next < lim; next += rtm->rtm_msglen) {
X  		rtm = (struct rt_msghdr *)next;
X--- 324,334 ----
X  	mib[4] = NET_RT_FLAGS;
X  	mib[5] = RTF_LLINFO;
X  	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
X! 		err(1, "route-sysctl-estimate");
X  	if ((buf = malloc(needed)) == NULL)
X! 		err(1, "malloc");
X  	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
X! 		err(1, "actual retrieval of routing table");
X  	lim = buf + needed;
X  	for (next = buf; next < lim; next += rtm->rtm_msglen) {
X  		rtm = (struct rt_msghdr *)next;
X***************
X*** 374,380 ****
X  		if (addr) {
X  			if (addr != sin->sin_addr.s_addr)
X  				continue;
X! 			found_entry = 1;
X  		}
X  		if (nflag == 0)
X  			hp = gethostbyaddr((caddr_t)&(sin->sin_addr),
X--- 337,343 ----
X  		if (addr) {
X  			if (addr != sin->sin_addr.s_addr)
X  				continue;
X! 			found = 1;
X  		}
X  		if (nflag == 0)
X  			hp = gethostbyaddr((caddr_t)&(sin->sin_addr),
X***************
X*** 407,515 ****
X  		}
X  		printf("\n");
X  	}
X  }
X  
X  ether_print(cp)
X  	u_char *cp;
X  {
X! 	printf("%x:%x:%x:%x:%x:%x", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
X  }
X  
X- ether_aton(a, n)
X- 	char *a;
X- 	u_char *n;
X- {
X- 	int i, o[6];
X- 
X- 					   &o[3], &o[4], &o[5]);
X- 	if (i != 6) {
X- 		return (1);
X- 	}
X- 	for (i=0; i<6; i++)
X- 		n[i] = o[i];
X- 	return (0);
X- }
X  
X  usage()
X  {
X! 	printf("usage: arp hostname\n");
X! 	printf("       arp -a [kernel] [kernel_memory]\n");
X! 	printf("       arp -d hostname\n");
X! 	printf("       arp -s hostname ether_addr [temp] [pub]\n");
X! 	printf("       arp -f filename\n");
X! 	exit(1);
X! }
X! 
X! rtmsg(cmd)
X! {
X! 	static int seq;
X! 	int rlen;
X! 	register struct rt_msghdr *rtm = &m_rtmsg.m_rtm;
X! 	register char *cp = m_rtmsg.m_space;
X! 	register int l;
X! 
X! 	errno = 0;
X! 	if (cmd == RTM_DELETE)
X! 		goto doit;
X! 	bzero((char *)&m_rtmsg, sizeof(m_rtmsg));
X! 	rtm->rtm_flags = flags;
X! 	rtm->rtm_version = RTM_VERSION;
X! 
X! 	switch (cmd) {
X! 	default:
X! 		fprintf(stderr, "arp: internal wrong cmd\n");
X! 		exit(1);
X! 	case RTM_ADD:
X! 		rtm->rtm_addrs |= RTA_GATEWAY;
X! 		rtm->rtm_rmx.rmx_expire = expire_time;
X! 		rtm->rtm_inits = RTV_EXPIRE;
X! 		rtm->rtm_flags |= (RTF_HOST | RTF_STATIC);
X! 		sin_m.sin_other = 0;
X! 		if (doing_proxy) {
X! 			if (export_only)
X! 				sin_m.sin_other = SIN_PROXY;
X! 			else {
X! 				rtm->rtm_addrs |= RTA_NETMASK;
X! 				rtm->rtm_flags &= ~RTF_HOST;
X! 			}
X! 		}
X! 		/* FALLTHROUGH */
X! 	case RTM_GET:
X! 		rtm->rtm_addrs |= RTA_DST;
X! 	}
X! #define NEXTADDR(w, s) \
X! 	if (rtm->rtm_addrs & (w)) { \
X! 		bcopy((char *)&s, cp, sizeof(s)); cp += sizeof(s);}
X! 
X! 	NEXTADDR(RTA_DST, sin_m);
X! 	NEXTADDR(RTA_GATEWAY, sdl_m);
X! 	NEXTADDR(RTA_NETMASK, so_mask);
X! 
X! 	rtm->rtm_msglen = cp - (char *)&m_rtmsg;
X! doit:
X! 	l = rtm->rtm_msglen;
X! 	rtm->rtm_seq = ++seq;
X! 	rtm->rtm_type = cmd;
X! 	if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) {
X! 		if (errno != ESRCH || cmd != RTM_DELETE) {
X! 			perror("writing to routing socket");
X! 			return (-1);
X! 		}
X! 	}
X! 	do {
X! 		l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
X! 	} while (l > 0 && (rtm->rtm_seq != seq || rtm->rtm_pid != pid));
X! 	if (l < 0)
X! 		(void) fprintf(stderr, "arp: read from routing socket: %s\n",
X! 		    strerror(errno));
X! 	return (0);
X! }
X! 
X! quit(msg)
X! char *msg;
X! {
X! 	fprintf(stderr, "%s\n", msg);
X! 	exit(1);
X  }
X--- 370,396 ----
X  		}
X  		printf("\n");
X  	}
X+ 	return found;
X  }
X  
X+ 
X+ static void
X  ether_print(cp)
X  	u_char *cp;
X  {
X! 	char buf[1024];
X! 	arp_etoa(cp, buf);
X! 	fputs(buf, stdout);
X  }
X  
X  
X+ static int
X  usage()
X  {
X! 	printf("usage: %s [-n] hostname\n", __progname);
X! 	printf("       %s [-n] -a [kernel] [kernel_memory]\n", __progname);
X! 	printf("       %s [-n] -d hostname\n", __progname);
X! 	printf("       %s [-n] -s hostname ether_addr [temp] [pub]\n", __progname);
X! 	printf("       %s [-n] -f filename\n", __progname);
X! 	return 1;
X  }
X*** arplib.c.dist	Sun May 29 15:27:28 1994
X***************
X*** 0 ****
X--- 1,387 ----
X+ /* $Header$ */
X+ /*
X+  * arplib.c: Library to manage an list of arp entries.
X+  */
X+ 
X+ #include "arplib.h"
X+ 
X+ #include <sys/param.h>
X+ #include <sys/file.h>
X+ #include <sys/socket.h>
X+  
X+ #include <net/if.h>
X+ #include <net/if_dl.h>
X+ #include <net/if_types.h> 
X+ #include <net/route.h> 
X+ 
X+ #include <netinet/if_ether.h>
X+ 
X+ #include <arpa/inet.h>
X+ 
X+ #include <netdb.h>
X+ #include <errno.h>
X+ #include <stdio.h>
X+ #include <stdlib.h>
X+ #include <string.h>
X+ #include <unistd.h>
X+ 
X+ struct arp_msg {
X+     struct rt_msghdr	m_rtm;
X+     char		m_space[512];
X+ };
X+ 
X+ struct arp_state {
X+ 	int				as_seq;
X+ 	int 				as_fd;
X+ 	pid_t				as_pid;
X+ 	struct sockaddr_inarp		as_sia;
X+ 	struct sockaddr_dl		as_sid;
X+ 	struct sockaddr_in		as_mask;
X+ 	struct arp_msg			as_msg;
X+ 	char*				as_err;
X+ 	int				as_errno;
X+ };
X+ 
X+ static const char ether_fmt[] = "%x:%x:%x:%x:%x:%x";
X+ 
X+ void *
X+ arp_open()
X+ {
X+ 	struct arp_state *as;
X+ 
X+ 	if ((as = malloc(sizeof(struct arp_state))) == NULL)
X+ 		return NULL;
X+ 
X+ 	if ((as->as_fd = socket(PF_ROUTE, SOCK_RAW, 0)) == -1) {
X+ 		free(as);
X+ 		return NULL;
X+ 	}
X+ 
X+ 	as->as_mask.sin_len = 8;
X+ 	as->as_mask.sin_family = AF_UNSPEC;
X+ 	as->as_mask.sin_port = 0;
X+ 	as->as_mask.sin_addr.s_addr = 0xffffffff;
X+ 	as->as_err = NULL;
X+ 	as->as_errno = 0;
X+ 	memset(as->as_mask.sin_zero, 0, sizeof(as->as_mask.sin_zero));
X+ 
X+ 	as->as_pid = getpid();
X+ 	as->as_seq = 0;
X+ 	return (void *) as;
X+ }
X+ 
X+ 
X+ void
X+ arp_close(vas)
X+ 	void *vas;
X+ {
X+ 	(void) close(((struct arp_state *) vas)->as_fd);
X+ 	free(vas);
X+ }
X+ 
X+ 
X+ /* arp_atoe():
X+  *	Ascii to ether format
X+  */
X+ int
X+ arp_atoe(ea, p)
X+ 	char *ea;
X+ 	u_char *p;
X+ {
X+ 	int i, x[6];
X+ 
X+ 	i = sscanf(ea, ether_fmt, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5]);
X+ 
X+ 	if (i != 6)
X+ 		return -1;
X+ 
X+ 	for (i = 0; i < 6; i++)
X+ 		p[i] = x[i];
X+ 	return 0;
X+ }
X+ 		
X+ /* arp_etoa():
X+  *	Ether address to ascii
X+  */
X+ void
X+ arp_etoa(p, ea)
X+ 	u_char *p;
X+ 	char *ea;
X+ {
X+ 	(void) sprintf(ea, ether_fmt, p[0], p[1], p[2], p[3], p[4], p[5]);
X+ }
X+ 
X+ 
X+ static int
X+ arp_msg(vas, cmd, flags)
X+ 	void *vas;
X+ 	int cmd;
X+ 	int flags;
X+ {
X+ 	struct arp_state *as = (struct arp_state *) vas;
X+ 	struct rt_msghdr *rtm = &as->as_msg.m_rtm;
X+ 	char *cp = as->as_msg.m_space;
X+ 	int l;
X+ 
X+ 	memset(rtm, 0, sizeof(*rtm));
X+ 
X+ 	switch (cmd) {
X+ 	case RTM_ADD:
X+ 	    rtm->rtm_addrs = RTA_DST|RTA_GATEWAY;
X+ 	    rtm->rtm_inits = RTV_EXPIRE;
X+ 	    rtm->rtm_flags = RTF_STATIC;
X+ 
X+ 	    if (flags & ARP_TEMP) {
X+ 		    struct timeval tv;
X+ 		    gettimeofday(&tv, NULL);
X+ 		    rtm->rtm_rmx.rmx_expire = tv.tv_sec + 20 * 60;
X+ 	    }
X+ 	    else
X+ 		    rtm->rtm_rmx.rmx_expire = 0;
X+ 
X+ 	    if (flags & ARP_PROXY) {
X+ 		    rtm->rtm_flags |= RTF_ANNOUNCE;
X+ 		    if (flags & ARP_EXPORT) {
X+ 			    as->as_sia.sin_other = SIN_PROXY;
X+ 			    rtm->rtm_flags |= RTF_HOST;
X+ 		    }
X+ 		    else {
X+ 			rtm->rtm_addrs |= RTA_NETMASK;
X+ 			as->as_sia.sin_other = 0;
X+ 		    }
X+ 	    }
X+ 	    else {
X+ 		as->as_sia.sin_other = 0;
X+ 		rtm->rtm_flags |= RTF_HOST;
X+ 	    }
X+ 	    break;
X+ 
X+ 	case RTM_DELETE:
X+ 	case RTM_GET:
X+ 	    if (flags & ARP_PROXY)
X+ 		    as->as_sia.sin_other = SIN_PROXY;
X+ 	    else
X+ 		    as->as_sia.sin_other = 0;
X+ 	    rtm->rtm_addrs = RTA_DST;
X+ 	    break;
X+ 
X+ 	default:
X+ 	    as->as_errno = EINVAL;
X+ 	    as->as_err = "Bad arp command";
X+ 	    return -1;
X+ 	}
X+ 
X+ #define NEXTADDR(w, s) \
X+         if (rtm->rtm_addrs & (w)) { \
X+                 memcpy(cp, &s, sizeof(s)); \
X+ 		cp += sizeof(s); \
X+ 	}
X+ 
X+ 	NEXTADDR(RTA_DST, as->as_sia);
X+ 	NEXTADDR(RTA_GATEWAY, as->as_sid);
X+ 	NEXTADDR(RTA_NETMASK, as->as_mask);
X+ 	rtm->rtm_version = RTM_VERSION;
X+ 	rtm->rtm_seq = ++(as->as_seq);
X+ 	rtm->rtm_type = cmd;
X+ 	l = rtm->rtm_msglen = cp - (char *)rtm;
X+ 
X+ 	if (write(as->as_fd, (char *) &as->as_msg, l) == -1)
X+ 		if (errno != ESRCH || cmd != RTM_DELETE) {
X+ 			as->as_errno = errno;
X+ 			return -1;
X+ 		}
X+ 
X+ 	do
X+ 		l = read(as->as_fd, (char*) &as->as_msg, sizeof(as->as_msg));
X+ 	while (l > 0 && (rtm->rtm_seq != as->as_seq ||
X+ 			 rtm->rtm_pid != as->as_pid));
X+ 
X+ 	if (l == -1) {
X+ 		as->as_errno = errno;
X+ 		return -1;
X+ 	}
X+ 	else
X+ 		return 0;
X+ }
X+ 
X+ 
X+ static int
X+ arp_process(vas, cmd, flags)
X+ 	void *vas;
X+ 	int cmd;
X+ 	int flags;
X+ {
X+ 	struct arp_state *as = (struct arp_state *) vas;
X+ 	struct rt_msghdr *rtm = &as->as_msg.m_rtm;
X+ 	struct sockaddr_inarp *sia = &as->as_sia;
X+ 	struct sockaddr_dl *sid = &as->as_sid;
X+ 	struct sockaddr_inarp *sin = (struct sockaddr_inarp *) (rtm + 1);
X+ 	struct sockaddr_dl *sdl;
X+ 
X+ 	for (;;) {
X+ 		if (arp_msg(vas, RTM_GET, flags) < 0)
X+ 			return -1;
X+ 
X+ 		sdl = (struct sockaddr_dl *) (((char *) sin) + sin->sin_len);
X+ 
X+ 		if (sin->sin_addr.s_addr == sia->sin_addr.s_addr) {
X+ 			if (sdl->sdl_family == AF_LINK &&
X+ 			    (rtm->rtm_flags & RTF_LLINFO) != 0 &&
X+ 			    (rtm->rtm_flags & RTF_GATEWAY) == 0)
X+ 				switch (sdl->sdl_type) {
X+ 				case IFT_ETHER:
X+ 				case IFT_FDDI:
X+ 				case IFT_ISO88023:
X+ 				case IFT_ISO88024:
X+ 				case IFT_ISO88025:
X+ 					sid->sdl_type = sdl->sdl_type;
X+ 					sid->sdl_index = sdl->sdl_index;
X+ 					return arp_msg(vas, cmd, flags);
X+ 				default:
X+ 					break;
X+ 				}
X+ 			if (cmd == RTM_ADD) {
X+ 				if ((flags & ARP_PROXY) == 0) {
X+ 					as->as_errno = EINVAL;
X+ 					as->as_err = "Cannot proxy";
X+ 					return -1;
X+ 				}
X+ 
X+ 				if (sia->sin_other & SIN_PROXY) {
X+ 					as->as_errno = EINVAL;
X+ 					as->as_err = "Proxy exists for non 802 device";
X+ 					return -1;
X+ 				}
X+ 				flags |= ARP_EXPORT;
X+ 				continue;
X+ 			}
X+ 
X+ 		}
X+ 		if (cmd == RTM_DELETE) {
X+ 		    if (sia->sin_other & SIN_PROXY) {
X+ 			    as->as_errno = EINVAL;
X+ 			    as->as_err = "Cannot locate host";
X+ 			    return -1;
X+ 		    }
X+ 		    else 
X+ 			flags |= ARP_PROXY;
X+ 		    continue;
X+ 		}
X+ 
X+ 		break;
X+ 	}
X+ 
X+ 	if (sdl->sdl_family != AF_LINK) {
X+ 		as->as_errno = EINVAL;
X+ 		as->as_err = "Cannot intuit interface index and type";
X+ 		return -1;
X+ 	}
X+ 
X+ 	sid->sdl_type = sdl->sdl_type;
X+ 	sid->sdl_index = sdl->sdl_index;
X+ 	return arp_msg(vas, cmd, flags);
X+ }
X+ 
X+ int
X+ arp_set(vas, ia, ea, flags)
X+ 	void *vas;
X+ 	struct in_addr *ia;
X+ 	u_char *ea;
X+ 	int flags;
X+ {
X+ 	struct arp_state *as = (struct arp_state *) vas;
X+ 	struct sockaddr_inarp *sia = &as->as_sia;
X+ 	struct sockaddr_dl *sid = &as->as_sid;
X+ 
X+ 	as->as_err = NULL;
X+ 	as->as_errno = 0;
X+ 
X+ 	memset(sid, 0, sizeof(*sid));
X+ 	memset(sia, 0, sizeof(*sia));
X+ 
X+ 	sia->sin_len = sizeof(*sia);
X+ 	sia->sin_family = AF_INET;
X+ 	sia->sin_addr = *ia;
X+ 
X+ 	sid->sdl_len = sizeof(*sid);
X+ 	sid->sdl_family = AF_LINK;
X+ 	sid->sdl_alen = 6;
X+ 
X+ 	memcpy(LLADDR(sid), ea, 6);
X+ 
X+ 	return arp_process(vas, RTM_ADD, flags);
X+ }
X+ 
X+ int
X+ arp_delete(vas, ia, flags)
X+ 	void *vas;
X+ 	struct in_addr *ia;
X+ 	int flags;
X+ {
X+ 	struct arp_state *as = (struct arp_state *) vas;
X+ 	struct sockaddr_inarp *sia = &as->as_sia;
X+ 
X+ 	as->as_err = NULL;
X+ 	memset(sia, 0, sizeof(*sia));
X+ 
X+ 	sia->sin_len = sizeof(*sia);
X+ 	sia->sin_family = AF_INET;
X+ 	sia->sin_addr = *ia;
X+ 
X+ 	return arp_process(vas, RTM_DELETE, flags);
X+ }
X+ 
X+ 
X+ /* arp_error():
X+  *	Print the error from the last call
X+  */
X+ const char *
X+ arp_error(vas)
X+ 	void *vas;
X+ {
X+ 	struct arp_state *as = (struct arp_state *) vas;
X+ 
X+ 	if (as == NULL)
X+ 		return strerror(errno);
X+ 	if (as->as_err == NULL)
X+ 		return strerror(as->as_errno);
X+ 
X+ 	return as->as_err;
X+ }
X+ 
X+ #ifdef TEST
X+ int
X+ main(argc, argv)
X+ 	int argc;
X+ 	char *argv[];
X+ {
X+ 	void *a;
X+ 	struct in_addr ia;
X+ 
X+ 	if ((a = arp_open()) == NULL) {
X+ 		(void) fprintf(stderr, "arp_open: %s\n", arp_error(a));
X+ 		return 1;
X+ 	}
X+ 	ia.s_addr = inet_addr("149.77.12.253");
X+ 
X+ 	if (arp_set(a, &ia, "01:01:02:03:04:05", 0) == -1) {
X+ 		(void) fprintf(stderr, "arp_set: %s\n", arp_error(a));
X+ 		return 1;
X+ 	}
X+ 
X+ 	system("arp -a");
X+ 
X+ 	if (arp_delete(a, &ia) == -1) {
X+ 		(void) fprintf(stderr, "arp_delete: %s\n", arp_error(a));
X+ 		return 1;
X+ 	}
X+ 
X+ 	system("arp -a");
X+ 
X+ 	arp_close(a);
X+ 
X+ 	return 0;
X+ }
X+ #endif
X+ 
X+ 
X*** arplib.h.dist	Sun May 29 15:27:28 1994
X***************
X*** 0 ****
X--- 1,22 ----
X+ /*
X+  * arplib.h: Simple library interface to add and delete arp addresses
X+  */
X+ #define ARP_NONE	0
X+ #define ARP_TEMP	1
X+ #define ARP_PROXY	2
X+ #define ARP_EXPORT	4
X+ 
X+ #include <sys/types.h>
X+ #include <netinet/in.h>
X+ 
X+ __BEGIN_DECLS
X+ 
X+ void       *arp_open   __P((void));
X+ int         arp_set    __P((void *, struct in_addr *, u_char *, int));
X+ int         arp_delete __P((void *, struct in_addr *, int));
X+ void   	    arp_close  __P((void *));
X+ const char *arp_error  __P((void *));
X+ void	    arp_etoa   __P((u_char *, char *));
X+ int	    arp_atoe   __P((char *, u_char *));
X+ 
X+ __END_DECLS
END_OF_FILE
if test 25133 -ne `wc -c <'arp.diff'`; then
    echo shar: \"'arp.diff'\" unpacked with wrong size!
fi
# end of 'arp.diff'
fi
if test -f 'bootpd.diff' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bootpd.diff'\"
else
echo shar: Extracting \"'bootpd.diff'\" \(2830 characters\)
sed "s/^X//" >'bootpd.diff' <<'END_OF_FILE'
X*** Makefile.dist	Wed May 25 07:40:39 1994
X***************
X*** 7,17 ****
X  # Remove the -DVEND_CMU if you don't wish to support the "CMU vendor format"
X  # in addition to the RFC1048 format.
X  
X  PROG=	bootpd
X  # Note: PRIVATE=static is defined by default in bootpd.h
X! CFLAGS+=-DETC_ETHERS -DSYSLOG -DDEBUG -DVEND_CMU ${FILESPECS}
X  SRCS=	bootpd.c dovend.c readfile.c hash.c dumptab.c \
X! 	 lookup.c getif.c hwaddr.c report.c tzone.c
X  MAN5=	bootptab.0
X  MAN8=	bootpd.0
X  
X--- 7,18 ----
X  # Remove the -DVEND_CMU if you don't wish to support the "CMU vendor format"
X  # in addition to the RFC1048 format.
X  
X+ ALIB=${.CURDIR}/../../usr.sbin/arp
X  PROG=	bootpd
X  # Note: PRIVATE=static is defined by default in bootpd.h
X! CFLAGS+=-DETC_ETHERS -DSYSLOG -DDEBUG -DVEND_CMU ${FILESPECS} -I${ALIB}
X  SRCS=	bootpd.c dovend.c readfile.c hash.c dumptab.c \
X! 	 lookup.c getif.c hwaddr.c report.c tzone.c arplib.c
X  MAN5=	bootptab.0
X  MAN8=	bootpd.0
X  
X***************
X*** 19,24 ****
X--- 20,27 ----
X  
X  BINDIR=/usr/sbin
X  
X+ .PATH.c: ${ALIB}
X+ 
X  .include <bsd.prog.mk>
X  
X  # Additional targets (bootpd is done automatically)
X***************
X*** 26,35 ****
X  CLEANFILES+= bootpef bootpgw bootptest
X  
X  bootpef: bootpef.o dovend.o readfile.o hash.o dumptab.o \
X! 	 lookup.o hwaddr.o report.o tzone.o
X  	${CC} -o ${.TARGET} ${CFLAGS} ${LDFLAGS} ${.ALLSRC} ${LIBS}
X  
X! bootpgw: bootpgw.o getif.o hwaddr.o report.o
X  	${CC} -o ${.TARGET} ${CFLAGS} ${LDFLAGS} ${.ALLSRC} ${LIBS}
X  
X  print-bootp.o : print-bootp.c
X--- 29,38 ----
X  CLEANFILES+= bootpef bootpgw bootptest
X  
X  bootpef: bootpef.o dovend.o readfile.o hash.o dumptab.o \
X! 	 lookup.o hwaddr.o report.o tzone.o arplib.o
X  	${CC} -o ${.TARGET} ${CFLAGS} ${LDFLAGS} ${.ALLSRC} ${LIBS}
X  
X! bootpgw: bootpgw.o getif.o hwaddr.o report.o arplib.o
X  	${CC} -o ${.TARGET} ${CFLAGS} ${LDFLAGS} ${.ALLSRC} ${LIBS}
X  
X  print-bootp.o : print-bootp.c
X*** hwaddr.c.dist	Sun May 29 15:16:51 1994
X***************
X*** 16,21 ****
X--- 16,25 ----
X  #include <stropts.h>
X  #include <fcntl.h>
X  #endif
X+ #ifdef __NetBSD__
X+ #include "arplib.h"
X+ #endif
X+ 
X  
X  #include <net/if_arp.h>
X  #include <netinet/in.h>
X***************
X*** 71,76 ****
X--- 75,81 ----
X  	u_char *ha;
X  	int len;
X  {
X+ #ifndef __NetBSD__
X  	struct arpreq arpreq;		/* Arp request ioctl block */
X  	struct sockaddr_in *si;
X  #ifdef	SVR4
X***************
X*** 121,126 ****
X--- 126,144 ----
X  		report(LOG_ERR, "ioctl SIOCSARP: %s", get_errmsg());
X  	}
X  #endif	/* SVR4 */
X+ #else
X+ 	void *ap;
X+ 
X+ 	if ((ap = arp_open()) == NULL) {
X+ 		report(LOG_ERR, "arp_open: %s", arp_error(ap));
X+ 		return;
X+ 	}
X+ 
X+ 	if (arp_set(ap, ia, ha, ARP_NONE) == -1)
X+ 		report(LOG_ERR, "arp_set: %s", arp_error(ap));
X+ 
X+ 	arp_close(ap);
X+ #endif /* __NetBSD__ */
X  }
X  
X  
END_OF_FILE
if test 2830 -ne `wc -c <'bootpd.diff'`; then
    echo shar: \"'bootpd.diff'\" unpacked with wrong size!
fi
# end of 'bootpd.diff'
fi
if test -f 'netboot.diff' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'netboot.diff'\"
else
echo shar: Extracting \"'netboot.diff'\" \(274 characters\)
sed "s/^X//" >'netboot.diff' <<'END_OF_FILE'
X*** exec.c.dist	Fri Dec 17 01:59:44 1993
X***************
X*** 35,41 ****
X  #include <sys/types.h>
X  #include <sys/cdefs.h>
X  #include <sys/mount.h>
X- #include <sys/exec.h>
X  #include <sys/errno.h>
X  #include <sys/time.h>
X  
X--- 35,40 ----
END_OF_FILE
if test 274 -ne `wc -c <'netboot.diff'`; then
    echo shar: \"'netboot.diff'\" unpacked with wrong size!
fi
# end of 'netboot.diff'
fi
if test -f 'pppd.diff' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'pppd.diff'\"
else
echo shar: Extracting \"'pppd.diff'\" \(4386 characters\)
sed "s/^X//" >'pppd.diff' <<'END_OF_FILE'
X*** Makefile.dist	Sun May 29 15:07:49 1994
X***************
X*** 1,12 ****
X  #	$Id: Makefile,v 1.6 1994/05/08 12:16:10 paulus Exp $
X  
X  PROG=	pppd
X  SRCS=	main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c \
X! 	auth.c options.c lock.c sys-bsd.c
X  MAN8=	pppd.0
X  SUBDIR=	pppstats chat
X  BINMODE=4555
X  BINOWN=	root
X  
X  LDADD=	-lcrypt -lutil
X  DPADD=	${LIBCRYPT} ${LIBUTIL}
X--- 1,16 ----
X  #	$Id: Makefile,v 1.6 1994/05/08 12:16:10 paulus Exp $
X  
X+ ALIB=${.CURDIR}/../arp
X  PROG=	pppd
X  SRCS=	main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c \
X! 	auth.c options.c lock.c sys-bsd.c arplib.c
X  MAN8=	pppd.0
X  SUBDIR=	pppstats chat
X  BINMODE=4555
X  BINOWN=	root
X+ CFLAGS+=-I${ALIB}
X+ .PATH.c: ${ALIB}
X+ 
X  
X  LDADD=	-lcrypt -lutil
X  DPADD=	${LIBCRYPT} ${LIBUTIL}
X*** sys-bsd.c.dist	Mon May  9 06:54:37 1994
X***************
X*** 41,46 ****
X--- 41,47 ----
X  
X  #include "pppd.h"
X  #include "ppp.h"
X+ #include "arplib.h"
X  
X  static int initdisc = -1;		/* Initial TTY discipline */
X  extern int kdebugflag;
X***************
X*** 445,471 ****
X      int unit;
X      u_long hisaddr;
X  {
X!     struct arpreq arpreq;
X! 
X!     BZERO(&arpreq, sizeof(arpreq));
X! 
X      /*
X       * Get the hardware address of an interface on the same subnet
X       * as our local address.
X       */
X!     if (!get_ether_addr(hisaddr, &arpreq.arp_ha)) {
X  	syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP");
X  	return 0;
X      }
X  
X!     SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
X!     ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
X!     arpreq.arp_flags = ATF_PERM | ATF_PUBL;
X!     if (ioctl(s, SIOCSARP, (caddr_t)&arpreq) < 0) {
X! 	syslog(LOG_ERR, "ioctl(SIOCSARP): %m");
X  	return 0;
X      }
X  
X      return 1;
X  }
X  
X--- 446,477 ----
X      int unit;
X      u_long hisaddr;
X  {
X!     void *ap;
X!     struct in_addr ia;
X!     u_char ea[6];
X      /*
X       * Get the hardware address of an interface on the same subnet
X       * as our local address.
X       */
X!     if (!get_ether_addr(hisaddr, ea)) {
X  	syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP");
X  	return 0;
X      }
X  
X!     if ((ap = arp_open()) == NULL) {
X! 	syslog(LOG_ERR, "arp_open: %s", arp_error(ap));
X! 	return 0;
X!     }
X! 
X!     ia.s_addr = hisaddr;
X! 
X!     if (arp_set(ap, &ia, ea, ARP_EXPORT) == -1) {
X! 	syslog(LOG_ERR, "arp_set: %s", arp_error(ap));
X! 	arp_close(ap);
X  	return 0;
X      }
X  
X+     arp_close(ap);
X      return 1;
X  }
X  
X***************
X*** 477,491 ****
X      int unit;
X      u_long hisaddr;
X  {
X!     struct arpreq arpreq;
X  
X!     BZERO(&arpreq, sizeof(arpreq));
X!     SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
X!     ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
X!     if (ioctl(s, SIOCDARP, (caddr_t)&arpreq) < 0) {
X! 	syslog(LOG_WARNING, "ioctl(SIOCDARP): %m");
X  	return 0;
X      }
X      return 1;
X  }
X  
X--- 483,505 ----
X      int unit;
X      u_long hisaddr;
X  {
X!     struct in_addr ia;
X!     void *ap;
X  
X!     if ((ap = arp_open()) == NULL) {
X! 	syslog(LOG_ERR, "arp_open: %s", arp_error(ap));
X  	return 0;
X      }
X+ 
X+     ia.s_addr = hisaddr;
X+ 
X+     if (arp_delete(ap, &ia, ARP_NONE) == -1) {
X+ 	syslog(LOG_ERR, "arp_delete: %s", arp_error(ap));
X+ 	arp_close(ap);
X+ 	return 0;
X+     }
X+ 
X+     arp_close(ap);
X      return 1;
X  }
X  
X***************
X*** 498,504 ****
X  int
X  get_ether_addr(ipaddr, hwaddr)
X      u_long ipaddr;
X!     struct sockaddr *hwaddr;
X  {
X      struct ifreq *ifr, *ifend, *ifp;
X      u_long ina, mask;
X--- 512,518 ----
X  int
X  get_ether_addr(ipaddr, hwaddr)
X      u_long ipaddr;
X!     u_char *hwaddr;
X  {
X      struct ifreq *ifr, *ifend, *ifp;
X      u_long ina, mask;
X***************
X*** 563,571 ****
X  	     * Found the link-level address - copy it out
X  	     */
X  	    dla = (struct sockaddr_dl *)&ifr->ifr_addr;
X! 	    hwaddr->sa_len = sizeof(struct sockaddr);
X! 	    hwaddr->sa_family = AF_UNSPEC;
X! 	    BCOPY(LLADDR(dla), hwaddr->sa_data, dla->sdl_alen);
X  	    return 1;
X  	}
X  	ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len);
X--- 577,583 ----
X  	     * Found the link-level address - copy it out
X  	     */
X  	    dla = (struct sockaddr_dl *)&ifr->ifr_addr;
X! 	    BCOPY(LLADDR(dla), hwaddr, dla->sdl_alen);
X  	    return 1;
X  	}
X  	ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len);
END_OF_FILE
if test 4386 -ne `wc -c <'pppd.diff'`; then
    echo shar: \"'pppd.diff'\" unpacked with wrong size!
fi
# end of 'pppd.diff'
fi
if test -f 'rarpd.diff' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rarpd.diff'\"
else
echo shar: Extracting \"'rarpd.diff'\" \(2127 characters\)
sed "s/^X//" >'rarpd.diff' <<'END_OF_FILE'
X*** Makefile.dist	Sun May 29 14:31:45 1994
X***************
X*** 1,9 ****
X  # @(#) $Id: Makefile,v 1.1 1993/12/16 05:31:05 deraadt Exp $
X  
X  PROG=	rarpd
X! SRCS=	rarpd.c
X  
X! CFLAGS+=-I${.CURDIR} -DTFTP_DIR=\"/tftpboot\"
X  
X  MAN8=	rarpd.0
X  
X--- 1,12 ----
X  # @(#) $Id: Makefile,v 1.1 1993/12/16 05:31:05 deraadt Exp $
X  
X+ ALIB=${.CURDIR}/../arp
X  PROG=	rarpd
X! SRCS=	rarpd.c arplib.c
X  
X! CFLAGS+=-I${.CURDIR} -I${ALIB} -DTFTP_DIR=\"/tftpboot\"
X! 
X! .PATH.c: ${ALIB}
X  
X  MAN8=	rarpd.0
X  
X*** rarpd.c.dist	Sun May 29 14:31:51 1994
X***************
X*** 57,62 ****
X--- 57,64 ----
X  #include <arpa/inet.h>
X  #include <dirent.h>
X  
X+ #include "arplib.h"
X+ 
X  #define FATAL		1	/* fatal error occurred */
X  #define NONFATAL	0	/* non fatal error occurred */
X  
X***************
X*** 629,654 ****
X  	u_char *ep;
X  	u_long  ipaddr;
X  {
X! 	int     s;
X! 	struct arpreq request;
X! 	struct sockaddr_in *sin;
X! 
X! 	request.arp_flags = 0;
X! 	sin = (struct sockaddr_in *) & request.arp_pa;
X! 	sin->sin_family = AF_INET;
X! 	sin->sin_addr.s_addr = ipaddr;
X! 	request.arp_ha.sa_family = AF_UNSPEC;
X! 	/* This is needed #if defined(COMPAT_43) && BYTE_ORDER != BIG_ENDIAN,
X! 	   because AF_UNSPEC is zero and the kernel assumes that a zero
X! 	   sa_family means that the real sa_family value is in sa_len.  */
X! 	request.arp_ha.sa_len = 16; /* XXX */
X! 	bcopy((char *) ep, (char *) request.arp_ha.sa_data, 6);
X! 
X! 	s = socket(AF_INET, SOCK_DGRAM, 0);
X! 	if (ioctl(s, SIOCSARP, (caddr_t) & request) < 0) {
X! 		err(NONFATAL, "SIOCSARP: %s", strerror(errno));
X  	}
X! 	(void) close(s);
X  }
X  /*
X   * Build a reverse ARP packet and sent it out on the interface.
X--- 631,650 ----
X  	u_char *ep;
X  	u_long  ipaddr;
X  {
X! 	void *ap;
X! 	struct in_addr ia;
X! 
X! 	if ((ap = arp_open()) == NULL) {
X! 		errx(NONFATAL, "arp_open: %s", arp_error(ap));
X! 		return;
X  	}
X! 
X! 	ia.s_addr = ipaddr;
X! 
X! 	if (arp_set(ap, &ia, ep, ARP_NONE) == -1)
X! 		errx(NONFATAL, "arp_set: %s", arp_error(ap));
X! 
X! 	arp_close(ap);
X  }
X  /*
X   * Build a reverse ARP packet and sent it out on the interface.
END_OF_FILE
if test 2127 -ne `wc -c <'rarpd.diff'`; then
    echo shar: \"'rarpd.diff'\" unpacked with wrong size!
fi
# end of 'rarpd.diff'
fi
echo shar: End of shell archive.
exit 0

------------------------------------------------------------------------------