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