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