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