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