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