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