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