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