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