xref: /openbsd-src/usr.sbin/rarpd/rarpd.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: rarpd.c,v 1.30 2001/06/13 20:13:29 markus 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 #ifndef lint
25 char    copyright[] =
26 "@(#) Copyright (c) 1990 The Regents of the University of California.\n\
27  All rights reserved.\n";
28 #endif				/* not lint */
29 
30 #ifndef lint
31 static char rcsid[] = "$OpenBSD: rarpd.c,v 1.30 2001/06/13 20:13:29 markus Exp $";
32 #endif
33 
34 
35 /*
36  * rarpd - Reverse ARP Daemon
37  *
38  * Usage:	rarpd -a [ -d ] [ -f ] [ -l ]
39  *		rarpd [ -d ] [ -f ] [ -l ] interface
40  */
41 
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <syslog.h>
45 #include <string.h>
46 #include <sys/types.h>
47 #include <unistd.h>
48 #include <sys/time.h>
49 #include <net/bpf.h>
50 #include <sys/socket.h>
51 #include <sys/ioctl.h>
52 #include <net/if.h>
53 #include <net/if_dl.h>
54 #include <net/if_types.h>
55 #include <netinet/in.h>
56 #include <netinet/if_ether.h>
57 #include <sys/errno.h>
58 #include <sys/file.h>
59 #include <netdb.h>
60 #include <arpa/inet.h>
61 #include <dirent.h>
62 #ifdef HAVE_IFADDRS_H
63 #include <ifaddrs.h>
64 #endif
65 
66 #include "pathnames.h"
67 
68 #define FATAL		1	/* fatal error occurred */
69 #define NONFATAL	0	/* non fatal error occurred */
70 
71 /*
72  * The structures for each interface.
73  */
74 struct if_addr {
75 	in_addr_t ia_ipaddr;		/* IP address of this interface */
76 	in_addr_t ia_netmask;		/* subnet or net mask */
77 	struct if_addr *ia_next;
78 };
79 
80 struct if_info {
81 	int     ii_fd;			/* BPF file descriptor */
82 	char	ii_name[IFNAMSIZ];	/* if name, e.g. "en0" */
83 	u_char  ii_eaddr[6];		/* Ethernet address of this iface */
84 	struct if_addr *ii_addrs;	/* Networks this interface is on */
85 	struct if_info *ii_next;
86 };
87 /*
88  * The list of all interfaces that are being listened to.  rarp_loop()
89  * "selects" on the descriptors in this list.
90  */
91 struct if_info *iflist;
92 
93 int    rarp_open     __P((char *));
94 void   init_one      __P((char *));
95 void   init_all      __P((void));
96 void   rarp_loop     __P((void));
97 void   lookup_addrs  __P((char *, struct if_info *));
98 void   usage         __P((void));
99 void   rarp_process  __P((struct if_info *, u_char *));
100 void   rarp_reply    __P((struct if_info *, struct if_addr *,
101 	struct ether_header *, u_int32_t, struct hostent *));
102 void   update_arptab __P((u_char *, u_int32_t));
103 void   err           __P((int, const char *,...));
104 void   debug         __P((const char *,...));
105 u_int32_t ipaddrtonetmask __P((u_int32_t));
106 
107 #ifdef REQUIRE_TFTPBOOT
108 int    rarp_bootable __P((u_int32_t));
109 #endif
110 
111 int     aflag = 0;		/* listen on "all" interfaces  */
112 int     dflag = 0;		/* print debugging messages */
113 int     fflag = 0;		/* don't fork */
114 int     lflag = 0;		/* log all replies */
115 
116 int
117 main(argc, argv)
118 	int     argc;
119 	char  **argv;
120 {
121 	int     op, pid, devnull, f;
122 	char   *ifname, *hostname;
123 	extern char *__progname;
124 	extern char *optarg;
125 	extern int optind, opterr;
126 
127 	/* All error reporting is done through syslogs. */
128 	openlog(__progname, LOG_PID | LOG_CONS, LOG_DAEMON);
129 
130 	opterr = 0;
131 	while ((op = getopt(argc, argv, "adfl")) != -1) {
132 		switch (op) {
133 		case 'a':
134 			++aflag;
135 			break;
136 
137 		case 'd':
138 			++dflag;
139 			break;
140 
141 		case 'f':
142 			++fflag;
143 			break;
144 
145 		case 'l':
146 			++lflag;
147 			break;
148 
149 		default:
150 			usage();
151 			/* NOTREACHED */
152 		}
153 	}
154 	ifname = argv[optind++];
155 	hostname = ifname ? argv[optind] : 0;
156 	if ((aflag && ifname) || (!aflag && ifname == 0))
157 		usage();
158 
159 	if (aflag)
160 		init_all();
161 	else
162 		init_one(ifname);
163 
164 	if ((!fflag) && (!dflag)) {
165 		FILE *fp;
166 
167 		pid = fork();
168 		if (pid > 0)
169 			/* Parent exits, leaving child in background. */
170 			exit(0);
171 		else
172 			if (pid == -1) {
173 				err(FATAL, "cannot fork");
174 				/* NOTREACHED */
175 			}
176 
177 		/* write pid file */
178 		if ((fp = fopen(_PATH_RARPDPID, "w")) != NULL) {
179 			fprintf(fp, "%u\n", getpid());
180 			(void)fclose(fp);
181 		}
182 
183 		/* Fade into the background */
184 		f = open("/dev/tty", O_RDWR);
185 		if (f >= 0) {
186 			if (ioctl(f, TIOCNOTTY, 0) < 0) {
187 				err(FATAL, "TIOCNOTTY: %s", strerror(errno));
188 				/* NOTREACHED */
189 			}
190 			(void) close(f);
191 		}
192 		(void) chdir("/");
193 		(void) setpgrp(0, getpid());
194 		devnull = open("/dev/null", O_RDWR);
195 		if (devnull >= 0) {
196 			(void) dup2(devnull, 0);
197 			(void) dup2(devnull, 1);
198 			(void) dup2(devnull, 2);
199 			if (devnull > 2)
200 				(void) close(devnull);
201 		}
202 	}
203 	rarp_loop();
204 	exit(0);
205 }
206 
207 /*
208  * Add 'ifname' to the interface list.  Lookup its IP address and network
209  * mask and Ethernet address, and open a BPF file for it.
210  */
211 void
212 init_one(ifname)
213 	char   *ifname;
214 {
215 	struct if_info *p;
216 	int fd;
217 
218 	/* first check to see if this "if" was already opened? */
219 	for (p = iflist; p; p = p->ii_next)
220 		if (!strncmp(p->ii_name, ifname, IFNAMSIZ))
221 			return;
222 
223 	fd = rarp_open(ifname);
224 	if (fd < 0)
225 		return;
226 
227 	p = (struct if_info *)malloc(sizeof(*p));
228 	if (p == 0) {
229 		err(FATAL, "malloc: %s", strerror(errno));
230 		/* NOTREACHED */
231 	}
232 
233 	p->ii_next = iflist;
234 	iflist = p;
235 
236 	p->ii_fd = fd;
237 	strncpy(p->ii_name, ifname, IFNAMSIZ);
238 	p->ii_addrs = NULL;
239 	lookup_addrs(ifname, p);
240 }
241 /*
242  * Initialize all "candidate" interfaces that are in the system
243  * configuration list.  A "candidate" is up, not loopback and not
244  * point to point.
245  */
246 void
247 init_all()
248 {
249 #ifdef HAVE_IFADDRS_H
250 	struct ifaddrs *ifap, *ifa;
251 	struct sockaddr_dl *sdl;
252 
253 	if (getifaddrs(&ifap) != 0) {
254 		err(FATAL, "getifaddrs: %s", strerror(errno));
255 		/* NOTREACHED */
256 	}
257 
258 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
259 		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
260 		if (sdl->sdl_family != AF_LINK || sdl->sdl_type != IFT_ETHER ||
261 		    sdl->sdl_alen != 6)
262 			continue;
263 
264 		if ((ifa->ifa_flags &
265 		    (IFF_UP | IFF_LOOPBACK | IFF_POINTOPOINT)) != IFF_UP)
266 			continue;
267 		init_one(ifa->ifa_name);
268 	}
269 	freeifaddrs(ifap);
270 #else
271 	char *inbuf = NULL, *ninbuf;
272 	struct ifconf ifc;
273 	struct ifreq *ifr;
274 	struct sockaddr_dl *sdl;
275 	int fd, inlen = 8192;
276 	int i, len;
277 
278 	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
279 		err(FATAL, "socket: %s", strerror(errno));
280 		/* NOTREACHED */
281 	}
282 
283 	while (1) {
284 		ifc.ifc_len = inlen;
285 		ninbuf = realloc(inbuf, inlen);
286 		if (ninbuf == NULL) {
287 			if (inbuf)
288 				free(inbuf);
289 			close(fd);
290 			err(FATAL, "init_all: malloc: %s", strerror(errno));
291 		}
292 		ifc.ifc_buf = inbuf = ninbuf;
293 		if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0) {
294 			(void) close(fd);
295 			free(inbuf);
296 			err(FATAL, "init_all: SIOCGIFCONF: %s",
297 			    strerror(errno));
298 			/* NOTREACHED */
299 		}
300 		if (ifc.ifc_len + sizeof(*ifr) < inlen)
301 			break;
302 		inlen *= 2;
303 	}
304 
305 	ifr = ifc.ifc_req;
306 	for (i = 0; i < ifc.ifc_len;
307 	     i += len, ifr = (struct ifreq *)((caddr_t)ifr + len)) {
308 		len = sizeof(ifr->ifr_name) +
309 		      (ifr->ifr_addr.sa_len > sizeof(struct sockaddr) ?
310 		       ifr->ifr_addr.sa_len : sizeof(struct sockaddr));
311 
312 		sdl = (struct sockaddr_dl *)&ifr->ifr_addr;
313 		if (sdl->sdl_family != AF_LINK || sdl->sdl_type != IFT_ETHER ||
314 		    sdl->sdl_alen != 6)
315 			continue;
316 
317 		if (ioctl(fd, SIOCGIFFLAGS, (caddr_t)ifr) < 0) {
318 			free(inbuf);
319 			err(FATAL, "init_all: SIOCGIFFLAGS %s: %s",
320 			    ifr->ifr_name, strerror(errno));
321 			/* NOTREACHED */
322 		}
323 		if ((ifr->ifr_flags &
324 		    (IFF_UP | IFF_LOOPBACK | IFF_POINTOPOINT)) != IFF_UP)
325 			continue;
326 		init_one(ifr->ifr_name);
327 	}
328 	free(inbuf);
329 	(void) close(fd);
330 #endif
331 }
332 
333 void
334 usage()
335 {
336 	(void) fprintf(stderr, "usage: rarpd -a [-dfl]\n");
337 	(void) fprintf(stderr, "       rarpd [-dfl] interface\n");
338 	exit(1);
339 }
340 
341 static int
342 bpf_open()
343 {
344 	int     fd;
345 	int     n = 0;
346 	char    device[sizeof "/dev/bpf0000000000"];
347 
348 	/* Go through all the minors and find one that isn't in use. */
349 	do {
350 		(void) snprintf(device, sizeof device, "/dev/bpf%d", n++);
351 		fd = open(device, O_RDWR);
352 	} while (fd < 0 && errno == EBUSY);
353 
354 	if (fd < 0) {
355 		err(FATAL, "%s: %s", device, strerror(errno));
356 		/* NOTREACHED */
357 	}
358 	return fd;
359 }
360 /*
361  * Open a BPF file and attach it to the interface named 'device'.
362  * Set immediate mode, and set a filter that accepts only RARP requests.
363  */
364 int
365 rarp_open(device)
366 	char   *device;
367 {
368 	int     fd;
369 	struct ifreq ifr;
370 	u_int   dlt;
371 	int     immediate;
372 
373 	static struct bpf_insn insns[] = {
374 		BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 12),
375 		BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ETHERTYPE_REVARP, 0, 3),
376 		BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 20),
377 		BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ARPOP_REVREQUEST, 0, 1),
378 		BPF_STMT(BPF_RET | BPF_K, sizeof(struct ether_arp) +
379 		    sizeof(struct ether_header)),
380 		BPF_STMT(BPF_RET | BPF_K, 0),
381 	};
382 	static struct bpf_program filter = {
383 		sizeof insns / sizeof(insns[0]),
384 		insns
385 	};
386 
387 	fd = bpf_open();
388 
389 	/* Set immediate mode so packets are processed as they arrive. */
390 	immediate = 1;
391 	if (ioctl(fd, BIOCIMMEDIATE, &immediate) < 0) {
392 		err(FATAL, "BIOCIMMEDIATE: %s", strerror(errno));
393 		/* NOTREACHED */
394 	}
395 	(void) strncpy(ifr.ifr_name, device, sizeof ifr.ifr_name);
396 	if (ioctl(fd, BIOCSETIF, (caddr_t) & ifr) < 0) {
397 		if (aflag) {	/* for -a skip not ethernet interfaces */
398 			close(fd);
399 			return -1;
400 		}
401 		err(FATAL, "BIOCSETIF: %s", strerror(errno));
402 		/* NOTREACHED */
403 	}
404 	/* Check that the data link layer is an Ethernet; this code won't work
405 	 * with anything else. */
406 	if (ioctl(fd, BIOCGDLT, (caddr_t) & dlt) < 0) {
407 		err(FATAL, "BIOCGDLT: %s", strerror(errno));
408 		/* NOTREACHED */
409 	}
410 	if (dlt != DLT_EN10MB) {
411 		if (aflag) {	/* for -a skip not ethernet interfaces */
412 			close(fd);
413 			return -1;
414 		}
415 		err(FATAL, "%s is not an ethernet", device);
416 		/* NOTREACHED */
417 	}
418 	/* Set filter program. */
419 	if (ioctl(fd, BIOCSETF, (caddr_t) & filter) < 0) {
420 		err(FATAL, "BIOCSETF: %s", strerror(errno));
421 		/* NOTREACHED */
422 	}
423 	return fd;
424 }
425 /*
426  * Perform various sanity checks on the RARP request packet.  Return
427  * false on failure and log the reason.
428  */
429 static int
430 rarp_check(p, len)
431 	u_char *p;
432 	int     len;
433 {
434 	struct ether_header *ep = (struct ether_header *) p;
435 	struct ether_arp *ap = (struct ether_arp *) (p + sizeof(*ep));
436 
437 	(void) debug("got a packet");
438 
439 	if (len < sizeof(*ep) + sizeof(*ap)) {
440 		err(NONFATAL, "truncated request");
441 		return 0;
442 	}
443 	/* XXX This test might be better off broken out... */
444 	if (ntohs (ep->ether_type) != ETHERTYPE_REVARP ||
445 	    ntohs (ap->arp_hrd) != ARPHRD_ETHER ||
446 	    ntohs (ap->arp_op) != ARPOP_REVREQUEST ||
447 	    ntohs (ap->arp_pro) != ETHERTYPE_IP ||
448 	    ap->arp_hln != 6 || ap->arp_pln != 4) {
449 		err(NONFATAL, "request fails sanity check");
450 		return 0;
451 	}
452 	if (memcmp((char *) &ep->ether_shost, (char *) &ap->arp_sha, 6) != 0) {
453 		err(NONFATAL, "ether/arp sender address mismatch");
454 		return 0;
455 	}
456 	if (memcmp((char *) &ap->arp_sha, (char *) &ap->arp_tha, 6) != 0) {
457 		err(NONFATAL, "ether/arp target address mismatch");
458 		return 0;
459 	}
460 	return 1;
461 }
462 
463 /*
464  * Loop indefinitely listening for RARP requests on the
465  * interfaces in 'iflist'.
466  */
467 void
468 rarp_loop()
469 {
470 	u_char *buf, *bp, *ep;
471 	int     cc, fd;
472 	fd_set  *fdsp, *lfdsp;
473 	int	fdsn;
474 	int     bufsize, maxfd = 0;
475 	struct if_info *ii;
476 
477 	if (iflist == 0) {
478 		err(FATAL, "no interfaces");
479 		/* NOTREACHED */
480 	}
481 	if (ioctl(iflist->ii_fd, BIOCGBLEN, (caddr_t) & bufsize) < 0) {
482 		err(FATAL, "BIOCGBLEN: %s", strerror(errno));
483 		/* NOTREACHED */
484 	}
485 	buf = (u_char *) malloc((unsigned) bufsize);
486 	if (buf == 0) {
487 		err(FATAL, "malloc: %s", strerror(errno));
488 		/* NOTREACHED */
489 	}
490 	/*
491          * Find the highest numbered file descriptor for select().
492          * Initialize the set of descriptors to listen to.
493          */
494 	for (ii = iflist; ii; ii = ii->ii_next)
495 		if (ii->ii_fd > maxfd)
496 			maxfd = ii->ii_fd;
497 
498 	fdsn = howmany(maxfd+1, NFDBITS) * sizeof(fd_mask);
499 	if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
500 		err(1, "malloc");
501 	if ((lfdsp = (fd_set *)malloc(fdsn)) == NULL)
502 		err(1, "malloc");
503 
504 	memset(fdsp, 0, fdsn);
505 	for (ii = iflist; ii; ii = ii->ii_next)
506 		FD_SET(ii->ii_fd, fdsp);
507 
508 	while (1) {
509 		memcpy(lfdsp, fdsp, fdsn);
510 		if (select(maxfd + 1, lfdsp, (fd_set *) 0,
511 			(fd_set *) 0, (struct timeval *) 0) < 0) {
512 			err(FATAL, "select: %s", strerror(errno));
513 			/* NOTREACHED */
514 		}
515 		for (ii = iflist; ii; ii = ii->ii_next) {
516 			fd = ii->ii_fd;
517 			if (!FD_ISSET(fd, lfdsp))
518 				continue;
519 		again:
520 			cc = read(fd, (char *) buf, bufsize);
521 			/* Don't choke when we get ptraced */
522 			if (cc < 0 && errno == EINTR)
523 				goto again;
524 			/* Due to a SunOS bug, after 2^31 bytes, the file
525 			 * offset overflows and read fails with EINVAL.  The
526 			 * lseek() to 0 will fix things. */
527 			if (cc < 0) {
528 				if (errno == EINVAL &&
529 				    (lseek(fd, 0, SEEK_CUR) + bufsize) < 0) {
530 					(void) lseek(fd, 0, 0);
531 					goto again;
532 				}
533 				err(FATAL, "read: %s", strerror(errno));
534 				/* NOTREACHED */
535 			}
536 			/* Loop through the packet(s) */
537 #define bhp ((struct bpf_hdr *)bp)
538 			bp = buf;
539 			ep = bp + cc;
540 			while (bp < ep) {
541 				register int caplen, hdrlen;
542 
543 				caplen = bhp->bh_caplen;
544 				hdrlen = bhp->bh_hdrlen;
545 				if (rarp_check(bp + hdrlen, caplen))
546 					rarp_process(ii, bp + hdrlen);
547 				bp += BPF_WORDALIGN(hdrlen + caplen);
548 			}
549 		}
550 	}
551 	free(fdsp);
552 	free(lfdsp);
553 }
554 
555 #ifdef REQUIRE_TFTPBOOT
556 
557 #ifndef TFTP_DIR
558 #define TFTP_DIR "/tftpboot"
559 #endif
560 
561 /*
562  * True if this server can boot the host whose IP address is 'addr'.
563  * This check is made by looking in the tftp directory for the
564  * configuration file.
565  */
566 int
567 rarp_bootable(addr)
568 	u_int32_t  addr;
569 {
570 	register struct dirent *dent;
571 	register DIR *d;
572 	char    ipname[40];
573 	static DIR *dd = 0;
574 
575 	(void) snprintf(ipname, sizeof ipname, "%08X", addr);
576 	/* If directory is already open, rewind it.  Otherwise, open it. */
577 	if (d = dd)
578 		rewinddir(d);
579 	else {
580 		if (chdir(TFTP_DIR) == -1) {
581 			err(FATAL, "chdir: %s", strerror(errno));
582 			/* NOTREACHED */
583 		}
584 		d = opendir(".");
585 		if (d == 0) {
586 			err(FATAL, "opendir: %s", strerror(errno));
587 			/* NOTREACHED */
588 		}
589 		dd = d;
590 	}
591 	while (dent = readdir(d))
592 		if (strncmp(dent->d_name, ipname, 8) == 0)
593 			return 1;
594 	return 0;
595 }
596 #endif /* REQUIRE_TFTPBOOT */
597 
598 /*
599  * Given a list of IP addresses, 'alist', return the first address that
600  * is on network 'net'; 'netmask' is a mask indicating the network portion
601  * of the address.
602  */
603 u_int32_t
604 choose_ipaddr(alist, net, netmask)
605 	u_int32_t **alist;
606 	u_int32_t  net;
607 	u_int32_t  netmask;
608 {
609 	for (; *alist; ++alist) {
610 		if ((**alist & netmask) == net)
611 			return **alist;
612 	}
613 	return 0;
614 }
615 /*
616  * Answer the RARP request in 'pkt', on the interface 'ii'.  'pkt' has
617  * already been checked for validity.  The reply is overlaid on the request.
618  */
619 void
620 rarp_process(ii, pkt)
621 	struct if_info *ii;
622 	u_char *pkt;
623 {
624 	struct ether_header *ep;
625 	struct ether_addr *ea;
626 	struct hostent *hp;
627 	u_int32_t  target_ipaddr;
628 	char    ename[MAXHOSTNAMELEN];
629 	struct	in_addr in;
630 	struct if_addr *ia;
631 
632 	ep = (struct ether_header *) pkt;
633 	ea = (struct ether_addr *) &ep->ether_shost;
634 
635 	debug(ether_ntoa(ea));
636 	if (ether_ntohost(ename, ea) != 0) {
637 		debug("ether_ntohost failed");
638 		return;
639 	}
640 	if ((hp = gethostbyname(ename)) == 0) {
641 		debug("gethostbyname (%s) failed", ename);
642 		return;
643 	}
644 
645 	/* Choose correct address from list. */
646 	if (hp->h_addrtype != AF_INET) {
647 		err(FATAL, "cannot handle non IP addresses");
648 		/* NOTREACHED */
649 	}
650 	for (target_ipaddr = 0, ia = ii->ii_addrs; ia; ia = ia->ia_next) {
651 		target_ipaddr = choose_ipaddr((u_int32_t **) hp->h_addr_list,
652 		    ia->ia_ipaddr & ia->ia_netmask, ia->ia_netmask);
653 		if (target_ipaddr)
654 			break;
655 	}
656 
657 	if (target_ipaddr == 0) {
658 		for (ia = ii->ii_addrs; ia; ia = ia->ia_next) {
659 			in.s_addr = ia->ia_ipaddr & ia->ia_netmask;
660 			err(NONFATAL, "cannot find %s on net %s",
661 			    ename, inet_ntoa(in));
662 		}
663 		return;
664 	}
665 #ifdef REQUIRE_TFTPBOOT
666 	if (rarp_bootable(htonl(target_ipaddr)))
667 #endif
668 		rarp_reply(ii, ia, ep, target_ipaddr, hp);
669 	debug("reply sent");
670 }
671 
672 /*
673  * Lookup the ethernet address of the interface attached to the BPF
674  * file descriptor 'fd'; return it in 'eaddr'.
675  */
676 void
677 lookup_addrs(ifname, p)
678 	char *ifname;
679 	struct if_info *p;
680 {
681 #ifdef HAVE_IFADDRS_H
682 	struct ifaddrs *ifap, *ifa;
683 	struct sockaddr_dl *sdl;
684 	u_char *eaddr = p->ii_eaddr;
685 	struct if_addr *ia, **iap = &p->ii_addrs;
686 	int found = 0;
687 	struct in_addr in;
688 
689 	if (getifaddrs(&ifap) != 0) {
690 		err(FATAL, "getifaddrs: %s", strerror(errno));
691 		/* NOTREACHED */
692 	}
693 
694 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
695 		if (strcmp(ifa->ifa_name, ifname))
696 			continue;
697 		sdl = (struct sockaddr_dl *) ifa->ifa_addr;
698 		if (sdl->sdl_family == AF_LINK &&
699 		    sdl->sdl_type == IFT_ETHER && sdl->sdl_alen == 6) {
700 			memcpy((caddr_t)eaddr, (caddr_t)LLADDR(sdl),
701 			    6);
702 			if (dflag)
703 				fprintf(stderr,
704 				    "%s: %x:%x:%x:%x:%x:%x\n",
705 				    ifa->ifa_name,
706 				    eaddr[0], eaddr[1], eaddr[2],
707 				    eaddr[3], eaddr[4], eaddr[5]);
708 			found = 1;
709 		} else if (sdl->sdl_family == AF_INET) {
710 			ia = malloc (sizeof (struct if_addr));
711 			if (ia == NULL)
712 				err(FATAL, "lookup_addrs: malloc: %s",
713 				    strerror(errno));
714 			ia->ia_next = NULL;
715 			ia->ia_ipaddr =
716 			    ((struct sockaddr_in *) ifa->ifa_addr)->
717 			    sin_addr.s_addr;
718 			ia->ia_netmask =
719 			    ((struct sockaddr_in *) ifa->ifa_netmask)->
720 			    sin_addr.s_addr;
721 			/* If SIOCGIFNETMASK didn't work,
722 			   figure out a mask from the IP
723 			   address class. */
724 			if (ia->ia_netmask == 0)
725 				ia->ia_netmask =
726 				    ipaddrtonetmask(ia->ia_ipaddr);
727 			if (dflag) {
728 				in.s_addr = ia->ia_ipaddr;
729 				fprintf(stderr, "\t%s\n",
730 				    inet_ntoa(in));
731 			}
732 			*iap = ia;
733 			iap = &ia->ia_next;
734 		}
735 	}
736 	freeifaddrs(ifap);
737 	if (!found)
738 		err(FATAL, "lookup_addrs: Never saw interface `%s'!", ifname);
739 #else
740 	u_char *eaddr = p->ii_eaddr;
741 	struct if_addr *ia, **iap = &p->ii_addrs;
742 	char *inbuf = NULL, *ninbuf;
743 	struct ifconf ifc;
744 	struct ifreq *ifr, ifr_mask;
745 	struct in_addr in;
746 	struct sockaddr_dl *sdl;
747 	int fd;
748 	int i, len, inlen = 8192, found = 0;
749 
750 	/* We cannot use SIOCGIFADDR on the BPF descriptor.
751 	   We must instead get all the interfaces with SIOCGIFCONF
752 	   and find the right one.  */
753 
754 	/* Use datagram socket to get Ethernet address. */
755 	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
756 		err(FATAL, "socket: %s", strerror(errno));
757 		/* NOTREACHED */
758 	}
759 
760 	while (1) {
761 		ifc.ifc_len = inlen;
762 		ninbuf= realloc(inbuf, inlen);
763 		if (ninbuf == NULL) {
764 			if (inbuf)
765 				free(inbuf);
766 			close(fd);
767 			err(FATAL, "lookup_addrs: malloc: %s",
768 			    strerror(errno));
769 		}
770 		ifc.ifc_buf = inbuf = ninbuf;
771 		if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0) {
772 			(void) close(fd);
773 			free(inbuf);
774 			err(FATAL, "lookup_addrs: SIOCGIFCONF: %s",
775 			    strerror(errno));
776 			/* NOTREACHED */
777 		}
778 		if (ifc.ifc_len + sizeof(*ifr) < inlen)
779 			break;
780 		inlen *= 2;
781 	}
782 
783 	ifr = ifc.ifc_req;
784 	for (i = 0; i < ifc.ifc_len;
785 	     i += len, ifr = (struct ifreq *)((caddr_t)ifr + len)) {
786 		len = sizeof(ifr->ifr_name) +
787 		      (ifr->ifr_addr.sa_len > sizeof(struct sockaddr) ?
788 		       ifr->ifr_addr.sa_len : sizeof(struct sockaddr));
789 		if (!strncmp(ifr->ifr_name, ifname, sizeof(ifr->ifr_name))) {
790 			sdl = (struct sockaddr_dl *) & ifr->ifr_addr;
791 			if (sdl->sdl_family == AF_LINK &&
792 			    sdl->sdl_type == IFT_ETHER && sdl->sdl_alen == 6) {
793 				memcpy((caddr_t)eaddr, (caddr_t)LLADDR(sdl),
794 				    6);
795 				if (dflag)
796 					fprintf(stderr,
797 					    "%s: %x:%x:%x:%x:%x:%x\n",
798 					    ifr->ifr_name,
799 					    eaddr[0], eaddr[1], eaddr[2],
800 					    eaddr[3], eaddr[4], eaddr[5]);
801 				found = 1;
802 			} else if (sdl->sdl_family == AF_INET) {
803 				ia = malloc (sizeof (struct if_addr));
804 				if (ia == NULL)
805 					err(FATAL, "lookup_addrs: malloc: %s",
806 					    strerror(errno));
807 				ia->ia_next = NULL;
808 				ia->ia_ipaddr =
809 				    ((struct sockaddr_in *) sdl)->
810 				    sin_addr.s_addr;
811 				memcpy(&ifr_mask, ifr, sizeof(*ifr));
812 				if (ioctl(fd, SIOCGIFNETMASK,
813 				    (char *) &ifr_mask) < 0)
814 					err(FATAL, "SIOCGIFNETMASK: %s",
815 					    strerror(errno));
816 				ia->ia_netmask =
817 				    ((struct sockaddr_in *)
818 				    & ifr_mask.ifr_addr)->sin_addr.s_addr;
819 				/* If SIOCGIFNETMASK didn't work,
820 				   figure out a mask from the IP
821 				   address class. */
822 				if (ia->ia_netmask == 0)
823 					ia->ia_netmask =
824 					    ipaddrtonetmask(ia->ia_ipaddr);
825 				if (dflag) {
826 					in.s_addr = ia->ia_ipaddr;
827 					fprintf(stderr, "\t%s\n",
828 					    inet_ntoa(in));
829 				}
830 				*iap = ia;
831 				iap = &ia->ia_next;
832 			}
833 		}
834 	}
835 
836 	free(inbuf);
837 	if (!found)
838 		err(FATAL, "lookup_addrs: Never saw interface `%s'!", ifname);
839 #endif
840 }
841 
842 int arptab_set __P((u_char *eaddr, u_int32_t host));
843 
844 /*
845  * Poke the kernel arp tables with the ethernet/ip address combinataion
846  * given.  When processing a reply, we must do this so that the booting
847  * host (i.e. the guy running rarpd), won't try to ARP for the hardware
848  * address of the guy being booted (he cannot answer the ARP).
849  */
850 void
851 update_arptab(ep, ipaddr)
852 	u_char *ep;
853 	u_int32_t  ipaddr;
854 {
855 #ifdef SIOCSARP
856 	int     s;
857 	struct arpreq request;
858 	struct sockaddr_in *sin;
859 
860 	u_char *eaddr;
861 	u_int32_t host;
862 
863 	request.arp_flags = 0;
864 	sin = (struct sockaddr_in *) & request.arp_pa;
865 	sin->sin_family = AF_INET;
866 	sin->sin_addr.s_addr = ipaddr;
867 	request.arp_ha.sa_family = AF_UNSPEC;
868 	/* This is needed #if defined(COMPAT_43) && BYTE_ORDER != BIG_ENDIAN,
869 	   because AF_UNSPEC is zero and the kernel assumes that a zero
870 	   sa_family means that the real sa_family value is in sa_len.  */
871 	request.arp_ha.sa_len = 16; /* XXX */
872 	memcpy((char *) request.arp_ha.sa_data, (char *) ep, 6);
873 
874 	s = socket(AF_INET, SOCK_DGRAM, 0);
875 	if (s < 0) {
876 		err(NONFATAL, "socket: %s", strerror(errno));
877 	} else {
878 		if (ioctl(s, SIOCSARP, (caddr_t) & request) < 0) {
879 		    err(NONFATAL, "SIOCSARP: %s", strerror(errno));
880 		}
881 		(void) close(s);
882 	}
883 #else
884 	if (arptab_set(ep, ipaddr) > 0)
885 		syslog(LOG_ERR, "couldn't update arp table");
886 #endif
887 }
888 /*
889  * Build a reverse ARP packet and sent it out on the interface.
890  * 'ep' points to a valid ARPOP_REVREQUEST.  The ARPOP_REVREPLY is built
891  * on top of the request, then written to the network.
892  *
893  * RFC 903 defines the ether_arp fields as follows.  The following comments
894  * are taken (more or less) straight from this document.
895  *
896  * ARPOP_REVREQUEST
897  *
898  * arp_sha is the hardware address of the sender of the packet.
899  * arp_spa is undefined.
900  * arp_tha is the 'target' hardware address.
901  *   In the case where the sender wishes to determine his own
902  *   protocol address, this, like arp_sha, will be the hardware
903  *   address of the sender.
904  * arp_tpa is undefined.
905  *
906  * ARPOP_REVREPLY
907  *
908  * arp_sha is the hardware address of the responder (the sender of the
909  *   reply packet).
910  * arp_spa is the protocol address of the responder (see the note below).
911  * arp_tha is the hardware address of the target, and should be the same as
912  *   that which was given in the request.
913  * arp_tpa is the protocol address of the target, that is, the desired address.
914  *
915  * Note that the requirement that arp_spa be filled in with the responder's
916  * protocol is purely for convenience.  For instance, if a system were to use
917  * both ARP and RARP, then the inclusion of the valid protocol-hardware
918  * address pair (arp_spa, arp_sha) may eliminate the need for a subsequent
919  * ARP request.
920  */
921 void
922 rarp_reply(ii, ia, ep, ipaddr, hp)
923 	struct if_info *ii;
924 	struct if_addr *ia;
925 	struct ether_header *ep;
926 	u_int32_t  ipaddr;
927 	struct hostent *hp;
928 {
929 	int     n;
930 	struct ether_arp *ap = (struct ether_arp *) (ep + 1);
931 	int     len;
932 
933 	update_arptab((u_char *) & ap->arp_sha, ipaddr);
934 
935 	/* Build the rarp reply by modifying the rarp request in place. */
936 	ep->ether_type = htons(ETHERTYPE_REVARP);
937 	ap->ea_hdr.ar_hrd = htons(ARPHRD_ETHER);
938 	ap->ea_hdr.ar_pro = htons(ETHERTYPE_IP);
939 	ap->arp_op = htons(ARPOP_REVREPLY);
940 
941 	memcpy((char *) &ep->ether_dhost, (char *) &ap->arp_sha, 6);
942 	memcpy((char *) &ep->ether_shost, (char *) ii->ii_eaddr, 6);
943 	memcpy((char *) &ap->arp_sha, (char *) ii->ii_eaddr, 6);
944 
945 	memcpy((char *) ap->arp_tpa, (char *) &ipaddr, 4);
946 	/* Target hardware is unchanged. */
947 	memcpy((char *) ap->arp_spa, (char *) &ia->ia_ipaddr, 4);
948 
949 	if (lflag) {
950 		struct ether_addr ea;
951 
952 		memcpy(&ea.ether_addr_octet, &ap->arp_sha, 6);
953 		syslog(LOG_INFO, "%s asked; %s replied", hp->h_name,
954 		    ether_ntoa(&ea));
955 	}
956 
957 	len = sizeof(*ep) + sizeof(*ap);
958 	n = write(ii->ii_fd, (char *) ep, len);
959 	if (n != len) {
960 		err(NONFATAL, "write: only %d of %d bytes written", n, len);
961 	}
962 }
963 /*
964  * Get the netmask of an IP address.  This routine is used if
965  * SIOCGIFNETMASK doesn't work.
966  */
967 u_int32_t
968 ipaddrtonetmask(addr)
969 	u_int32_t  addr;
970 {
971 	if (IN_CLASSA(addr))
972 		return IN_CLASSA_NET;
973 	if (IN_CLASSB(addr))
974 		return IN_CLASSB_NET;
975 	if (IN_CLASSC(addr))
976 		return IN_CLASSC_NET;
977 	err(FATAL, "unknown IP address class: %08X", addr);
978 	/* NOTREACHED */
979 }
980 
981 #ifdef __STDC__
982 #include <stdarg.h>
983 #else
984 #include <varargs.h>
985 #endif
986 
987 void
988 #ifdef __STDC__
989 err(int fatal, const char *fmt,...)
990 #else
991 err(fmt, va_alist)
992 	int     fatal;
993 	char   *fmt;
994 va_dcl
995 #endif
996 {
997 	va_list ap;
998 	if (dflag) {
999 		if (fatal)
1000 			(void) fprintf(stderr, "rarpd: error: ");
1001 		else
1002 			(void) fprintf(stderr, "rarpd: warning: ");
1003 #ifdef __STDC__
1004 		va_start(ap, fmt);
1005 #else
1006 		va_start(ap);
1007 #endif
1008 		(void) vfprintf(stderr, fmt, ap);
1009 		va_end(ap);
1010 		(void) fprintf(stderr, "\n");
1011 	}
1012 #ifdef __STDC__
1013 	va_start(ap, fmt);
1014 #else
1015 	va_start(ap);
1016 #endif
1017 	vsyslog(LOG_ERR, fmt, ap);
1018 	va_end(ap);
1019 	if (fatal) {
1020 		unlink(_PATH_RARPDPID);
1021 		exit(1);
1022 	}
1023 	/* NOTREACHED */
1024 }
1025 
1026 void
1027 #ifdef __STDC__
1028 debug(const char *fmt,...)
1029 #else
1030 debug(fmt, va_alist)
1031 	char   *fmt;
1032 va_dcl
1033 #endif
1034 {
1035 	va_list ap;
1036 
1037 	if (dflag) {
1038 #ifdef __STDC__
1039 		va_start(ap, fmt);
1040 #else
1041 		va_start(ap);
1042 #endif
1043 		(void) fprintf(stderr, "rarpd: ");
1044 		(void) vfprintf(stderr, fmt, ap);
1045 		va_end(ap);
1046 		(void) fprintf(stderr, "\n");
1047 	}
1048 }
1049