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