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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 29 /* 30 * Portions of this source code were derived from Berkeley 4.3 BSD 31 * under license from the Regents of the University of California. 32 */ 33 34 #pragma ident "%Z%%M% %I% %E% SMI" 35 36 /* 37 * rarpd.c Reverse-ARP server. 38 * Refer to RFC 903 "A Reverse Address Resolution Protocol". 39 */ 40 41 #define _REENTRANT 42 43 #include <thread.h> 44 #include <synch.h> 45 #include <stdlib.h> 46 #include <unistd.h> 47 #include <sys/resource.h> 48 #include <stdio.h> 49 #include <stdarg.h> 50 #include <string.h> 51 #include <ctype.h> 52 #include <fcntl.h> 53 #include <sys/types.h> 54 #include <dirent.h> 55 #include <syslog.h> 56 #include <signal.h> 57 #include <netdb.h> 58 #include <errno.h> 59 #include <sys/socket.h> 60 #include <sys/sockio.h> 61 #include <net/if.h> 62 #include <netinet/if_ether.h> 63 #include <netinet/in.h> 64 #include <arpa/inet.h> 65 #include <stropts.h> 66 #include <sys/dlpi.h> 67 #include <libinetutil.h> 68 #include <net/if_types.h> 69 #include <net/if_dl.h> 70 71 #define BOOTDIR "/tftpboot" /* boot files directory */ 72 #define DEVDIR "/dev" /* devices directory */ 73 #define DEVIP "/dev/ip" /* path to ip driver */ 74 #define DEVARP "/dev/arp" /* path to arp driver */ 75 76 #define BUFSIZE 2048 /* max receive frame length */ 77 #define MAXPATHL 128 /* max path length */ 78 #define MAXHOSTL 128 /* max host name length */ 79 #define MAXIFS 256 80 81 /* 82 * Logical network devices 83 */ 84 struct ifdev { 85 char ldevice[IFNAMSIZ]; 86 int lunit; 87 ipaddr_t ipaddr; /* network order */ 88 ipaddr_t if_netmask; /* host order */ 89 ipaddr_t if_ipaddr; /* host order */ 90 ipaddr_t if_netnum; /* host order, with subnet */ 91 struct ifdev *next; 92 }; 93 94 /* 95 * Physical network device 96 */ 97 struct rarpdev { 98 char device[IFNAMSIZ]; 99 int unit; 100 int fd; 101 uchar_t *lladdr; /* mac address of interface */ 102 int ifaddrlen; /* mac address length */ 103 int ifsaplen; /* indicates dlsap format */ 104 int ifrarplen; /* size of rarp data packet */ 105 struct ifdev *ifdev; /* private interface info */ 106 struct rarpdev *next; /* list of managed devices */ 107 }; 108 109 struct rarpreply { 110 struct rarpdev *rdev; /* which device reply for */ 111 struct timeval tv; /* send RARP reply by when */ 112 uchar_t *lldest; /* target mac to send reply */ 113 uchar_t *arprep; /* [R]ARP response */ 114 struct rarpreply *next; 115 }; 116 117 static struct rarpreply *delay_list; 118 static sema_t delay_sema; 119 static mutex_t delay_mutex; 120 static mutex_t debug_mutex; 121 122 static struct rarpdev *rarpdev_head; 123 124 /* 125 * Globals initialized before multi-threading 126 */ 127 static char *cmdname; /* command name from argv[0] */ 128 static int dflag = 0; /* enable diagnostics */ 129 static int aflag = 0; /* start rarpd on all interfaces */ 130 static char *alarmmsg; /* alarm() error message */ 131 132 static void getintf(void); 133 static struct rarpdev *find_device(ifspec_t *); 134 static void init_rarpdev(struct rarpdev *); 135 static void do_rarp(void *); 136 static void rarp_request(struct rarpdev *, struct arphdr *, 137 uchar_t *); 138 static void add_arp(struct rarpdev *, uchar_t *, uchar_t *); 139 static void arp_request(struct rarpdev *, struct arphdr *, uchar_t *); 140 static int rarp_open(struct rarpdev *, ushort_t); 141 static void do_delay_write(void *); 142 static void delay_write(struct rarpdev *, struct rarpreply *); 143 static int rarp_write(int, struct rarpreply *); 144 static int mightboot(ipaddr_t); 145 static void get_ifdata(char *, int, ipaddr_t *, ipaddr_t *); 146 static int get_ipaddr(struct rarpdev *, uchar_t *, uchar_t *, ipaddr_t *); 147 static void sigalarm(int); 148 static int strioctl(int, int, int, int, char *); 149 static void usage(); 150 static void syserr(char *); 151 static void error(char *, ...); 152 static void debug(char *, ...); 153 154 extern int optind; 155 extern char *optarg; 156 157 int 158 main(int argc, char *argv[]) 159 { 160 int c; 161 struct rlimit rl; 162 struct rarpdev *rdev; 163 int i; 164 165 cmdname = argv[0]; 166 167 while ((c = getopt(argc, argv, "ad")) != -1) { 168 switch (c) { 169 case 'a': 170 aflag = 1; 171 break; 172 173 case 'd': 174 dflag = 1; 175 break; 176 177 default: 178 usage(); 179 } 180 } 181 182 if ((!aflag && (argc - optind) != 2) || 183 (aflag && (argc - optind) != 0)) { 184 usage(); 185 /* NOTREACHED */ 186 } 187 188 if (!dflag) { 189 /* 190 * Background 191 */ 192 switch (fork()) { 193 case -1: /* error */ 194 syserr("fork"); 195 /*NOTREACHED*/ 196 197 case 0: /* child */ 198 break; 199 200 default: /* parent */ 201 return (0); 202 } 203 for (i = 0; i < 3; i++) { 204 (void) close(i); 205 } 206 (void) open("/", O_RDONLY, 0); 207 (void) dup2(0, 1); 208 (void) dup2(0, 2); 209 /* 210 * Detach terminal 211 */ 212 if (setsid() < 0) 213 syserr("setsid"); 214 } 215 216 rl.rlim_cur = RLIM_INFINITY; 217 rl.rlim_max = RLIM_INFINITY; 218 if (setrlimit(RLIMIT_NOFILE, &rl) == -1) 219 syserr("setrlimit"); 220 221 (void) openlog(cmdname, LOG_PID, LOG_DAEMON); 222 223 if (aflag) { 224 /* 225 * Get each interface name and load rarpdev list 226 */ 227 getintf(); 228 } else { 229 ifspec_t ifsp; 230 struct ifdev *ifdev; 231 char buf[IFNAMSIZ + 1]; 232 233 /* 234 * Load specified device as only element of the list 235 */ 236 rarpdev_head = (struct rarpdev *)calloc(1, 237 sizeof (struct rarpdev)); 238 if (rarpdev_head == NULL) { 239 error("out of memory"); 240 } 241 (void) strncpy(buf, argv[optind], IFNAMSIZ); 242 (void) strncat(buf, argv[optind + 1], IFNAMSIZ - strlen(buf)); 243 244 if ((ifdev = calloc(1, sizeof (struct ifdev))) == NULL) { 245 error("out of memory"); 246 } 247 248 if (!ifparse_ifspec(buf, &ifsp) || ifsp.ifsp_modcnt != 0) { 249 error("invalid interface specification"); 250 } 251 252 if (ifsp.ifsp_lunvalid) { 253 (void) snprintf(ifdev->ldevice, 254 sizeof (ifdev->ldevice), "%s%d:", 255 ifsp.ifsp_devnm, ifsp.ifsp_ppa); 256 ifdev->lunit = ifsp.ifsp_lun; 257 } else 258 ifdev->lunit = -1; /* no logical unit */ 259 (void) strlcpy(rarpdev_head->device, ifsp.ifsp_devnm, 260 sizeof (rarpdev_head->device)); 261 rarpdev_head->unit = ifsp.ifsp_ppa; 262 263 ifdev->next = rarpdev_head->ifdev; 264 rarpdev_head->ifdev = ifdev; 265 } 266 267 /* 268 * Initialize each rarpdev 269 */ 270 for (rdev = rarpdev_head; rdev != NULL; rdev = rdev->next) { 271 init_rarpdev(rdev); 272 } 273 274 (void) sema_init(&delay_sema, 0, USYNC_THREAD, NULL); 275 (void) mutex_init(&delay_mutex, USYNC_THREAD, NULL); 276 (void) mutex_init(&debug_mutex, USYNC_THREAD, NULL); 277 278 /* 279 * Start delayed processing thread 280 */ 281 (void) thr_create(NULL, NULL, (void *(*)(void *))do_delay_write, NULL, 282 THR_NEW_LWP, NULL); 283 284 /* 285 * Start RARP processing for each device 286 */ 287 for (rdev = rarpdev_head; rdev != NULL; rdev = rdev->next) { 288 if (rdev->fd != -1) { 289 (void) thr_create(NULL, NULL, 290 (void *(*)(void *))do_rarp, (void *)rdev, 291 THR_NEW_LWP, NULL); 292 } 293 } 294 295 /* 296 * Exit main() thread 297 */ 298 thr_exit(NULL); 299 300 return (0); 301 } 302 303 static void 304 getintf(void) 305 { 306 int fd; 307 int numifs; 308 unsigned bufsize; 309 struct ifreq *reqbuf; 310 struct ifconf ifconf; 311 struct ifreq *ifr; 312 struct rarpdev *rdev; 313 struct ifdev *ifdev; 314 315 /* 316 * Open the IP provider. 317 */ 318 if ((fd = open(DEVIP, 0)) < 0) 319 syserr(DEVIP); 320 321 /* 322 * Ask IP for the list of configured interfaces. 323 */ 324 if (ioctl(fd, SIOCGIFNUM, (char *)&numifs) < 0) { 325 numifs = MAXIFS; 326 } 327 bufsize = numifs * sizeof (struct ifreq); 328 reqbuf = (struct ifreq *)malloc(bufsize); 329 if (reqbuf == NULL) { 330 error("out of memory"); 331 } 332 333 ifconf.ifc_len = bufsize; 334 ifconf.ifc_buf = (caddr_t)reqbuf; 335 if (ioctl(fd, SIOCGIFCONF, (char *)&ifconf) < 0) 336 syserr("SIOCGIFCONF"); 337 338 /* 339 * Initialize a rarpdev for each interface 340 */ 341 for (ifr = ifconf.ifc_req; ifconf.ifc_len > 0; 342 ifr++, ifconf.ifc_len -= sizeof (struct ifreq)) { 343 ifspec_t ifsp; 344 345 if (ioctl(fd, SIOCGIFFLAGS, (char *)ifr) < 0) { 346 syserr("ioctl SIOCGIFFLAGS"); 347 exit(1); 348 } 349 if ((ifr->ifr_flags & IFF_LOOPBACK) || 350 !(ifr->ifr_flags & IFF_UP) || 351 !(ifr->ifr_flags & IFF_BROADCAST) || 352 (ifr->ifr_flags & IFF_NOARP) || 353 (ifr->ifr_flags & IFF_POINTOPOINT)) 354 continue; 355 356 if (!ifparse_ifspec(ifr->ifr_name, &ifsp)) 357 error("ifparse_ifspec failed"); 358 359 /* 360 * Look for an existing device for logical interfaces 361 */ 362 if ((rdev = find_device(&ifsp)) == NULL) { 363 rdev = calloc(1, sizeof (struct rarpdev)); 364 if (rdev == NULL) 365 error("out of memory"); 366 367 (void) strlcpy(rdev->device, ifsp.ifsp_devnm, 368 sizeof (rdev->device)); 369 rdev->unit = ifsp.ifsp_ppa; 370 371 rdev->next = rarpdev_head; 372 rarpdev_head = rdev; 373 } 374 375 if ((ifdev = calloc(1, sizeof (struct ifdev))) == NULL) 376 error("out of memory"); 377 378 if (ifsp.ifsp_lunvalid) { 379 (void) snprintf(ifdev->ldevice, 380 sizeof (ifdev->ldevice), "%s%d:", 381 ifsp.ifsp_devnm, ifsp.ifsp_ppa); 382 ifdev->lunit = ifsp.ifsp_lun; 383 } else 384 ifdev->lunit = -1; /* no logical unit */ 385 386 ifdev->next = rdev->ifdev; 387 rdev->ifdev = ifdev; 388 } 389 (void) free((char *)reqbuf); 390 } 391 392 static struct rarpdev * 393 find_device(ifspec_t *specp) 394 { 395 struct rarpdev *rdev; 396 397 for (rdev = rarpdev_head; rdev != NULL; rdev = rdev->next) { 398 if (specp->ifsp_ppa == rdev->unit && 399 strcmp(specp->ifsp_devnm, rdev->device) == 0) 400 return (rdev); 401 } 402 return (NULL); 403 } 404 405 static void 406 init_rarpdev(struct rarpdev *rdev) 407 { 408 char *dev; 409 int unit; 410 struct ifdev *ifdev; 411 412 /* 413 * Open datalink provider and get our mac address. 414 */ 415 rdev->fd = rarp_open(rdev, ETHERTYPE_REVARP); 416 417 /* 418 * rarp_open may fail on certain types of interfaces 419 */ 420 if (rdev->fd < 0) { 421 rdev->fd = -1; 422 return; 423 } 424 425 /* 426 * Get the IP address and netmask from directory service for 427 * each logical interface. 428 */ 429 for (ifdev = rdev->ifdev; ifdev != NULL; ifdev = ifdev->next) { 430 /* 431 * If lunit == -1 then this is the primary interface name 432 */ 433 if (ifdev->lunit == -1) { 434 dev = rdev->device; 435 unit = rdev->unit; 436 } else { 437 dev = ifdev->ldevice; 438 unit = ifdev->lunit; 439 } 440 get_ifdata(dev, unit, &ifdev->if_ipaddr, &ifdev->if_netmask); 441 442 /* 443 * Use IP address of the interface. 444 */ 445 ifdev->if_netnum = ifdev->if_ipaddr & ifdev->if_netmask; 446 ifdev->ipaddr = (ipaddr_t)htonl(ifdev->if_ipaddr); 447 } 448 } 449 450 static void 451 do_rarp(void *buf) 452 { 453 struct rarpdev *rdev = (struct rarpdev *)buf; 454 struct strbuf ctl; 455 char ctlbuf[BUFSIZE]; 456 struct strbuf data; 457 char databuf[BUFSIZE]; 458 char *cause; 459 struct arphdr *ans; 460 uchar_t *shost; 461 int flags, ret; 462 union DL_primitives *dlp; 463 uchar_t *laddrp; 464 char *str = NULL; 465 466 /* 467 * Sanity check; if we hit this limit, ctlbuf/databuf needs 468 * to be malloc'ed. 469 */ 470 if ((sizeof (ctlbuf) < (DL_UNITDATA_IND_SIZE + rdev->ifaddrlen)) || 471 (sizeof (databuf) < rdev->ifrarplen)) 472 error("unsupported media"); 473 474 if (((shost = (uchar_t *)malloc(rdev->ifaddrlen)) == NULL) || 475 ((ans = (struct arphdr *)malloc(rdev->ifrarplen)) == NULL)) 476 syserr("malloc"); 477 478 if (dflag) { 479 str = _link_ntoa(rdev->lladdr, str, rdev->ifaddrlen, IFT_OTHER); 480 if (str != NULL) { 481 debug("starting rarp service on device %s%d address %s", 482 rdev->device, rdev->unit, str); 483 free(str); 484 } 485 } 486 487 /* 488 * read RARP packets and respond to them. 489 */ 490 for (;;) { 491 ctl.len = 0; 492 ctl.maxlen = BUFSIZE; 493 ctl.buf = ctlbuf; 494 data.len = 0; 495 data.maxlen = BUFSIZE; 496 data.buf = databuf; 497 flags = 0; 498 499 if ((ret = getmsg(rdev->fd, &ctl, &data, &flags)) < 0) 500 syserr("getmsg"); 501 502 /* 503 * Validate DL_UNITDATA_IND. 504 */ 505 /* LINTED pointer */ 506 dlp = (union DL_primitives *)ctlbuf; 507 508 (void) memcpy(ans, databuf, rdev->ifrarplen); 509 510 cause = NULL; 511 if (ctl.len == 0) 512 cause = "missing control part of message"; 513 else if (ctl.len < 0) 514 cause = "short control part of message"; 515 else if (dlp->dl_primitive != DL_UNITDATA_IND) 516 cause = "not unitdata_ind"; 517 else if (ret & MORECTL) 518 cause = "MORECTL flag"; 519 else if (ret & MOREDATA) 520 cause = "MOREDATA flag"; 521 else if (ctl.len < DL_UNITDATA_IND_SIZE) 522 cause = "short unitdata_ind"; 523 else if (data.len < rdev->ifrarplen) 524 cause = "short arp"; 525 else if (ans->ar_hrd != htons(ARPHRD_ETHER)) 526 cause = "hrd"; 527 else if (ans->ar_pro != htons(ETHERTYPE_IP)) 528 cause = "pro"; 529 else if (ans->ar_hln != rdev->ifaddrlen) 530 cause = "hln"; 531 else if (ans->ar_pln != sizeof (ipaddr_t)) 532 cause = "pln"; 533 if (cause) { 534 if (dflag) 535 debug("receive check failed: cause: %s", 536 cause); 537 continue; 538 } 539 540 /* 541 * Good request. 542 * Pick out the mac source address of this RARP request. 543 */ 544 laddrp = (uchar_t *)ctlbuf + 545 dlp->unitdata_ind.dl_src_addr_offset; 546 (void) memcpy(shost, laddrp, ans->ar_hln); 547 548 /* 549 * Handle the request. 550 */ 551 switch (ntohs(ans->ar_op)) { 552 case REVARP_REQUEST: 553 rarp_request(rdev, ans, shost); 554 break; 555 556 case ARPOP_REQUEST: 557 arp_request(rdev, ans, shost); 558 break; 559 560 case REVARP_REPLY: 561 if (dflag) 562 debug("REVARP_REPLY ignored"); 563 break; 564 565 case ARPOP_REPLY: 566 if (dflag) 567 debug("ARPOP_REPLY ignored"); 568 break; 569 570 default: 571 if (dflag) 572 debug("unknown opcode 0x%x", ans->ar_op); 573 break; 574 } 575 } 576 /* NOTREACHED */ 577 } 578 579 /* 580 * Reverse address determination and allocation code. 581 */ 582 static void 583 rarp_request(struct rarpdev *rdev, struct arphdr *rp, uchar_t *shost) 584 { 585 ipaddr_t tpa, spa; 586 struct rarpreply *rrp; 587 uchar_t *shap, *thap, *spap, *tpap; 588 char *str = NULL; 589 590 shap = (uchar_t *)rp + sizeof (struct arphdr); 591 spap = shap + rp->ar_hln; 592 thap = spap + rp->ar_pln; 593 tpap = thap + rp->ar_hln; 594 595 if (dflag) { 596 str = _link_ntoa(thap, str, rdev->ifaddrlen, IFT_OTHER); 597 if (str != NULL) { 598 debug("RARP_REQUEST for %s", str); 599 free(str); 600 } 601 } 602 603 /* 604 * third party lookups are rare and wonderful 605 */ 606 if ((memcmp(shap, thap, rdev->ifaddrlen) != 0) || 607 (memcmp(shap, shost, rdev->ifaddrlen) != 0)) { 608 if (dflag) 609 debug("weird (3rd party lookup)"); 610 } 611 612 /* 613 * fill in given parts of reply packet 614 */ 615 (void) memcpy(shap, rdev->lladdr, rdev->ifaddrlen); 616 617 /* 618 * If a good address is stored in our lookup tables, return it 619 * immediately or after a delay. Store it our kernel's ARP cache. 620 */ 621 if (get_ipaddr(rdev, thap, tpap, &spa)) 622 return; 623 (void) memcpy(spap, &spa, sizeof (spa)); 624 625 add_arp(rdev, tpap, thap); 626 627 rp->ar_op = htons(REVARP_REPLY); 628 629 if (dflag) { 630 struct in_addr addr; 631 632 (void) memcpy(&addr, tpap, sizeof (ipaddr_t)); 633 debug("good lookup, maps to %s", inet_ntoa(addr)); 634 } 635 636 rrp = (struct rarpreply *)calloc(1, sizeof (struct rarpreply) + 637 rdev->ifaddrlen + rdev->ifrarplen); 638 if (rrp == NULL) 639 error("out of memory"); 640 rrp->lldest = (uchar_t *)rrp + sizeof (struct rarpreply); 641 rrp->arprep = rrp->lldest + rdev->ifaddrlen; 642 643 /* 644 * Create rarpreply structure. 645 */ 646 (void) gettimeofday(&rrp->tv, NULL); 647 rrp->tv.tv_sec += 3; /* delay */ 648 rrp->rdev = rdev; 649 (void) memcpy(rrp->lldest, shost, rdev->ifaddrlen); 650 (void) memcpy(rrp->arprep, rp, rdev->ifrarplen); 651 652 /* 653 * If this is diskless and we're not its bootserver, let the 654 * bootserver reply first by delaying a while. 655 */ 656 (void) memcpy(&tpa, tpap, sizeof (ipaddr_t)); 657 if (mightboot(ntohl(tpa))) { 658 if (rarp_write(rdev->fd, rrp) < 0) 659 syslog(LOG_ERR, "Bad rarp_write: %m"); 660 if (dflag) 661 debug("immediate reply sent"); 662 (void) free(rrp); 663 } else { 664 delay_write(rdev, rrp); 665 } 666 } 667 668 /* 669 * Download an ARP entry into our kernel. 670 */ 671 static void 672 add_arp(struct rarpdev *rdev, uchar_t *ip, uchar_t *laddr) 673 { 674 struct xarpreq ar; 675 struct sockaddr_in *sin; 676 int fd; 677 678 /* 679 * Common part of query or set 680 */ 681 (void) memset(&ar, 0, sizeof (ar)); 682 ar.xarp_pa.ss_family = AF_INET; 683 sin = (struct sockaddr_in *)&ar.xarp_pa; 684 (void) memcpy(&sin->sin_addr, ip, sizeof (ipaddr_t)); 685 686 /* 687 * Open the IP provider. 688 */ 689 if ((fd = open(DEVARP, 0)) < 0) 690 syserr(DEVARP); 691 692 /* 693 * Set the entry 694 */ 695 (void) memcpy(LLADDR(&ar.xarp_ha), laddr, rdev->ifaddrlen); 696 ar.xarp_ha.sdl_alen = rdev->ifaddrlen; 697 ar.xarp_ha.sdl_family = AF_LINK; 698 (void) strioctl(fd, SIOCDXARP, -1, sizeof (struct xarpreq), 699 (char *)&ar); 700 if (strioctl(fd, SIOCSXARP, -1, sizeof (struct xarpreq), 701 (char *)&ar) < 0) 702 syserr("SIOCSXARP"); 703 704 (void) close(fd); 705 } 706 707 /* 708 * The RARP spec says we must be able to process ARP requests, 709 * even through the packet type is RARP. Let's hope this feature 710 * is not heavily used. 711 */ 712 static void 713 arp_request(struct rarpdev *rdev, struct arphdr *rp, uchar_t *shost) 714 { 715 struct rarpreply *rrp; 716 struct ifdev *ifdev; 717 uchar_t *shap, *thap, *spap, *tpap; 718 int ret; 719 720 shap = (uchar_t *)rp + sizeof (struct arphdr); 721 spap = shap + rp->ar_hln; 722 thap = spap + rp->ar_pln; 723 tpap = thap + rp->ar_hln; 724 725 if (dflag) 726 debug("ARPOP_REQUEST"); 727 728 for (ifdev = rdev->ifdev; ifdev != NULL; ifdev = ifdev->next) { 729 if (memcmp(&ifdev->ipaddr, tpap, sizeof (ipaddr_t)) == 0) 730 break; 731 } 732 if (ifdev == NULL) 733 return; 734 735 rp->ar_op = ARPOP_REPLY; 736 (void) memcpy(shap, rdev->lladdr, rdev->ifaddrlen); 737 (void) memcpy(spap, &ifdev->ipaddr, sizeof (ipaddr_t)); 738 (void) memcpy(thap, rdev->lladdr, rdev->ifaddrlen); 739 740 add_arp(rdev, tpap, thap); 741 742 /* 743 * Create rarp reply structure. 744 */ 745 rrp = (struct rarpreply *)calloc(1, sizeof (struct rarpreply) + 746 rdev->ifaddrlen + rdev->ifrarplen); 747 if (rrp == NULL) 748 error("out of memory"); 749 rrp->lldest = (uchar_t *)rrp + sizeof (struct rarpreply); 750 rrp->arprep = rrp->lldest + rdev->ifaddrlen; 751 rrp->rdev = rdev; 752 753 (void) memcpy(rrp->lldest, shost, rdev->ifaddrlen); 754 (void) memcpy(rrp->arprep, rp, rdev->ifrarplen); 755 756 ret = rarp_write(rdev->fd, rrp); 757 free(rrp); 758 if (ret < 0) 759 error("rarp_write error"); 760 } 761 762 /* 763 * OPEN the datalink provider device, ATTACH to the unit, 764 * and BIND to the revarp type. 765 * Return the resulting descriptor. 766 * 767 * MT-UNSAFE 768 */ 769 static int 770 rarp_open(struct rarpdev *rarpdev, ushort_t type) 771 { 772 register int fd; 773 char path[MAXPATHL]; 774 union DL_primitives *dlp; 775 char buf[BUFSIZE]; 776 struct strbuf ctl; 777 int flags; 778 uchar_t *eap; 779 char *device = rarpdev->device; 780 int unit = rarpdev->unit; 781 char *str = NULL; 782 783 /* 784 * Prefix the device name with "/dev/" if it doesn't 785 * start with a "/" . 786 */ 787 if (*device == '/') 788 (void) snprintf(path, sizeof (path), "%s", device); 789 else 790 (void) snprintf(path, sizeof (path), "%s/%s", DEVDIR, device); 791 792 /* 793 * Open the datalink provider. 794 */ 795 if ((fd = open(path, O_RDWR)) < 0) 796 syserr(path); 797 798 /* 799 * Issue DL_INFO_REQ and check DL_INFO_ACK for sanity. 800 */ 801 /* LINTED pointer */ 802 dlp = (union DL_primitives *)buf; 803 dlp->info_req.dl_primitive = DL_INFO_REQ; 804 805 ctl.buf = (char *)dlp; 806 ctl.len = DL_INFO_REQ_SIZE; 807 808 if (putmsg(fd, &ctl, NULL, 0) < 0) 809 syserr("putmsg"); 810 811 (void) signal(SIGALRM, sigalarm); 812 813 alarmmsg = "DL_INFO_REQ failed: timeout waiting for DL_INFO_ACK"; 814 (void) alarm(10); 815 816 ctl.buf = (char *)dlp; 817 ctl.len = 0; 818 ctl.maxlen = BUFSIZE; 819 flags = 0; 820 if (getmsg(fd, &ctl, NULL, &flags) < 0) 821 syserr("getmsg"); 822 823 (void) alarm(0); 824 (void) signal(SIGALRM, SIG_DFL); 825 826 /* 827 * Validate DL_INFO_ACK reply. 828 */ 829 if (ctl.len < sizeof (ulong_t)) 830 error("DL_INFO_REQ failed: short reply to DL_INFO_REQ"); 831 832 if (dlp->dl_primitive != DL_INFO_ACK) 833 error("DL_INFO_REQ failed: dl_primitive 0x%lx received", 834 dlp->dl_primitive); 835 836 if (ctl.len < DL_INFO_ACK_SIZE) 837 error("DL_INFO_REQ failed: short info_ack: %d bytes", 838 ctl.len); 839 840 if (dlp->info_ack.dl_version != DL_VERSION_2) 841 error("DL_INFO_ACK: incompatible version: %lu", 842 dlp->info_ack.dl_version); 843 844 if (dlp->info_ack.dl_sap_length != -2) { 845 if (dflag) 846 debug( 847 "%s%d DL_INFO_ACK: incompatible dl_sap_length: %ld", 848 device, unit, dlp->info_ack.dl_sap_length); 849 (void) close(fd); 850 return (-1); 851 } 852 853 if ((dlp->info_ack.dl_service_mode & DL_CLDLS) == 0) { 854 if (dflag) 855 debug( 856 "%s%d DL_INFO_ACK: incompatible dl_service_mode: 0x%lx", 857 device, unit, dlp->info_ack.dl_service_mode); 858 (void) close(fd); 859 return (-1); 860 } 861 862 rarpdev->ifsaplen = dlp->info_ack.dl_sap_length; 863 rarpdev->ifaddrlen = dlp->info_ack.dl_addr_length - 864 abs(rarpdev->ifsaplen); 865 rarpdev->ifrarplen = sizeof (struct arphdr) + 866 (2 * sizeof (ipaddr_t)) + (2 * rarpdev->ifaddrlen); 867 868 /* 869 * Issue DL_ATTACH_REQ. 870 */ 871 /* LINTED pointer */ 872 dlp = (union DL_primitives *)buf; 873 dlp->attach_req.dl_primitive = DL_ATTACH_REQ; 874 dlp->attach_req.dl_ppa = unit; 875 876 ctl.buf = (char *)dlp; 877 ctl.len = DL_ATTACH_REQ_SIZE; 878 879 if (putmsg(fd, &ctl, NULL, 0) < 0) 880 syserr("putmsg"); 881 882 (void) signal(SIGALRM, sigalarm); 883 alarmmsg = "DL_ATTACH_REQ failed: timeout waiting for DL_OK_ACK"; 884 885 (void) alarm(10); 886 887 ctl.buf = (char *)dlp; 888 ctl.len = 0; 889 ctl.maxlen = BUFSIZE; 890 flags = 0; 891 if (getmsg(fd, &ctl, NULL, &flags) < 0) 892 syserr("getmsg"); 893 894 (void) alarm(0); 895 (void) signal(SIGALRM, SIG_DFL); 896 897 /* 898 * Validate DL_OK_ACK reply. 899 */ 900 if (ctl.len < sizeof (ulong_t)) 901 error("DL_ATTACH_REQ failed: short reply to attach request"); 902 903 if (dlp->dl_primitive == DL_ERROR_ACK) 904 error("DL_ATTACH_REQ failed: dl_errno %lu unix_errno %lu", 905 dlp->error_ack.dl_errno, dlp->error_ack.dl_unix_errno); 906 907 if (dlp->dl_primitive != DL_OK_ACK) 908 error("DL_ATTACH_REQ failed: dl_primitive 0x%lx received", 909 dlp->dl_primitive); 910 911 if (ctl.len < DL_OK_ACK_SIZE) 912 error("attach failed: short ok_ack: %d bytes", 913 ctl.len); 914 915 /* 916 * Issue DL_BIND_REQ. 917 */ 918 /* LINTED pointer */ 919 dlp = (union DL_primitives *)buf; 920 dlp->bind_req.dl_primitive = DL_BIND_REQ; 921 dlp->bind_req.dl_sap = type; 922 dlp->bind_req.dl_max_conind = 0; 923 dlp->bind_req.dl_service_mode = DL_CLDLS; 924 dlp->bind_req.dl_conn_mgmt = 0; 925 dlp->bind_req.dl_xidtest_flg = 0; 926 927 ctl.buf = (char *)dlp; 928 ctl.len = DL_BIND_REQ_SIZE; 929 930 if (putmsg(fd, &ctl, NULL, 0) < 0) 931 syserr("putmsg"); 932 933 (void) signal(SIGALRM, sigalarm); 934 935 alarmmsg = "DL_BIND_REQ failed: timeout waiting for DL_BIND_ACK"; 936 (void) alarm(10); 937 938 ctl.buf = (char *)dlp; 939 ctl.len = 0; 940 ctl.maxlen = BUFSIZE; 941 flags = 0; 942 if (getmsg(fd, &ctl, NULL, &flags) < 0) 943 syserr("getmsg"); 944 945 (void) alarm(0); 946 (void) signal(SIGALRM, SIG_DFL); 947 948 /* 949 * Validate DL_BIND_ACK reply. 950 */ 951 if (ctl.len < sizeof (ulong_t)) 952 error("DL_BIND_REQ failed: short reply"); 953 954 if (dlp->dl_primitive == DL_ERROR_ACK) 955 error("DL_BIND_REQ failed: dl_errno %lu unix_errno %lu", 956 dlp->error_ack.dl_errno, dlp->error_ack.dl_unix_errno); 957 958 if (dlp->dl_primitive != DL_BIND_ACK) 959 error("DL_BIND_REQ failed: dl_primitive 0x%lx received", 960 dlp->dl_primitive); 961 962 if (ctl.len < DL_BIND_ACK_SIZE) 963 error( 964 "DL_BIND_REQ failed: short bind acknowledgement received"); 965 966 if (dlp->bind_ack.dl_sap != type) 967 error( 968 "DL_BIND_REQ failed: returned dl_sap %lu != requested sap %d", 969 dlp->bind_ack.dl_sap, type); 970 971 /* 972 * Issue DL_PHYS_ADDR_REQ to get our local mac address. 973 */ 974 /* LINTED pointer */ 975 dlp = (union DL_primitives *)buf; 976 dlp->physaddr_req.dl_primitive = DL_PHYS_ADDR_REQ; 977 dlp->physaddr_req.dl_addr_type = DL_CURR_PHYS_ADDR; 978 979 ctl.buf = (char *)dlp; 980 ctl.len = DL_PHYS_ADDR_REQ_SIZE; 981 982 if (putmsg(fd, &ctl, NULL, 0) < 0) 983 syserr("putmsg"); 984 985 (void) signal(SIGALRM, sigalarm); 986 987 alarmmsg = 988 "DL_PHYS_ADDR_REQ failed: timeout waiting for DL_PHYS_ADDR_ACK"; 989 (void) alarm(10); 990 991 ctl.buf = (char *)dlp; 992 ctl.len = 0; 993 ctl.maxlen = BUFSIZE; 994 flags = 0; 995 if (getmsg(fd, &ctl, NULL, &flags) < 0) 996 syserr("getmsg"); 997 998 (void) alarm(0); 999 (void) signal(SIGALRM, SIG_DFL); 1000 1001 /* 1002 * Validate DL_PHYS_ADDR_ACK reply. 1003 */ 1004 if (ctl.len < sizeof (ulong_t)) 1005 error("DL_PHYS_ADDR_REQ failed: short reply"); 1006 1007 if (dlp->dl_primitive == DL_ERROR_ACK) 1008 error("DL_PHYS_ADDR_REQ failed: dl_errno %lu unix_errno %lu", 1009 dlp->error_ack.dl_errno, dlp->error_ack.dl_unix_errno); 1010 1011 if (dlp->dl_primitive != DL_PHYS_ADDR_ACK) 1012 error("DL_PHYS_ADDR_REQ failed: dl_primitive 0x%lx received", 1013 dlp->dl_primitive); 1014 1015 if (ctl.len < DL_PHYS_ADDR_ACK_SIZE) 1016 error("DL_PHYS_ADDR_REQ failed: short ack received"); 1017 1018 if (dlp->physaddr_ack.dl_addr_length != rarpdev->ifaddrlen) { 1019 if (dflag) 1020 debug( 1021 "%s%d DL_PHYS_ADDR_ACK failed: incompatible dl_addr_length: %lu", 1022 device, unit, dlp->physaddr_ack.dl_addr_length); 1023 (void) close(fd); 1024 return (-1); 1025 } 1026 1027 /* 1028 * Save our mac address. 1029 */ 1030 if ((rarpdev->lladdr = (uchar_t *)malloc(rarpdev->ifaddrlen)) == NULL) { 1031 if (dflag) 1032 debug(" %s%d malloc failed: %d bytes", device, 1033 unit, rarpdev->ifaddrlen); 1034 (void) close(fd); 1035 return (-1); 1036 } 1037 1038 eap = (uchar_t *)dlp + dlp->physaddr_ack.dl_addr_offset; 1039 (void) memcpy(rarpdev->lladdr, eap, dlp->physaddr_ack.dl_addr_length); 1040 1041 if (dflag) { 1042 str = _link_ntoa(rarpdev->lladdr, str, rarpdev->ifaddrlen, 1043 IFT_OTHER); 1044 if (str != NULL) { 1045 debug("device %s%d lladdress %s", device, unit, str); 1046 free(str); 1047 } 1048 } 1049 1050 return (fd); 1051 } 1052 1053 /* ARGSUSED */ 1054 static void 1055 do_delay_write(void *buf) 1056 { 1057 struct timeval tv; 1058 struct rarpreply *rrp; 1059 int err; 1060 1061 for (;;) { 1062 if ((err = sema_wait(&delay_sema)) != 0) { 1063 if (err == EINTR) 1064 continue; 1065 error("do_delay_write: sema_wait failed"); 1066 } 1067 1068 (void) mutex_lock(&delay_mutex); 1069 rrp = delay_list; 1070 delay_list = delay_list->next; 1071 (void) mutex_unlock(&delay_mutex); 1072 1073 (void) gettimeofday(&tv, NULL); 1074 if (tv.tv_sec < rrp->tv.tv_sec) 1075 (void) sleep(rrp->tv.tv_sec - tv.tv_sec); 1076 1077 if (rarp_write(rrp->rdev->fd, rrp) < 0) 1078 error("rarp_write error"); 1079 1080 (void) free(rrp); 1081 } 1082 /* NOTREACHED */ 1083 } 1084 1085 /* ARGSUSED */ 1086 static void 1087 delay_write(struct rarpdev *rdev, struct rarpreply *rrp) 1088 { 1089 struct rarpreply *trp; 1090 1091 (void) mutex_lock(&delay_mutex); 1092 if (delay_list == NULL) { 1093 delay_list = rrp; 1094 } else { 1095 trp = delay_list; 1096 while (trp->next != NULL) 1097 trp = trp->next; 1098 trp->next = rrp; 1099 } 1100 (void) mutex_unlock(&delay_mutex); 1101 1102 (void) sema_post(&delay_sema); 1103 } 1104 1105 static int 1106 rarp_write(int fd, struct rarpreply *rrp) 1107 { 1108 struct strbuf ctl, data; 1109 union DL_primitives *dlp; 1110 char ctlbuf[BUFSIZE]; 1111 ushort_t etype = ETHERTYPE_REVARP; 1112 int ifaddrlen = rrp->rdev->ifaddrlen; 1113 1114 /* 1115 * Construct DL_UNITDATA_REQ. 1116 */ 1117 /* LINTED pointer */ 1118 dlp = (union DL_primitives *)ctlbuf; 1119 ctl.len = DL_UNITDATA_REQ_SIZE + ifaddrlen + abs(rrp->rdev->ifsaplen); 1120 ctl.buf = ctlbuf; 1121 data.len = rrp->rdev->ifrarplen; 1122 data.buf = (char *)rrp->arprep; 1123 if (ctl.len > sizeof (ctlbuf)) 1124 return (-1); 1125 1126 dlp->unitdata_req.dl_primitive = DL_UNITDATA_REQ; 1127 dlp->unitdata_req.dl_dest_addr_length = ifaddrlen + 1128 abs(rrp->rdev->ifsaplen); 1129 dlp->unitdata_req.dl_dest_addr_offset = DL_UNITDATA_REQ_SIZE; 1130 dlp->unitdata_req.dl_priority.dl_min = 0; 1131 dlp->unitdata_req.dl_priority.dl_max = 0; 1132 (void) memcpy(ctlbuf + DL_UNITDATA_REQ_SIZE, rrp->lldest, ifaddrlen); 1133 (void) memcpy(ctlbuf + DL_UNITDATA_REQ_SIZE + ifaddrlen, &etype, 1134 sizeof (etype)); 1135 1136 /* 1137 * Send DL_UNITDATA_REQ. 1138 */ 1139 return (putmsg(fd, &ctl, &data, 0)); 1140 } 1141 1142 /* 1143 * See if we have a TFTP boot file for this guy. Filenames in TFTP 1144 * boot requests are of the form <ipaddr> for Sun-3's and of the form 1145 * <ipaddr>.<arch> for all other architectures. Since we don't know 1146 * the client's architecture, either format will do. 1147 */ 1148 static int 1149 mightboot(ipaddr_t ipa) 1150 { 1151 char path[MAXPATHL]; 1152 DIR *dirp; 1153 struct dirent *dp; 1154 1155 (void) snprintf(path, sizeof (path), "%s/%08X", BOOTDIR, ipa); 1156 1157 /* 1158 * Try a quick access() first. 1159 */ 1160 if (access(path, 0) == 0) 1161 return (1); 1162 1163 /* 1164 * Not there, do it the slow way by 1165 * reading through the directory. 1166 */ 1167 (void) sprintf(path, "%08X", ipa); 1168 1169 if (!(dirp = opendir(BOOTDIR))) 1170 return (0); 1171 1172 while ((dp = readdir(dirp)) != NULL) { 1173 if (strncmp(dp->d_name, path, 8) != 0) 1174 continue; 1175 if ((strlen(dp->d_name) != 8) && (dp->d_name[8] != '.')) 1176 continue; 1177 break; 1178 } 1179 1180 (void) closedir(dirp); 1181 1182 return (dp? 1: 0); 1183 } 1184 1185 /* 1186 * Get our IP address and local netmask. 1187 */ 1188 static void 1189 get_ifdata(char *dev, int unit, ipaddr_t *ipp, ipaddr_t *maskp) 1190 { 1191 int fd; 1192 struct ifreq ifr; 1193 struct sockaddr_in *sin; 1194 1195 /* LINTED pointer */ 1196 sin = (struct sockaddr_in *)&ifr.ifr_addr; 1197 1198 /* 1199 * Open the IP provider. 1200 */ 1201 if ((fd = open(DEVIP, 0)) < 0) 1202 syserr(DEVIP); 1203 1204 /* 1205 * Ask IP for our IP address. 1206 */ 1207 (void) snprintf(ifr.ifr_name, sizeof (ifr.ifr_name), "%s%d", dev, unit); 1208 if (strioctl(fd, SIOCGIFADDR, -1, sizeof (struct ifreq), 1209 (char *)&ifr) < 0) 1210 syserr("SIOCGIFADDR"); 1211 *ipp = (ipaddr_t)ntohl(sin->sin_addr.s_addr); 1212 1213 if (dflag) 1214 debug("device %s%d address %s", 1215 dev, unit, inet_ntoa(sin->sin_addr)); 1216 1217 /* 1218 * Ask IP for our netmask. 1219 */ 1220 if (strioctl(fd, SIOCGIFNETMASK, -1, sizeof (struct ifreq), 1221 (char *)&ifr) < 0) 1222 syserr("SIOCGIFNETMASK"); 1223 *maskp = (ipaddr_t)ntohl(sin->sin_addr.s_addr); 1224 1225 if (dflag) 1226 debug("device %s%d subnet mask %s", 1227 dev, unit, inet_ntoa(sin->sin_addr)); 1228 1229 /* 1230 * Thankyou ip. 1231 */ 1232 (void) close(fd); 1233 } 1234 1235 /* 1236 * Translate mac address to IP address. 1237 * Return 0 on success, nonzero on failure. 1238 */ 1239 static int 1240 get_ipaddr(struct rarpdev *rdev, uchar_t *laddr, uchar_t *ipp, ipaddr_t *ipaddr) 1241 { 1242 char host[MAXHOSTL]; 1243 char hbuffer[BUFSIZE]; 1244 struct hostent *hp, res; 1245 int herror; 1246 struct in_addr addr; 1247 char **p; 1248 struct ifdev *ifdev; 1249 1250 if (rdev->ifaddrlen != ETHERADDRL) { 1251 if (dflag) 1252 debug("%s %s", " can not map non 6 byte hardware ", 1253 "address to IP address"); 1254 return (1); 1255 } 1256 1257 /* 1258 * Translate mac address to hostname 1259 * and IP address. 1260 */ 1261 if (ether_ntohost(host, (struct ether_addr *)laddr) != 0 || 1262 !(hp = gethostbyname_r(host, &res, hbuffer, sizeof (hbuffer), 1263 &herror)) || 1264 hp->h_addrtype != AF_INET || hp->h_length != sizeof (ipaddr_t)) { 1265 if (dflag) 1266 debug("could not map hardware address to IP address"); 1267 return (1); 1268 } 1269 1270 /* 1271 * Find the IP address on the right net. 1272 */ 1273 for (p = hp->h_addr_list; *p; p++) { 1274 (void) memcpy(&addr, *p, sizeof (ipaddr_t)); 1275 for (ifdev = rdev->ifdev; ifdev != NULL; ifdev = ifdev->next) { 1276 if (dflag) { 1277 struct in_addr daddr; 1278 ipaddr_t netnum; 1279 1280 netnum = htonl(ifdev->if_netnum); 1281 (void) memcpy(&daddr, &netnum, 1282 sizeof (ipaddr_t)); 1283 if (ifdev->lunit == -1) 1284 debug( 1285 "trying physical netnum %s mask %x", 1286 inet_ntoa(daddr), 1287 ifdev->if_netmask); 1288 else 1289 debug( 1290 "trying logical %d netnum %s mask %x", 1291 ifdev->lunit, 1292 inet_ntoa(daddr), 1293 ifdev->if_netmask); 1294 } 1295 if ((ntohl(addr.s_addr) & ifdev->if_netmask) == 1296 ifdev->if_netnum) { 1297 /* 1298 * Return the correct IP address. 1299 */ 1300 (void) memcpy(ipp, &addr, sizeof (ipaddr_t)); 1301 1302 /* 1303 * Return the interface's ipaddr 1304 */ 1305 (void) memcpy(ipaddr, &ifdev->ipaddr, 1306 sizeof (ipaddr_t)); 1307 1308 return (0); 1309 } 1310 } 1311 } 1312 1313 if (dflag) 1314 debug("got host entry but no IP address on this net"); 1315 return (1); 1316 } 1317 1318 /*ARGSUSED*/ 1319 void 1320 sigalarm(int i) 1321 { 1322 error(alarmmsg); 1323 } 1324 1325 static int 1326 strioctl(int fd, int cmd, int timout, int len, char *dp) 1327 { 1328 struct strioctl si; 1329 1330 si.ic_cmd = cmd; 1331 si.ic_timout = timout; 1332 si.ic_len = len; 1333 si.ic_dp = dp; 1334 return (ioctl(fd, I_STR, &si)); 1335 } 1336 1337 static void 1338 usage() 1339 { 1340 error("Usage: %s [ -ad ] device unit", cmdname); 1341 } 1342 1343 static void 1344 syserr(s) 1345 char *s; 1346 { 1347 char buf[256]; 1348 int status = 1; 1349 1350 (void) snprintf(buf, sizeof (buf), "%s: %s", s, strerror(errno)); 1351 (void) fprintf(stderr, "%s: %s\n", cmdname, buf); 1352 syslog(LOG_ERR, "%s", buf); 1353 thr_exit(&status); 1354 } 1355 1356 /*PRINTFLIKE1*/ 1357 static void 1358 error(char *fmt, ...) 1359 { 1360 char buf[256]; 1361 va_list ap; 1362 int status = 1; 1363 1364 va_start(ap, fmt); 1365 (void) vsprintf(buf, fmt, ap); 1366 va_end(ap); 1367 (void) fprintf(stderr, "%s: %s\n", cmdname, buf); 1368 syslog(LOG_ERR, buf); 1369 thr_exit(&status); 1370 } 1371 1372 /*PRINTFLIKE1*/ 1373 static void 1374 debug(char *fmt, ...) 1375 { 1376 va_list ap; 1377 1378 (void) mutex_lock(&debug_mutex); 1379 va_start(ap, fmt); 1380 (void) fprintf(stderr, "%s:[%u] ", cmdname, thr_self()); 1381 (void) vfprintf(stderr, fmt, ap); 1382 (void) fprintf(stderr, "\n"); 1383 va_end(ap); 1384 (void) mutex_unlock(&debug_mutex); 1385 } 1386