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