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