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