xref: /openbsd/usr.sbin/rarpd/rarpd.c (revision a6445c1d)
1 /*	$OpenBSD: rarpd.c,v 1.56 2014/10/31 20:11:52 deraadt Exp $ */
2 /*	$NetBSD: rarpd.c,v 1.25 1998/04/23 02:48:33 mrg Exp $	*/
3 
4 /*
5  * Copyright (c) 1990 The Regents of the University of California.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that: (1) source code distributions
10  * retain the above copyright notice and this paragraph in its entirety, (2)
11  * distributions including binary code include the above copyright notice and
12  * this paragraph in its entirety in the documentation or other materials
13  * provided with the distribution, and (3) all advertising materials mentioning
14  * features or use of this software display the following acknowledgement:
15  * ``This product includes software developed by the University of California,
16  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
17  * the University nor the names of its contributors may be used to endorse
18  * or promote products derived from this software without specific prior
19  * written permission.
20  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
21  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
22  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23  */
24 
25 /*
26  * rarpd - Reverse ARP Daemon
27  */
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <syslog.h>
32 #include <string.h>
33 #include <stdarg.h>
34 #include <sys/param.h>
35 #include <unistd.h>
36 #include <sys/time.h>
37 #include <net/bpf.h>
38 #include <sys/socket.h>
39 #include <sys/ioctl.h>
40 #include <net/if.h>
41 #include <net/if_dl.h>
42 #include <net/if_types.h>
43 #include <netinet/in.h>
44 #include <netinet/if_ether.h>
45 #include <sys/file.h>
46 #include <errno.h>
47 #include <netdb.h>
48 #include <arpa/inet.h>
49 #include <dirent.h>
50 #include <util.h>
51 #include <poll.h>
52 #include <ifaddrs.h>
53 #include <paths.h>
54 
55 #define FATAL		1	/* fatal error occurred */
56 #define NONFATAL	0	/* non fatal error occurred */
57 
58 /*
59  * The structures for each interface.
60  */
61 struct if_addr {
62 	in_addr_t ia_ipaddr;		/* IP address of this interface */
63 	in_addr_t ia_netmask;		/* subnet or net mask */
64 	struct if_addr *ia_next;
65 };
66 
67 struct if_info {
68 	int	ii_fd;			/* BPF file descriptor */
69 	char	ii_name[IFNAMSIZ];	/* if name, e.g. "en0" */
70 	u_char	ii_eaddr[ETHER_ADDR_LEN];	/* Ethernet address of this iface */
71 	struct if_addr *ii_addrs;	/* Networks this interface is on */
72 	struct if_info *ii_next;
73 };
74 /*
75  * The list of all interfaces that are being listened to.  rarp_loop()
76  * "selects" on the descriptors in this list.
77  */
78 struct if_info *iflist;
79 
80 int    rarp_open(char *);
81 void   init_one(char *);
82 void   init_all(void);
83 void   rarp_loop(void);
84 void   lookup_addrs(char *, struct if_info *);
85 void   usage(void);
86 void   rarp_process(struct if_info *, u_char *);
87 void   rarp_reply(struct if_info *, struct if_addr *,
88 	    struct ether_header *, u_int32_t, struct hostent *);
89 void   update_arptab(u_char *, u_int32_t);
90 void   error(int, const char *,...);
91 void   debug(const char *,...);
92 u_int32_t ipaddrtonetmask(u_int32_t);
93 int    rarp_bootable(u_int32_t);
94 
95 int	aflag = 0;		/* listen on "all" interfaces  */
96 int	dflag = 0;		/* print debugging messages */
97 int	fflag = 0;		/* don't fork */
98 int	lflag = 0;		/* log all replies */
99 int	tflag = 0;		/* tftpboot check */
100 
101 int
102 main(int argc, char *argv[])
103 {
104 	extern char *__progname;
105 	extern int optind, opterr;
106 	int op, devnull, f;
107 	pid_t pid;
108 
109 	/* All error reporting is done through syslogs. */
110 	openlog(__progname, LOG_PID | LOG_CONS, LOG_DAEMON);
111 
112 	opterr = 0;
113 	while ((op = getopt(argc, argv, "adflt")) != -1) {
114 		switch (op) {
115 		case 'a':
116 			++aflag;
117 			break;
118 		case 'd':
119 			++dflag;
120 			break;
121 		case 'f':
122 			++fflag;
123 			break;
124 		case 'l':
125 			++lflag;
126 			break;
127 		case 't':
128 			++tflag;
129 			break;
130 		default:
131 			usage();
132 			/* NOTREACHED */
133 		}
134 	}
135 	argc -= optind;
136 	argv += optind;
137 
138 	if ((aflag && argc > 0) || (!aflag && argc == 0))
139 		usage();
140 
141 	if (aflag)
142 		init_all();
143 	else
144 		while (argc > 0) {
145 			init_one(argv[0]);
146 			argc--;
147 			argv++;
148 		}
149 
150 	if ((!fflag) && (!dflag)) {
151 		pid = fork();
152 		if (pid > 0)
153 			/* Parent exits, leaving child in background. */
154 			exit(0);
155 		else
156 			if (pid == -1) {
157 				error(FATAL, "cannot fork");
158 				/* NOTREACHED */
159 			}
160 
161 		/* write pid file */
162 		pidfile(NULL);
163 
164 		/* Fade into the background */
165 		f = open(_PATH_TTY, O_RDWR);
166 		if (f >= 0) {
167 			if (ioctl(f, TIOCNOTTY, 0) < 0) {
168 				error(FATAL, "TIOCNOTTY: %s", strerror(errno));
169 				/* NOTREACHED */
170 			}
171 			(void) close(f);
172 		}
173 		(void) chdir("/");
174 		(void) setpgrp(0, getpid());
175 		devnull = open(_PATH_DEVNULL, O_RDWR);
176 		if (devnull >= 0) {
177 			(void) dup2(devnull, STDIN_FILENO);
178 			(void) dup2(devnull, STDOUT_FILENO);
179 			(void) dup2(devnull, STDERR_FILENO);
180 			if (devnull > 2)
181 				(void) close(devnull);
182 		}
183 	}
184 	rarp_loop();
185 	exit(0);
186 }
187 
188 /*
189  * Add 'ifname' to the interface list.  Lookup its IP address and network
190  * mask and Ethernet address, and open a BPF file for it.
191  */
192 void
193 init_one(char *ifname)
194 {
195 	struct if_info *p;
196 	int fd;
197 
198 	/* first check to see if this "if" was already opened? */
199 	for (p = iflist; p; p = p->ii_next)
200 		if (!strncmp(p->ii_name, ifname, IFNAMSIZ))
201 			return;
202 
203 	fd = rarp_open(ifname);
204 	if (fd < 0)
205 		return;
206 
207 	p = (struct if_info *)malloc(sizeof(*p));
208 	if (p == 0) {
209 		error(FATAL, "malloc: %s", strerror(errno));
210 		/* NOTREACHED */
211 	}
212 
213 	p->ii_next = iflist;
214 	iflist = p;
215 
216 	p->ii_fd = fd;
217 	strncpy(p->ii_name, ifname, IFNAMSIZ);
218 	p->ii_addrs = NULL;
219 	lookup_addrs(ifname, p);
220 }
221 /*
222  * Initialize all "candidate" interfaces that are in the system
223  * configuration list.  A "candidate" is up, not loopback and not
224  * point to point.
225  */
226 void
227 init_all(void)
228 {
229 	struct ifaddrs *ifap, *ifa;
230 	struct sockaddr_dl *sdl;
231 
232 	if (getifaddrs(&ifap) != 0) {
233 		error(FATAL, "getifaddrs: %s", strerror(errno));
234 		/* NOTREACHED */
235 	}
236 
237 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
238 		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
239 		if (sdl->sdl_family != AF_LINK || sdl->sdl_type != IFT_ETHER ||
240 		    sdl->sdl_alen != 6)
241 			continue;
242 
243 		if ((ifa->ifa_flags &
244 		    (IFF_UP | IFF_LOOPBACK | IFF_POINTOPOINT)) != IFF_UP)
245 			continue;
246 		init_one(ifa->ifa_name);
247 	}
248 	freeifaddrs(ifap);
249 }
250 
251 void
252 usage(void)
253 {
254 	(void) fprintf(stderr, "usage: rarpd [-adflt] if0 [... ifN]\n");
255 	exit(1);
256 }
257 
258 static int
259 bpf_open(void)
260 {
261 	int	fd, n = 0;
262 	char    device[sizeof "/dev/bpf0000000000"];
263 
264 	/* Go through all the minors and find one that isn't in use. */
265 	do {
266 		(void) snprintf(device, sizeof device, "/dev/bpf%d", n++);
267 		fd = open(device, O_RDWR);
268 	} while (fd < 0 && errno == EBUSY);
269 
270 	if (fd < 0) {
271 		error(FATAL, "%s: %s", device, strerror(errno));
272 		/* NOTREACHED */
273 	}
274 	return fd;
275 }
276 
277 static struct bpf_insn insns[] = {
278 	BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 12),
279 	BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ETHERTYPE_REVARP, 0, 3),
280 	BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 20),
281 	BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ARPOP_REVREQUEST, 0, 1),
282 	BPF_STMT(BPF_RET | BPF_K, sizeof(struct ether_arp) +
283 	    sizeof(struct ether_header)),
284 	BPF_STMT(BPF_RET | BPF_K, 0),
285 };
286 
287 static struct bpf_program filter = {
288 	sizeof insns / sizeof(insns[0]),
289 	insns
290 };
291 
292 /*
293  * Open a BPF file and attach it to the interface named 'device'.
294  * Set immediate mode, and set a filter that accepts only RARP requests.
295  */
296 int
297 rarp_open(char *device)
298 {
299 	int	fd, immediate;
300 	struct ifreq ifr;
301 	u_int   dlt;
302 
303 	fd = bpf_open();
304 
305 	/* Set immediate mode so packets are processed as they arrive. */
306 	immediate = 1;
307 	if (ioctl(fd, BIOCIMMEDIATE, &immediate) < 0) {
308 		error(FATAL, "BIOCIMMEDIATE: %s", strerror(errno));
309 		/* NOTREACHED */
310 	}
311 
312 	(void) strncpy(ifr.ifr_name, device, sizeof ifr.ifr_name);
313 	if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
314 		if (aflag) {	/* for -a skip not ethernet interfaces */
315 			close(fd);
316 			return -1;
317 		}
318 		error(FATAL, "BIOCSETIF: %s", strerror(errno));
319 		/* NOTREACHED */
320 	}
321 
322 	/*
323 	 * Check that the data link layer is an Ethernet; this code
324 	 * won't work with anything else.
325 	 */
326 	if (ioctl(fd, BIOCGDLT, (caddr_t) &dlt) < 0) {
327 		error(FATAL, "BIOCGDLT: %s", strerror(errno));
328 		/* NOTREACHED */
329 	}
330 	if (dlt != DLT_EN10MB) {
331 		if (aflag) {	/* for -a skip not ethernet interfaces */
332 			close(fd);
333 			return -1;
334 		}
335 		error(FATAL, "%s is not an ethernet", device);
336 		/* NOTREACHED */
337 	}
338 	/* Set filter program. */
339 	if (ioctl(fd, BIOCSETF, (caddr_t)&filter) < 0) {
340 		error(FATAL, "BIOCSETF: %s", strerror(errno));
341 		/* NOTREACHED */
342 	}
343 	return fd;
344 }
345 /*
346  * Perform various sanity checks on the RARP request packet.  Return
347  * false on failure and log the reason.
348  */
349 static int
350 rarp_check(u_char *p, int len)
351 {
352 	struct ether_header *ep = (struct ether_header *) p;
353 	struct ether_arp *ap = (struct ether_arp *) (p + sizeof(*ep));
354 
355 	(void) debug("got a packet");
356 
357 	if (len < sizeof(*ep) + sizeof(*ap)) {
358 		error(NONFATAL, "truncated request");
359 		return 0;
360 	}
361 	/* XXX This test might be better off broken out... */
362 	if (ntohs (ep->ether_type) != ETHERTYPE_REVARP ||
363 	    ntohs (ap->arp_hrd) != ARPHRD_ETHER ||
364 	    ntohs (ap->arp_op) != ARPOP_REVREQUEST ||
365 	    ntohs (ap->arp_pro) != ETHERTYPE_IP ||
366 	    ap->arp_hln != 6 || ap->arp_pln != 4) {
367 		error(NONFATAL, "request fails sanity check");
368 		return 0;
369 	}
370 	if (memcmp((char *) &ep->ether_shost, (char *) &ap->arp_sha, 6) != 0) {
371 		error(NONFATAL, "ether/arp sender address mismatch");
372 		return 0;
373 	}
374 	if (memcmp((char *) &ap->arp_sha, (char *) &ap->arp_tha, 6) != 0) {
375 		error(NONFATAL, "ether/arp target address mismatch");
376 		return 0;
377 	}
378 	return 1;
379 }
380 
381 /*
382  * Loop indefinitely listening for RARP requests on the
383  * interfaces in 'iflist'.
384  */
385 void
386 rarp_loop(void)
387 {
388 	int	cc, fd, numfd = 0, i;
389 	u_int	bufsize;
390 	struct pollfd *pfd;
391 	u_char	*buf, *bp, *ep;
392 	struct if_info *ii;
393 
394 	if (iflist == 0) {
395 		error(FATAL, "no interfaces");
396 		/* NOTREACHED */
397 	}
398 	if (ioctl(iflist->ii_fd, BIOCGBLEN, (caddr_t)&bufsize) < 0) {
399 		error(FATAL, "BIOCGBLEN: %s", strerror(errno));
400 		/* NOTREACHED */
401 	}
402 	buf = (u_char *) malloc((size_t) bufsize);
403 	if (buf == 0) {
404 		error(FATAL, "malloc: %s", strerror(errno));
405 		/* NOTREACHED */
406 	}
407 	/*
408 	 * Initialize the set of descriptors to listen to.
409 	 */
410 	for (ii = iflist; ii; ii = ii->ii_next)
411 		numfd++;
412 	pfd = reallocarray(NULL, numfd, sizeof(*pfd));
413 	if (pfd == NULL) {
414 		error(FATAL, "malloc: %s", strerror(errno));
415 		/* NOTREACHED */
416 	}
417 	for (i = 0, ii = iflist; ii; ii = ii->ii_next, i++) {
418 		pfd[i].fd = ii->ii_fd;
419 		pfd[i].events = POLLIN;
420 	}
421 
422 	while (1) {
423 		if (poll(pfd, numfd, -1) == -1) {
424 			if (errno == EINTR)
425 				continue;
426 			error(FATAL, "select: %s", strerror(errno));
427 			/* NOTREACHED */
428 		}
429 		for (i = 0, ii = iflist; ii; ii = ii->ii_next, i++) {
430 			if (pfd[i].revents == 0)
431 				continue;
432 			fd = ii->ii_fd;
433 		again:
434 			cc = read(fd, (char *)buf, bufsize);
435 			/* Don't choke when we get ptraced */
436 			if (cc < 0 && errno == EINTR)
437 				goto again;
438 			if (cc < 0) {
439 				error(FATAL, "read: %s", strerror(errno));
440 				/* NOTREACHED */
441 			}
442 			/* Loop through the packet(s) */
443 #define bhp ((struct bpf_hdr *)bp)
444 			bp = buf;
445 			ep = bp + cc;
446 			while (bp < ep) {
447 				int caplen, hdrlen;
448 
449 				caplen = bhp->bh_caplen;
450 				hdrlen = bhp->bh_hdrlen;
451 				if (rarp_check(bp + hdrlen, caplen))
452 					rarp_process(ii, bp + hdrlen);
453 				bp += BPF_WORDALIGN(hdrlen + caplen);
454 			}
455 		}
456 	}
457 	free(pfd);
458 }
459 
460 #ifndef TFTP_DIR
461 #define TFTP_DIR "/tftpboot"
462 #endif
463 
464 /*
465  * True if this server can boot the host whose IP address is 'addr'.
466  * This check is made by looking in the tftp directory for the
467  * configuration file.
468  */
469 int
470 rarp_bootable(u_int32_t addr)
471 {
472 	struct dirent *dent;
473 	char    ipname[40];
474 	static DIR *dd = 0;
475 	DIR *d;
476 
477 	(void) snprintf(ipname, sizeof ipname, "%08X", addr);
478 	/* If directory is already open, rewind it.  Otherwise, open it. */
479 	if ((d = dd))
480 		rewinddir(d);
481 	else {
482 		if (chdir(TFTP_DIR) == -1) {
483 			error(FATAL, "chdir: %s", strerror(errno));
484 			/* NOTREACHED */
485 		}
486 		d = opendir(".");
487 		if (d == 0) {
488 			error(FATAL, "opendir: %s", strerror(errno));
489 			/* NOTREACHED */
490 		}
491 		dd = d;
492 	}
493 	while ((dent = readdir(d)))
494 		if (strncmp(dent->d_name, ipname, 8) == 0)
495 			return 1;
496 	return 0;
497 }
498 
499 
500 /*
501  * Given a list of IP addresses, 'alist', return the first address that
502  * is on network 'net'; 'netmask' is a mask indicating the network portion
503  * of the address.
504  */
505 static u_int32_t
506 choose_ipaddr(u_int32_t **alist, u_int32_t net, u_int32_t netmask)
507 {
508 	for (; *alist; ++alist) {
509 		if ((**alist & netmask) == net)
510 			return **alist;
511 	}
512 	return 0;
513 }
514 /*
515  * Answer the RARP request in 'pkt', on the interface 'ii'.  'pkt' has
516  * already been checked for validity.  The reply is overlaid on the request.
517  */
518 void
519 rarp_process(struct if_info *ii, u_char *pkt)
520 {
521 	char    ename[MAXHOSTNAMELEN];
522 	u_int32_t  target_ipaddr;
523 	struct ether_header *ep;
524 	struct ether_addr *ea;
525 	struct hostent *hp;
526 	struct	in_addr in;
527 	struct if_addr *ia;
528 
529 	ep = (struct ether_header *) pkt;
530 	ea = (struct ether_addr *) &ep->ether_shost;
531 
532 	debug("%s", ether_ntoa(ea));
533 	if (ether_ntohost(ename, ea) != 0) {
534 		debug("ether_ntohost failed");
535 		return;
536 	}
537 	if ((hp = gethostbyname(ename)) == 0) {
538 		debug("gethostbyname (%s) failed", ename);
539 		return;
540 	}
541 
542 	/* Choose correct address from list. */
543 	if (hp->h_addrtype != AF_INET) {
544 		error(FATAL, "cannot handle non IP addresses");
545 		/* NOTREACHED */
546 	}
547 	for (target_ipaddr = 0, ia = ii->ii_addrs; ia; ia = ia->ia_next) {
548 		target_ipaddr = choose_ipaddr((u_int32_t **) hp->h_addr_list,
549 		    ia->ia_ipaddr & ia->ia_netmask, ia->ia_netmask);
550 		if (target_ipaddr)
551 			break;
552 	}
553 
554 	if (target_ipaddr == 0) {
555 		for (ia = ii->ii_addrs; ia; ia = ia->ia_next) {
556 			in.s_addr = ia->ia_ipaddr & ia->ia_netmask;
557 			error(NONFATAL, "cannot find %s on net %s",
558 			    ename, inet_ntoa(in));
559 		}
560 		return;
561 	}
562 	if (tflag == 0 || rarp_bootable(htonl(target_ipaddr)))
563 		rarp_reply(ii, ia, ep, target_ipaddr, hp);
564 	debug("reply sent");
565 }
566 
567 /*
568  * Lookup the ethernet address of the interface attached to the BPF
569  * file descriptor 'fd'; return it in 'eaddr'.
570  */
571 void
572 lookup_addrs(char *ifname, struct if_info *p)
573 {
574 	struct ifaddrs *ifap, *ifa;
575 	struct sockaddr_dl *sdl;
576 	u_char *eaddr = p->ii_eaddr;
577 	struct if_addr *ia, **iap = &p->ii_addrs;
578 	struct in_addr in;
579 	int found = 0;
580 
581 	if (getifaddrs(&ifap) != 0) {
582 		error(FATAL, "getifaddrs: %s", strerror(errno));
583 		/* NOTREACHED */
584 	}
585 
586 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
587 		if (strcmp(ifa->ifa_name, ifname))
588 			continue;
589 		sdl = (struct sockaddr_dl *) ifa->ifa_addr;
590 		if (sdl->sdl_family == AF_LINK &&
591 		    sdl->sdl_type == IFT_ETHER && sdl->sdl_alen == 6) {
592 			memcpy((caddr_t)eaddr, (caddr_t)LLADDR(sdl), 6);
593 			if (dflag)
594 				fprintf(stderr, "%s: %x:%x:%x:%x:%x:%x\n",
595 				    ifa->ifa_name,
596 				    eaddr[0], eaddr[1], eaddr[2],
597 				    eaddr[3], eaddr[4], eaddr[5]);
598 			found = 1;
599 		} else if (sdl->sdl_family == AF_INET) {
600 			ia = malloc(sizeof (struct if_addr));
601 			if (ia == NULL)
602 				error(FATAL, "lookup_addrs: malloc: %s",
603 				    strerror(errno));
604 			ia->ia_next = NULL;
605 			ia->ia_ipaddr =
606 			    ((struct sockaddr_in *) ifa->ifa_addr)->
607 			    sin_addr.s_addr;
608 			ia->ia_netmask =
609 			    ((struct sockaddr_in *) ifa->ifa_netmask)->
610 			    sin_addr.s_addr;
611 			/* If SIOCGIFNETMASK didn't work,
612 			   figure out a mask from the IP
613 			   address class. */
614 			if (ia->ia_netmask == 0)
615 				ia->ia_netmask =
616 				    ipaddrtonetmask(ia->ia_ipaddr);
617 			if (dflag) {
618 				in.s_addr = ia->ia_ipaddr;
619 				fprintf(stderr, "\t%s\n",
620 				    inet_ntoa(in));
621 			}
622 			*iap = ia;
623 			iap = &ia->ia_next;
624 		}
625 	}
626 	freeifaddrs(ifap);
627 	if (!found)
628 		error(FATAL, "lookup_addrs: Never saw interface `%s'!", ifname);
629 }
630 
631 int arptab_set(u_char *eaddr, u_int32_t host);
632 
633 /*
634  * Poke the kernel arp tables with the ethernet/ip address combinataion
635  * given.  When processing a reply, we must do this so that the booting
636  * host (i.e. the guy running rarpd), won't try to ARP for the hardware
637  * address of the guy being booted (he cannot answer the ARP).
638  */
639 void
640 update_arptab(u_char *ep, u_int32_t ipaddr)
641 {
642 #ifdef SIOCSARP
643 	struct sockaddr_in *sin;
644 	struct arpreq request;
645 	u_int32_t host;
646 	u_char *eaddr;
647 	int s;
648 
649 	request.arp_flags = 0;
650 	sin = (struct sockaddr_in *)&request.arp_pa;
651 	sin->sin_family = AF_INET;
652 	sin->sin_addr.s_addr = ipaddr;
653 	request.arp_ha.sa_family = AF_UNSPEC;
654 	/* This is needed #if defined(COMPAT_43) && BYTE_ORDER != BIG_ENDIAN,
655 	   because AF_UNSPEC is zero and the kernel assumes that a zero
656 	   sa_family means that the real sa_family value is in sa_len.  */
657 	request.arp_ha.sa_len = 16; /* XXX */
658 	memcpy((char *) request.arp_ha.sa_data, (char *) ep, 6);
659 
660 	s = socket(AF_INET, SOCK_DGRAM, 0);
661 	if (s < 0) {
662 		error(NONFATAL, "socket: %s", strerror(errno));
663 	} else {
664 		if (ioctl(s, SIOCSARP, (caddr_t)&request) < 0)
665 		    error(NONFATAL, "SIOCSARP: %s", strerror(errno));
666 		(void) close(s);
667 	}
668 #else
669 	if (arptab_set(ep, ipaddr) > 0)
670 		syslog(LOG_ERR, "couldn't update arp table");
671 #endif
672 }
673 /*
674  * Build a reverse ARP packet and sent it out on the interface.
675  * 'ep' points to a valid ARPOP_REVREQUEST.  The ARPOP_REVREPLY is built
676  * on top of the request, then written to the network.
677  *
678  * RFC 903 defines the ether_arp fields as follows.  The following comments
679  * are taken (more or less) straight from this document.
680  *
681  * ARPOP_REVREQUEST
682  *
683  * arp_sha is the hardware address of the sender of the packet.
684  * arp_spa is undefined.
685  * arp_tha is the 'target' hardware address.
686  *   In the case where the sender wishes to determine his own
687  *   protocol address, this, like arp_sha, will be the hardware
688  *   address of the sender.
689  * arp_tpa is undefined.
690  *
691  * ARPOP_REVREPLY
692  *
693  * arp_sha is the hardware address of the responder (the sender of the
694  *   reply packet).
695  * arp_spa is the protocol address of the responder (see the note below).
696  * arp_tha is the hardware address of the target, and should be the same as
697  *   that which was given in the request.
698  * arp_tpa is the protocol address of the target, that is, the desired address.
699  *
700  * Note that the requirement that arp_spa be filled in with the responder's
701  * protocol is purely for convenience.  For instance, if a system were to use
702  * both ARP and RARP, then the inclusion of the valid protocol-hardware
703  * address pair (arp_spa, arp_sha) may eliminate the need for a subsequent
704  * ARP request.
705  */
706 void
707 rarp_reply(struct if_info *ii, struct if_addr *ia, struct ether_header *ep,
708     u_int32_t ipaddr, struct hostent *hp)
709 {
710 	struct ether_arp *ap = (struct ether_arp *) (ep + 1);
711 	int len, n;
712 
713 	update_arptab((u_char *)&ap->arp_sha, ipaddr);
714 
715 	/* Build the rarp reply by modifying the rarp request in place. */
716 	ep->ether_type = htons(ETHERTYPE_REVARP);
717 	ap->ea_hdr.ar_hrd = htons(ARPHRD_ETHER);
718 	ap->ea_hdr.ar_pro = htons(ETHERTYPE_IP);
719 	ap->arp_op = htons(ARPOP_REVREPLY);
720 
721 	memcpy((char *) &ep->ether_dhost, (char *) &ap->arp_sha, 6);
722 	memcpy((char *) &ep->ether_shost, (char *) ii->ii_eaddr, 6);
723 	memcpy((char *) &ap->arp_sha, (char *) ii->ii_eaddr, 6);
724 
725 	memcpy((char *) ap->arp_tpa, (char *) &ipaddr, 4);
726 	/* Target hardware is unchanged. */
727 	memcpy((char *) ap->arp_spa, (char *) &ia->ia_ipaddr, 4);
728 
729 	if (lflag) {
730 		struct ether_addr ea;
731 
732 		memcpy(&ea.ether_addr_octet, &ap->arp_sha, 6);
733 		syslog(LOG_INFO, "%s asked; %s replied", hp->h_name,
734 		    ether_ntoa(&ea));
735 	}
736 
737 	len = sizeof(*ep) + sizeof(*ap);
738 	n = write(ii->ii_fd, (char *) ep, len);
739 	if (n != len)
740 		error(NONFATAL, "write: only %d of %d bytes written", n, len);
741 }
742 /*
743  * Get the netmask of an IP address.  This routine is used if
744  * SIOCGIFNETMASK doesn't work.
745  */
746 u_int32_t
747 ipaddrtonetmask(u_int32_t addr)
748 {
749 	if (IN_CLASSA(addr))
750 		return IN_CLASSA_NET;
751 	if (IN_CLASSB(addr))
752 		return IN_CLASSB_NET;
753 	if (IN_CLASSC(addr))
754 		return IN_CLASSC_NET;
755 	error(FATAL, "unknown IP address class: %08X", addr);
756 	/* NOTREACHED */
757 }
758 
759 void
760 error(int fatal, const char *fmt,...)
761 {
762 	va_list ap;
763 
764 	if (dflag) {
765 		if (fatal)
766 			(void) fprintf(stderr, "rarpd: error: ");
767 		else
768 			(void) fprintf(stderr, "rarpd: warning: ");
769 		va_start(ap, fmt);
770 		(void) vfprintf(stderr, fmt, ap);
771 		va_end(ap);
772 		(void) fprintf(stderr, "\n");
773 	}
774 	va_start(ap, fmt);
775 	vsyslog(LOG_ERR, fmt, ap);
776 	va_end(ap);
777 	if (fatal)
778 		exit(1);
779 	/* NOTREACHED */
780 }
781 
782 void
783 debug(const char *fmt,...)
784 {
785 	va_list ap;
786 
787 	if (dflag) {
788 		va_start(ap, fmt);
789 		(void) fprintf(stderr, "rarpd: ");
790 		(void) vfprintf(stderr, fmt, ap);
791 		va_end(ap);
792 		(void) fprintf(stderr, "\n");
793 	}
794 }
795