1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 26 /* All Rights Reserved */ 27 28 /* 29 * Portions of this source code were derived from Berkeley 4.3 BSD 30 * under license from the Regents of the University of California. 31 */ 32 33 #pragma ident "%Z%%M% %I% %E% SMI" 34 35 /* 36 * rarpd.c Reverse-ARP server. 37 * Refer to RFC 903 "A Reverse Address Resolution Protocol". 38 */ 39 40 #define _REENTRANT 41 42 #include <thread.h> 43 #include <synch.h> 44 #include <stdlib.h> 45 #include <unistd.h> 46 #include <sys/resource.h> 47 #include <stdio.h> 48 #include <stdio_ext.h> 49 #include <stdarg.h> 50 #include <string.h> 51 #include <fcntl.h> 52 #include <sys/types.h> 53 #include <dirent.h> 54 #include <syslog.h> 55 #include <netdb.h> 56 #include <errno.h> 57 #include <sys/socket.h> 58 #include <sys/sockio.h> 59 #include <net/if.h> 60 #include <netinet/if_ether.h> 61 #include <netinet/in.h> 62 #include <arpa/inet.h> 63 #include <stropts.h> 64 #include <libinetutil.h> 65 #include <libdlpi.h> 66 #include <net/if_types.h> 67 #include <net/if_dl.h> 68 69 #define BOOTDIR "/tftpboot" /* boot files directory */ 70 #define DEVIP "/dev/ip" /* path to ip driver */ 71 #define DEVARP "/dev/arp" /* path to arp driver */ 72 73 #define BUFSIZE 2048 /* max receive frame length */ 74 #define MAXPATHL 128 /* max path length */ 75 #define MAXHOSTL 128 /* max host name length */ 76 #define MAXIFS 256 77 78 /* 79 * Logical network devices 80 */ 81 struct ifdev { 82 char ldevice[IFNAMSIZ]; 83 int lunit; 84 ipaddr_t ipaddr; /* network order */ 85 ipaddr_t if_netmask; /* host order */ 86 ipaddr_t if_ipaddr; /* host order */ 87 ipaddr_t if_netnum; /* host order, with subnet */ 88 struct ifdev *next; 89 }; 90 91 /* 92 * Physical network device 93 */ 94 struct rarpdev { 95 char device[DLPI_LINKNAME_MAX]; 96 uint_t unit; 97 dlpi_handle_t dh_rarp; 98 uchar_t physaddr[DLPI_PHYSADDR_MAX]; 99 /* mac address of interface */ 100 uint_t physaddrlen; /* mac address length */ 101 int ifrarplen; /* size of rarp data packet */ 102 struct ifdev *ifdev; /* private interface info */ 103 struct rarpdev *next; /* list of managed devices */ 104 }; 105 106 struct rarpreply { 107 struct rarpdev *rdev; /* which device reply for */ 108 struct timeval tv; /* send RARP reply by when */ 109 uchar_t *lldest; /* target mac to send reply */ 110 uchar_t *arprep; /* [R]ARP response */ 111 struct rarpreply *next; 112 }; 113 114 static struct rarpreply *delay_list; 115 static sema_t delay_sema; 116 static mutex_t delay_mutex; 117 static mutex_t debug_mutex; 118 119 static struct rarpdev *rarpdev_head; 120 121 /* 122 * Globals initialized before multi-threading 123 */ 124 static char *cmdname; /* command name from argv[0] */ 125 static int dflag = 0; /* enable diagnostics */ 126 static int aflag = 0; /* start rarpd on all interfaces */ 127 128 static void getintf(void); 129 static struct rarpdev *find_device(ifspec_t *); 130 static void init_rarpdev(struct rarpdev *); 131 static void do_rarp(void *); 132 static void rarp_request(struct rarpdev *, struct arphdr *, 133 uchar_t *); 134 static void add_arp(struct rarpdev *, uchar_t *, uchar_t *); 135 static void arp_request(struct rarpdev *, struct arphdr *, uchar_t *); 136 static void do_delay_write(void *); 137 static void delay_write(struct rarpdev *, struct rarpreply *); 138 static int mightboot(ipaddr_t); 139 static void get_ifdata(char *, int, ipaddr_t *, ipaddr_t *); 140 static int get_ipaddr(struct rarpdev *, uchar_t *, uchar_t *, ipaddr_t *); 141 static int strioctl(int, int, int, int, char *); 142 static void usage(); 143 static void syserr(const char *); 144 /*PRINTFLIKE1*/ 145 static void error(const char *, ...); 146 static void debug(char *, ...); 147 148 extern int optind; 149 extern char *optarg; 150 151 int 152 main(int argc, char *argv[]) 153 { 154 int c; 155 struct rlimit rl; 156 struct rarpdev *rdev; 157 int i; 158 159 cmdname = argv[0]; 160 161 while ((c = getopt(argc, argv, "ad")) != -1) { 162 switch (c) { 163 case 'a': 164 aflag = 1; 165 break; 166 167 case 'd': 168 dflag = 1; 169 break; 170 171 default: 172 usage(); 173 } 174 } 175 176 if ((!aflag && (argc - optind) != 2) || 177 (aflag && (argc - optind) != 0)) { 178 usage(); 179 /* NOTREACHED */ 180 } 181 182 if (!dflag) { 183 /* 184 * Background 185 */ 186 switch (fork()) { 187 case -1: /* error */ 188 syserr("fork"); 189 /*NOTREACHED*/ 190 191 case 0: /* child */ 192 break; 193 194 default: /* parent */ 195 return (0); 196 } 197 for (i = 0; i < 3; i++) { 198 (void) close(i); 199 } 200 (void) open("/", O_RDONLY, 0); 201 (void) dup2(0, 1); 202 (void) dup2(0, 2); 203 /* 204 * Detach terminal 205 */ 206 if (setsid() < 0) 207 syserr("setsid"); 208 } 209 210 rl.rlim_cur = RLIM_INFINITY; 211 rl.rlim_max = RLIM_INFINITY; 212 if (setrlimit(RLIMIT_NOFILE, &rl) == -1) 213 syserr("setrlimit"); 214 (void) enable_extended_FILE_stdio(-1, -1); 215 216 (void) openlog(cmdname, LOG_PID, LOG_DAEMON); 217 218 if (aflag) { 219 /* 220 * Get each interface name and load rarpdev list. 221 */ 222 getintf(); 223 } else { 224 ifspec_t ifsp; 225 struct ifdev *ifdev; 226 char buf[IFNAMSIZ + 1]; 227 228 /* 229 * Load specified device as only element of the list. 230 */ 231 rarpdev_head = (struct rarpdev *)calloc(1, 232 sizeof (struct rarpdev)); 233 if (rarpdev_head == NULL) { 234 error("out of memory"); 235 } 236 (void) strncpy(buf, argv[optind], IFNAMSIZ); 237 (void) strncat(buf, argv[optind + 1], IFNAMSIZ - strlen(buf)); 238 239 if ((ifdev = calloc(1, sizeof (struct ifdev))) == NULL) { 240 error("out of memory"); 241 } 242 243 if (!ifparse_ifspec(buf, &ifsp) || ifsp.ifsp_modcnt != 0) { 244 error("invalid interface specification"); 245 } 246 247 if (ifsp.ifsp_lunvalid) { 248 (void) snprintf(ifdev->ldevice, 249 sizeof (ifdev->ldevice), "%s%d:", 250 ifsp.ifsp_devnm, ifsp.ifsp_ppa); 251 ifdev->lunit = ifsp.ifsp_lun; 252 } else { 253 ifdev->lunit = -1; /* no logical unit */ 254 } 255 (void) strlcpy(rarpdev_head->device, ifsp.ifsp_devnm, 256 sizeof (rarpdev_head->device)); 257 rarpdev_head->unit = ifsp.ifsp_ppa; 258 259 ifdev->next = rarpdev_head->ifdev; 260 rarpdev_head->ifdev = ifdev; 261 } 262 263 /* 264 * Initialize each rarpdev. 265 */ 266 for (rdev = rarpdev_head; rdev != NULL; rdev = rdev->next) { 267 init_rarpdev(rdev); 268 } 269 270 (void) sema_init(&delay_sema, 0, USYNC_THREAD, NULL); 271 (void) mutex_init(&delay_mutex, USYNC_THREAD, NULL); 272 (void) mutex_init(&debug_mutex, USYNC_THREAD, NULL); 273 274 /* 275 * Start delayed processing thread. 276 */ 277 (void) thr_create(NULL, NULL, (void *(*)(void *))do_delay_write, NULL, 278 THR_NEW_LWP, NULL); 279 280 /* 281 * Start RARP processing for each device. 282 */ 283 for (rdev = rarpdev_head; rdev != NULL; rdev = rdev->next) { 284 if (rdev->dh_rarp != NULL) { 285 (void) thr_create(NULL, NULL, 286 (void *(*)(void *))do_rarp, (void *)rdev, 287 THR_NEW_LWP, NULL); 288 } 289 } 290 291 /* 292 * Exit main() thread 293 */ 294 thr_exit(NULL); 295 296 return (0); 297 } 298 299 static void 300 getintf(void) 301 { 302 int fd; 303 int numifs; 304 unsigned bufsize; 305 struct ifreq *reqbuf; 306 struct ifconf ifconf; 307 struct ifreq *ifr; 308 struct rarpdev *rdev; 309 struct ifdev *ifdev; 310 311 /* 312 * Open the IP provider. 313 */ 314 if ((fd = open(DEVIP, 0)) < 0) 315 syserr(DEVIP); 316 317 /* 318 * Ask IP for the list of configured interfaces. 319 */ 320 if (ioctl(fd, SIOCGIFNUM, (char *)&numifs) < 0) { 321 numifs = MAXIFS; 322 } 323 bufsize = numifs * sizeof (struct ifreq); 324 reqbuf = (struct ifreq *)malloc(bufsize); 325 if (reqbuf == NULL) { 326 error("out of memory"); 327 } 328 329 ifconf.ifc_len = bufsize; 330 ifconf.ifc_buf = (caddr_t)reqbuf; 331 if (ioctl(fd, SIOCGIFCONF, (char *)&ifconf) < 0) 332 syserr("SIOCGIFCONF"); 333 334 /* 335 * Initialize a rarpdev for each interface. 336 */ 337 for (ifr = ifconf.ifc_req; ifconf.ifc_len > 0; 338 ifr++, ifconf.ifc_len -= sizeof (struct ifreq)) { 339 ifspec_t ifsp; 340 341 if (ioctl(fd, SIOCGIFFLAGS, (char *)ifr) < 0) { 342 syserr("ioctl SIOCGIFFLAGS"); 343 exit(1); 344 } 345 if ((ifr->ifr_flags & IFF_LOOPBACK) || 346 !(ifr->ifr_flags & IFF_UP) || 347 !(ifr->ifr_flags & IFF_BROADCAST) || 348 (ifr->ifr_flags & IFF_NOARP) || 349 (ifr->ifr_flags & IFF_POINTOPOINT)) 350 continue; 351 352 if (!ifparse_ifspec(ifr->ifr_name, &ifsp)) 353 error("ifparse_ifspec failed"); 354 355 /* 356 * Look for an existing device for logical interfaces. 357 */ 358 if ((rdev = find_device(&ifsp)) == NULL) { 359 rdev = calloc(1, sizeof (struct rarpdev)); 360 if (rdev == NULL) 361 error("out of memory"); 362 363 (void) strlcpy(rdev->device, ifsp.ifsp_devnm, 364 sizeof (rdev->device)); 365 rdev->unit = ifsp.ifsp_ppa; 366 367 rdev->next = rarpdev_head; 368 rarpdev_head = rdev; 369 } 370 371 if ((ifdev = calloc(1, sizeof (struct ifdev))) == NULL) 372 error("out of memory"); 373 374 if (ifsp.ifsp_lunvalid) { 375 (void) snprintf(ifdev->ldevice, 376 sizeof (ifdev->ldevice), "%s%d:", 377 ifsp.ifsp_devnm, ifsp.ifsp_ppa); 378 ifdev->lunit = ifsp.ifsp_lun; 379 } else 380 ifdev->lunit = -1; /* no logical unit */ 381 382 ifdev->next = rdev->ifdev; 383 rdev->ifdev = ifdev; 384 } 385 (void) free((char *)reqbuf); 386 } 387 388 static struct rarpdev * 389 find_device(ifspec_t *specp) 390 { 391 struct rarpdev *rdev; 392 393 for (rdev = rarpdev_head; rdev != NULL; rdev = rdev->next) { 394 if (specp->ifsp_ppa == rdev->unit && 395 strcmp(specp->ifsp_devnm, rdev->device) == 0) 396 return (rdev); 397 } 398 return (NULL); 399 } 400 401 static void 402 init_rarpdev(struct rarpdev *rdev) 403 { 404 char *dev; 405 int unit; 406 struct ifdev *ifdev; 407 int retval; 408 char *str = NULL; 409 uint_t physaddrlen = DLPI_PHYSADDR_MAX; 410 char linkname[DLPI_LINKNAME_MAX]; 411 dlpi_handle_t dh; 412 413 (void) snprintf(linkname, DLPI_LINKNAME_MAX, "%s%d", rdev->device, 414 rdev->unit); 415 /* 416 * Open datalink provider and get our mac address. 417 */ 418 if ((retval = dlpi_open(linkname, &dh, 0)) != DLPI_SUCCESS) { 419 error("cannot open link %s: %s", linkname, 420 dlpi_strerror(retval)); 421 } 422 423 if ((retval = dlpi_bind(dh, ETHERTYPE_REVARP, NULL)) != DLPI_SUCCESS) { 424 dlpi_close(dh); 425 error("dlpi_bind failed: %s", dlpi_strerror(retval)); 426 } 427 428 /* 429 * Save our mac address. 430 */ 431 if ((retval = dlpi_get_physaddr(dh, DL_CURR_PHYS_ADDR, rdev->physaddr, 432 &physaddrlen)) != DLPI_SUCCESS) { 433 dlpi_close(dh); 434 error("dlpi_get_physaddr failed: %s", dlpi_strerror(retval)); 435 } 436 437 rdev->physaddrlen = physaddrlen; 438 rdev->ifrarplen = sizeof (struct arphdr) + (2 * sizeof (ipaddr_t)) + 439 (2 * physaddrlen); 440 441 if (dflag) { 442 str = _link_ntoa(rdev->physaddr, str, 443 rdev->physaddrlen, IFT_OTHER); 444 if (str != NULL) { 445 debug("device %s physical address %s", linkname, str); 446 free(str); 447 } 448 } 449 450 /* 451 * Assign dlpi handle to rdev. 452 */ 453 rdev->dh_rarp = dh; 454 455 /* 456 * Get the IP address and netmask from directory service for 457 * each logical interface. 458 */ 459 for (ifdev = rdev->ifdev; ifdev != NULL; ifdev = ifdev->next) { 460 /* 461 * If lunit == -1 then this is the primary interface name. 462 */ 463 if (ifdev->lunit == -1) { 464 dev = rdev->device; 465 unit = rdev->unit; 466 } else { 467 dev = ifdev->ldevice; 468 unit = ifdev->lunit; 469 } 470 get_ifdata(dev, unit, &ifdev->if_ipaddr, &ifdev->if_netmask); 471 472 /* 473 * Use IP address of the interface. 474 */ 475 ifdev->if_netnum = ifdev->if_ipaddr & ifdev->if_netmask; 476 ifdev->ipaddr = (ipaddr_t)htonl(ifdev->if_ipaddr); 477 } 478 } 479 480 static void 481 do_rarp(void *buf) 482 { 483 struct rarpdev *rdev = buf; 484 char *cause; 485 struct arphdr *ans; 486 uchar_t *shost; 487 uint_t saddrlen; 488 size_t anslen = rdev->ifrarplen; 489 char *str = NULL; 490 int retval; 491 492 if (((shost = malloc(rdev->physaddrlen)) == NULL) || 493 ((ans = malloc(rdev->ifrarplen)) == NULL)) 494 syserr("malloc"); 495 496 if (dflag) { 497 str = _link_ntoa(rdev->physaddr, str, rdev->physaddrlen, 498 IFT_OTHER); 499 if (str != NULL) { 500 debug("starting rarp service on device %s%d physical" 501 " address %s", rdev->device, rdev->unit, str); 502 free(str); 503 } 504 } 505 506 /* 507 * Read RARP packets and respond to them. 508 */ 509 for (;;) { 510 saddrlen = DLPI_PHYSADDR_MAX; 511 retval = dlpi_recv(rdev->dh_rarp, shost, 512 &saddrlen, ans, &anslen, -1, NULL); 513 if (retval == DLPI_ETIMEDOUT) { 514 continue; 515 } else if (retval != DLPI_SUCCESS) { 516 error("error in dlpi_recv %s: %s", rdev->dh_rarp, 517 dlpi_strerror(retval)); 518 } 519 520 cause = NULL; 521 522 if (anslen < rdev->ifrarplen) 523 cause = "short packet"; 524 else if (ans->ar_hrd != htons(ARPHRD_ETHER)) 525 cause = "hardware type not Ethernet"; 526 else if (ans->ar_pro != htons(ETHERTYPE_IP)) 527 cause = "protocol type not IP"; 528 else if (ans->ar_hln != rdev->physaddrlen) 529 cause = "unexpected hardware address length"; 530 else if (ans->ar_pln != sizeof (ipaddr_t)) 531 cause = "unexpected protocol address length"; 532 if (cause != NULL) { 533 if (dflag) 534 debug("RARP packet received but " 535 "discarded: %s", cause); 536 continue; 537 } 538 539 /* 540 * Handle the request. 541 */ 542 switch (ntohs(ans->ar_op)) { 543 case REVARP_REQUEST: 544 rarp_request(rdev, ans, shost); 545 break; 546 547 case ARPOP_REQUEST: 548 arp_request(rdev, ans, shost); 549 break; 550 551 case REVARP_REPLY: 552 if (dflag) 553 debug("REVARP_REPLY ignored"); 554 break; 555 556 case ARPOP_REPLY: 557 if (dflag) 558 debug("ARPOP_REPLY ignored"); 559 break; 560 561 default: 562 if (dflag) 563 debug("unknown opcode 0x%x", ans->ar_op); 564 break; 565 } 566 } 567 } 568 569 /* 570 * Reverse address determination and allocation code. 571 */ 572 static void 573 rarp_request(struct rarpdev *rdev, struct arphdr *rp, uchar_t *shost) 574 { 575 ipaddr_t tpa, spa; 576 struct rarpreply *rrp; 577 uchar_t *shap, *thap, *spap, *tpap; 578 char *str = NULL; 579 int retval; 580 581 shap = (uchar_t *)rp + sizeof (struct arphdr); 582 spap = shap + rp->ar_hln; 583 thap = spap + rp->ar_pln; 584 tpap = thap + rp->ar_hln; 585 586 if (dflag) { 587 str = _link_ntoa(thap, str, rdev->physaddrlen, IFT_OTHER); 588 if (str != NULL) { 589 debug("RARP_REQUEST for %s", str); 590 free(str); 591 } 592 } 593 594 /* 595 * Third party lookups are rare and wonderful. 596 */ 597 if ((memcmp(shap, thap, rdev->physaddrlen) != 0) || 598 (memcmp(shap, shost, rdev->physaddrlen) != 0)) { 599 if (dflag) 600 debug("weird (3rd party lookup)"); 601 } 602 603 /* 604 * Fill in given parts of reply packet. 605 */ 606 (void) memcpy(shap, rdev->physaddr, rdev->physaddrlen); 607 608 /* 609 * If a good address is stored in our lookup tables, return it 610 * immediately or after a delay. Store it in our kernel's ARP cache. 611 */ 612 if (get_ipaddr(rdev, thap, tpap, &spa)) 613 return; 614 (void) memcpy(spap, &spa, sizeof (spa)); 615 616 add_arp(rdev, tpap, thap); 617 618 rp->ar_op = htons(REVARP_REPLY); 619 620 if (dflag) { 621 struct in_addr addr; 622 623 (void) memcpy(&addr, tpap, sizeof (ipaddr_t)); 624 debug("good lookup, maps to %s", inet_ntoa(addr)); 625 } 626 627 rrp = calloc(1, sizeof (struct rarpreply) + rdev->physaddrlen + 628 rdev->ifrarplen); 629 if (rrp == NULL) 630 error("out of memory"); 631 rrp->lldest = (uchar_t *)rrp + sizeof (struct rarpreply); 632 rrp->arprep = rrp->lldest + rdev->physaddrlen; 633 634 /* 635 * Create rarpreply structure. 636 */ 637 (void) gettimeofday(&rrp->tv, NULL); 638 rrp->tv.tv_sec += 3; /* delay */ 639 rrp->rdev = rdev; 640 (void) memcpy(rrp->lldest, shost, rdev->physaddrlen); 641 (void) memcpy(rrp->arprep, rp, rdev->ifrarplen); 642 643 /* 644 * If this is diskless and we're not its bootserver, let the 645 * bootserver reply first by delaying a while. 646 */ 647 (void) memcpy(&tpa, tpap, sizeof (ipaddr_t)); 648 if (mightboot(ntohl(tpa))) { 649 retval = dlpi_send(rdev->dh_rarp, rrp->lldest, 650 rdev->physaddrlen, rrp->arprep, rdev->ifrarplen, NULL); 651 if (retval != DLPI_SUCCESS) { 652 error("dlpi_send failed: %s", dlpi_strerror(retval)); 653 } else if (dflag) { 654 debug("immediate reply sent"); 655 } 656 (void) free(rrp); 657 } else { 658 delay_write(rdev, rrp); 659 } 660 } 661 662 /* 663 * Download an ARP entry into our kernel. 664 */ 665 static void 666 add_arp(struct rarpdev *rdev, uchar_t *ip, uchar_t *laddr) 667 { 668 struct xarpreq ar; 669 struct sockaddr_in *sin; 670 int fd; 671 672 /* 673 * Common part of query or set. 674 */ 675 (void) memset(&ar, 0, sizeof (ar)); 676 ar.xarp_pa.ss_family = AF_INET; 677 sin = (struct sockaddr_in *)&ar.xarp_pa; 678 (void) memcpy(&sin->sin_addr, ip, sizeof (ipaddr_t)); 679 680 /* 681 * Open the IP provider. 682 */ 683 if ((fd = open(DEVARP, 0)) < 0) 684 syserr(DEVARP); 685 686 /* 687 * Set the entry. 688 */ 689 (void) memcpy(LLADDR(&ar.xarp_ha), laddr, rdev->physaddrlen); 690 ar.xarp_ha.sdl_alen = rdev->physaddrlen; 691 ar.xarp_ha.sdl_family = AF_LINK; 692 (void) strioctl(fd, SIOCDXARP, -1, sizeof (struct xarpreq), 693 (char *)&ar); 694 if (strioctl(fd, SIOCSXARP, -1, sizeof (struct xarpreq), 695 (char *)&ar) < 0) 696 syserr("SIOCSXARP"); 697 698 (void) close(fd); 699 } 700 701 /* 702 * The RARP spec says we must be able to process ARP requests, 703 * even through the packet type is RARP. Let's hope this feature 704 * is not heavily used. 705 */ 706 static void 707 arp_request(struct rarpdev *rdev, struct arphdr *rp, uchar_t *shost) 708 { 709 struct rarpreply *rrp; 710 struct ifdev *ifdev; 711 uchar_t *shap, *thap, *spap, *tpap; 712 int retval; 713 714 shap = (uchar_t *)rp + sizeof (struct arphdr); 715 spap = shap + rp->ar_hln; 716 thap = spap + rp->ar_pln; 717 tpap = thap + rp->ar_hln; 718 719 if (dflag) 720 debug("ARPOP_REQUEST"); 721 722 for (ifdev = rdev->ifdev; ifdev != NULL; ifdev = ifdev->next) { 723 if (memcmp(&ifdev->ipaddr, tpap, sizeof (ipaddr_t)) == 0) 724 break; 725 } 726 if (ifdev == NULL) 727 return; 728 729 rp->ar_op = ARPOP_REPLY; 730 (void) memcpy(shap, rdev->physaddr, rdev->physaddrlen); 731 (void) memcpy(spap, &ifdev->ipaddr, sizeof (ipaddr_t)); 732 (void) memcpy(thap, rdev->physaddr, rdev->physaddrlen); 733 734 add_arp(rdev, tpap, thap); 735 736 /* 737 * Create rarp reply structure. 738 */ 739 rrp = calloc(1, sizeof (struct rarpreply) + rdev->physaddrlen + 740 rdev->ifrarplen); 741 if (rrp == NULL) 742 error("out of memory"); 743 rrp->lldest = (uchar_t *)rrp + sizeof (struct rarpreply); 744 rrp->arprep = rrp->lldest + rdev->physaddrlen; 745 rrp->rdev = rdev; 746 747 (void) memcpy(rrp->lldest, shost, rdev->physaddrlen); 748 (void) memcpy(rrp->arprep, rp, rdev->ifrarplen); 749 750 retval = dlpi_send(rdev->dh_rarp, rrp->lldest, rdev->physaddrlen, 751 rrp->arprep, rdev->ifrarplen, NULL); 752 free(rrp); 753 if (retval != DLPI_SUCCESS) 754 error("dlpi_send failed: %s", dlpi_strerror(retval)); 755 } 756 757 /* ARGSUSED */ 758 static void 759 do_delay_write(void *buf) 760 { 761 struct timeval tv; 762 struct rarpreply *rrp; 763 struct rarpdev *rdev; 764 int err; 765 766 for (;;) { 767 if ((err = sema_wait(&delay_sema)) != 0) { 768 if (err == EINTR) 769 continue; 770 error("do_delay_write: sema_wait failed"); 771 } 772 773 (void) mutex_lock(&delay_mutex); 774 rrp = delay_list; 775 rdev = rrp->rdev; 776 delay_list = delay_list->next; 777 (void) mutex_unlock(&delay_mutex); 778 779 (void) gettimeofday(&tv, NULL); 780 if (tv.tv_sec < rrp->tv.tv_sec) 781 (void) sleep(rrp->tv.tv_sec - tv.tv_sec); 782 783 err = dlpi_send(rdev->dh_rarp, rrp->lldest, rdev->physaddrlen, 784 rrp->arprep, rdev->ifrarplen, NULL); 785 if (err != DLPI_SUCCESS) 786 error("dlpi_send failed: %s", dlpi_strerror(err)); 787 788 (void) free(rrp); 789 } 790 } 791 792 /* ARGSUSED */ 793 static void 794 delay_write(struct rarpdev *rdev, struct rarpreply *rrp) 795 { 796 struct rarpreply *trp; 797 798 (void) mutex_lock(&delay_mutex); 799 if (delay_list == NULL) { 800 delay_list = rrp; 801 } else { 802 trp = delay_list; 803 while (trp->next != NULL) 804 trp = trp->next; 805 trp->next = rrp; 806 } 807 (void) mutex_unlock(&delay_mutex); 808 809 (void) sema_post(&delay_sema); 810 } 811 812 /* 813 * See if we have a TFTP boot file for this guy. Filenames in TFTP 814 * boot requests are of the form <ipaddr> for Sun-3's and of the form 815 * <ipaddr>.<arch> for all other architectures. Since we don't know 816 * the client's architecture, either format will do. 817 */ 818 static int 819 mightboot(ipaddr_t ipa) 820 { 821 char path[MAXPATHL]; 822 DIR *dirp; 823 struct dirent *dp; 824 825 (void) snprintf(path, sizeof (path), "%s/%08X", BOOTDIR, ipa); 826 827 /* 828 * Try a quick access() first. 829 */ 830 if (access(path, 0) == 0) 831 return (1); 832 833 /* 834 * Not there, do it the slow way by 835 * reading through the directory. 836 */ 837 (void) sprintf(path, "%08X", ipa); 838 839 if (!(dirp = opendir(BOOTDIR))) 840 return (0); 841 842 while ((dp = readdir(dirp)) != NULL) { 843 if (strncmp(dp->d_name, path, 8) != 0) 844 continue; 845 if ((strlen(dp->d_name) != 8) && (dp->d_name[8] != '.')) 846 continue; 847 break; 848 } 849 850 (void) closedir(dirp); 851 852 return ((dp != NULL) ? 1 : 0); 853 } 854 855 /* 856 * Get our IP address and local netmask. 857 */ 858 static void 859 get_ifdata(char *dev, int unit, ipaddr_t *ipp, ipaddr_t *maskp) 860 { 861 int fd; 862 struct ifreq ifr; 863 struct sockaddr_in *sin; 864 865 /* LINTED pointer */ 866 sin = (struct sockaddr_in *)&ifr.ifr_addr; 867 868 /* 869 * Open the IP provider. 870 */ 871 if ((fd = open(DEVIP, 0)) < 0) 872 syserr(DEVIP); 873 874 /* 875 * Ask IP for our IP address. 876 */ 877 (void) snprintf(ifr.ifr_name, sizeof (ifr.ifr_name), "%s%d", dev, unit); 878 if (strioctl(fd, SIOCGIFADDR, -1, sizeof (struct ifreq), 879 (char *)&ifr) < 0) 880 syserr("SIOCGIFADDR"); 881 *ipp = (ipaddr_t)ntohl(sin->sin_addr.s_addr); 882 883 if (dflag) 884 debug("device %s%d address %s", dev, unit, 885 inet_ntoa(sin->sin_addr)); 886 887 /* 888 * Ask IP for our netmask. 889 */ 890 if (strioctl(fd, SIOCGIFNETMASK, -1, sizeof (struct ifreq), 891 (char *)&ifr) < 0) 892 syserr("SIOCGIFNETMASK"); 893 *maskp = (ipaddr_t)ntohl(sin->sin_addr.s_addr); 894 895 if (dflag) 896 debug("device %s%d subnet mask %s", dev, unit, 897 inet_ntoa(sin->sin_addr)); 898 899 /* 900 * Thankyou ip. 901 */ 902 (void) close(fd); 903 } 904 905 /* 906 * Translate mac address to IP address. 907 * Return 0 on success, nonzero on failure. 908 */ 909 static int 910 get_ipaddr(struct rarpdev *rdev, uchar_t *laddr, uchar_t *ipp, ipaddr_t *ipaddr) 911 { 912 char host[MAXHOSTL]; 913 char hbuffer[BUFSIZE]; 914 struct hostent *hp, res; 915 int herror; 916 struct in_addr addr; 917 char **p; 918 struct ifdev *ifdev; 919 920 if (rdev->physaddrlen != ETHERADDRL) { 921 if (dflag) 922 debug("%s %s", " cannot map non 6 byte hardware ", 923 "address to IP address"); 924 return (1); 925 } 926 927 /* 928 * Translate mac address to hostname and IP address. 929 */ 930 if (ether_ntohost(host, (struct ether_addr *)laddr) != 0 || 931 !(hp = gethostbyname_r(host, &res, hbuffer, sizeof (hbuffer), 932 &herror)) || 933 hp->h_addrtype != AF_INET || hp->h_length != sizeof (ipaddr_t)) { 934 if (dflag) 935 debug("could not map hardware address to IP address"); 936 return (1); 937 } 938 939 /* 940 * Find the IP address on the right net. 941 */ 942 for (p = hp->h_addr_list; *p; p++) { 943 (void) memcpy(&addr, *p, sizeof (ipaddr_t)); 944 for (ifdev = rdev->ifdev; ifdev != NULL; ifdev = ifdev->next) { 945 if (dflag) { 946 struct in_addr daddr; 947 ipaddr_t netnum; 948 949 netnum = htonl(ifdev->if_netnum); 950 (void) memcpy(&daddr, &netnum, 951 sizeof (ipaddr_t)); 952 if (ifdev->lunit == -1) 953 debug("trying physical netnum %s" 954 " mask %x", inet_ntoa(daddr), 955 ifdev->if_netmask); 956 else 957 debug("trying logical %d netnum %s" 958 " mask %x", ifdev->lunit, 959 inet_ntoa(daddr), 960 ifdev->if_netmask); 961 } 962 if ((ntohl(addr.s_addr) & ifdev->if_netmask) == 963 ifdev->if_netnum) { 964 /* 965 * Return the correct IP address. 966 */ 967 (void) memcpy(ipp, &addr, sizeof (ipaddr_t)); 968 969 /* 970 * Return the interface's ipaddr 971 */ 972 (void) memcpy(ipaddr, &ifdev->ipaddr, 973 sizeof (ipaddr_t)); 974 975 return (0); 976 } 977 } 978 } 979 980 if (dflag) 981 debug("got host entry but no IP address on this net"); 982 return (1); 983 } 984 985 static int 986 strioctl(int fd, int cmd, int timout, int len, char *dp) 987 { 988 struct strioctl si; 989 990 si.ic_cmd = cmd; 991 si.ic_timout = timout; 992 si.ic_len = len; 993 si.ic_dp = dp; 994 return (ioctl(fd, I_STR, &si)); 995 } 996 997 static void 998 usage(void) 999 { 1000 error("Usage: %s [ -ad ] device unit", cmdname); 1001 } 1002 1003 static void 1004 syserr(const char *s) 1005 { 1006 char buf[256]; 1007 int status = 1; 1008 1009 (void) snprintf(buf, sizeof (buf), "%s: %s", s, strerror(errno)); 1010 (void) fprintf(stderr, "%s: %s\n", cmdname, buf); 1011 syslog(LOG_ERR, "%s", buf); 1012 thr_exit(&status); 1013 } 1014 1015 static void 1016 error(const char *fmt, ...) 1017 { 1018 char buf[256]; 1019 va_list ap; 1020 int status = 1; 1021 1022 va_start(ap, fmt); 1023 (void) vsprintf(buf, fmt, ap); 1024 va_end(ap); 1025 (void) fprintf(stderr, "%s: %s\n", cmdname, buf); 1026 syslog(LOG_ERR, buf); 1027 thr_exit(&status); 1028 } 1029 1030 /*PRINTFLIKE1*/ 1031 static void 1032 debug(char *fmt, ...) 1033 { 1034 va_list ap; 1035 1036 (void) mutex_lock(&debug_mutex); 1037 va_start(ap, fmt); 1038 (void) fprintf(stderr, "%s:[%u] ", cmdname, thr_self()); 1039 (void) vfprintf(stderr, fmt, ap); 1040 (void) fprintf(stderr, "\n"); 1041 va_end(ap); 1042 (void) mutex_unlock(&debug_mutex); 1043 } 1044