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