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