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