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