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