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 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include "defs.h" 29 #include "tables.h" 30 #include <fcntl.h> 31 32 static void initlog(void); 33 static void run_timeouts(void); 34 35 static void advertise(struct sockaddr_in6 *sin6, struct phyint *pi, 36 boolean_t no_prefixes); 37 static void solicit(struct sockaddr_in6 *sin6, struct phyint *pi); 38 static void initifs(boolean_t first); 39 static void check_if_removed(struct phyint *pi); 40 static void loopback_ra_enqueue(struct phyint *pi, 41 struct nd_router_advert *ra, int len); 42 static void loopback_ra_dequeue(void); 43 static void check_daemonize(void); 44 45 struct in6_addr all_nodes_mcast = { { 0xff, 0x2, 0x0, 0x0, 46 0x0, 0x0, 0x0, 0x0, 47 0x0, 0x0, 0x0, 0x0, 48 0x0, 0x0, 0x0, 0x1 } }; 49 50 struct in6_addr all_routers_mcast = { { 0xff, 0x2, 0x0, 0x0, 51 0x0, 0x0, 0x0, 0x0, 52 0x0, 0x0, 0x0, 0x0, 53 0x0, 0x0, 0x0, 0x2 } }; 54 55 static struct sockaddr_in6 v6allnodes = { AF_INET6, 0, 0, 56 { 0xff, 0x2, 0x0, 0x0, 57 0x0, 0x0, 0x0, 0x0, 58 0x0, 0x0, 0x0, 0x0, 59 0x0, 0x0, 0x0, 0x1 } }; 60 61 static struct sockaddr_in6 v6allrouters = { AF_INET6, 0, 0, 62 { 0xff, 0x2, 0x0, 0x0, 63 0x0, 0x0, 0x0, 0x0, 64 0x0, 0x0, 0x0, 0x0, 65 0x0, 0x0, 0x0, 0x2 } }; 66 67 static char **argv0; /* Saved for re-exec on SIGHUP */ 68 69 static uint64_t packet[(IP_MAXPACKET + 1)/8]; 70 71 static int show_ifs = 0; 72 static boolean_t already_daemonized = _B_FALSE; 73 int debug = 0; 74 int no_loopback = 0; /* Do not send RA packets to ourselves */ 75 76 /* 77 * Size of routing socket message used by in.ndpd which includes the header, 78 * space for the RTA_DST, RTA_GATEWAY and RTA_NETMASK (each a sockaddr_in6) 79 * plus space for the RTA_IFP (a sockaddr_dl). 80 */ 81 #define NDP_RTM_MSGLEN sizeof (struct rt_msghdr) + \ 82 sizeof (struct sockaddr_in6) + \ 83 sizeof (struct sockaddr_in6) + \ 84 sizeof (struct sockaddr_in6) + \ 85 sizeof (struct sockaddr_dl) 86 87 /* 88 * These are referenced externally in tables.c in order to fill in the 89 * dynamic portions of the routing socket message and then to send the message 90 * itself. 91 */ 92 int rtsock = -1; /* Routing socket */ 93 struct rt_msghdr *rt_msg; /* Routing socket message */ 94 struct sockaddr_in6 *rta_gateway; /* RTA_GATEWAY sockaddr */ 95 struct sockaddr_dl *rta_ifp; /* RTA_IFP sockaddr */ 96 97 /* 98 * Return the current time in milliseconds truncated to 99 * fit in an integer. 100 */ 101 uint_t 102 getcurrenttime(void) 103 { 104 struct timeval tp; 105 106 if (gettimeofday(&tp, NULL) < 0) { 107 logperror("getcurrenttime: gettimeofday failed"); 108 exit(1); 109 } 110 return (tp.tv_sec * 1000 + tp.tv_usec / 1000); 111 } 112 113 /* 114 * Output a preformated packet from the packet[] buffer. 115 */ 116 static void 117 sendpacket(struct sockaddr_in6 *sin6, int sock, int size, int flags) 118 { 119 int cc; 120 char abuf[INET6_ADDRSTRLEN]; 121 122 cc = sendto(sock, (char *)packet, size, flags, 123 (struct sockaddr *)sin6, sizeof (*sin6)); 124 if (cc < 0 || cc != size) { 125 if (cc < 0) { 126 logperror("sendpacket: sendto"); 127 } 128 logmsg(LOG_ERR, "sendpacket: wrote %s %d chars, ret=%d\n", 129 inet_ntop(sin6->sin6_family, 130 (void *)&sin6->sin6_addr, 131 abuf, sizeof (abuf)), 132 size, cc); 133 } 134 } 135 136 /* Send a Router Solicitation */ 137 static void 138 solicit(struct sockaddr_in6 *sin6, struct phyint *pi) 139 { 140 int packetlen = 0; 141 struct nd_router_solicit *rs = (struct nd_router_solicit *)packet; 142 char *pptr = (char *)packet; 143 144 rs->nd_rs_type = ND_ROUTER_SOLICIT; 145 rs->nd_rs_code = 0; 146 rs->nd_rs_cksum = htons(0); 147 rs->nd_rs_reserved = htonl(0); 148 149 packetlen += sizeof (*rs); 150 pptr += sizeof (*rs); 151 152 /* Attach any options */ 153 if (pi->pi_hdw_addr_len != 0) { 154 struct nd_opt_lla *lo = (struct nd_opt_lla *)pptr; 155 int optlen; 156 157 /* roundup to multiple of 8 and make padding zero */ 158 optlen = ((sizeof (struct nd_opt_hdr) + 159 pi->pi_hdw_addr_len + 7) / 8) * 8; 160 bzero(pptr, optlen); 161 162 lo->nd_opt_lla_type = ND_OPT_SOURCE_LINKADDR; 163 lo->nd_opt_lla_len = optlen / 8; 164 bcopy((char *)pi->pi_hdw_addr, 165 (char *)lo->nd_opt_lla_hdw_addr, 166 pi->pi_hdw_addr_len); 167 packetlen += optlen; 168 pptr += optlen; 169 } 170 171 if (debug & D_PKTOUT) { 172 print_route_sol("Sending solicitation to ", pi, rs, packetlen, 173 sin6); 174 } 175 sendpacket(sin6, pi->pi_sock, packetlen, 0); 176 } 177 178 /* 179 * Send a (set of) Router Advertisements and feed them back to ourselves 180 * for processing. Unless no_prefixes is set all prefixes are included. 181 * If there are too many prefix options to fit in one packet multiple 182 * packets will be sent - each containing a subset of the prefix options. 183 */ 184 static void 185 advertise(struct sockaddr_in6 *sin6, struct phyint *pi, boolean_t no_prefixes) 186 { 187 struct nd_opt_prefix_info *po; 188 char *pptr = (char *)packet; 189 struct nd_router_advert *ra; 190 struct adv_prefix *adv_pr; 191 int packetlen = 0; 192 193 ra = (struct nd_router_advert *)pptr; 194 ra->nd_ra_type = ND_ROUTER_ADVERT; 195 ra->nd_ra_code = 0; 196 ra->nd_ra_cksum = htons(0); 197 ra->nd_ra_curhoplimit = pi->pi_AdvCurHopLimit; 198 ra->nd_ra_flags_reserved = 0; 199 if (pi->pi_AdvManagedFlag) 200 ra->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED; 201 if (pi->pi_AdvOtherConfigFlag) 202 ra->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER; 203 204 if (pi->pi_adv_state == FINAL_ADV) 205 ra->nd_ra_router_lifetime = htons(0); 206 else 207 ra->nd_ra_router_lifetime = htons(pi->pi_AdvDefaultLifetime); 208 ra->nd_ra_reachable = htonl(pi->pi_AdvReachableTime); 209 ra->nd_ra_retransmit = htonl(pi->pi_AdvRetransTimer); 210 211 packetlen = sizeof (*ra); 212 pptr += sizeof (*ra); 213 214 if (pi->pi_adv_state == FINAL_ADV) { 215 if (debug & D_PKTOUT) { 216 print_route_adv("Sending advert (FINAL) to ", pi, 217 ra, packetlen, sin6); 218 } 219 sendpacket(sin6, pi->pi_sock, packetlen, 0); 220 /* Feed packet back in for router operation */ 221 loopback_ra_enqueue(pi, ra, packetlen); 222 return; 223 } 224 225 /* Attach any options */ 226 if (pi->pi_hdw_addr_len != 0) { 227 struct nd_opt_lla *lo = (struct nd_opt_lla *)pptr; 228 int optlen; 229 230 /* roundup to multiple of 8 and make padding zero */ 231 optlen = ((sizeof (struct nd_opt_hdr) + 232 pi->pi_hdw_addr_len + 7) / 8) * 8; 233 bzero(pptr, optlen); 234 235 lo->nd_opt_lla_type = ND_OPT_SOURCE_LINKADDR; 236 lo->nd_opt_lla_len = optlen / 8; 237 bcopy((char *)pi->pi_hdw_addr, 238 (char *)lo->nd_opt_lla_hdw_addr, 239 pi->pi_hdw_addr_len); 240 packetlen += optlen; 241 pptr += optlen; 242 } 243 244 if (pi->pi_AdvLinkMTU != 0) { 245 struct nd_opt_mtu *mo = (struct nd_opt_mtu *)pptr; 246 247 mo->nd_opt_mtu_type = ND_OPT_MTU; 248 mo->nd_opt_mtu_len = sizeof (struct nd_opt_mtu) / 8; 249 mo->nd_opt_mtu_reserved = 0; 250 mo->nd_opt_mtu_mtu = htonl(pi->pi_AdvLinkMTU); 251 252 packetlen += sizeof (struct nd_opt_mtu); 253 pptr += sizeof (struct nd_opt_mtu); 254 } 255 256 if (no_prefixes) { 257 if (debug & D_PKTOUT) { 258 print_route_adv("Sending advert to ", pi, 259 ra, packetlen, sin6); 260 } 261 sendpacket(sin6, pi->pi_sock, packetlen, 0); 262 /* Feed packet back in for router operation */ 263 loopback_ra_enqueue(pi, ra, packetlen); 264 return; 265 } 266 267 po = (struct nd_opt_prefix_info *)pptr; 268 for (adv_pr = pi->pi_adv_prefix_list; adv_pr != NULL; 269 adv_pr = adv_pr->adv_pr_next) { 270 if (!adv_pr->adv_pr_AdvOnLinkFlag && 271 !adv_pr->adv_pr_AdvAutonomousFlag) { 272 continue; 273 } 274 275 /* 276 * If the prefix doesn't fit in packet send 277 * what we have so far and start with new packet. 278 */ 279 if (packetlen + sizeof (*po) > 280 pi->pi_LinkMTU - sizeof (struct ip6_hdr)) { 281 if (debug & D_PKTOUT) { 282 print_route_adv("Sending advert " 283 "(FRAG) to ", 284 pi, ra, packetlen, sin6); 285 } 286 sendpacket(sin6, pi->pi_sock, packetlen, 0); 287 /* Feed packet back in for router operation */ 288 loopback_ra_enqueue(pi, ra, packetlen); 289 packetlen = sizeof (*ra); 290 pptr = (char *)packet + sizeof (*ra); 291 po = (struct nd_opt_prefix_info *)pptr; 292 } 293 po->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION; 294 po->nd_opt_pi_len = sizeof (*po)/8; 295 po->nd_opt_pi_flags_reserved = 0; 296 if (adv_pr->adv_pr_AdvOnLinkFlag) { 297 po->nd_opt_pi_flags_reserved |= 298 ND_OPT_PI_FLAG_ONLINK; 299 } 300 if (adv_pr->adv_pr_AdvAutonomousFlag) { 301 po->nd_opt_pi_flags_reserved |= 302 ND_OPT_PI_FLAG_AUTO; 303 } 304 po->nd_opt_pi_prefix_len = adv_pr->adv_pr_prefix_len; 305 /* 306 * If both Adv*Expiration and Adv*Lifetime are 307 * set we prefer the former and make the lifetime 308 * decrement in real time. 309 */ 310 if (adv_pr->adv_pr_AdvValidRealTime) { 311 po->nd_opt_pi_valid_time = 312 htonl(adv_pr->adv_pr_AdvValidExpiration); 313 } else { 314 po->nd_opt_pi_valid_time = 315 htonl(adv_pr->adv_pr_AdvValidLifetime); 316 } 317 if (adv_pr->adv_pr_AdvPreferredRealTime) { 318 po->nd_opt_pi_preferred_time = 319 htonl(adv_pr->adv_pr_AdvPreferredExpiration); 320 } else { 321 po->nd_opt_pi_preferred_time = 322 htonl(adv_pr->adv_pr_AdvPreferredLifetime); 323 } 324 po->nd_opt_pi_reserved2 = htonl(0); 325 po->nd_opt_pi_prefix = adv_pr->adv_pr_prefix; 326 327 po++; 328 packetlen += sizeof (*po); 329 } 330 if (debug & D_PKTOUT) { 331 print_route_adv("Sending advert to ", pi, 332 ra, packetlen, sin6); 333 } 334 sendpacket(sin6, pi->pi_sock, packetlen, 0); 335 /* Feed packet back in for router operation */ 336 loopback_ra_enqueue(pi, ra, packetlen); 337 } 338 339 /* Poll support */ 340 static int pollfd_num = 0; /* Allocated and initialized */ 341 static struct pollfd *pollfds = NULL; 342 343 /* 344 * Add fd to the set being polled. Returns 0 if ok; -1 if failed. 345 */ 346 int 347 poll_add(int fd) 348 { 349 int i; 350 int new_num; 351 struct pollfd *newfds; 352 retry: 353 /* Check if already present */ 354 for (i = 0; i < pollfd_num; i++) { 355 if (pollfds[i].fd == fd) 356 return (0); 357 } 358 /* Check for empty spot already present */ 359 for (i = 0; i < pollfd_num; i++) { 360 if (pollfds[i].fd == -1) { 361 pollfds[i].fd = fd; 362 return (0); 363 } 364 } 365 366 /* Allocate space for 32 more fds and initialize to -1 */ 367 new_num = pollfd_num + 32; 368 newfds = realloc(pollfds, new_num * sizeof (struct pollfd)); 369 if (newfds == NULL) { 370 logperror("poll_add: realloc"); 371 return (-1); 372 } 373 for (i = pollfd_num; i < new_num; i++) { 374 newfds[i].fd = -1; 375 newfds[i].events = POLLIN; 376 } 377 pollfd_num = new_num; 378 pollfds = newfds; 379 goto retry; 380 } 381 382 /* 383 * Remove fd from the set being polled. Returns 0 if ok; -1 if failed. 384 */ 385 int 386 poll_remove(int fd) 387 { 388 int i; 389 390 /* Check if already present */ 391 for (i = 0; i < pollfd_num; i++) { 392 if (pollfds[i].fd == fd) { 393 pollfds[i].fd = -1; 394 return (0); 395 } 396 } 397 return (-1); 398 } 399 400 /* 401 * Extract information about the ifname (either a physical interface and 402 * the ":0" logical interface or just a logical interface). 403 * If the interface (still) exists in kernel set pr_in_use 404 * for caller to be able to detect interfaces that are removed. 405 * Starts sending advertisements/solicitations when new physical interfaces 406 * are detected. 407 */ 408 static void 409 if_process(int s, char *ifname, boolean_t first) 410 { 411 struct lifreq lifr; 412 struct phyint *pi; 413 struct prefix *pr; 414 char *cp; 415 char phyintname[LIFNAMSIZ + 1]; 416 417 if (debug & D_IFSCAN) 418 logmsg(LOG_DEBUG, "if_process(%s)\n", ifname); 419 420 (void) strncpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name)); 421 lifr.lifr_name[sizeof (lifr.lifr_name) - 1] = '\0'; 422 if (ioctl(s, SIOCGLIFFLAGS, (char *)&lifr) < 0) { 423 if (errno == ENXIO) { 424 /* 425 * Interface has disappeared 426 */ 427 return; 428 } 429 logperror("if_process: ioctl (get interface flags)"); 430 return; 431 } 432 433 /* 434 * Ignore loopback and point-to-multipoint interfaces. 435 * Point-to-point interfaces always have IFF_MULTICAST set. 436 */ 437 if (!(lifr.lifr_flags & IFF_MULTICAST) || 438 (lifr.lifr_flags & IFF_LOOPBACK)) { 439 return; 440 } 441 442 if (!(lifr.lifr_flags & IFF_IPV6)) 443 return; 444 445 (void) strncpy(phyintname, ifname, sizeof (phyintname)); 446 phyintname[sizeof (phyintname) - 1] = '\0'; 447 if ((cp = strchr(phyintname, IF_SEPARATOR)) != NULL) { 448 *cp = '\0'; 449 } 450 451 pi = phyint_lookup(phyintname); 452 if (pi == NULL) { 453 /* 454 * Do not add anything for new interfaces until they are UP. 455 * For existing interfaces we track the up flag. 456 */ 457 if (!(lifr.lifr_flags & IFF_UP)) 458 return; 459 460 pi = phyint_create(phyintname); 461 if (pi == NULL) { 462 logmsg(LOG_ERR, "if_process: out of memory\n"); 463 return; 464 } 465 } 466 (void) phyint_init_from_k(pi); 467 if (pi->pi_sock == -1 && !(pi->pi_kernel_state & PI_PRESENT)) { 468 /* Interface is not yet present */ 469 if (debug & D_PHYINT) { 470 logmsg(LOG_DEBUG, "if_process: interface not yet " 471 "present %s\n", pi->pi_name); 472 } 473 return; 474 } 475 476 if (pi->pi_sock != -1) { 477 if (poll_add(pi->pi_sock) == -1) { 478 /* 479 * reset state. 480 */ 481 phyint_cleanup(pi); 482 } 483 } 484 485 /* 486 * Check if IFF_ROUTER has been turned off in kernel in which 487 * case we have to turn off AdvSendAdvertisements. 488 * The kernel will automatically turn off IFF_ROUTER if 489 * ip6_forwarding is turned off. 490 * Note that we do not switch back should IFF_ROUTER be turned on. 491 */ 492 if (!first && 493 pi->pi_AdvSendAdvertisements && !(pi->pi_flags & IFF_ROUTER)) { 494 logmsg(LOG_INFO, "No longer a router on %s\n", pi->pi_name); 495 check_to_advertise(pi, START_FINAL_ADV); 496 497 pi->pi_AdvSendAdvertisements = 0; 498 pi->pi_sol_state = NO_SOLICIT; 499 } 500 501 /* 502 * Send advertisments and solicitation only if the interface is 503 * present in the kernel. 504 */ 505 if (pi->pi_kernel_state & PI_PRESENT) { 506 507 if (pi->pi_AdvSendAdvertisements) { 508 if (pi->pi_adv_state == NO_ADV) 509 check_to_advertise(pi, START_INIT_ADV); 510 } else { 511 if (pi->pi_sol_state == NO_SOLICIT) 512 check_to_solicit(pi, START_INIT_SOLICIT); 513 } 514 } 515 516 /* 517 * Track static kernel prefixes to prevent in.ndpd from clobbering 518 * them by creating a struct prefix for each prefix detected in the 519 * kernel. 520 */ 521 pr = prefix_lookup_name(pi, ifname); 522 if (pr == NULL) { 523 pr = prefix_create_name(pi, ifname); 524 if (pr == NULL) { 525 logmsg(LOG_ERR, "if_process: out of memory\n"); 526 return; 527 } 528 if (prefix_init_from_k(pr) == -1) { 529 prefix_delete(pr); 530 return; 531 } 532 } 533 /* Detect prefixes which are removed */ 534 if (pr->pr_kernel_state != 0) 535 pr->pr_in_use = _B_TRUE; 536 537 if ((lifr.lifr_flags & IFF_DUPLICATE) && 538 (pr->pr_flags & IFF_TEMPORARY)) { 539 in6_addr_t *token; 540 int i; 541 char abuf[INET6_ADDRSTRLEN]; 542 543 if (++pr->pr_attempts >= MAX_DAD_FAILURES) { 544 logmsg(LOG_ERR, "%s: token %s is duplicate after %d " 545 "attempts; disabling temporary addresses on %s", 546 pr->pr_name, inet_ntop(AF_INET6, 547 (void *)&pi->pi_tmp_token, abuf, sizeof (abuf)), 548 pr->pr_attempts, pi->pi_name); 549 pi->pi_TmpAddrsEnabled = 0; 550 tmptoken_delete(pi); 551 prefix_delete(pr); 552 return; 553 } 554 logmsg(LOG_WARNING, "%s: token %s is duplicate; trying again", 555 pr->pr_name, inet_ntop(AF_INET6, (void *)&pi->pi_tmp_token, 556 abuf, sizeof (abuf))); 557 if (!tmptoken_create(pi)) { 558 prefix_delete(pr); 559 return; 560 } 561 token = &pi->pi_tmp_token; 562 for (i = 0; i < 16; i++) { 563 /* 564 * prefix_create ensures that pr_prefix has all-zero 565 * bits after prefixlen. 566 */ 567 pr->pr_address.s6_addr[i] = pr->pr_prefix.s6_addr[i] | 568 token->s6_addr[i]; 569 } 570 if (prefix_lookup_addr_match(pr) != NULL) { 571 prefix_delete(pr); 572 return; 573 } 574 pr->pr_CreateTime = getcurrenttime() / MILLISEC; 575 /* 576 * We've got a new token. Clearing PR_AUTO causes 577 * prefix_update_k to bring the interface up and set the 578 * address. 579 */ 580 pr->pr_kernel_state &= ~PR_AUTO; 581 prefix_update_k(pr); 582 } 583 } 584 585 static int ifsock = -1; 586 587 /* 588 * Scan all interfaces to detect changes as well as new and deleted intefaces 589 * 'first' is set for the initial call only. Do not effect anything. 590 */ 591 static void 592 initifs(boolean_t first) 593 { 594 char *buf; 595 int bufsize; 596 int numifs; 597 int n; 598 struct lifnum lifn; 599 struct lifconf lifc; 600 struct lifreq *lifr; 601 struct phyint *pi; 602 struct phyint *next_pi; 603 struct prefix *pr; 604 605 if (debug & D_IFSCAN) 606 logmsg(LOG_DEBUG, "Reading interface configuration\n"); 607 if (ifsock < 0) { 608 ifsock = socket(AF_INET6, SOCK_DGRAM, 0); 609 if (ifsock < 0) { 610 logperror("initifs: socket"); 611 return; 612 } 613 } 614 lifn.lifn_family = AF_INET6; 615 lifn.lifn_flags = LIFC_NOXMIT | LIFC_TEMPORARY; 616 if (ioctl(ifsock, SIOCGLIFNUM, (char *)&lifn) < 0) { 617 logperror("initifs: ioctl (get interface numbers)"); 618 return; 619 } 620 numifs = lifn.lifn_count; 621 bufsize = numifs * sizeof (struct lifreq); 622 623 buf = (char *)malloc(bufsize); 624 if (buf == NULL) { 625 logmsg(LOG_ERR, "initifs: out of memory\n"); 626 return; 627 } 628 629 /* 630 * Mark the interfaces so that we can find phyints and prefixes 631 * which have disappeared from the kernel. 632 * if_process will set pr_in_use when it finds the interface 633 * in the kernel. 634 */ 635 for (pi = phyints; pi != NULL; pi = pi->pi_next) { 636 /* 637 * Before re-examining the state of the interfaces, 638 * PI_PRESENT should be cleared from pi_kernel_state. 639 */ 640 pi->pi_kernel_state &= ~PI_PRESENT; 641 for (pr = pi->pi_prefix_list; pr != NULL; pr = pr->pr_next) { 642 pr->pr_in_use = _B_FALSE; 643 } 644 } 645 646 lifc.lifc_family = AF_INET6; 647 lifc.lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY; 648 lifc.lifc_len = bufsize; 649 lifc.lifc_buf = buf; 650 651 if (ioctl(ifsock, SIOCGLIFCONF, (char *)&lifc) < 0) { 652 logperror("initifs: ioctl (get interface configuration)"); 653 free(buf); 654 return; 655 } 656 657 lifr = (struct lifreq *)lifc.lifc_req; 658 for (n = lifc.lifc_len / sizeof (struct lifreq); n > 0; n--, lifr++) 659 if_process(ifsock, lifr->lifr_name, first); 660 free(buf); 661 662 /* 663 * Detect phyints that have been removed from the kernel. 664 * Since we can't recreate it here (would require ifconfig plumb 665 * logic) we just terminate use of that phyint. 666 */ 667 for (pi = phyints; pi != NULL; pi = next_pi) { 668 next_pi = pi->pi_next; 669 /* 670 * If interface (still) exists in kernel, set 671 * pi_state to indicate that. 672 */ 673 if (pi->pi_kernel_state & PI_PRESENT) { 674 pi->pi_state |= PI_PRESENT; 675 } 676 677 check_if_removed(pi); 678 } 679 if (show_ifs) 680 phyint_print_all(); 681 } 682 683 684 /* 685 * Router advertisement state machine. Used for everything but timer 686 * events which use advertise_event directly. 687 */ 688 void 689 check_to_advertise(struct phyint *pi, enum adv_events event) 690 { 691 uint_t delay; 692 enum adv_states old_state = pi->pi_adv_state; 693 694 if (debug & D_STATE) { 695 logmsg(LOG_DEBUG, "check_to_advertise(%s, %d) state %d\n", 696 pi->pi_name, (int)event, (int)old_state); 697 } 698 delay = advertise_event(pi, event, 0); 699 if (delay != TIMER_INFINITY) { 700 /* Make sure the global next event is updated */ 701 timer_schedule(delay); 702 } 703 704 if (debug & D_STATE) { 705 logmsg(LOG_DEBUG, "check_to_advertise(%s, %d) state %d -> %d\n", 706 pi->pi_name, (int)event, (int)old_state, 707 (int)pi->pi_adv_state); 708 } 709 } 710 711 /* 712 * Router advertisement state machine. 713 * Return the number of milliseconds until next timeout (TIMER_INFINITY 714 * if never). 715 * For the ADV_TIMER event the caller passes in the number of milliseconds 716 * since the last timer event in the 'elapsed' parameter. 717 */ 718 uint_t 719 advertise_event(struct phyint *pi, enum adv_events event, uint_t elapsed) 720 { 721 uint_t delay; 722 723 if (debug & D_STATE) { 724 logmsg(LOG_DEBUG, "advertise_event(%s, %d, %d) state %d\n", 725 pi->pi_name, (int)event, elapsed, (int)pi->pi_adv_state); 726 } 727 check_daemonize(); 728 if (!pi->pi_AdvSendAdvertisements) 729 return (TIMER_INFINITY); 730 if (pi->pi_flags & IFF_NORTEXCH) { 731 if (debug & D_PKTOUT) { 732 logmsg(LOG_DEBUG, "Suppress sending RA packet on %s " 733 "(no route exchange on interface)\n", 734 pi->pi_name); 735 } 736 return (TIMER_INFINITY); 737 } 738 739 switch (event) { 740 case ADV_OFF: 741 pi->pi_adv_state = NO_ADV; 742 return (TIMER_INFINITY); 743 744 case START_INIT_ADV: 745 if (pi->pi_adv_state == INIT_ADV) 746 return (pi->pi_adv_time_left); 747 pi->pi_adv_count = ND_MAX_INITIAL_RTR_ADVERTISEMENTS; 748 pi->pi_adv_time_left = 0; 749 pi->pi_adv_state = INIT_ADV; 750 break; /* send advertisement */ 751 752 case START_FINAL_ADV: 753 if (pi->pi_adv_state == NO_ADV) 754 return (TIMER_INFINITY); 755 if (pi->pi_adv_state == FINAL_ADV) 756 return (pi->pi_adv_time_left); 757 pi->pi_adv_count = ND_MAX_FINAL_RTR_ADVERTISEMENTS; 758 pi->pi_adv_time_left = 0; 759 pi->pi_adv_state = FINAL_ADV; 760 break; /* send advertisement */ 761 762 case RECEIVED_SOLICIT: 763 if (pi->pi_adv_state == NO_ADV) 764 return (TIMER_INFINITY); 765 if (pi->pi_adv_state == SOLICIT_ADV) { 766 if (pi->pi_adv_time_left != 0) 767 return (pi->pi_adv_time_left); 768 break; 769 } 770 delay = GET_RANDOM(0, ND_MAX_RA_DELAY_TIME); 771 if (delay < pi->pi_adv_time_left) 772 pi->pi_adv_time_left = delay; 773 if (pi->pi_adv_time_since_sent < ND_MIN_DELAY_BETWEEN_RAS) { 774 /* 775 * Send an advertisement (ND_MIN_DELAY_BETWEEN_RAS 776 * plus random delay) after the previous 777 * advertisement was sent. 778 */ 779 pi->pi_adv_time_left = delay + 780 ND_MIN_DELAY_BETWEEN_RAS - 781 pi->pi_adv_time_since_sent; 782 } 783 pi->pi_adv_state = SOLICIT_ADV; 784 break; 785 786 case ADV_TIMER: 787 if (pi->pi_adv_state == NO_ADV) 788 return (TIMER_INFINITY); 789 /* Decrease time left */ 790 if (pi->pi_adv_time_left >= elapsed) 791 pi->pi_adv_time_left -= elapsed; 792 else 793 pi->pi_adv_time_left = 0; 794 795 /* Increase time since last advertisement was sent */ 796 pi->pi_adv_time_since_sent += elapsed; 797 break; 798 default: 799 logmsg(LOG_ERR, "advertise_event: Unknown event %d\n", 800 (int)event); 801 return (TIMER_INFINITY); 802 } 803 804 if (pi->pi_adv_time_left != 0) 805 return (pi->pi_adv_time_left); 806 807 /* Send advertisement and calculate next time to send */ 808 if (pi->pi_adv_state == FINAL_ADV) { 809 /* Omit the prefixes */ 810 advertise(&v6allnodes, pi, _B_TRUE); 811 } else { 812 advertise(&v6allnodes, pi, _B_FALSE); 813 } 814 pi->pi_adv_time_since_sent = 0; 815 816 switch (pi->pi_adv_state) { 817 case SOLICIT_ADV: 818 /* 819 * The solicited advertisement has been sent. 820 * Revert to periodic advertisements. 821 */ 822 pi->pi_adv_state = REG_ADV; 823 /* FALLTHRU */ 824 case REG_ADV: 825 pi->pi_adv_time_left = 826 GET_RANDOM(1000 * pi->pi_MinRtrAdvInterval, 827 1000 * pi->pi_MaxRtrAdvInterval); 828 break; 829 830 case INIT_ADV: 831 if (--pi->pi_adv_count > 0) { 832 delay = GET_RANDOM(1000 * pi->pi_MinRtrAdvInterval, 833 1000 * pi->pi_MaxRtrAdvInterval); 834 if (delay > ND_MAX_INITIAL_RTR_ADVERT_INTERVAL) 835 delay = ND_MAX_INITIAL_RTR_ADVERT_INTERVAL; 836 pi->pi_adv_time_left = delay; 837 } else { 838 pi->pi_adv_time_left = 839 GET_RANDOM(1000 * pi->pi_MinRtrAdvInterval, 840 1000 * pi->pi_MaxRtrAdvInterval); 841 pi->pi_adv_state = REG_ADV; 842 } 843 break; 844 845 case FINAL_ADV: 846 if (--pi->pi_adv_count > 0) { 847 pi->pi_adv_time_left = 848 ND_MAX_INITIAL_RTR_ADVERT_INTERVAL; 849 } else { 850 pi->pi_adv_state = NO_ADV; 851 } 852 break; 853 } 854 if (pi->pi_adv_state != NO_ADV) 855 return (pi->pi_adv_time_left); 856 else 857 return (TIMER_INFINITY); 858 } 859 860 /* 861 * Router solicitation state machine. Used for everything but timer 862 * events which use solicit_event directly. 863 */ 864 void 865 check_to_solicit(struct phyint *pi, enum solicit_events event) 866 { 867 uint_t delay; 868 enum solicit_states old_state = pi->pi_sol_state; 869 870 if (debug & D_STATE) { 871 logmsg(LOG_DEBUG, "check_to_solicit(%s, %d) state %d\n", 872 pi->pi_name, (int)event, (int)old_state); 873 } 874 delay = solicit_event(pi, event, 0); 875 if (delay != TIMER_INFINITY) { 876 /* Make sure the global next event is updated */ 877 timer_schedule(delay); 878 } 879 880 if (debug & D_STATE) { 881 logmsg(LOG_DEBUG, "check_to_solicit(%s, %d) state %d -> %d\n", 882 pi->pi_name, (int)event, (int)old_state, 883 (int)pi->pi_sol_state); 884 } 885 } 886 887 static void 888 daemonize_ndpd(void) 889 { 890 FILE *pidfp; 891 mode_t pidmode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* 0644 */ 892 struct itimerval it; 893 boolean_t timerval = _B_TRUE; 894 895 /* 896 * Need to get current timer settings so they can be restored 897 * after the fork(), as the it_value and it_interval values for 898 * the ITIMER_REAL timer are reset to 0 in the child process. 899 */ 900 if (getitimer(ITIMER_REAL, &it) < 0) { 901 if (debug & D_TIMER) 902 logmsg(LOG_DEBUG, 903 "daemonize_ndpd: failed to get itimerval\n"); 904 timerval = _B_FALSE; 905 } 906 907 /* Daemonize. */ 908 switch (fork()) { 909 case 0: 910 /* Child */ 911 break; 912 case -1: 913 logperror("fork"); 914 exit(1); 915 default: 916 /* Parent */ 917 _exit(0); 918 } 919 920 /* Store our process id, blow away any existing file if it exists. */ 921 if ((pidfp = fopen(PATH_PID, "w")) == NULL) { 922 (void) fprintf(stderr, "%s: unable to open " PATH_PID ": %s\n", 923 argv0[0], strerror(errno)); 924 } else { 925 (void) fprintf(pidfp, "%ld\n", getpid()); 926 (void) fclose(pidfp); 927 (void) chmod(PATH_PID, pidmode); 928 } 929 930 (void) close(0); 931 (void) close(1); 932 (void) close(2); 933 934 (void) chdir("/"); 935 (void) open("/dev/null", O_RDWR); 936 (void) dup2(0, 1); 937 (void) dup2(0, 2); 938 (void) setsid(); 939 940 already_daemonized = _B_TRUE; 941 942 /* 943 * Restore timer values, if we were able to save them; if not, 944 * check and set the right value by calling run_timeouts(). 945 */ 946 if (timerval) { 947 if (setitimer(ITIMER_REAL, &it, NULL) < 0) { 948 logperror("daemonize_ndpd: setitimer"); 949 exit(2); 950 } 951 } else { 952 run_timeouts(); 953 } 954 } 955 956 /* 957 * Check to see if the time is right to daemonize. The right time is when: 958 * 959 * 1. We haven't already daemonized. 960 * 2. We are not in debug mode. 961 * 3. All interfaces are marked IFF_NOXMIT. 962 * 4. All non-router interfaces have their prefixes set up and we're 963 * done sending router solicitations on those interfaces without 964 * prefixes. 965 */ 966 static void 967 check_daemonize(void) 968 { 969 struct phyint *pi; 970 971 if (already_daemonized || debug != 0) 972 return; 973 974 for (pi = phyints; pi != NULL; pi = pi->pi_next) { 975 if (!(pi->pi_flags & IFF_NOXMIT)) 976 break; 977 } 978 979 /* 980 * If we can't transmit on any of the interfaces there is no reason 981 * to hold up progress. 982 */ 983 if (pi == NULL) { 984 daemonize_ndpd(); 985 return; 986 } 987 988 /* Check all interfaces. If any are still soliciting, just return. */ 989 for (pi = phyints; pi != NULL; pi = pi->pi_next) { 990 if (pi->pi_AdvSendAdvertisements || 991 !(pi->pi_kernel_state & PI_PRESENT)) 992 continue; 993 994 if (pi->pi_sol_state == INIT_SOLICIT) 995 return; 996 } 997 998 daemonize_ndpd(); 999 } 1000 1001 /* 1002 * Router solicitation state machine. 1003 * Return the number of milliseconds until next timeout (TIMER_INFINITY 1004 * if never). 1005 * For the SOL_TIMER event the caller passes in the number of milliseconds 1006 * since the last timer event in the 'elapsed' parameter. 1007 */ 1008 uint_t 1009 solicit_event(struct phyint *pi, enum solicit_events event, uint_t elapsed) 1010 { 1011 if (debug & D_STATE) { 1012 logmsg(LOG_DEBUG, "solicit_event(%s, %d, %d) state %d\n", 1013 pi->pi_name, (int)event, elapsed, (int)pi->pi_sol_state); 1014 } 1015 1016 if (pi->pi_AdvSendAdvertisements) 1017 return (TIMER_INFINITY); 1018 if (pi->pi_flags & IFF_NORTEXCH) { 1019 if (debug & D_PKTOUT) { 1020 logmsg(LOG_DEBUG, "Suppress sending RS packet on %s " 1021 "(no route exchange on interface)\n", 1022 pi->pi_name); 1023 } 1024 return (TIMER_INFINITY); 1025 } 1026 1027 switch (event) { 1028 case SOLICIT_OFF: 1029 pi->pi_sol_state = NO_SOLICIT; 1030 check_daemonize(); 1031 return (TIMER_INFINITY); 1032 1033 case SOLICIT_DONE: 1034 pi->pi_sol_state = DONE_SOLICIT; 1035 check_daemonize(); 1036 return (TIMER_INFINITY); 1037 1038 case START_INIT_SOLICIT: 1039 if (pi->pi_sol_state == INIT_SOLICIT) 1040 return (pi->pi_sol_time_left); 1041 pi->pi_sol_count = ND_MAX_RTR_SOLICITATIONS; 1042 pi->pi_sol_time_left = 1043 GET_RANDOM(0, ND_MAX_RTR_SOLICITATION_DELAY); 1044 pi->pi_sol_state = INIT_SOLICIT; 1045 break; 1046 1047 case SOL_TIMER: 1048 if (pi->pi_sol_state == NO_SOLICIT) 1049 return (TIMER_INFINITY); 1050 /* Decrease time left */ 1051 if (pi->pi_sol_time_left >= elapsed) 1052 pi->pi_sol_time_left -= elapsed; 1053 else 1054 pi->pi_sol_time_left = 0; 1055 break; 1056 default: 1057 logmsg(LOG_ERR, "solicit_event: Unknown event %d\n", 1058 (int)event); 1059 return (TIMER_INFINITY); 1060 } 1061 1062 if (pi->pi_sol_time_left != 0) 1063 return (pi->pi_sol_time_left); 1064 1065 /* Send solicitation and calculate next time */ 1066 switch (pi->pi_sol_state) { 1067 case INIT_SOLICIT: 1068 solicit(&v6allrouters, pi); 1069 if (--pi->pi_sol_count == 0) { 1070 pi->pi_sol_state = DONE_SOLICIT; 1071 check_daemonize(); 1072 return (TIMER_INFINITY); 1073 } 1074 pi->pi_sol_time_left = ND_RTR_SOLICITATION_INTERVAL; 1075 return (pi->pi_sol_time_left); 1076 case NO_SOLICIT: 1077 case DONE_SOLICIT: 1078 return (TIMER_INFINITY); 1079 default: 1080 return (pi->pi_sol_time_left); 1081 } 1082 } 1083 1084 /* 1085 * Timer mechanism using relative time (in milliseconds) from the 1086 * previous timer event. Timers exceeding TIMER_INFINITY milliseconds 1087 * will fire after TIMER_INFINITY milliseconds. 1088 */ 1089 static uint_t timer_previous; /* When last SIGALRM occurred */ 1090 static uint_t timer_next; /* Currently scheduled timeout */ 1091 1092 static void 1093 timer_init(void) 1094 { 1095 timer_previous = getcurrenttime(); 1096 timer_next = TIMER_INFINITY; 1097 run_timeouts(); 1098 } 1099 1100 /* 1101 * Make sure the next SIGALRM occurs delay milliseconds from the current 1102 * time if not earlier. 1103 * Handles getcurrenttime (32 bit integer holding milliseconds) wraparound 1104 * by treating differences greater than 0x80000000 as negative. 1105 */ 1106 void 1107 timer_schedule(uint_t delay) 1108 { 1109 uint_t now; 1110 struct itimerval itimerval; 1111 1112 now = getcurrenttime(); 1113 if (debug & D_TIMER) { 1114 logmsg(LOG_DEBUG, "timer_schedule(%u): now %u next %u\n", 1115 delay, now, timer_next); 1116 } 1117 /* Will this timer occur before the currently scheduled SIGALRM? */ 1118 if (delay >= timer_next - now) { 1119 if (debug & D_TIMER) { 1120 logmsg(LOG_DEBUG, "timer_schedule(%u): no action - " 1121 "next in %u ms\n", 1122 delay, timer_next - now); 1123 } 1124 return; 1125 } 1126 if (delay == 0) { 1127 /* Minimum allowed delay */ 1128 delay = 1; 1129 } 1130 timer_next = now + delay; 1131 1132 itimerval.it_value.tv_sec = delay / 1000; 1133 itimerval.it_value.tv_usec = (delay % 1000) * 1000; 1134 itimerval.it_interval.tv_sec = 0; 1135 itimerval.it_interval.tv_usec = 0; 1136 if (debug & D_TIMER) { 1137 logmsg(LOG_DEBUG, "timer_schedule(%u): sec %lu usec %lu\n", 1138 delay, 1139 itimerval.it_value.tv_sec, itimerval.it_value.tv_usec); 1140 } 1141 if (setitimer(ITIMER_REAL, &itimerval, NULL) < 0) { 1142 logperror("timer_schedule: setitimer"); 1143 exit(2); 1144 } 1145 } 1146 1147 /* 1148 * Conditional running of timer. If more than 'minimal_time' millseconds 1149 * since the timer routines were last run we run them. 1150 * Used when packets arrive. 1151 */ 1152 static void 1153 conditional_run_timeouts(uint_t minimal_time) 1154 { 1155 uint_t now; 1156 uint_t elapsed; 1157 1158 now = getcurrenttime(); 1159 elapsed = now - timer_previous; 1160 if (elapsed > minimal_time) { 1161 if (debug & D_TIMER) { 1162 logmsg(LOG_DEBUG, "conditional_run_timeouts: " 1163 "elapsed %d\n", elapsed); 1164 } 1165 run_timeouts(); 1166 } 1167 } 1168 1169 /* 1170 * Timer has fired. 1171 * Determine when the next timer event will occur by asking all 1172 * the timer routines. 1173 * Should not be called from a timer routine but in some cases this is 1174 * done because the code doesn't know that e.g. it was called from 1175 * ifconfig_timer(). In this case the nested run_timeouts will just return but 1176 * the running run_timeouts will ensure to call all the timer functions by 1177 * looping once more. 1178 */ 1179 static void 1180 run_timeouts(void) 1181 { 1182 uint_t now; 1183 uint_t elapsed; 1184 uint_t next; 1185 uint_t nexti; 1186 struct phyint *pi; 1187 struct phyint *next_pi; 1188 struct prefix *pr; 1189 struct prefix *next_pr; 1190 struct adv_prefix *adv_pr; 1191 struct adv_prefix *next_adv_pr; 1192 struct router *dr; 1193 struct router *next_dr; 1194 static boolean_t timeout_running; 1195 static boolean_t do_retry; 1196 1197 if (timeout_running) { 1198 if (debug & D_TIMER) 1199 logmsg(LOG_DEBUG, "run_timeouts: nested call\n"); 1200 do_retry = _B_TRUE; 1201 return; 1202 } 1203 timeout_running = _B_TRUE; 1204 retry: 1205 /* How much time since the last time we were called? */ 1206 now = getcurrenttime(); 1207 elapsed = now - timer_previous; 1208 timer_previous = now; 1209 1210 if (debug & D_TIMER) 1211 logmsg(LOG_DEBUG, "run_timeouts: elapsed %d\n", elapsed); 1212 1213 next = TIMER_INFINITY; 1214 for (pi = phyints; pi != NULL; pi = next_pi) { 1215 next_pi = pi->pi_next; 1216 nexti = phyint_timer(pi, elapsed); 1217 if (nexti != TIMER_INFINITY && nexti < next) 1218 next = nexti; 1219 if (debug & D_TIMER) { 1220 logmsg(LOG_DEBUG, "run_timeouts (pi %s): %d -> %u ms\n", 1221 pi->pi_name, nexti, next); 1222 } 1223 for (pr = pi->pi_prefix_list; pr != NULL; pr = next_pr) { 1224 next_pr = pr->pr_next; 1225 nexti = prefix_timer(pr, elapsed); 1226 if (nexti != TIMER_INFINITY && nexti < next) 1227 next = nexti; 1228 if (debug & D_TIMER) { 1229 logmsg(LOG_DEBUG, "run_timeouts (pr %s): " 1230 "%d -> %u ms\n", pr->pr_name, nexti, next); 1231 } 1232 } 1233 for (adv_pr = pi->pi_adv_prefix_list; adv_pr != NULL; 1234 adv_pr = next_adv_pr) { 1235 next_adv_pr = adv_pr->adv_pr_next; 1236 nexti = adv_prefix_timer(adv_pr, elapsed); 1237 if (nexti != TIMER_INFINITY && nexti < next) 1238 next = nexti; 1239 if (debug & D_TIMER) { 1240 logmsg(LOG_DEBUG, "run_timeouts " 1241 "(adv pr on %s): %d -> %u ms\n", 1242 adv_pr->adv_pr_physical->pi_name, 1243 nexti, next); 1244 } 1245 } 1246 for (dr = pi->pi_router_list; dr != NULL; dr = next_dr) { 1247 next_dr = dr->dr_next; 1248 nexti = router_timer(dr, elapsed); 1249 if (nexti != TIMER_INFINITY && nexti < next) 1250 next = nexti; 1251 if (debug & D_TIMER) { 1252 logmsg(LOG_DEBUG, "run_timeouts (dr): " 1253 "%d -> %u ms\n", nexti, next); 1254 } 1255 } 1256 if (pi->pi_TmpAddrsEnabled) { 1257 nexti = tmptoken_timer(pi, elapsed); 1258 if (nexti != TIMER_INFINITY && nexti < next) 1259 next = nexti; 1260 if (debug & D_TIMER) { 1261 logmsg(LOG_DEBUG, "run_timeouts (tmp on %s): " 1262 "%d -> %u ms\n", pi->pi_name, nexti, next); 1263 } 1264 } 1265 } 1266 /* 1267 * Make sure the timer functions are run at least once 1268 * an hour. 1269 */ 1270 if (next == TIMER_INFINITY) 1271 next = 3600 * 1000; /* 1 hour */ 1272 1273 if (debug & D_TIMER) 1274 logmsg(LOG_DEBUG, "run_timeouts: %u ms\n", next); 1275 timer_schedule(next); 1276 if (do_retry) { 1277 if (debug & D_TIMER) 1278 logmsg(LOG_DEBUG, "run_timeouts: retry\n"); 1279 do_retry = _B_FALSE; 1280 goto retry; 1281 } 1282 timeout_running = _B_FALSE; 1283 } 1284 1285 static int eventpipe_read = -1; /* Used for synchronous signal delivery */ 1286 static int eventpipe_write = -1; 1287 1288 /* 1289 * Ensure that signals are processed synchronously with the rest of 1290 * the code by just writing a one character signal number on the pipe. 1291 * The poll loop will pick this up and process the signal event. 1292 */ 1293 static void 1294 sig_handler(int signo) 1295 { 1296 uchar_t buf = (uchar_t)signo; 1297 1298 if (eventpipe_write == -1) { 1299 logmsg(LOG_ERR, "sig_handler: no pipe\n"); 1300 return; 1301 } 1302 if (write(eventpipe_write, &buf, sizeof (buf)) < 0) 1303 logperror("sig_handler: write"); 1304 } 1305 1306 /* 1307 * Pick up a signal "byte" from the pipe and process it. 1308 */ 1309 static void 1310 in_signal(int fd) 1311 { 1312 uchar_t buf; 1313 struct phyint *pi; 1314 struct phyint *next_pi; 1315 1316 switch (read(fd, &buf, sizeof (buf))) { 1317 case -1: 1318 logperror("in_signal: read"); 1319 exit(1); 1320 /* NOTREACHED */ 1321 case 1: 1322 break; 1323 case 0: 1324 logmsg(LOG_ERR, "in_signal: read eof\n"); 1325 exit(1); 1326 /* NOTREACHED */ 1327 default: 1328 logmsg(LOG_ERR, "in_signal: read > 1\n"); 1329 exit(1); 1330 } 1331 1332 if (debug & D_TIMER) 1333 logmsg(LOG_DEBUG, "in_signal() got %d\n", buf); 1334 1335 switch (buf) { 1336 case SIGALRM: 1337 if (debug & D_TIMER) { 1338 uint_t now = getcurrenttime(); 1339 1340 logmsg(LOG_DEBUG, "in_signal(SIGALRM) delta %u\n", 1341 now - timer_next); 1342 } 1343 timer_next = TIMER_INFINITY; 1344 run_timeouts(); 1345 break; 1346 case SIGHUP: 1347 /* Re-read config file by exec'ing ourselves */ 1348 for (pi = phyints; pi != NULL; pi = next_pi) { 1349 next_pi = pi->pi_next; 1350 if (pi->pi_AdvSendAdvertisements) 1351 check_to_advertise(pi, START_FINAL_ADV); 1352 1353 phyint_delete(pi); 1354 } 1355 1356 /* 1357 * Prevent fd leaks. Everything gets re-opened at start-up 1358 * time. 0, 1, and 2 are closed and re-opened as 1359 * /dev/null, so we'll leave those open. 1360 */ 1361 closefrom(3); 1362 1363 logmsg(LOG_ERR, "SIGHUP: restart and reread config file\n"); 1364 (void) execv(argv0[0], argv0); 1365 (void) unlink(PATH_PID); 1366 _exit(0177); 1367 /* NOTREACHED */ 1368 case SIGUSR1: 1369 logmsg(LOG_DEBUG, "Printing configuration:\n"); 1370 phyint_print_all(); 1371 break; 1372 case SIGINT: 1373 case SIGTERM: 1374 case SIGQUIT: 1375 for (pi = phyints; pi != NULL; pi = next_pi) { 1376 next_pi = pi->pi_next; 1377 if (pi->pi_AdvSendAdvertisements) 1378 check_to_advertise(pi, START_FINAL_ADV); 1379 1380 phyint_delete(pi); 1381 } 1382 (void) unlink(PATH_PID); 1383 exit(0); 1384 /* NOTREACHED */ 1385 case 255: 1386 /* 1387 * Special "signal" from looback_ra_enqueue. 1388 * Handle any queued loopback router advertisements. 1389 */ 1390 loopback_ra_dequeue(); 1391 break; 1392 default: 1393 logmsg(LOG_ERR, "in_signal: unknown signal: %d\n", buf); 1394 } 1395 } 1396 1397 /* 1398 * Create pipe for signal delivery and set up signal handlers. 1399 */ 1400 static void 1401 setup_eventpipe(void) 1402 { 1403 int fds[2]; 1404 struct sigaction act; 1405 1406 if ((pipe(fds)) < 0) { 1407 logperror("setup_eventpipe: pipe"); 1408 exit(1); 1409 } 1410 eventpipe_read = fds[0]; 1411 eventpipe_write = fds[1]; 1412 if (poll_add(eventpipe_read) == -1) { 1413 exit(1); 1414 } 1415 act.sa_handler = sig_handler; 1416 act.sa_flags = SA_RESTART; 1417 (void) sigaction(SIGALRM, &act, NULL); 1418 1419 (void) sigset(SIGHUP, sig_handler); 1420 (void) sigset(SIGUSR1, sig_handler); 1421 (void) sigset(SIGTERM, sig_handler); 1422 (void) sigset(SIGINT, sig_handler); 1423 (void) sigset(SIGQUIT, sig_handler); 1424 } 1425 1426 /* 1427 * Create a routing socket for receiving RTM_IFINFO messages and initialize 1428 * the routing socket message header and as much of the sockaddrs as possible. 1429 */ 1430 static int 1431 setup_rtsock(void) 1432 { 1433 int s; 1434 int ret; 1435 char *cp; 1436 struct sockaddr_in6 *sin6; 1437 1438 s = socket(PF_ROUTE, SOCK_RAW, AF_INET6); 1439 if (s == -1) { 1440 logperror("socket(PF_ROUTE)"); 1441 exit(1); 1442 } 1443 ret = fcntl(s, F_SETFL, O_NDELAY|O_NONBLOCK); 1444 if (ret < 0) { 1445 logperror("fcntl(O_NDELAY)"); 1446 exit(1); 1447 } 1448 if (poll_add(s) == -1) { 1449 exit(1); 1450 } 1451 1452 /* 1453 * Allocate storage for the routing socket message. 1454 */ 1455 rt_msg = (struct rt_msghdr *)malloc(NDP_RTM_MSGLEN); 1456 if (rt_msg == NULL) { 1457 logperror("malloc"); 1458 exit(1); 1459 } 1460 1461 /* 1462 * Initialize the routing socket message by zero-filling it and then 1463 * setting the fields where are constant through the lifetime of the 1464 * process. 1465 */ 1466 bzero(rt_msg, NDP_RTM_MSGLEN); 1467 rt_msg->rtm_msglen = NDP_RTM_MSGLEN; 1468 rt_msg->rtm_version = RTM_VERSION; 1469 rt_msg->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK | RTA_IFP; 1470 rt_msg->rtm_pid = getpid(); 1471 if (rt_msg->rtm_pid < 0) { 1472 logperror("getpid"); 1473 exit(1); 1474 } 1475 1476 /* 1477 * The RTA_DST sockaddr does not change during the lifetime of the 1478 * process so it can be completely initialized at this time. 1479 */ 1480 cp = (char *)rt_msg + sizeof (struct rt_msghdr); 1481 sin6 = (struct sockaddr_in6 *)cp; 1482 sin6->sin6_family = AF_INET6; 1483 sin6->sin6_addr = in6addr_any; 1484 1485 /* 1486 * Initialize the constant portion of the RTA_GATEWAY sockaddr. 1487 */ 1488 cp += sizeof (struct sockaddr_in6); 1489 rta_gateway = (struct sockaddr_in6 *)cp; 1490 rta_gateway->sin6_family = AF_INET6; 1491 1492 /* 1493 * The RTA_NETMASK sockaddr does not change during the lifetime of the 1494 * process so it can be completely initialized at this time. 1495 */ 1496 cp += sizeof (struct sockaddr_in6); 1497 sin6 = (struct sockaddr_in6 *)cp; 1498 sin6->sin6_family = AF_INET6; 1499 sin6->sin6_addr = in6addr_any; 1500 1501 /* 1502 * Initialize the constant portion of the RTA_IFP sockaddr. 1503 */ 1504 cp += sizeof (struct sockaddr_in6); 1505 rta_ifp = (struct sockaddr_dl *)cp; 1506 rta_ifp->sdl_family = AF_LINK; 1507 1508 return (s); 1509 } 1510 1511 /* 1512 * Retrieve one routing socket message. If RTM_IFINFO indicates 1513 * new phyint do a full scan of the interfaces. If RTM_IFINFO 1514 * indicates an existing phyint, only scan that phyint and associated 1515 * prefixes. 1516 */ 1517 static void 1518 process_rtsock(int rtsock) 1519 { 1520 int n; 1521 #define MSG_SIZE 2048/8 1522 int64_t msg[MSG_SIZE]; 1523 struct rt_msghdr *rtm; 1524 struct if_msghdr *ifm; 1525 struct phyint *pi; 1526 struct prefix *pr; 1527 boolean_t need_initifs = _B_FALSE; 1528 boolean_t need_ifscan = _B_FALSE; 1529 int64_t ifscan_msg[10][MSG_SIZE]; 1530 int ifscan_index = 0; 1531 int i; 1532 1533 /* Empty the rtsock and coealesce all the work that we have */ 1534 while (ifscan_index < 10) { 1535 n = read(rtsock, msg, sizeof (msg)); 1536 if (n <= 0) { 1537 /* No more messages */ 1538 break; 1539 } 1540 rtm = (struct rt_msghdr *)msg; 1541 if (rtm->rtm_version != RTM_VERSION) { 1542 logmsg(LOG_ERR, 1543 "process_rtsock: version %d not understood\n", 1544 rtm->rtm_version); 1545 return; 1546 } 1547 switch (rtm->rtm_type) { 1548 case RTM_NEWADDR: 1549 case RTM_DELADDR: 1550 /* 1551 * Some logical interface has changed - have to scan 1552 * everything to determine what actually changed. 1553 */ 1554 if (debug & D_IFSCAN) { 1555 logmsg(LOG_DEBUG, "process_rtsock: " 1556 "message %d\n", rtm->rtm_type); 1557 } 1558 need_initifs = _B_TRUE; 1559 break; 1560 case RTM_IFINFO: 1561 need_ifscan = _B_TRUE; 1562 (void) memcpy(ifscan_msg[ifscan_index], rtm, 1563 sizeof (msg)); 1564 ifscan_index++; 1565 /* Handled below */ 1566 break; 1567 default: 1568 /* Not interesting */ 1569 break; 1570 } 1571 } 1572 /* 1573 * If we do full scan i.e initifs, we don't need to 1574 * scan a particular interface as we should have 1575 * done that as part of initifs. 1576 */ 1577 if (need_initifs) { 1578 initifs(_B_FALSE); 1579 return; 1580 } 1581 1582 if (!need_ifscan) 1583 return; 1584 1585 for (i = 0; i < ifscan_index; i++) { 1586 ifm = (struct if_msghdr *)ifscan_msg[i]; 1587 if (debug & D_IFSCAN) 1588 logmsg(LOG_DEBUG, "process_rtsock: index %d\n", 1589 ifm->ifm_index); 1590 1591 pi = phyint_lookup_on_index(ifm->ifm_index); 1592 if (pi == NULL) { 1593 /* 1594 * A new physical interface. Do a full scan of the 1595 * to catch any new logical interfaces. 1596 */ 1597 initifs(_B_FALSE); 1598 return; 1599 } 1600 1601 if (ifm->ifm_flags != pi->pi_flags) { 1602 if (debug & D_IFSCAN) { 1603 logmsg(LOG_DEBUG, "process_rtsock: clr for " 1604 "%s old flags 0x%x new flags 0x%x\n", 1605 pi->pi_name, pi->pi_flags, ifm->ifm_flags); 1606 } 1607 } 1608 1609 1610 /* 1611 * Mark the interfaces so that we can find phyints and prefixes 1612 * which have disappeared from the kernel. 1613 * if_process will set pr_in_use when it finds the 1614 * interface in the kernel. 1615 * Before re-examining the state of the interfaces, 1616 * PI_PRESENT should be cleared from pi_kernel_state. 1617 */ 1618 pi->pi_kernel_state &= ~PI_PRESENT; 1619 for (pr = pi->pi_prefix_list; pr != NULL; pr = pr->pr_next) { 1620 pr->pr_in_use = _B_FALSE; 1621 } 1622 1623 if (ifsock < 0) { 1624 ifsock = socket(AF_INET6, SOCK_DGRAM, 0); 1625 if (ifsock < 0) { 1626 logperror("process_rtsock: socket"); 1627 return; 1628 } 1629 } 1630 if_process(ifsock, pi->pi_name, _B_FALSE); 1631 for (pr = pi->pi_prefix_list; pr != NULL; pr = pr->pr_next) { 1632 if_process(ifsock, pr->pr_name, _B_FALSE); 1633 } 1634 /* 1635 * If interface (still) exists in kernel, set 1636 * pi_state to indicate that. 1637 */ 1638 if (pi->pi_kernel_state & PI_PRESENT) { 1639 pi->pi_state |= PI_PRESENT; 1640 } 1641 check_if_removed(pi); 1642 if (show_ifs) 1643 phyint_print_all(); 1644 } 1645 } 1646 1647 /* 1648 * Check whether the address formed by pr->pr_prefix and pi_token 1649 * exists in the kernel. Cannot call SIOCTMYADDR/ONLINK as it 1650 * does not check for down addresses. This function should not 1651 * be called for onlink prefixes. 1652 */ 1653 static boolean_t 1654 is_address_present(struct phyint *pi, struct prefix *pr, uint64_t flags) 1655 { 1656 int s; 1657 in6_addr_t addr, *token; 1658 int i; 1659 int ret; 1660 struct sockaddr_in6 sin6; 1661 1662 s = socket(AF_INET6, SOCK_DGRAM, 0); 1663 if (s < 0) { 1664 logperror("is_address_present: socket"); 1665 /* 1666 * By returning B_TRUE, we make the caller delete 1667 * the prefix from the internal table. In the worst 1668 * case the next RA will create the prefix. 1669 */ 1670 return (_B_TRUE); 1671 } 1672 if (flags & IFF_TEMPORARY) 1673 token = &pi->pi_tmp_token; 1674 else 1675 token = &pi->pi_token; 1676 for (i = 0; i < 16; i++) { 1677 /* 1678 * prefix_create ensures that pr_prefix has all-zero 1679 * bits after prefixlen. 1680 */ 1681 addr.s6_addr[i] = pr->pr_prefix.s6_addr[i] | token->s6_addr[i]; 1682 } 1683 (void) memset(&sin6, 0, sizeof (struct sockaddr_in6)); 1684 sin6.sin6_family = AF_INET6; 1685 sin6.sin6_addr = addr; 1686 ret = bind(s, (struct sockaddr *)&sin6, sizeof (struct sockaddr_in6)); 1687 (void) close(s); 1688 if (ret < 0 && errno == EADDRNOTAVAIL) 1689 return (_B_FALSE); 1690 else 1691 return (_B_TRUE); 1692 } 1693 1694 /* 1695 * Look if the phyint or one of its prefixes have been removed from 1696 * the kernel and take appropriate action. 1697 * Uses {pi,pr}_in_use. 1698 */ 1699 static void 1700 check_if_removed(struct phyint *pi) 1701 { 1702 struct prefix *pr; 1703 struct prefix *next_pr; 1704 1705 /* 1706 * Detect phyints that have been removed from the kernel. 1707 * Since we can't recreate it here (would require ifconfig plumb 1708 * logic) we just terminate use of that phyint. 1709 */ 1710 if (!(pi->pi_kernel_state & PI_PRESENT) && 1711 (pi->pi_state & PI_PRESENT)) { 1712 logmsg(LOG_ERR, "Interface %s has been removed from kernel. " 1713 "in.ndpd will no longer use it\n", pi->pi_name); 1714 /* 1715 * Clear state so that should the phyint reappear 1716 * we will start with initial advertisements or 1717 * solicitations. 1718 */ 1719 phyint_cleanup(pi); 1720 } 1721 /* 1722 * Detect prefixes which are removed. 1723 * 1724 * We remove the prefix in all of the following cases : 1725 * 1726 * 1) Static prefixes are not the ones we create. So, 1727 * just remove it from our tables. 1728 * 1729 * 2) On-link prefixes potentially move to a different 1730 * phyint during failover. As it does not have 1731 * an address, we can't use the logic in is_address_present 1732 * to detect whether it is present in the kernel or not. 1733 * Thus when it is manually removed we don't recreate it. 1734 * 1735 * 3) If there is a token mis-match and this prefix is not 1736 * in the kernel, it means we don't need this prefix on 1737 * this interface anymore. It must have been moved to a 1738 * different interface by in.mpathd. This normally 1739 * happens after a failover followed by a failback (or 1740 * another failover) and we re-read the network 1741 * configuration. For the failover from A to B, we would 1742 * have created state on B about A's address, which will 1743 * not be in use after the subsequent failback. So, we 1744 * remove that prefix here. 1745 * 1746 * 4) If the physical interface is not present, then remove 1747 * the prefix. In the cases where we are advertising 1748 * prefixes, the state is kept in advertisement prefix and 1749 * hence we can delete the prefix. 1750 * 1751 * 5) Similar to case (3), when we failover from A to B, the 1752 * prefix in A will not be in use as it has been moved to B. 1753 * We will delete it from our tables and recreate it when 1754 * it fails back. is_address_present makes sure that the 1755 * address is still valid in kernel. 1756 * 1757 * If none of the above is true, we recreate the prefix as it 1758 * has been manually removed. We do it only when the interface 1759 * is not FAILED or INACTIVE or OFFLINE. 1760 */ 1761 for (pr = pi->pi_prefix_list; pr != NULL; pr = next_pr) { 1762 next_pr = pr->pr_next; 1763 if (!pr->pr_in_use) { 1764 /* Clear PR_AUTO and PR_ONLINK */ 1765 pr->pr_kernel_state &= PR_STATIC; 1766 if ((pr->pr_state & PR_STATIC) || 1767 !(pr->pr_state & PR_AUTO) || 1768 !(prefix_token_match(pi, pr, pr->pr_flags)) || 1769 (!(pi->pi_kernel_state & PI_PRESENT)) || 1770 (is_address_present(pi, pr, pr->pr_flags))) { 1771 prefix_delete(pr); 1772 } else if (!(pi->pi_flags & 1773 (IFF_FAILED|IFF_INACTIVE|IFF_OFFLINE)) && 1774 pr->pr_state != pr->pr_kernel_state) { 1775 pr->pr_name[0] = '\0'; 1776 logmsg(LOG_INFO, "Prefix manually removed " 1777 "on %s - recreating it!\n", 1778 pi->pi_name); 1779 prefix_update_k(pr); 1780 } 1781 } 1782 } 1783 } 1784 1785 1786 /* 1787 * Queuing mechanism for router advertisements that are sent by in.ndpd 1788 * and that also need to be processed by in.ndpd. 1789 * Uses "signal number" 255 to indicate to the main poll loop 1790 * that there is something to dequeue and send to incomining_ra(). 1791 */ 1792 struct raq { 1793 struct raq *raq_next; 1794 struct phyint *raq_pi; 1795 int raq_packetlen; 1796 uchar_t *raq_packet; 1797 }; 1798 static struct raq *raq_head = NULL; 1799 1800 /* 1801 * Allocate a struct raq and memory for the packet. 1802 * Send signal 255 to have poll dequeue. 1803 */ 1804 static void 1805 loopback_ra_enqueue(struct phyint *pi, struct nd_router_advert *ra, int len) 1806 { 1807 struct raq *raq; 1808 struct raq **raqp; 1809 1810 if (no_loopback) 1811 return; 1812 1813 if (debug & D_PKTOUT) 1814 logmsg(LOG_DEBUG, "loopback_ra_enqueue for %s\n", pi->pi_name); 1815 1816 raq = calloc(sizeof (struct raq), 1); 1817 if (raq == NULL) { 1818 logmsg(LOG_ERR, "loopback_ra_enqueue: out of memory\n"); 1819 return; 1820 } 1821 raq->raq_packet = malloc(len); 1822 if (raq->raq_packet == NULL) { 1823 free(raq); 1824 logmsg(LOG_ERR, "loopback_ra_enqueue: out of memory\n"); 1825 return; 1826 } 1827 bcopy(ra, raq->raq_packet, len); 1828 raq->raq_packetlen = len; 1829 raq->raq_pi = pi; 1830 1831 /* Tail insert */ 1832 raqp = &raq_head; 1833 while (*raqp != NULL) 1834 raqp = &((*raqp)->raq_next); 1835 *raqp = raq; 1836 1837 /* Signal for poll loop */ 1838 sig_handler(255); 1839 } 1840 1841 /* 1842 * Dequeue and process all queued advertisements. 1843 */ 1844 static void 1845 loopback_ra_dequeue(void) 1846 { 1847 struct sockaddr_in6 from = IN6ADDR_LOOPBACK_INIT; 1848 struct raq *raq; 1849 1850 if (debug & D_PKTIN) 1851 logmsg(LOG_DEBUG, "loopback_ra_dequeue()\n"); 1852 1853 while ((raq = raq_head) != NULL) { 1854 raq_head = raq->raq_next; 1855 raq->raq_next = NULL; 1856 1857 if (debug & D_PKTIN) { 1858 logmsg(LOG_DEBUG, "loopback_ra_dequeue for %s\n", 1859 raq->raq_pi->pi_name); 1860 } 1861 1862 incoming_ra(raq->raq_pi, 1863 (struct nd_router_advert *)raq->raq_packet, 1864 raq->raq_packetlen, &from, _B_TRUE); 1865 free(raq->raq_packet); 1866 free(raq); 1867 } 1868 } 1869 1870 1871 static void 1872 usage(char *cmd) 1873 { 1874 (void) fprintf(stderr, 1875 "usage: %s [ -adt ] [-f <config file>]\n", cmd); 1876 } 1877 1878 int 1879 main(int argc, char *argv[]) 1880 { 1881 int i; 1882 struct phyint *pi; 1883 int c; 1884 char *config_file = PATH_NDPD_CONF; 1885 boolean_t file_required = _B_FALSE; 1886 1887 argv0 = argv; 1888 srandom(gethostid()); 1889 (void) umask(0022); 1890 1891 while ((c = getopt(argc, argv, "adD:ntIf:")) != EOF) { 1892 switch (c) { 1893 case 'a': 1894 /* 1895 * The StatelessAddrConf variable in ndpd.conf, if 1896 * present, will override this setting. 1897 */ 1898 ifdefaults[I_StatelessAddrConf].cf_value = 0; 1899 break; 1900 case 'd': 1901 debug = D_ALL; 1902 break; 1903 case 'D': 1904 i = strtol((char *)optarg, NULL, 0); 1905 if (i == 0) { 1906 (void) fprintf(stderr, "Bad debug flags: %s\n", 1907 (char *)optarg); 1908 exit(1); 1909 } 1910 debug |= i; 1911 break; 1912 case 'n': 1913 no_loopback = 1; 1914 break; 1915 case 'I': 1916 show_ifs = 1; 1917 break; 1918 case 't': 1919 debug |= D_PKTIN | D_PKTOUT | D_PKTBAD; 1920 break; 1921 case 'f': 1922 config_file = (char *)optarg; 1923 file_required = _B_TRUE; 1924 break; 1925 case '?': 1926 usage(argv[0]); 1927 exit(1); 1928 } 1929 } 1930 1931 if (parse_config(config_file, file_required) == -1) 1932 exit(2); 1933 1934 if (show_ifs) 1935 phyint_print_all(); 1936 1937 if (debug == 0) { 1938 initlog(); 1939 } 1940 1941 setup_eventpipe(); 1942 rtsock = setup_rtsock(); 1943 timer_init(); 1944 initifs(_B_TRUE); 1945 1946 check_daemonize(); 1947 1948 for (;;) { 1949 if (poll(pollfds, pollfd_num, -1) < 0) { 1950 if (errno == EINTR) 1951 continue; 1952 logperror("main: poll"); 1953 exit(1); 1954 } 1955 for (i = 0; i < pollfd_num; i++) { 1956 if (!(pollfds[i].revents & POLLIN)) 1957 continue; 1958 if (pollfds[i].fd == eventpipe_read) { 1959 in_signal(eventpipe_read); 1960 break; 1961 } 1962 if (pollfds[i].fd == rtsock) { 1963 process_rtsock(rtsock); 1964 break; 1965 } 1966 /* 1967 * Run timer routine to advance clock if more than 1968 * half a second since the clock was advanced. 1969 * This limits CPU usage under severe packet 1970 * arrival rates but it creates a slight inaccuracy 1971 * in the timer mechanism. 1972 */ 1973 conditional_run_timeouts(500U); 1974 for (pi = phyints; pi != NULL; pi = pi->pi_next) { 1975 if (pollfds[i].fd == pi->pi_sock) { 1976 in_data(pi); 1977 break; 1978 } 1979 } 1980 } 1981 } 1982 /* NOTREACHED */ 1983 return (0); 1984 } 1985 1986 /* 1987 * LOGGER 1988 */ 1989 1990 static boolean_t logging = _B_FALSE; 1991 1992 static void 1993 initlog(void) 1994 { 1995 logging = _B_TRUE; 1996 openlog("in.ndpd", LOG_PID | LOG_CONS, LOG_DAEMON); 1997 } 1998 1999 /* Print the date/time without a trailing carridge return */ 2000 static void 2001 fprintdate(FILE *file) 2002 { 2003 char buf[BUFSIZ]; 2004 struct tm tms; 2005 time_t now; 2006 2007 now = time(NULL); 2008 (void) localtime_r(&now, &tms); 2009 (void) strftime(buf, sizeof (buf), "%h %d %X", &tms); 2010 (void) fprintf(file, "%s ", buf); 2011 } 2012 2013 /* PRINTFLIKE2 */ 2014 void 2015 logmsg(int level, const char *fmt, ...) 2016 { 2017 va_list ap; 2018 va_start(ap, fmt); 2019 2020 if (logging) { 2021 vsyslog(level, fmt, ap); 2022 } else { 2023 fprintdate(stderr); 2024 (void) vfprintf(stderr, fmt, ap); 2025 } 2026 va_end(ap); 2027 } 2028 2029 void 2030 logperror(const char *str) 2031 { 2032 if (logging) { 2033 syslog(LOG_ERR, "%s: %m\n", str); 2034 } else { 2035 fprintdate(stderr); 2036 (void) fprintf(stderr, "%s: %s\n", str, strerror(errno)); 2037 } 2038 } 2039 2040 void 2041 logperror_pi(const struct phyint *pi, const char *str) 2042 { 2043 if (logging) { 2044 syslog(LOG_ERR, "%s (interface %s): %m\n", 2045 str, pi->pi_name); 2046 } else { 2047 fprintdate(stderr); 2048 (void) fprintf(stderr, "%s (interface %s): %s\n", 2049 str, pi->pi_name, strerror(errno)); 2050 } 2051 } 2052 2053 void 2054 logperror_pr(const struct prefix *pr, const char *str) 2055 { 2056 if (logging) { 2057 syslog(LOG_ERR, "%s (prefix %s if %s): %m\n", 2058 str, pr->pr_name, pr->pr_physical->pi_name); 2059 } else { 2060 fprintdate(stderr); 2061 (void) fprintf(stderr, "%s (prefix %s if %s): %s\n", 2062 str, pr->pr_name, pr->pr_physical->pi_name, 2063 strerror(errno)); 2064 } 2065 } 2066