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