1 /* 2 * dhcpcd - DHCP client daemon 3 * SPDX-License-Identifier: BSD-2-Clause 4 * Copyright (c) 2006-2025 Roy Marples <roy (at) marples.name> 5 * All rights reserved 6 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #define __APPLE_USE_RFC_3542 30 31 #include <sys/types.h> 32 #include <sys/param.h> 33 #include <sys/ioctl.h> 34 #include <sys/socket.h> 35 36 #include <net/if.h> 37 #include <net/if_arp.h> 38 #include <netinet/in.h> 39 40 #include <fcntl.h> /* Needs to be here for old Linux */ 41 42 #include "config.h" 43 #ifdef AF_LINK 44 #include <net/if_dl.h> 45 #include <net/if_types.h> 46 #include <netinet/in_var.h> 47 #undef AF_PACKET /* Newer Illumos defines this */ 48 #endif 49 #ifdef AF_PACKET 50 #include <netpacket/packet.h> 51 #endif 52 #ifdef SIOCGIFMEDIA 53 #include <net/if_media.h> 54 #endif 55 #include <net/route.h> 56 57 #include <ctype.h> 58 #include <errno.h> 59 #include <fnmatch.h> 60 #include <ifaddrs.h> 61 #include <inttypes.h> 62 #include <stddef.h> 63 #include <stdio.h> 64 #include <stdlib.h> 65 #include <string.h> 66 #include <syslog.h> 67 #include <unistd.h> 68 69 #define ELOOP_QUEUE ELOOP_IF 70 #include "common.h" 71 #include "dev.h" 72 #include "dhcp.h" 73 #include "dhcp6.h" 74 #include "eloop.h" 75 #include "if-options.h" 76 #include "if.h" 77 #include "ipv4.h" 78 #include "ipv4ll.h" 79 #include "ipv6nd.h" 80 #include "logerr.h" 81 #include "privsep.h" 82 83 void 84 if_free(struct interface *ifp) 85 { 86 if (ifp == NULL) 87 return; 88 #ifdef IPV4LL 89 ipv4ll_free(ifp); 90 #endif 91 #ifdef INET 92 dhcp_free(ifp); 93 ipv4_free(ifp); 94 #endif 95 #ifdef DHCP6 96 dhcp6_free(ifp); 97 #endif 98 #ifdef INET6 99 ipv6nd_free(ifp); 100 ipv6_free(ifp); 101 #endif 102 rt_freeif(ifp); 103 free_options(ifp->ctx, ifp->options); 104 free(ifp->argv); 105 free(ifp); 106 } 107 108 int 109 if_opensockets(struct dhcpcd_ctx *ctx) 110 { 111 if (if_opensockets_os(ctx) == -1) 112 return -1; 113 114 #ifdef IFLR_ACTIVE 115 ctx->pf_link_fd = xsocket(PF_LINK, SOCK_DGRAM | SOCK_CLOEXEC, 0); 116 if (ctx->pf_link_fd == -1) 117 return -1; 118 #ifdef HAVE_CAPSICUM 119 if (ps_rights_limit_ioctl(ctx->pf_link_fd) == -1) 120 return -1; 121 #endif 122 #endif 123 124 /* We use this socket for some operations without INET. */ 125 ctx->pf_inet_fd = xsocket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); 126 if (ctx->pf_inet_fd == -1) 127 return -1; 128 129 return 0; 130 } 131 132 void 133 if_closesockets(struct dhcpcd_ctx *ctx) 134 { 135 if (ctx->link_fd != -1) { 136 eloop_event_delete(ctx->eloop, ctx->link_fd); 137 close(ctx->link_fd); 138 ctx->link_fd = -1; 139 } 140 141 if (ctx->pf_inet_fd != -1) { 142 close(ctx->pf_inet_fd); 143 ctx->pf_inet_fd = -1; 144 } 145 146 if_closesockets_os(ctx); 147 } 148 149 int 150 if_ioctl(struct dhcpcd_ctx *ctx, ioctl_request_t req, void *data, size_t len) 151 { 152 #ifdef PRIVSEP 153 if (ctx->options & DHCPCD_PRIVSEP) 154 return (int)ps_root_ioctl(ctx, req, data, len); 155 #endif 156 return ioctl(ctx->pf_inet_fd, req, data, len); 157 } 158 159 int 160 if_setflag(struct interface *ifp, short setflag, short unsetflag) 161 { 162 struct ifreq ifr = { .ifr_flags = 0 }; 163 short oflags; 164 165 strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); 166 if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFFLAGS, &ifr) == -1) 167 return -1; 168 169 oflags = ifr.ifr_flags; 170 ifr.ifr_flags |= setflag; 171 ifr.ifr_flags &= (short)~unsetflag; 172 if (ifr.ifr_flags != oflags && 173 if_ioctl(ifp->ctx, SIOCSIFFLAGS, &ifr, sizeof(ifr)) == -1) 174 return -1; 175 176 /* 177 * Do NOT set ifp->flags here. 178 * We need to listen for flag updates from the kernel as they 179 * need to sync with carrier. 180 */ 181 return 0; 182 } 183 184 bool 185 if_is_link_up(const struct interface *ifp) 186 { 187 return ifp->flags & IFF_UP && 188 (ifp->carrier != LINK_DOWN || 189 (ifp->options != NULL && 190 !(ifp->options->options & DHCPCD_LINK))); 191 } 192 193 int 194 if_randomisemac(struct interface *ifp) 195 { 196 uint32_t randnum; 197 size_t hwlen = ifp->hwlen, rlen = 0; 198 uint8_t buf[HWADDR_LEN], *bp = buf, *rp = (uint8_t *)&randnum; 199 char sbuf[HWADDR_LEN * 3]; 200 int retval; 201 202 if (hwlen == 0) { 203 errno = ENOTSUP; 204 return -1; 205 } 206 if (hwlen > sizeof(buf)) { 207 errno = ENOBUFS; 208 return -1; 209 } 210 211 for (; hwlen != 0; hwlen--) { 212 if (rlen == 0) { 213 randnum = arc4random(); 214 rp = (uint8_t *)&randnum; 215 rlen = sizeof(randnum); 216 } 217 *bp++ = *rp++; 218 rlen--; 219 } 220 221 /* Unicast address and locally administered. */ 222 buf[0] &= 0xFC; 223 buf[0] |= 0x02; 224 225 logdebugx("%s: hardware address randomised to %s", ifp->name, 226 hwaddr_ntoa(buf, ifp->hwlen, sbuf, sizeof(sbuf))); 227 retval = if_setmac(ifp, buf, ifp->hwlen); 228 if (retval == 0) 229 memcpy(ifp->hwaddr, buf, ifp->hwlen); 230 return retval; 231 } 232 233 static int 234 if_hasconf(struct dhcpcd_ctx *ctx, const char *ifname) 235 { 236 int i; 237 238 for (i = 0; i < ctx->ifcc; i++) { 239 if (fnmatch(ctx->ifcv[i], ifname, 0) == 0) 240 return 1; 241 } 242 return 0; 243 } 244 245 void 246 if_markaddrsstale(struct if_head *ifs) 247 { 248 struct interface *ifp; 249 250 TAILQ_FOREACH(ifp, ifs, next) { 251 #ifdef INET 252 ipv4_markaddrsstale(ifp); 253 #endif 254 #ifdef INET6 255 ipv6_markaddrsstale(ifp, 0); 256 #endif 257 } 258 } 259 260 void 261 if_learnaddrs(struct dhcpcd_ctx *ctx, struct if_head *ifs, 262 struct ifaddrs **ifaddrs) 263 { 264 struct ifaddrs *ifa; 265 struct interface *ifp; 266 #ifdef INET 267 const struct sockaddr_in *addr, *net, *brd; 268 #endif 269 #ifdef INET6 270 struct sockaddr_in6 *addr6, *net6, *dstaddr6; 271 #endif 272 int addrflags; 273 274 for (ifa = *ifaddrs; ifa; ifa = ifa->ifa_next) { 275 if (ifa->ifa_addr == NULL) 276 continue; 277 if ((ifp = if_find(ifs, ifa->ifa_name)) == NULL) 278 continue; 279 #ifdef HAVE_IFADDRS_ADDRFLAGS 280 addrflags = (int)ifa->ifa_addrflags; 281 #endif 282 switch (ifa->ifa_addr->sa_family) { 283 #ifdef INET 284 case AF_INET: 285 addr = (void *)ifa->ifa_addr; 286 net = (void *)ifa->ifa_netmask; 287 if (ifa->ifa_flags & IFF_POINTOPOINT) 288 brd = (void *)ifa->ifa_dstaddr; 289 else 290 brd = (void *)ifa->ifa_broadaddr; 291 #ifndef HAVE_IFADDRS_ADDRFLAGS 292 addrflags = if_addrflags(ifp, &addr->sin_addr, 293 ifa->ifa_name); 294 if (addrflags == -1) { 295 if (errno != EEXIST && errno != EADDRNOTAVAIL) { 296 char dbuf[INET_ADDRSTRLEN]; 297 const char *dbp; 298 299 dbp = inet_ntop(AF_INET, 300 &addr->sin_addr, dbuf, 301 sizeof(dbuf)); 302 logerr("%s: if_addrflags: %s%%%s", 303 __func__, dbp, ifp->name); 304 } 305 continue; 306 } 307 #endif 308 ipv4_handleifa(ctx, RTM_NEWADDR, ifs, ifa->ifa_name, 309 &addr->sin_addr, &net->sin_addr, 310 brd ? &brd->sin_addr : NULL, addrflags, 0); 311 break; 312 #endif 313 #ifdef INET6 314 case AF_INET6: 315 addr6 = (void *)ifa->ifa_addr; 316 dstaddr6 = (void *)ifa->ifa_dstaddr; 317 net6 = (void *)ifa->ifa_netmask; 318 319 #ifdef __KAME__ 320 if (IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr)) 321 /* Remove the scope from the address */ 322 addr6->sin6_addr.s6_addr[2] = 323 addr6->sin6_addr.s6_addr[3] = '\0'; 324 #endif 325 #ifndef HAVE_IFADDRS_ADDRFLAGS 326 addrflags = if_addrflags6(ifp, &addr6->sin6_addr, 327 ifa->ifa_name); 328 if (addrflags == -1) { 329 if (errno != EEXIST && errno != EADDRNOTAVAIL) { 330 char dbuf[INET6_ADDRSTRLEN]; 331 const char *dbp; 332 333 dbp = inet_ntop(AF_INET6, 334 &addr6->sin6_addr, dbuf, 335 sizeof(dbuf)); 336 logerr("%s: if_addrflags6: %s%%%s", 337 __func__, dbp, ifp->name); 338 } 339 continue; 340 } 341 #endif 342 ipv6_handleifa(ctx, RTM_NEWADDR, ifs, ifa->ifa_name, 343 &addr6->sin6_addr, ipv6_prefixlen(&net6->sin6_addr), 344 dstaddr6 ? &dstaddr6->sin6_addr : NULL, addrflags, 345 0); 346 break; 347 #endif 348 } 349 } 350 } 351 352 void 353 if_freeifaddrs(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs) 354 { 355 #ifndef PRIVSEP_GETIFADDRS 356 UNUSED(ctx); 357 #endif 358 359 if (ifaddrs == NULL) 360 return; 361 362 #ifdef PRIVSEP_GETIFADDRS 363 if (IN_PRIVSEP(ctx)) 364 free(*ifaddrs); 365 else 366 #endif 367 freeifaddrs(*ifaddrs); 368 } 369 370 void 371 if_deletestaleaddrs(struct if_head *ifs) 372 { 373 struct interface *ifp; 374 375 TAILQ_FOREACH(ifp, ifs, next) { 376 #ifdef INET 377 ipv4_deletestaleaddrs(ifp); 378 #endif 379 #ifdef INET6 380 ipv6_deletestaleaddrs(ifp); 381 #endif 382 } 383 } 384 385 bool 386 if_valid_hwaddr(const uint8_t *hwaddr, size_t hwlen) 387 { 388 size_t i; 389 bool all_zeros, all_ones; 390 391 all_zeros = all_ones = true; 392 for (i = 0; i < hwlen; i++) { 393 if (hwaddr[i] != 0x00) 394 all_zeros = false; 395 if (hwaddr[i] != 0xff) 396 all_ones = false; 397 if (!all_zeros && !all_ones) 398 return true; 399 } 400 return false; 401 } 402 403 #ifndef AF_LINK 404 static unsigned int 405 if_check_arphrd(struct interface *ifp, unsigned int active, bool if_noconf) 406 { 407 switch (ifp->hwtype) { 408 #ifdef ARPHRD_NONE 409 case ARPHRD_NONE: /* FALLTHROUGH */ 410 #endif 411 case ARPHRD_ETHER: /* FALLTHROUGH */ 412 case ARPHRD_IEEE1394: /* FALLTHROUGH */ 413 case ARPHRD_INFINIBAND: /* FALLTHROUGH */ 414 break; 415 case ARPHRD_LOOPBACK: 416 case ARPHRD_PPP: 417 if (if_noconf && active) { 418 logdebugx("%s: ignoring due to interface type and" 419 " no config", 420 ifp->name); 421 active = IF_INACTIVE; 422 } 423 break; 424 default: 425 if (active) { 426 int i; 427 428 if (if_noconf) 429 active = IF_INACTIVE; 430 i = active ? LOG_WARNING : LOG_DEBUG; 431 logmessage(i, 432 "%s: unsupported" 433 " interface type 0x%.2x", 434 ifp->name, ifp->hwtype); 435 } 436 break; 437 } 438 439 return active; 440 } 441 #endif 442 443 struct if_head * 444 if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs, int argc, 445 char *const *argv) 446 { 447 struct ifaddrs *ifa; 448 int i; 449 unsigned int active; 450 struct if_head *ifs; 451 struct interface *ifp; 452 struct if_spec spec; 453 bool if_noconf; 454 #ifdef AF_LINK 455 const struct sockaddr_dl *sdl; 456 #ifdef IFLR_ACTIVE 457 struct if_laddrreq iflr = { .flags = IFLR_PREFIX }; 458 #endif 459 #elif defined(AF_PACKET) 460 const struct sockaddr_ll *sll; 461 #endif 462 #if defined(SIOCGIFPRIORITY) 463 struct ifreq ifr; 464 #endif 465 466 if ((ifs = malloc(sizeof(*ifs))) == NULL) { 467 logerr(__func__); 468 return NULL; 469 } 470 TAILQ_INIT(ifs); 471 472 #ifdef PRIVSEP_GETIFADDRS 473 if (ctx->options & DHCPCD_PRIVSEP) { 474 if (ps_root_getifaddrs(ctx, ifaddrs) == -1) { 475 logerr("ps_root_getifaddrs"); 476 free(ifs); 477 return NULL; 478 } 479 } else 480 #endif 481 if (getifaddrs(ifaddrs) == -1) { 482 logerr("getifaddrs"); 483 free(ifs); 484 return NULL; 485 } 486 487 for (ifa = *ifaddrs; ifa; ifa = ifa->ifa_next) { 488 if (ifa->ifa_addr != NULL) { 489 #ifdef AF_LINK 490 if (ifa->ifa_addr->sa_family != AF_LINK) 491 continue; 492 #elif defined(AF_PACKET) 493 if (ifa->ifa_addr->sa_family != AF_PACKET) 494 continue; 495 #endif 496 } 497 if (if_nametospec(ifa->ifa_name, &spec) != 0) 498 continue; 499 500 /* It's possible for an interface to have >1 AF_LINK. 501 * For our purposes, we use the first one. */ 502 TAILQ_FOREACH(ifp, ifs, next) { 503 if (strcmp(ifp->name, spec.devname) == 0) 504 break; 505 } 506 if (ifp) 507 continue; 508 509 if (argc > 0) { 510 for (i = 0; i < argc; i++) { 511 if (strcmp(argv[i], spec.devname) == 0) 512 break; 513 } 514 active = (i == argc) ? IF_INACTIVE : IF_ACTIVE_USER; 515 } else { 516 /* -1 means we're discovering against a specific 517 * interface, but we still need the below rules 518 * to apply. */ 519 if (argc == -1 && strcmp(argv[0], spec.devname) != 0) 520 continue; 521 active = ctx->options & DHCPCD_INACTIVE ? 522 IF_INACTIVE : 523 IF_ACTIVE_USER; 524 } 525 526 for (i = 0; i < ctx->ifdc; i++) 527 if (fnmatch(ctx->ifdv[i], spec.devname, 0) == 0) 528 break; 529 if (i < ctx->ifdc) 530 active = IF_INACTIVE; 531 for (i = 0; i < ctx->ifc; i++) 532 if (fnmatch(ctx->ifv[i], spec.devname, 0) == 0) 533 break; 534 if (ctx->ifc && i == ctx->ifc) 535 active = IF_INACTIVE; 536 for (i = 0; i < ctx->ifac; i++) 537 if (fnmatch(ctx->ifav[i], spec.devname, 0) == 0) 538 break; 539 if (ctx->ifac && i == ctx->ifac) 540 active = IF_INACTIVE; 541 542 #ifdef PLUGIN_DEV 543 /* Ensure that the interface name has settled */ 544 if (!dev_initialised(ctx, spec.devname)) { 545 logdebugx("%s: waiting for interface to initialise", 546 spec.devname); 547 continue; 548 } 549 #endif 550 551 if (if_vimaster(ctx, spec.devname) == 1) { 552 int loglevel = argc != 0 ? LOG_ERR : LOG_DEBUG; 553 logmessage(loglevel, 554 "%s: is a Virtual Interface Master, skipping", 555 spec.devname); 556 continue; 557 } 558 559 if_noconf = ((argc == 0 || argc == -1) && ctx->ifac == 0 && 560 !if_hasconf(ctx, spec.devname)); 561 562 /* Don't allow some reserved interface names unless explicit. */ 563 if (if_noconf && if_ignore(ctx, spec.devname)) { 564 logdebugx("%s: ignoring due to interface type and" 565 " no config", 566 spec.devname); 567 active = IF_INACTIVE; 568 } 569 570 ifp = calloc(1, sizeof(*ifp)); 571 if (ifp == NULL) { 572 logerr(__func__); 573 break; 574 } 575 ifp->ctx = ctx; 576 strlcpy(ifp->name, spec.devname, sizeof(ifp->name)); 577 ifp->flags = ifa->ifa_flags; 578 579 if (ifa->ifa_addr != NULL) { 580 #ifdef AF_LINK 581 sdl = (const void *)ifa->ifa_addr; 582 583 #ifdef IFLR_ACTIVE 584 /* We need to check for active address */ 585 strlcpy(iflr.iflr_name, ifp->name, 586 sizeof(iflr.iflr_name)); 587 memcpy(&iflr.addr, ifa->ifa_addr, 588 MIN(ifa->ifa_addr->sa_len, sizeof(iflr.addr))); 589 iflr.flags = IFLR_PREFIX; 590 iflr.prefixlen = (unsigned int)sdl->sdl_alen * NBBY; 591 if (ioctl(ctx->pf_link_fd, SIOCGLIFADDR, &iflr) == -1 || 592 !(iflr.flags & IFLR_ACTIVE)) { 593 if_free(ifp); 594 continue; 595 } 596 #endif 597 598 ifp->index = sdl->sdl_index; 599 switch (sdl->sdl_type) { 600 #ifdef IFT_BRIDGE 601 case IFT_BRIDGE: /* FALLTHROUGH */ 602 #endif 603 #ifdef IFT_PROPVIRTUAL 604 case IFT_PROPVIRTUAL: /* FALLTHROUGH */ 605 #endif 606 #ifdef IFT_TUNNEL 607 case IFT_TUNNEL: /* FALLTHROUGH */ 608 #endif 609 case IFT_LOOP: /* FALLTHROUGH */ 610 case IFT_PPP: 611 /* Don't allow unless explicit */ 612 if (if_noconf && active) { 613 logdebugx("%s: ignoring due to" 614 " interface type and" 615 " no config", 616 ifp->name); 617 active = IF_INACTIVE; 618 } 619 __fallthrough; /* appease gcc */ 620 /* FALLTHROUGH */ 621 #ifdef IFT_L2VLAN 622 case IFT_L2VLAN: /* FALLTHROUGH */ 623 #endif 624 #ifdef IFT_L3IPVLAN 625 case IFT_L3IPVLAN: /* FALLTHROUGH */ 626 #endif 627 case IFT_ETHER: 628 ifp->hwtype = ARPHRD_ETHER; 629 break; 630 #ifdef IFT_IEEE1394 631 case IFT_IEEE1394: 632 ifp->hwtype = ARPHRD_IEEE1394; 633 break; 634 #endif 635 #ifdef IFT_INFINIBAND 636 case IFT_INFINIBAND: 637 ifp->hwtype = ARPHRD_INFINIBAND; 638 break; 639 #endif 640 default: 641 /* Don't allow unless explicit */ 642 if (active) { 643 if (if_noconf) 644 active = IF_INACTIVE; 645 i = active ? LOG_WARNING : LOG_DEBUG; 646 logmessage(i, 647 "%s: unsupported" 648 " interface type 0x%.2x", 649 ifp->name, sdl->sdl_type); 650 } 651 /* Pretend it's ethernet */ 652 ifp->hwtype = ARPHRD_ETHER; 653 break; 654 } 655 ifp->hwlen = sdl->sdl_alen; 656 memcpy(ifp->hwaddr, CLLADDR(sdl), ifp->hwlen); 657 #elif defined(AF_PACKET) 658 sll = (const void *)ifa->ifa_addr; 659 ifp->index = (unsigned int)sll->sll_ifindex; 660 ifp->hwtype = sll->sll_hatype; 661 ifp->hwlen = sll->sll_halen; 662 if (ifp->hwlen != 0) 663 memcpy(ifp->hwaddr, sll->sll_addr, ifp->hwlen); 664 #endif 665 } 666 667 if (if_init(ifp) == -1) { 668 logerr("%s: if_init", ifp->name); 669 if_free(ifp); 670 continue; 671 } 672 #ifndef AF_LINK 673 active = if_check_arphrd(ifp, active, if_noconf); 674 #endif 675 676 if (!(ctx->options & (DHCPCD_DUMPLEASE | DHCPCD_TEST))) { 677 /* Handle any platform init for the interface */ 678 if (active != IF_INACTIVE && if_init_os(ifp) == -1) { 679 logerr("%s: if_init_os", ifp->name); 680 if_free(ifp); 681 continue; 682 } 683 } 684 685 ifp->mtu = if_getmtu(ifp); 686 ifp->vlanid = if_vlanid(ifp); 687 688 #ifdef SIOCGIFPRIORITY 689 /* Respect the interface priority */ 690 memset(&ifr, 0, sizeof(ifr)); 691 strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); 692 if (pioctl(ctx, SIOCGIFPRIORITY, &ifr, sizeof(ifr)) == 0) 693 ifp->metric = (unsigned int)ifr.ifr_metric; 694 if_getssid(ifp); 695 #else 696 /* Leave a low portion for user config */ 697 ifp->metric = RTMETRIC_BASE + ifp->index; 698 if (if_getssid(ifp) != -1) { 699 ifp->wireless = true; 700 ifp->metric += RTMETRIC_WIRELESS; 701 } 702 #endif 703 704 ifp->active = active; 705 ifp->carrier = if_carrier(ifp, ifa->ifa_data); 706 TAILQ_INSERT_TAIL(ifs, ifp, next); 707 } 708 709 return ifs; 710 } 711 712 /* 713 * eth0.100:2 OR eth0i100:2 (seems to be NetBSD xvif(4) only) 714 * 715 * drvname == eth 716 * devname == eth0.100 OR eth0i100 717 * ppa = 0 718 * lun = 2 719 */ 720 int 721 if_nametospec(const char *ifname, struct if_spec *spec) 722 { 723 char *ep, *pp; 724 int e; 725 726 if (ifname == NULL || *ifname == '\0' || 727 strlcpy(spec->ifname, ifname, sizeof(spec->ifname)) >= 728 sizeof(spec->ifname) || 729 strlcpy(spec->drvname, ifname, sizeof(spec->drvname)) >= 730 sizeof(spec->drvname)) { 731 errno = EINVAL; 732 return -1; 733 } 734 735 /* :N is an alias */ 736 ep = strchr(spec->drvname, ':'); 737 if (ep) { 738 spec->lun = (int)strtoi(ep + 1, NULL, 10, 0, INT_MAX, &e); 739 if (e != 0) { 740 errno = e; 741 return -1; 742 } 743 *ep = '\0'; 744 #ifdef __sun 745 ep--; 746 #endif 747 } else { 748 spec->lun = -1; 749 #ifdef __sun 750 ep = spec->drvname + strlen(spec->drvname) - 1; 751 #endif 752 } 753 754 strlcpy(spec->devname, spec->drvname, sizeof(spec->devname)); 755 #ifdef __sun 756 /* Solaris has numbers in the driver name, such as e1000g */ 757 while (ep > spec->drvname && isdigit((int)*ep)) 758 ep--; 759 if (*ep++ == ':') { 760 errno = EINVAL; 761 return -1; 762 } 763 #else 764 /* BSD and Linux no not have numbers in the driver name */ 765 for (ep = spec->drvname; *ep != '\0' && !isdigit((int)*ep); ep++) { 766 if (*ep == ':') { 767 errno = EINVAL; 768 return -1; 769 } 770 } 771 #endif 772 spec->ppa = (int)strtoi(ep, &pp, 10, 0, INT_MAX, &e); 773 *ep = '\0'; 774 775 #ifndef __sun 776 /* 777 * . is used for VLAN style names 778 * i is used on NetBSD for xvif interfaces 779 */ 780 if (pp != NULL && (*pp == '.' || *pp == 'i')) { 781 spec->vlid = (int)strtoi(pp + 1, NULL, 10, 0, INT_MAX, &e); 782 if (e) 783 spec->vlid = -1; 784 } else 785 #endif 786 spec->vlid = -1; 787 788 return 0; 789 } 790 791 static struct interface * 792 if_findindexname(struct if_head *ifaces, unsigned int idx, const char *name) 793 { 794 if (ifaces != NULL) { 795 struct if_spec spec; 796 struct interface *ifp; 797 798 if (name && if_nametospec(name, &spec) == -1) 799 return NULL; 800 801 TAILQ_FOREACH(ifp, ifaces, next) { 802 if ((name && strcmp(ifp->name, spec.devname) == 0) || 803 (!name && ifp->index == idx)) 804 return ifp; 805 } 806 } 807 808 errno = ENXIO; 809 return NULL; 810 } 811 812 struct interface * 813 if_find(struct if_head *ifaces, const char *name) 814 { 815 return if_findindexname(ifaces, 0, name); 816 } 817 818 struct interface * 819 if_findindex(struct if_head *ifaces, unsigned int idx) 820 { 821 return if_findindexname(ifaces, idx, NULL); 822 } 823 824 struct interface * 825 if_loopback(struct dhcpcd_ctx *ctx) 826 { 827 struct interface *ifp; 828 829 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 830 if (ifp->flags & IFF_LOOPBACK) 831 return ifp; 832 } 833 return NULL; 834 } 835 836 int 837 if_getmtu(const struct interface *ifp) 838 { 839 #ifdef __sun 840 return if_mtu_os(ifp); 841 #else 842 struct ifreq ifr = { .ifr_mtu = 0 }; 843 844 strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); 845 if (pioctl(ifp->ctx, SIOCGIFMTU, &ifr, sizeof(ifr)) == -1) 846 return -1; 847 return ifr.ifr_mtu; 848 #endif 849 } 850 851 #ifdef ALIAS_ADDR 852 int 853 if_makealias(char *alias, size_t alias_len, const char *ifname, int lun) 854 { 855 if (lun == 0) 856 return strlcpy(alias, ifname, alias_len); 857 return snprintf(alias, alias_len, "%s:%u", ifname, lun); 858 } 859 #endif 860 861 struct interface * 862 if_findifpfromcmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg, int *hoplimit) 863 { 864 struct cmsghdr *cm; 865 unsigned int ifindex = 0; 866 struct interface *ifp; 867 #ifdef INET 868 #ifdef IP_RECVIF 869 struct sockaddr_dl sdl; 870 #else 871 struct in_pktinfo ipi; 872 #endif 873 #endif 874 #ifdef INET6 875 struct in6_pktinfo ipi6; 876 #else 877 UNUSED(hoplimit); 878 #endif 879 880 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(msg); cm; 881 cm = (struct cmsghdr *)CMSG_NXTHDR(msg, cm)) { 882 #ifdef INET 883 if (cm->cmsg_level == IPPROTO_IP) { 884 switch (cm->cmsg_type) { 885 #ifdef IP_RECVIF 886 case IP_RECVIF: 887 if (cm->cmsg_len < 888 offsetof(struct sockaddr_dl, sdl_index) + 889 sizeof(sdl.sdl_index)) 890 continue; 891 memcpy(&sdl, CMSG_DATA(cm), 892 MIN(sizeof(sdl), cm->cmsg_len)); 893 ifindex = sdl.sdl_index; 894 break; 895 #else 896 case IP_PKTINFO: 897 if (cm->cmsg_len != CMSG_LEN(sizeof(ipi))) 898 continue; 899 memcpy(&ipi, CMSG_DATA(cm), sizeof(ipi)); 900 ifindex = (unsigned int)ipi.ipi_ifindex; 901 break; 902 #endif 903 } 904 } 905 #endif 906 #ifdef INET6 907 if (cm->cmsg_level == IPPROTO_IPV6) { 908 switch (cm->cmsg_type) { 909 case IPV6_PKTINFO: 910 if (cm->cmsg_len != CMSG_LEN(sizeof(ipi6))) 911 continue; 912 memcpy(&ipi6, CMSG_DATA(cm), sizeof(ipi6)); 913 ifindex = (unsigned int)ipi6.ipi6_ifindex; 914 break; 915 case IPV6_HOPLIMIT: 916 if (cm->cmsg_len != CMSG_LEN(sizeof(int))) 917 continue; 918 if (hoplimit == NULL) 919 break; 920 memcpy(hoplimit, CMSG_DATA(cm), sizeof(int)); 921 break; 922 } 923 } 924 #endif 925 } 926 927 /* Find the receiving interface */ 928 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 929 if (ifp->index == ifindex) 930 break; 931 } 932 if (ifp == NULL) 933 errno = ESRCH; 934 return ifp; 935 } 936 937 int 938 xsocket(int domain, int type, int protocol) 939 { 940 int s; 941 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK) 942 int xflags, xtype = type; 943 #endif 944 945 #ifndef HAVE_SOCK_CLOEXEC 946 if (xtype & SOCK_CLOEXEC) 947 type &= ~SOCK_CLOEXEC; 948 #endif 949 #ifndef HAVE_SOCK_NONBLOCK 950 if (xtype & SOCK_NONBLOCK) 951 type &= ~SOCK_NONBLOCK; 952 #endif 953 954 if ((s = socket(domain, type, protocol)) == -1) 955 return -1; 956 #ifdef DEBUG_FD 957 logerrx("pid %d fd=%d domain=%d type=%d protocol=%d", getpid(), s, 958 domain, type, protocol); 959 #endif 960 961 #ifndef HAVE_SOCK_CLOEXEC 962 if ((xtype & SOCK_CLOEXEC) && 963 ((xflags = fcntl(s, F_GETFD)) == -1 || 964 fcntl(s, F_SETFD, xflags | FD_CLOEXEC) == -1)) 965 goto out; 966 #endif 967 #ifndef HAVE_SOCK_NONBLOCK 968 if ((xtype & SOCK_NONBLOCK) && 969 ((xflags = fcntl(s, F_GETFL)) == -1 || 970 fcntl(s, F_SETFL, xflags | O_NONBLOCK) == -1)) 971 goto out; 972 #endif 973 974 return s; 975 976 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK) 977 out: 978 close(s); 979 return -1; 980 #endif 981 } 982 983 int 984 xsocketpair(int domain, int type, int protocol, int fd[2]) 985 { 986 int s; 987 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK) 988 int xflags, xtype = type; 989 #endif 990 991 #ifndef HAVE_SOCK_CLOEXEC 992 if (xtype & SOCK_CLOEXEC) 993 type &= ~SOCK_CLOEXEC; 994 #endif 995 #ifndef HAVE_SOCK_NONBLOCK 996 if (xtype & SOCK_NONBLOCK) 997 type &= ~SOCK_NONBLOCK; 998 #endif 999 1000 if ((s = socketpair(domain, type, protocol, fd)) == -1) 1001 return -1; 1002 1003 #ifdef DEBUG_FD 1004 logerrx("pid %d fd[0]=%d fd[1]=%d", getpid(), fd[0], fd[1]); 1005 #endif 1006 1007 #ifndef HAVE_SOCK_CLOEXEC 1008 if ((xtype & SOCK_CLOEXEC) && 1009 ((xflags = fcntl(fd[0], F_GETFD)) == -1 || 1010 fcntl(fd[0], F_SETFD, xflags | FD_CLOEXEC) == -1)) 1011 goto out; 1012 if ((xtype & SOCK_CLOEXEC) && 1013 ((xflags = fcntl(fd[1], F_GETFD)) == -1 || 1014 fcntl(fd[1], F_SETFD, xflags | FD_CLOEXEC) == -1)) 1015 goto out; 1016 #endif 1017 #ifndef HAVE_SOCK_NONBLOCK 1018 if ((xtype & SOCK_NONBLOCK) && 1019 ((xflags = fcntl(fd[0], F_GETFL)) == -1 || 1020 fcntl(fd[0], F_SETFL, xflags | O_NONBLOCK) == -1)) 1021 goto out; 1022 if ((xtype & SOCK_NONBLOCK) && 1023 ((xflags = fcntl(fd[1], F_GETFL)) == -1 || 1024 fcntl(fd[1], F_SETFL, xflags | O_NONBLOCK) == -1)) 1025 goto out; 1026 #endif 1027 1028 return s; 1029 1030 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK) 1031 out: 1032 close(fd[0]); 1033 close(fd[1]); 1034 return -1; 1035 #endif 1036 } 1037