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