1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * BSD interface driver for dhcpcd 4 * Copyright (c) 2006-2019 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/ioctl.h> 30 #include <sys/param.h> 31 #include <sys/socket.h> 32 #include <sys/stat.h> 33 #include <sys/sysctl.h> 34 #include <sys/time.h> 35 #include <sys/types.h> 36 #include <sys/uio.h> 37 #include <sys/utsname.h> 38 39 #include "config.h" 40 41 #include <arpa/inet.h> 42 #include <net/bpf.h> 43 #include <net/if.h> 44 #include <net/if_dl.h> 45 #include <net/if_media.h> 46 #include <net/route.h> 47 #include <netinet/if_ether.h> 48 #include <netinet/in.h> 49 #include <netinet/in_var.h> 50 #include <netinet6/in6_var.h> 51 #include <netinet6/nd6.h> 52 #ifdef __NetBSD__ 53 #include <net/if_vlanvar.h> /* Needs netinet/if_ether.h */ 54 #elif defined(__DragonFly__) 55 #include <net/vlan/if_vlan_var.h> 56 #else 57 #include <net/if_vlan_var.h> 58 #endif 59 #ifdef __DragonFly__ 60 # include <netproto/802_11/ieee80211_ioctl.h> 61 #elif __APPLE__ 62 /* FIXME: Add apple includes so we can work out SSID */ 63 #else 64 # include <net80211/ieee80211.h> 65 # include <net80211/ieee80211_ioctl.h> 66 #endif 67 68 #include <assert.h> 69 #include <errno.h> 70 #include <fcntl.h> 71 #include <fnmatch.h> 72 #include <paths.h> 73 #include <stddef.h> 74 #include <stdio.h> 75 #include <stdlib.h> 76 #include <string.h> 77 #include <unistd.h> 78 79 #if defined(OpenBSD) && OpenBSD >= 201411 80 /* OpenBSD dropped the global setting from sysctl but left the #define 81 * which causes a EPERM error when trying to use it. 82 * I think both the error and keeping the define are wrong, so we #undef it. */ 83 #undef IPV6CTL_ACCEPT_RTADV 84 #endif 85 86 #include "common.h" 87 #include "dhcp.h" 88 #include "if.h" 89 #include "if-options.h" 90 #include "ipv4.h" 91 #include "ipv4ll.h" 92 #include "ipv6.h" 93 #include "ipv6nd.h" 94 #include "logerr.h" 95 #include "route.h" 96 #include "sa.h" 97 98 #ifndef RT_ROUNDUP 99 #define RT_ROUNDUP(a) \ 100 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 101 #define RT_ADVANCE(x, n) (x += RT_ROUNDUP((n)->sa_len)) 102 #endif 103 104 /* Ignore these interface names which look like ethernet but are virtual. */ 105 static const char * const ifnames_ignore[] = { 106 "bridge", 107 "fwe", /* Firewire */ 108 "tap", 109 NULL 110 }; 111 112 #ifdef INET6 113 static void ifa_setscope(struct sockaddr_in6 *, unsigned int); 114 static unsigned int ifa_getscope(const struct sockaddr_in6 *); 115 #endif 116 117 struct priv { 118 int pf_inet6_fd; 119 }; 120 121 struct rtm 122 { 123 struct rt_msghdr hdr; 124 char buffer[sizeof(struct sockaddr_storage) * RTAX_MAX]; 125 }; 126 127 int 128 if_init(__unused struct interface *iface) 129 { 130 /* BSD promotes secondary address by default */ 131 return 0; 132 } 133 134 int 135 if_conf(__unused struct interface *iface) 136 { 137 /* No extra checks needed on BSD */ 138 return 0; 139 } 140 141 int 142 if_opensockets_os(struct dhcpcd_ctx *ctx) 143 { 144 struct priv *priv; 145 int n; 146 #if defined(RO_MSGFILTER) || defined(ROUTE_MSGFILTER) 147 unsigned char msgfilter[] = { 148 RTM_IFINFO, 149 #ifdef RTM_IFANNOUNCE 150 RTM_IFANNOUNCE, 151 #endif 152 RTM_ADD, RTM_CHANGE, RTM_DELETE, RTM_MISS, 153 #ifdef RTM_CHGADDR 154 RTM_CHGADDR, 155 #endif 156 RTM_NEWADDR, RTM_DELADDR 157 }; 158 #ifdef ROUTE_MSGFILTER 159 unsigned int i, msgfilter_mask; 160 #endif 161 #endif 162 163 if ((priv = malloc(sizeof(*priv))) == NULL) 164 return -1; 165 ctx->priv = priv; 166 167 #ifdef INET6 168 priv->pf_inet6_fd = xsocket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0); 169 /* Don't return an error so we at least work on kernels witout INET6 170 * even though we expect INET6 support. 171 * We will fail noisily elsewhere anyway. */ 172 #else 173 priv->pf_inet6_fd = -1; 174 #endif 175 176 #define SOCK_FLAGS (SOCK_CLOEXEC | SOCK_NONBLOCK) 177 ctx->link_fd = xsocket(PF_ROUTE, SOCK_RAW | SOCK_FLAGS, AF_UNSPEC); 178 #undef SOCK_FLAGS 179 if (ctx->link_fd == -1) 180 return -1; 181 182 /* Ignore our own route(4) messages. 183 * Sadly there is no way of doing this for route(4) messages 184 * generated from addresses we add/delete. */ 185 n = 0; 186 if (setsockopt(ctx->link_fd, SOL_SOCKET, SO_USELOOPBACK, 187 &n, sizeof(n)) == -1) 188 logerr("%s: SO_USELOOPBACK", __func__); 189 190 #if defined(RO_MSGFILTER) 191 if (setsockopt(ctx->link_fd, PF_ROUTE, RO_MSGFILTER, 192 &msgfilter, sizeof(msgfilter)) == -1) 193 logerr(__func__); 194 #elif defined(ROUTE_MSGFILTER) 195 /* Convert the array into a bitmask. */ 196 msgfilter_mask = 0; 197 for (i = 0; i < __arraycount(msgfilter); i++) 198 msgfilter_mask |= ROUTE_FILTER(msgfilter[i]); 199 if (setsockopt(ctx->link_fd, PF_ROUTE, ROUTE_MSGFILTER, 200 &msgfilter_mask, sizeof(msgfilter_mask)) == -1) 201 logerr(__func__); 202 #else 203 #warning kernel does not support route message filtering 204 #endif 205 206 return 0; 207 } 208 209 void 210 if_closesockets_os(struct dhcpcd_ctx *ctx) 211 { 212 struct priv *priv; 213 214 priv = (struct priv *)ctx->priv; 215 if (priv->pf_inet6_fd != -1) 216 close(priv->pf_inet6_fd); 217 } 218 219 static bool 220 if_ignore1(const char *drvname) 221 { 222 const char * const *p; 223 224 for (p = ifnames_ignore; *p; p++) { 225 if (strcmp(*p, drvname) == 0) 226 return true; 227 } 228 return false; 229 } 230 231 bool 232 if_ignore(struct dhcpcd_ctx *ctx, const char *ifname) 233 { 234 struct if_spec spec; 235 236 if (if_nametospec(ifname, &spec) != 0) 237 return false; 238 239 if (if_ignore1(spec.drvname)) 240 return true; 241 242 #ifdef SIOCGIFGROUP 243 struct ifgroupreq ifgr = { .ifgr_len = 0 }; 244 struct ifg_req *ifg; 245 size_t ifg_len; 246 247 /* Sadly it is possible to remove the device name 248 * from the interface groups, but hopefully this 249 * will be very unlikely.... */ 250 251 strlcpy(ifgr.ifgr_name, ifname, sizeof(ifgr.ifgr_name)); 252 if (ioctl(ctx->pf_inet_fd, SIOCGIFGROUP, &ifgr) == -1 || 253 (ifgr.ifgr_groups = malloc(ifgr.ifgr_len)) == NULL || 254 ioctl(ctx->pf_inet_fd, SIOCGIFGROUP, &ifgr) == -1) 255 { 256 logerr(__func__); 257 return false; 258 } 259 260 for (ifg = ifgr.ifgr_groups, ifg_len = ifgr.ifgr_len; 261 ifg && ifg_len >= sizeof(*ifg); 262 ifg++, ifg_len -= sizeof(*ifg)) 263 { 264 if (if_ignore1(ifg->ifgrq_group)) 265 return true; 266 } 267 #else 268 UNUSED(ctx); 269 #endif 270 271 return false; 272 } 273 274 int 275 if_carrier(struct interface *ifp) 276 { 277 struct ifmediareq ifmr = { .ifm_status = 0 }; 278 279 strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name)); 280 if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFMEDIA, &ifmr) == -1 || 281 !(ifmr.ifm_status & IFM_AVALID)) 282 return LINK_UNKNOWN; 283 284 return (ifmr.ifm_status & IFM_ACTIVE) ? LINK_UP : LINK_DOWN; 285 } 286 287 static void 288 if_linkaddr(struct sockaddr_dl *sdl, const struct interface *ifp) 289 { 290 291 memset(sdl, 0, sizeof(*sdl)); 292 sdl->sdl_family = AF_LINK; 293 sdl->sdl_len = sizeof(*sdl); 294 sdl->sdl_nlen = sdl->sdl_alen = sdl->sdl_slen = 0; 295 sdl->sdl_index = (unsigned short)ifp->index; 296 } 297 298 #if defined(SIOCG80211NWID) || defined(SIOCGETVLAN) 299 static int if_direct_ioctl(int s, const char *ifname, 300 unsigned long cmd, void *data) 301 { 302 303 strlcpy(data, ifname, IFNAMSIZ); 304 return ioctl(s, cmd, data); 305 } 306 307 static int if_indirect_ioctl(int s, const char *ifname, 308 unsigned long cmd, void *data) 309 { 310 struct ifreq ifr; 311 312 memset(&ifr, 0, sizeof(ifr)); 313 ifr.ifr_data = data; 314 return if_direct_ioctl(s, ifname, cmd, &ifr); 315 } 316 #endif 317 318 static int 319 if_getssid1(int s, const char *ifname, void *ssid) 320 { 321 int retval = -1; 322 #if defined(SIOCG80211NWID) 323 struct ieee80211_nwid nwid; 324 #elif defined(IEEE80211_IOC_SSID) 325 struct ieee80211req ireq; 326 char nwid[IEEE80211_NWID_LEN]; 327 #endif 328 329 #if defined(SIOCG80211NWID) /* NetBSD */ 330 memset(&nwid, 0, sizeof(nwid)); 331 if (if_indirect_ioctl(s, ifname, SIOCG80211NWID, &nwid) == 0) { 332 if (ssid == NULL) 333 retval = nwid.i_len; 334 else if (nwid.i_len > IF_SSIDLEN) 335 errno = ENOBUFS; 336 else { 337 retval = nwid.i_len; 338 memcpy(ssid, nwid.i_nwid, nwid.i_len); 339 } 340 } 341 #elif defined(IEEE80211_IOC_SSID) /* FreeBSD */ 342 memset(&ireq, 0, sizeof(ireq)); 343 strlcpy(ireq.i_name, ifname, sizeof(ireq.i_name)); 344 ireq.i_type = IEEE80211_IOC_SSID; 345 ireq.i_val = -1; 346 memset(nwid, 0, sizeof(nwid)); 347 ireq.i_data = &nwid; 348 if (ioctl(s, SIOCG80211, &ireq) == 0) { 349 if (ssid == NULL) 350 retval = ireq.i_len; 351 else if (ireq.i_len > IF_SSIDLEN) 352 errno = ENOBUFS; 353 else { 354 retval = ireq.i_len; 355 memcpy(ssid, nwid, ireq.i_len); 356 } 357 } 358 #else 359 errno = ENOSYS; 360 #endif 361 362 return retval; 363 } 364 365 int 366 if_getssid(struct interface *ifp) 367 { 368 int r; 369 370 r = if_getssid1(ifp->ctx->pf_inet_fd, ifp->name, ifp->ssid); 371 if (r != -1) 372 ifp->ssid_len = (unsigned int)r; 373 else 374 ifp->ssid_len = 0; 375 ifp->ssid[ifp->ssid_len] = '\0'; 376 return r; 377 } 378 379 /* 380 * FreeBSD allows for Virtual Access Points 381 * We need to check if the interface is a Virtual Interface Master 382 * and if so, don't use it. 383 * This check is made by virtue of being a IEEE80211 device but 384 * returning the SSID gives an error. 385 */ 386 int 387 if_vimaster(const struct dhcpcd_ctx *ctx, const char *ifname) 388 { 389 int r; 390 struct ifmediareq ifmr; 391 392 memset(&ifmr, 0, sizeof(ifmr)); 393 strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name)); 394 r = ioctl(ctx->pf_inet_fd, SIOCGIFMEDIA, &ifmr); 395 if (r == -1) 396 return -1; 397 if (ifmr.ifm_status & IFM_AVALID && 398 IFM_TYPE(ifmr.ifm_active) == IFM_IEEE80211) 399 { 400 if (if_getssid1(ctx->pf_inet_fd, ifname, NULL) == -1) 401 return 1; 402 } 403 return 0; 404 } 405 406 unsigned short 407 if_vlanid(const struct interface *ifp) 408 { 409 #ifdef SIOCGETVLAN 410 struct vlanreq vlr; 411 412 memset(&vlr, 0, sizeof(vlr)); 413 if (if_indirect_ioctl(ifp->ctx->pf_inet_fd, 414 ifp->name, SIOCGETVLAN, &vlr) != 0) 415 return 0; /* 0 means no VLANID */ 416 return vlr.vlr_tag; 417 #elif defined(SIOCGVNETID) 418 struct ifreq ifr; 419 420 memset(&ifr, 0, sizeof(ifr)); 421 strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); 422 if (ioctl(ifp->ctx->pf_inet_fd, SIOCGVNETID, &ifr) != 0) 423 return 0; /* 0 means no VLANID */ 424 return ifr.ifr_vnetid; 425 #else 426 UNUSED(ifp); 427 return 0; /* 0 means no VLANID */ 428 #endif 429 } 430 431 static int 432 get_addrs(int type, const void *data, size_t data_len, 433 const struct sockaddr **sa) 434 { 435 const char *cp, *ep; 436 int i; 437 438 cp = data; 439 ep = cp + data_len; 440 for (i = 0; i < RTAX_MAX; i++) { 441 if (type & (1 << i)) { 442 if (cp >= ep) { 443 errno = EINVAL; 444 return -1; 445 } 446 sa[i] = (const struct sockaddr *)cp; 447 RT_ADVANCE(cp, sa[i]); 448 } else 449 sa[i] = NULL; 450 } 451 452 return 0; 453 } 454 455 static struct interface * 456 if_findsdl(struct dhcpcd_ctx *ctx, const struct sockaddr_dl *sdl) 457 { 458 459 if (sdl->sdl_index) 460 return if_findindex(ctx->ifaces, sdl->sdl_index); 461 462 if (sdl->sdl_nlen) { 463 char ifname[IF_NAMESIZE]; 464 465 memcpy(ifname, sdl->sdl_data, sdl->sdl_nlen); 466 ifname[sdl->sdl_nlen] = '\0'; 467 return if_find(ctx->ifaces, ifname); 468 } 469 if (sdl->sdl_alen) { 470 struct interface *ifp; 471 472 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 473 if (ifp->hwlen == sdl->sdl_alen && 474 memcmp(ifp->hwaddr, 475 sdl->sdl_data, sdl->sdl_alen) == 0) 476 return ifp; 477 } 478 } 479 480 errno = ENOENT; 481 return NULL; 482 } 483 484 static struct interface * 485 if_findsa(struct dhcpcd_ctx *ctx, const struct sockaddr *sa) 486 { 487 if (sa == NULL) { 488 errno = EINVAL; 489 return NULL; 490 } 491 492 switch (sa->sa_family) { 493 case AF_LINK: 494 { 495 const struct sockaddr_dl *sdl; 496 497 sdl = (const void *)sa; 498 return if_findsdl(ctx, sdl); 499 } 500 #ifdef INET 501 case AF_INET: 502 { 503 const struct sockaddr_in *sin; 504 struct ipv4_addr *ia; 505 506 sin = (const void *)sa; 507 if ((ia = ipv4_findmaskaddr(ctx, &sin->sin_addr))) 508 return ia->iface; 509 break; 510 } 511 #endif 512 #ifdef INET6 513 case AF_INET6: 514 { 515 const struct sockaddr_in6 *sin; 516 unsigned int scope; 517 struct ipv6_addr *ia; 518 519 sin = (const void *)sa; 520 scope = ifa_getscope(sin); 521 if (scope != 0) 522 return if_findindex(ctx->ifaces, scope); 523 if ((ia = ipv6_findmaskaddr(ctx, &sin->sin6_addr))) 524 return ia->iface; 525 break; 526 } 527 #endif 528 default: 529 errno = EAFNOSUPPORT; 530 return NULL; 531 } 532 533 errno = ENOENT; 534 return NULL; 535 } 536 537 static void 538 if_copysa(struct sockaddr *dst, const struct sockaddr *src) 539 { 540 541 assert(dst != NULL); 542 assert(src != NULL); 543 544 memcpy(dst, src, src->sa_len); 545 #if defined(INET6) && defined(__KAME__) 546 if (dst->sa_family == AF_INET6) { 547 struct in6_addr *in6; 548 549 in6 = &satosin6(dst)->sin6_addr; 550 if (IN6_IS_ADDR_LINKLOCAL(in6)) 551 in6->s6_addr[2] = in6->s6_addr[3] = '\0'; 552 } 553 #endif 554 } 555 556 int 557 if_route(unsigned char cmd, const struct rt *rt) 558 { 559 struct dhcpcd_ctx *ctx; 560 struct rtm rtmsg; 561 struct rt_msghdr *rtm = &rtmsg.hdr; 562 char *bp = rtmsg.buffer; 563 struct sockaddr_dl sdl; 564 bool gateway_unspec; 565 566 assert(rt != NULL); 567 assert(rt->rt_ifp != NULL); 568 assert(rt->rt_ifp->ctx != NULL); 569 ctx = rt->rt_ifp->ctx; 570 571 #define ADDSA(sa) do { \ 572 memcpy(bp, (sa), (sa)->sa_len); \ 573 bp += RT_ROUNDUP((sa)->sa_len); \ 574 } while (0 /* CONSTCOND */) 575 576 memset(&rtmsg, 0, sizeof(rtmsg)); 577 rtm->rtm_version = RTM_VERSION; 578 rtm->rtm_type = cmd; 579 #ifdef __OpenBSD__ 580 rtm->rtm_pid = getpid(); 581 #endif 582 rtm->rtm_seq = ++ctx->seq; 583 rtm->rtm_flags = (int)rt->rt_flags; 584 rtm->rtm_addrs = RTA_DST; 585 #ifdef RTF_PINNED 586 if (cmd != RTM_ADD) 587 rtm->rtm_flags |= RTF_PINNED; 588 #endif 589 590 gateway_unspec = sa_is_unspecified(&rt->rt_gateway); 591 592 if (cmd == RTM_ADD || cmd == RTM_CHANGE) { 593 bool netmask_bcast = sa_is_allones(&rt->rt_netmask); 594 595 rtm->rtm_flags |= RTF_UP; 596 rtm->rtm_addrs |= RTA_GATEWAY; 597 if (!(rtm->rtm_flags & RTF_REJECT) && 598 !sa_is_loopback(&rt->rt_gateway)) 599 { 600 rtm->rtm_index = (unsigned short)rt->rt_ifp->index; 601 /* 602 * OpenBSD rejects the message for on-link routes. 603 * FreeBSD-12 kernel apparently panics. 604 * I can't replicate the panic, but better safe than sorry! 605 * https://roy.marples.name/archives/dhcpcd-discuss/0002286.html 606 * 607 * Neither OS currently allows IPv6 address sharing anyway, so let's 608 * try to encourage someone to fix that by logging a waring during compile. 609 */ 610 #if defined(__FreeBSD__) || defined(__OpenBSD__) 611 #warning kernel does not allow IPv6 address sharing 612 if (!gateway_unspec || rt->rt_dest.sa_family!=AF_INET6) 613 #endif 614 rtm->rtm_addrs |= RTA_IFP; 615 if (!sa_is_unspecified(&rt->rt_ifa)) 616 rtm->rtm_addrs |= RTA_IFA; 617 } 618 if (netmask_bcast) 619 rtm->rtm_flags |= RTF_HOST; 620 /* Network routes are cloning or connected if supported. 621 * All other routes are static. */ 622 if (gateway_unspec) { 623 #ifdef RTF_CLONING 624 rtm->rtm_flags |= RTF_CLONING; 625 #endif 626 #ifdef RTF_CONNECTED 627 rtm->rtm_flags |= RTF_CONNECTED; 628 #endif 629 #ifdef RTP_CONNECTED 630 rtm->rtm_priority = RTP_CONNECTED; 631 #endif 632 #ifdef RTF_CLONING 633 if (netmask_bcast) { 634 /* 635 * We add a cloning network route for a single 636 * host. Traffic to the host will generate a 637 * cloned route and the hardware address will 638 * resolve correctly. 639 * It might be more correct to use RTF_HOST 640 * instead of RTF_CLONING, and that does work, 641 * but some OS generate an arp warning 642 * diagnostic which we don't want to do. 643 */ 644 rtm->rtm_flags &= ~RTF_HOST; 645 } 646 #endif 647 } else 648 rtm->rtm_flags |= RTF_GATEWAY; 649 650 /* Emulate the kernel by marking address generated 651 * network routes non-static. */ 652 if (!(rt->rt_dflags & RTDF_IFA_ROUTE)) 653 rtm->rtm_flags |= RTF_STATIC; 654 655 if (rt->rt_mtu != 0) { 656 rtm->rtm_inits |= RTV_MTU; 657 rtm->rtm_rmx.rmx_mtu = rt->rt_mtu; 658 } 659 } 660 661 if (!(rtm->rtm_flags & RTF_HOST)) 662 rtm->rtm_addrs |= RTA_NETMASK; 663 664 if_linkaddr(&sdl, rt->rt_ifp); 665 666 ADDSA(&rt->rt_dest); 667 668 if (rtm->rtm_addrs & RTA_GATEWAY) { 669 if (gateway_unspec) 670 ADDSA((struct sockaddr *)&sdl); 671 else { 672 union sa_ss gateway; 673 674 if_copysa(&gateway.sa, &rt->rt_gateway); 675 #ifdef INET6 676 if (gateway.sa.sa_family == AF_INET6) 677 ifa_setscope(&gateway.sin6, rt->rt_ifp->index); 678 #endif 679 ADDSA(&gateway.sa); 680 } 681 } 682 683 if (rtm->rtm_addrs & RTA_NETMASK) 684 ADDSA(&rt->rt_netmask); 685 686 if (rtm->rtm_addrs & RTA_IFP) 687 ADDSA((struct sockaddr *)&sdl); 688 689 if (rtm->rtm_addrs & RTA_IFA) 690 ADDSA(&rt->rt_ifa); 691 692 #undef ADDSA 693 694 rtm->rtm_msglen = (unsigned short)(bp - (char *)rtm); 695 if (write(ctx->link_fd, rtm, rtm->rtm_msglen) == -1) 696 return -1; 697 return 0; 698 } 699 700 static int 701 if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, const struct rt_msghdr *rtm) 702 { 703 const struct sockaddr *rti_info[RTAX_MAX]; 704 705 if (!(rtm->rtm_addrs & RTA_DST)) { 706 errno = EINVAL; 707 return -1; 708 } 709 if (rtm->rtm_type != RTM_MISS && !(rtm->rtm_addrs & RTA_GATEWAY)) { 710 errno = EINVAL; 711 return -1; 712 } 713 #ifdef RTF_CLONED 714 if (rtm->rtm_flags & RTF_CLONED) { 715 errno = ENOTSUP; 716 return -1; 717 } 718 #endif 719 #ifdef RTF_WASCLONED 720 if (rtm->rtm_flags & RTF_WASCLONED) { 721 errno = ENOTSUP; 722 return -1; 723 } 724 #endif 725 #ifdef RTF_LOCAL 726 if (rtm->rtm_flags & RTF_LOCAL) { 727 errno = ENOTSUP; 728 return -1; 729 } 730 #endif 731 #ifdef RTF_BROADCAST 732 if (rtm->rtm_flags & RTF_BROADCAST) { 733 errno = ENOTSUP; 734 return -1; 735 } 736 #endif 737 738 if (get_addrs(rtm->rtm_addrs, (const char *)rtm + sizeof(*rtm), 739 rtm->rtm_msglen - sizeof(*rtm), rti_info) == -1) 740 return -1; 741 memset(rt, 0, sizeof(*rt)); 742 743 rt->rt_flags = (unsigned int)rtm->rtm_flags; 744 if_copysa(&rt->rt_dest, rti_info[RTAX_DST]); 745 if (rtm->rtm_addrs & RTA_NETMASK) { 746 if_copysa(&rt->rt_netmask, rti_info[RTAX_NETMASK]); 747 if (rt->rt_netmask.sa_family == 255) /* Why? */ 748 rt->rt_netmask.sa_family = rt->rt_dest.sa_family; 749 } 750 751 /* dhcpcd likes an unspecified gateway to indicate via the link. 752 * However we need to know if gateway was a link with an address. */ 753 if (rtm->rtm_addrs & RTA_GATEWAY) { 754 if (rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) { 755 const struct sockaddr_dl *sdl; 756 757 sdl = (const struct sockaddr_dl*) 758 (const void *)rti_info[RTAX_GATEWAY]; 759 if (sdl->sdl_alen != 0) 760 rt->rt_dflags |= RTDF_GATELINK; 761 } else if (rtm->rtm_flags & RTF_GATEWAY) 762 if_copysa(&rt->rt_gateway, rti_info[RTAX_GATEWAY]); 763 } 764 765 if (rtm->rtm_addrs & RTA_IFA) 766 if_copysa(&rt->rt_ifa, rti_info[RTAX_IFA]); 767 768 rt->rt_mtu = (unsigned int)rtm->rtm_rmx.rmx_mtu; 769 770 if (rtm->rtm_index) 771 rt->rt_ifp = if_findindex(ctx->ifaces, rtm->rtm_index); 772 else if (rtm->rtm_addrs & RTA_IFP) 773 rt->rt_ifp = if_findsa(ctx, rti_info[RTAX_IFP]); 774 else if (rtm->rtm_addrs & RTA_GATEWAY) 775 rt->rt_ifp = if_findsa(ctx, rti_info[RTAX_GATEWAY]); 776 else 777 rt->rt_ifp = if_findsa(ctx, rti_info[RTAX_DST]); 778 779 if (rt->rt_ifp == NULL && rtm->rtm_type == RTM_MISS) 780 rt->rt_ifp = if_find(ctx->ifaces, "lo0"); 781 782 if (rt->rt_ifp == NULL) { 783 errno = ESRCH; 784 return -1; 785 } 786 return 0; 787 } 788 789 int 790 if_initrt(struct dhcpcd_ctx *ctx, rb_tree_t *kroutes, int af) 791 { 792 struct rt_msghdr *rtm; 793 int mib[6]; 794 size_t needed; 795 char *buf, *p, *end; 796 struct rt rt, *rtn; 797 798 mib[0] = CTL_NET; 799 mib[1] = PF_ROUTE; 800 mib[2] = 0; 801 mib[3] = af; 802 mib[4] = NET_RT_DUMP; 803 mib[5] = 0; 804 805 if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) 806 return -1; 807 if (needed == 0) 808 return 0; 809 if ((buf = malloc(needed)) == NULL) 810 return -1; 811 if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) { 812 free(buf); 813 return -1; 814 } 815 816 end = buf + needed; 817 for (p = buf; p < end; p += rtm->rtm_msglen) { 818 rtm = (void *)p; 819 if (p + rtm->rtm_msglen >= end) { 820 errno = EINVAL; 821 break; 822 } 823 if (if_copyrt(ctx, &rt, rtm) != 0) 824 continue; 825 if ((rtn = rt_new(rt.rt_ifp)) == NULL) { 826 logerr(__func__); 827 break; 828 } 829 memcpy(rtn, &rt, sizeof(*rtn)); 830 if (rb_tree_insert_node(kroutes, rtn) != rtn) 831 rt_free(rtn); 832 } 833 free(buf); 834 return p == end ? 0 : -1; 835 } 836 837 #ifdef INET 838 int 839 if_address(unsigned char cmd, const struct ipv4_addr *ia) 840 { 841 int r; 842 struct in_aliasreq ifra; 843 844 memset(&ifra, 0, sizeof(ifra)); 845 strlcpy(ifra.ifra_name, ia->iface->name, sizeof(ifra.ifra_name)); 846 847 #define ADDADDR(var, addr) do { \ 848 (var)->sin_family = AF_INET; \ 849 (var)->sin_len = sizeof(*(var)); \ 850 (var)->sin_addr = *(addr); \ 851 } while (/*CONSTCOND*/0) 852 ADDADDR(&ifra.ifra_addr, &ia->addr); 853 ADDADDR(&ifra.ifra_mask, &ia->mask); 854 if (cmd == RTM_NEWADDR && ia->brd.s_addr != INADDR_ANY) 855 ADDADDR(&ifra.ifra_broadaddr, &ia->brd); 856 #undef ADDADDR 857 858 r = ioctl(ia->iface->ctx->pf_inet_fd, 859 cmd == RTM_DELADDR ? SIOCDIFADDR : SIOCAIFADDR, &ifra); 860 return r; 861 } 862 863 864 865 #if !(defined(HAVE_IFADDRS_ADDRFLAGS) && defined(HAVE_IFAM_ADDRFLAGS)) 866 int 867 if_addrflags(const struct interface *ifp, const struct in_addr *addr, 868 __unused const char *alias) 869 { 870 #ifdef SIOCGIFAFLAG_IN 871 struct ifreq ifr; 872 struct sockaddr_in *sin; 873 874 memset(&ifr, 0, sizeof(ifr)); 875 strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); 876 sin = (void *)&ifr.ifr_addr; 877 sin->sin_family = AF_INET; 878 sin->sin_addr = *addr; 879 if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFAFLAG_IN, &ifr) == -1) 880 return -1; 881 return ifr.ifr_addrflags; 882 #else 883 UNUSED(ifp); 884 UNUSED(addr); 885 return 0; 886 #endif 887 } 888 #endif 889 #endif /* INET */ 890 891 #ifdef INET6 892 static void 893 ifa_setscope(struct sockaddr_in6 *sin, unsigned int ifindex) 894 { 895 896 #ifdef __KAME__ 897 /* KAME based systems want to store the scope inside the sin6_addr 898 * for link local addresses */ 899 if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) { 900 uint16_t scope = htons((uint16_t)ifindex); 901 memcpy(&sin->sin6_addr.s6_addr[2], &scope, 902 sizeof(scope)); 903 } 904 sin->sin6_scope_id = 0; 905 #else 906 if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) 907 sin->sin6_scope_id = ifindex; 908 else 909 sin->sin6_scope_id = 0; 910 #endif 911 } 912 913 static unsigned int 914 ifa_getscope(const struct sockaddr_in6 *sin) 915 { 916 #ifdef __KAME__ 917 uint16_t scope; 918 #endif 919 920 if (!IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) 921 return 0; 922 #ifdef __KAME__ 923 memcpy(&scope, &sin->sin6_addr.s6_addr[2], sizeof(scope)); 924 return (unsigned int)ntohs(scope); 925 #else 926 return (unsigned int)sin->sin6_scope_id; 927 #endif 928 } 929 930 int 931 if_address6(unsigned char cmd, const struct ipv6_addr *ia) 932 { 933 struct in6_aliasreq ifa; 934 struct in6_addr mask; 935 struct priv *priv; 936 937 priv = (struct priv *)ia->iface->ctx->priv; 938 939 memset(&ifa, 0, sizeof(ifa)); 940 strlcpy(ifa.ifra_name, ia->iface->name, sizeof(ifa.ifra_name)); 941 /* 942 * We should not set IN6_IFF_TENTATIVE as the kernel should be 943 * able to work out if it's a new address or not. 944 * 945 * We should set IN6_IFF_AUTOCONF, but the kernel won't let us. 946 * This is probably a safety measure, but still it's not entirely right 947 * either. 948 */ 949 #if 0 950 if (ia->autoconf) 951 ifa.ifra_flags |= IN6_IFF_AUTOCONF; 952 #endif 953 #if defined(__FreeBSD__) || defined(__DragonFly__) 954 if (ia->addr_flags & IN6_IFF_TENTATIVE) 955 ifa.ifra_flags |= IN6_IFF_TENTATIVE; 956 #endif 957 #ifdef IPV6_MANGETEMPADDR 958 if (ia->flags & IPV6_AF_TEMPORARY) 959 ifa.ifra_flags |= IN6_IFF_TEMPORARY; 960 #endif 961 962 #define ADDADDR(v, addr) { \ 963 (v)->sin6_family = AF_INET6; \ 964 (v)->sin6_len = sizeof(*v); \ 965 (v)->sin6_addr = *(addr); \ 966 } 967 968 ADDADDR(&ifa.ifra_addr, &ia->addr); 969 ifa_setscope(&ifa.ifra_addr, ia->iface->index); 970 ipv6_mask(&mask, ia->prefix_len); 971 ADDADDR(&ifa.ifra_prefixmask, &mask); 972 973 #undef ADDADDR 974 975 /* 976 * Every BSD kernel wants to add the prefix of the address to it's 977 * list of RA received prefixes. 978 * THIS IS WRONG because there (as the comments in the kernel state) 979 * is no API for managing prefix lifetime and the kernel should not 980 * pretend it's from a RA either. 981 * 982 * The issue is that the very first assigned prefix will inherit the 983 * lifetime of the address, but any subsequent alteration of the 984 * address OR it's lifetime will not affect the prefix lifetime. 985 * As such, we cannot stop the prefix from timing out and then 986 * constantly removing the prefix route dhcpcd is capable of adding 987 * in it's absense. 988 * 989 * What we can do to mitigate the issue is to add the address with 990 * infinite lifetimes, so the prefix route will never time out. 991 * Once done, we can then set lifetimes on the address and all is good. 992 * The downside of this approach is that we need to manually remove 993 * the kernel route because it has no lifetime, but this is OK as 994 * dhcpcd will handle this too. 995 * 996 * This issue is discussed on the NetBSD mailing lists here: 997 * http://mail-index.netbsd.org/tech-net/2016/08/05/msg006044.html 998 * 999 * Fixed in NetBSD-7.99.36 1000 * NOT fixed in FreeBSD - bug 195197 1001 * Fixed in OpenBSD-5.9 1002 */ 1003 1004 #if !((defined(__NetBSD_Version__) && __NetBSD_Version__ >= 799003600) || \ 1005 (defined(__OpenBSD__) && OpenBSD >= 201605)) 1006 if (cmd == RTM_NEWADDR && !(ia->flags & IPV6_AF_ADDED)) { 1007 ifa.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; 1008 ifa.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; 1009 (void)ioctl(priv->pf_inet6_fd, SIOCAIFADDR_IN6, &ifa); 1010 } 1011 #endif 1012 1013 #if defined(__OpenBSD__) && OpenBSD <= 201705 1014 /* BUT OpenBSD older than 6.2 does not reset the address lifetime 1015 * for subsequent calls... 1016 * Luckily dhcpcd will remove the lease when it expires so 1017 * just set an infinite lifetime, unless a temporary address. */ 1018 if (ifa.ifra_flags & IN6_IFF_PRIVACY) { 1019 ifa.ifra_lifetime.ia6t_vltime = ia->prefix_vltime; 1020 ifa.ifra_lifetime.ia6t_pltime = ia->prefix_pltime; 1021 } else { 1022 ifa.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; 1023 ifa.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; 1024 } 1025 #else 1026 ifa.ifra_lifetime.ia6t_vltime = ia->prefix_vltime; 1027 ifa.ifra_lifetime.ia6t_pltime = ia->prefix_pltime; 1028 #endif 1029 1030 return ioctl(priv->pf_inet6_fd, 1031 cmd == RTM_DELADDR ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa); 1032 } 1033 1034 int 1035 if_addrflags6(const struct interface *ifp, const struct in6_addr *addr, 1036 __unused const char *alias) 1037 { 1038 int flags; 1039 struct in6_ifreq ifr6; 1040 struct priv *priv; 1041 1042 memset(&ifr6, 0, sizeof(ifr6)); 1043 strlcpy(ifr6.ifr_name, ifp->name, sizeof(ifr6.ifr_name)); 1044 ifr6.ifr_addr.sin6_family = AF_INET6; 1045 ifr6.ifr_addr.sin6_addr = *addr; 1046 ifa_setscope(&ifr6.ifr_addr, ifp->index); 1047 priv = (struct priv *)ifp->ctx->priv; 1048 if (ioctl(priv->pf_inet6_fd, SIOCGIFAFLAG_IN6, &ifr6) != -1) 1049 flags = ifr6.ifr_ifru.ifru_flags6; 1050 else 1051 flags = -1; 1052 return flags; 1053 } 1054 1055 int 1056 if_getlifetime6(struct ipv6_addr *ia) 1057 { 1058 struct in6_ifreq ifr6; 1059 time_t t; 1060 struct in6_addrlifetime *lifetime; 1061 struct priv *priv; 1062 1063 memset(&ifr6, 0, sizeof(ifr6)); 1064 strlcpy(ifr6.ifr_name, ia->iface->name, sizeof(ifr6.ifr_name)); 1065 ifr6.ifr_addr.sin6_family = AF_INET6; 1066 ifr6.ifr_addr.sin6_addr = ia->addr; 1067 ifa_setscope(&ifr6.ifr_addr, ia->iface->index); 1068 priv = (struct priv *)ia->iface->ctx->priv; 1069 if (ioctl(priv->pf_inet6_fd, SIOCGIFALIFETIME_IN6, &ifr6) == -1) 1070 return -1; 1071 clock_gettime(CLOCK_MONOTONIC, &ia->created); 1072 1073 #if defined(__FreeBSD__) || defined(__DragonFly__) 1074 t = ia->created.tv_sec; 1075 #else 1076 t = time(NULL); 1077 #endif 1078 1079 lifetime = &ifr6.ifr_ifru.ifru_lifetime; 1080 if (lifetime->ia6t_preferred) 1081 ia->prefix_pltime = (uint32_t)(lifetime->ia6t_preferred - 1082 MIN(t, lifetime->ia6t_preferred)); 1083 else 1084 ia->prefix_pltime = ND6_INFINITE_LIFETIME; 1085 if (lifetime->ia6t_expire) { 1086 ia->prefix_vltime = (uint32_t)(lifetime->ia6t_expire - 1087 MIN(t, lifetime->ia6t_expire)); 1088 /* Calculate the created time */ 1089 ia->created.tv_sec -= lifetime->ia6t_vltime - ia->prefix_vltime; 1090 } else 1091 ia->prefix_vltime = ND6_INFINITE_LIFETIME; 1092 return 0; 1093 } 1094 #endif 1095 1096 static int 1097 if_announce(struct dhcpcd_ctx *ctx, const struct if_announcemsghdr *ifan) 1098 { 1099 1100 if (ifan->ifan_msglen < sizeof(*ifan)) { 1101 errno = EINVAL; 1102 return -1; 1103 } 1104 1105 switch(ifan->ifan_what) { 1106 case IFAN_ARRIVAL: 1107 return dhcpcd_handleinterface(ctx, 1, ifan->ifan_name); 1108 case IFAN_DEPARTURE: 1109 return dhcpcd_handleinterface(ctx, -1, ifan->ifan_name); 1110 } 1111 1112 return 0; 1113 } 1114 1115 static int 1116 if_ifinfo(struct dhcpcd_ctx *ctx, const struct if_msghdr *ifm) 1117 { 1118 struct interface *ifp; 1119 int link_state; 1120 1121 if (ifm->ifm_msglen < sizeof(*ifm)) { 1122 errno = EINVAL; 1123 return -1; 1124 } 1125 1126 if ((ifp = if_findindex(ctx->ifaces, ifm->ifm_index)) == NULL) 1127 return 0; 1128 1129 switch (ifm->ifm_data.ifi_link_state) { 1130 case LINK_STATE_UNKNOWN: 1131 link_state = LINK_UNKNOWN; 1132 break; 1133 #ifdef LINK_STATE_FULL_DUPLEX 1134 case LINK_STATE_HALF_DUPLEX: /* FALLTHROUGH */ 1135 case LINK_STATE_FULL_DUPLEX: /* FALLTHROUGH */ 1136 #endif 1137 case LINK_STATE_UP: 1138 link_state = LINK_UP; 1139 break; 1140 default: 1141 link_state = LINK_DOWN; 1142 break; 1143 } 1144 1145 dhcpcd_handlecarrier(ctx, link_state, 1146 (unsigned int)ifm->ifm_flags, ifp->name); 1147 return 0; 1148 } 1149 1150 static int 1151 if_rtm(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm) 1152 { 1153 struct rt rt; 1154 1155 if (rtm->rtm_msglen < sizeof(*rtm)) { 1156 errno = EINVAL; 1157 return -1; 1158 } 1159 1160 /* Ignore errors. */ 1161 if (rtm->rtm_errno != 0) 1162 return 0; 1163 1164 if (if_copyrt(ctx, &rt, rtm) == -1) 1165 return errno == ENOTSUP ? 0 : -1; 1166 1167 #ifdef INET6 1168 /* 1169 * BSD announces host routes. 1170 * As such, we should be notified of reachability by its 1171 * existance with a hardware address. 1172 * Ensure we don't call this for a newly incomplete state. 1173 */ 1174 if (rt.rt_dest.sa_family == AF_INET6 && 1175 (rt.rt_flags & RTF_HOST || rtm->rtm_type == RTM_MISS) && 1176 !(rtm->rtm_type == RTM_ADD && !(rt.rt_dflags & RTDF_GATELINK))) 1177 { 1178 bool reachable; 1179 1180 reachable = (rtm->rtm_type == RTM_ADD || 1181 rtm->rtm_type == RTM_CHANGE) && 1182 rt.rt_dflags & RTDF_GATELINK; 1183 ipv6nd_neighbour(ctx, &rt.rt_ss_dest.sin6.sin6_addr, reachable); 1184 } 1185 #endif 1186 1187 if (rtm->rtm_type != RTM_MISS) 1188 rt_recvrt(rtm->rtm_type, &rt, rtm->rtm_pid); 1189 return 0; 1190 } 1191 1192 static int 1193 if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam) 1194 { 1195 struct interface *ifp; 1196 const struct sockaddr *rti_info[RTAX_MAX]; 1197 int addrflags; 1198 pid_t pid; 1199 1200 if (ifam->ifam_msglen < sizeof(*ifam)) { 1201 errno = EINVAL; 1202 return -1; 1203 } 1204 if (~ifam->ifam_addrs & RTA_IFA) 1205 return 0; 1206 if ((ifp = if_findindex(ctx->ifaces, ifam->ifam_index)) == NULL) 1207 return 0; 1208 1209 if (get_addrs(ifam->ifam_addrs, (const char *)ifam + sizeof(*ifam), 1210 ifam->ifam_msglen - sizeof(*ifam), rti_info) == -1) 1211 return -1; 1212 1213 #ifdef HAVE_IFAM_PID 1214 pid = ifam->ifam_pid; 1215 #else 1216 pid = 0; 1217 #endif 1218 1219 #ifdef HAVE_IFAM_ADDRFLAGS 1220 addrflags = ifam->ifam_addrflags; 1221 #endif 1222 switch (rti_info[RTAX_IFA]->sa_family) { 1223 case AF_LINK: 1224 { 1225 struct sockaddr_dl sdl; 1226 1227 #ifdef RTM_CHGADDR 1228 if (ifam->ifam_type != RTM_CHGADDR) 1229 break; 1230 #else 1231 if (ifam->ifam_type != RTM_NEWADDR) 1232 break; 1233 #endif 1234 memcpy(&sdl, rti_info[RTAX_IFA], rti_info[RTAX_IFA]->sa_len); 1235 dhcpcd_handlehwaddr(ctx, ifp->name, CLLADDR(&sdl),sdl.sdl_alen); 1236 break; 1237 } 1238 #ifdef INET 1239 case AF_INET: 1240 case 255: /* FIXME: Why 255? */ 1241 { 1242 const struct sockaddr_in *sin; 1243 struct in_addr addr, mask, bcast; 1244 1245 sin = (const void *)rti_info[RTAX_IFA]; 1246 addr.s_addr = sin != NULL && sin->sin_family == AF_INET ? 1247 sin->sin_addr.s_addr : INADDR_ANY; 1248 sin = (const void *)rti_info[RTAX_NETMASK]; 1249 mask.s_addr = sin != NULL && sin->sin_family == AF_INET ? 1250 sin->sin_addr.s_addr : INADDR_ANY; 1251 sin = (const void *)rti_info[RTAX_BRD]; 1252 bcast.s_addr = sin != NULL && sin->sin_family == AF_INET ? 1253 sin->sin_addr.s_addr : INADDR_ANY; 1254 1255 #if defined(__NetBSD_Version__) && __NetBSD_Version__ < 800000000 1256 /* 1257 * NetBSD-7 and older send an invalid broadcast address. 1258 * So we need to query the actual address to get 1259 * the right one. 1260 */ 1261 { 1262 #else 1263 /* 1264 * If the address was deleted, lets check if it's 1265 * a late message and it still exists (maybe modified). 1266 * If so, ignore it as deleting an address causes 1267 * dhcpcd to drop any lease to which it belongs. 1268 */ 1269 if (ifam->ifam_type == RTM_DELADDR) { 1270 #endif 1271 #ifdef SIOCGIFALIAS 1272 struct in_aliasreq ifra; 1273 1274 memset(&ifra, 0, sizeof(ifra)); 1275 strlcpy(ifra.ifra_name, ifp->name, 1276 sizeof(ifra.ifra_name)); 1277 ifra.ifra_addr.sin_family = AF_INET; 1278 ifra.ifra_addr.sin_len = sizeof(ifra.ifra_addr); 1279 ifra.ifra_addr.sin_addr = addr; 1280 if (ioctl(ctx->pf_inet_fd, SIOCGIFALIAS, &ifra) == -1) { 1281 if (errno != ENXIO && errno != EADDRNOTAVAIL) 1282 logerr("%s: SIOCGIFALIAS", __func__); 1283 if (ifam->ifam_type != RTM_DELADDR) 1284 break; 1285 } 1286 #if defined(__NetBSD_Version__) && __NetBSD_Version__ < 800000000 1287 else 1288 bcast = ifra.ifra_broadaddr.sin_addr; 1289 #endif 1290 #else 1291 #warning No SIOCGIFALIAS support 1292 /* 1293 * No SIOCGIFALIAS? That sucks! 1294 * This makes this call very heavy weight, but we 1295 * really need to know if the message is late or not. 1296 */ 1297 const struct sockaddr *sa; 1298 struct ifaddrs *ifaddrs = NULL, *ifa; 1299 1300 sa = rti_info[RTAX_IFA]; 1301 getifaddrs(&ifaddrs); 1302 for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) { 1303 if (ifa->ifa_addr == NULL) 1304 continue; 1305 if (sa_cmp(ifa->ifa_addr, sa) == 0 && 1306 strcmp(ifa->ifa_name, ifp->name) == 0) 1307 break; 1308 } 1309 freeifaddrs(ifaddrs); 1310 if (ifa != NULL) 1311 return 0; 1312 #endif 1313 } 1314 1315 #ifndef HAVE_IFAM_ADDRFLAGS 1316 if (ifam->ifam_type == RTM_DELADDR) 1317 addrflags = 0 ; 1318 else if ((addrflags = if_addrflags(ifp, &addr, NULL)) == -1) { 1319 if (errno != EADDRNOTAVAIL) 1320 logerr("%s: if_addrflags", __func__); 1321 break; 1322 } 1323 #endif 1324 1325 ipv4_handleifa(ctx, ifam->ifam_type, NULL, ifp->name, 1326 &addr, &mask, &bcast, addrflags, pid); 1327 break; 1328 } 1329 #endif 1330 #ifdef INET6 1331 case AF_INET6: 1332 { 1333 struct in6_addr addr6, mask6; 1334 const struct sockaddr_in6 *sin6; 1335 int flags; 1336 1337 sin6 = (const void *)rti_info[RTAX_IFA]; 1338 addr6 = sin6->sin6_addr; 1339 sin6 = (const void *)rti_info[RTAX_NETMASK]; 1340 mask6 = sin6->sin6_addr; 1341 1342 /* 1343 * If the address was deleted, lets check if it's 1344 * a late message and it still exists (maybe modified). 1345 * If so, ignore it as deleting an address causes 1346 * dhcpcd to drop any lease to which it belongs. 1347 */ 1348 if (ifam->ifam_type == RTM_DELADDR) { 1349 flags = if_addrflags6(ifp, &addr6, NULL); 1350 if (flags != -1) 1351 break; 1352 addrflags = 0; 1353 } 1354 #ifndef HAVE_IFAM_ADDRFLAGS 1355 else if ((addrflags = if_addrflags6(ifp, &addr6, NULL)) == -1) { 1356 if (errno != EADDRNOTAVAIL) 1357 logerr("%s: if_addrflags6", __func__); 1358 break; 1359 } 1360 #endif 1361 1362 #ifdef __KAME__ 1363 if (IN6_IS_ADDR_LINKLOCAL(&addr6)) 1364 /* Remove the scope from the address */ 1365 addr6.s6_addr[2] = addr6.s6_addr[3] = '\0'; 1366 #endif 1367 1368 ipv6_handleifa(ctx, ifam->ifam_type, NULL, 1369 ifp->name, &addr6, ipv6_prefixlen(&mask6), addrflags, pid); 1370 break; 1371 } 1372 #endif 1373 } 1374 1375 return 0; 1376 } 1377 1378 static int 1379 if_dispatch(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm) 1380 { 1381 1382 if (rtm->rtm_version != RTM_VERSION) 1383 return 0; 1384 1385 switch(rtm->rtm_type) { 1386 #ifdef RTM_IFANNOUNCE 1387 case RTM_IFANNOUNCE: 1388 return if_announce(ctx, (const void *)rtm); 1389 #endif 1390 case RTM_IFINFO: 1391 return if_ifinfo(ctx, (const void *)rtm); 1392 case RTM_ADD: /* FALLTHROUGH */ 1393 case RTM_CHANGE: /* FALLTHROUGH */ 1394 case RTM_DELETE: /* FALLTHROUGH */ 1395 case RTM_MISS: 1396 return if_rtm(ctx, (const void *)rtm); 1397 #ifdef RTM_CHGADDR 1398 case RTM_CHGADDR: /* FALLTHROUGH */ 1399 #endif 1400 case RTM_DELADDR: /* FALLTHROUGH */ 1401 case RTM_NEWADDR: 1402 return if_ifa(ctx, (const void *)rtm); 1403 #ifdef RTM_DESYNC 1404 case RTM_DESYNC: 1405 dhcpcd_linkoverflow(ctx); 1406 #elif !defined(SO_RERROR) 1407 #warning cannot detect route socket overflow within kernel 1408 #endif 1409 } 1410 1411 return 0; 1412 } 1413 1414 __CTASSERT(offsetof(struct rt_msghdr, rtm_msglen) == 0); 1415 int 1416 if_handlelink(struct dhcpcd_ctx *ctx) 1417 { 1418 struct rtm rtm; 1419 ssize_t len; 1420 1421 len = read(ctx->link_fd, &rtm, sizeof(rtm)); 1422 if (len == -1) 1423 return -1; 1424 if (len == 0) 1425 return 0; 1426 if ((size_t)len < sizeof(rtm.hdr.rtm_msglen) || 1427 len != rtm.hdr.rtm_msglen) 1428 { 1429 errno = EINVAL; 1430 return -1; 1431 } 1432 /* 1433 * Coverity thinks that the data could be tainted from here. 1434 * I have no idea how because the length of the data we read 1435 * is guarded by len and checked to match rtm_msglen. 1436 * The issue seems to be related to extracting the addresses 1437 * at the end of the header, but seems to have no issues with the 1438 * equivalent call in if_initrt. 1439 */ 1440 /* coverity[tainted_data] */ 1441 return if_dispatch(ctx, &rtm.hdr); 1442 } 1443 1444 #ifndef SYS_NMLN /* OSX */ 1445 # define SYS_NMLN 256 1446 #endif 1447 #ifndef HW_MACHINE_ARCH 1448 # ifdef HW_MODEL /* OpenBSD */ 1449 # define HW_MACHINE_ARCH HW_MODEL 1450 # endif 1451 #endif 1452 int 1453 if_machinearch(char *str, size_t len) 1454 { 1455 int mib[2] = { CTL_HW, HW_MACHINE_ARCH }; 1456 char march[SYS_NMLN]; 1457 size_t marchlen = sizeof(march); 1458 1459 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 1460 march, &marchlen, NULL, 0) != 0) 1461 return -1; 1462 return snprintf(str, len, ":%s", march); 1463 } 1464 1465 #ifdef INET6 1466 #if (defined(IPV6CTL_ACCEPT_RTADV) && !defined(ND6_IFF_ACCEPT_RTADV)) || \ 1467 defined(IPV6CTL_USETEMPADDR) || defined(IPV6CTL_TEMPVLTIME) || \ 1468 defined(IPV6CTL_FORWARDING) 1469 #define get_inet6_sysctl(code) inet6_sysctl(code, 0, 0) 1470 #define set_inet6_sysctl(code, val) inet6_sysctl(code, val, 1) 1471 static int 1472 inet6_sysctl(int code, int val, int action) 1473 { 1474 int mib[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, 0 }; 1475 size_t size; 1476 1477 mib[3] = code; 1478 size = sizeof(val); 1479 if (action) { 1480 if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), 1481 NULL, 0, &val, size) == -1) 1482 return -1; 1483 return 0; 1484 } 1485 if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &val, &size, NULL, 0) == -1) 1486 return -1; 1487 return val; 1488 } 1489 #endif 1490 1491 int 1492 if_applyra(const struct ra *rap) 1493 { 1494 #ifdef SIOCSIFINFO_IN6 1495 struct in6_ndireq ndi = { .ndi.chlim = 0 }; 1496 struct priv *priv = rap->iface->ctx->priv; 1497 int error; 1498 1499 strlcpy(ndi.ifname, rap->iface->name, sizeof(ndi.ifname)); 1500 if (ioctl(priv->pf_inet6_fd, SIOCGIFINFO_IN6, &ndi) == -1) 1501 return -1; 1502 1503 ndi.ndi.linkmtu = rap->mtu; 1504 ndi.ndi.chlim = rap->hoplimit; 1505 ndi.ndi.retrans = rap->retrans; 1506 ndi.ndi.basereachable = rap->reachable; 1507 error = ioctl(priv->pf_inet6_fd, SIOCSIFINFO_IN6, &ndi); 1508 if (error == -1 && errno == EINVAL) { 1509 /* 1510 * Very likely that this is caused by a dodgy MTU 1511 * setting specific to the interface. 1512 * Let's set it to "unspecified" and try again. 1513 * Doesn't really matter as we fix the MTU against the 1514 * routes we add as not all OS support SIOCSIFINFO_IN6. 1515 */ 1516 ndi.ndi.linkmtu = 0; 1517 error = ioctl(priv->pf_inet6_fd, SIOCSIFINFO_IN6, &ndi); 1518 } 1519 return error; 1520 #else 1521 #warning OS does not allow setting of RA bits hoplimit, retrans or reachable 1522 UNUSED(rap); 1523 return 0; 1524 #endif 1525 } 1526 1527 #ifdef IPV6_MANAGETEMPADDR 1528 #ifndef IPV6CTL_TEMPVLTIME 1529 #define get_inet6_sysctlbyname(code) inet6_sysctlbyname(code, 0, 0) 1530 #define set_inet6_sysctlbyname(code, val) inet6_sysctlbyname(code, val, 1) 1531 static int 1532 inet6_sysctlbyname(const char *name, int val, int action) 1533 { 1534 size_t size; 1535 1536 size = sizeof(val); 1537 if (action) { 1538 if (sysctlbyname(name, NULL, 0, &val, size) == -1) 1539 return -1; 1540 return 0; 1541 } 1542 if (sysctlbyname(name, &val, &size, NULL, 0) == -1) 1543 return -1; 1544 return val; 1545 } 1546 #endif 1547 1548 int 1549 ip6_use_tempaddr(__unused const char *ifname) 1550 { 1551 int val; 1552 1553 #ifdef IPV6CTL_USETEMPADDR 1554 val = get_inet6_sysctl(IPV6CTL_USETEMPADDR); 1555 #else 1556 val = get_inet6_sysctlbyname("net.inet6.ip6.use_tempaddr"); 1557 #endif 1558 return val == -1 ? 0 : val; 1559 } 1560 1561 int 1562 ip6_temp_preferred_lifetime(__unused const char *ifname) 1563 { 1564 int val; 1565 1566 #ifdef IPV6CTL_TEMPPLTIME 1567 val = get_inet6_sysctl(IPV6CTL_TEMPPLTIME); 1568 #else 1569 val = get_inet6_sysctlbyname("net.inet6.ip6.temppltime"); 1570 #endif 1571 return val < 0 ? TEMP_PREFERRED_LIFETIME : val; 1572 } 1573 1574 int 1575 ip6_temp_valid_lifetime(__unused const char *ifname) 1576 { 1577 int val; 1578 1579 #ifdef IPV6CTL_TEMPVLTIME 1580 val = get_inet6_sysctl(IPV6CTL_TEMPVLTIME); 1581 #else 1582 val = get_inet6_sysctlbyname("net.inet6.ip6.tempvltime"); 1583 #endif 1584 return val < 0 ? TEMP_VALID_LIFETIME : val; 1585 } 1586 #endif 1587 1588 int 1589 ip6_forwarding(__unused const char *ifname) 1590 { 1591 int val; 1592 1593 #ifdef IPV6CTL_FORWARDING 1594 val = get_inet6_sysctl(IPV6CTL_FORWARDING); 1595 #else 1596 val = get_inet6_sysctlbyname("net.inet6.ip6.forwarding"); 1597 #endif 1598 return val < 0 ? 0 : val; 1599 } 1600 1601 #ifdef SIOCIFAFATTACH 1602 static int 1603 af_attach(int s, const struct interface *ifp, int af) 1604 { 1605 struct if_afreq ifar; 1606 1607 strlcpy(ifar.ifar_name, ifp->name, sizeof(ifar.ifar_name)); 1608 ifar.ifar_af = af; 1609 return ioctl(s, SIOCIFAFATTACH, (void *)&ifar); 1610 } 1611 #endif 1612 1613 #ifdef SIOCGIFXFLAGS 1614 static int 1615 set_ifxflags(int s, const struct interface *ifp) 1616 { 1617 struct ifreq ifr; 1618 int flags; 1619 1620 strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); 1621 if (ioctl(s, SIOCGIFXFLAGS, (void *)&ifr) == -1) 1622 return -1; 1623 flags = ifr.ifr_flags; 1624 #ifdef IFXF_NOINET6 1625 flags &= ~IFXF_NOINET6; 1626 #endif 1627 /* 1628 * If not doing autoconf, don't disable the kernel from doing it. 1629 * If we need to, we should have another option actively disable it. 1630 * 1631 * OpenBSD moved from kernel based SLAAC to userland via slaacd(8). 1632 * It has a similar featureset to dhcpcd such as stable private 1633 * addresses, but lacks the ability to handle DNS inside the RA 1634 * which is a serious shortfall in this day and age. 1635 * Appease their user base by working alongside slaacd(8) if 1636 * dhcpcd is instructed not to do auto configuration of addresses. 1637 */ 1638 #if defined(ND6_IFF_ACCEPT_RTADV) 1639 #define BSD_AUTOCONF DHCPCD_IPV6RS 1640 #else 1641 #define BSD_AUTOCONF DHCPCD_IPV6RA_AUTOCONF 1642 #endif 1643 if (ifp->options->options & BSD_AUTOCONF) 1644 flags &= ~IFXF_AUTOCONF6; 1645 if (ifr.ifr_flags == flags) 1646 return 0; 1647 ifr.ifr_flags = flags; 1648 return ioctl(s, SIOCSIFXFLAGS, (void *)&ifr); 1649 } 1650 #endif 1651 1652 /* OpenBSD removed ND6 flags entirely, so we need to check for their 1653 * existance. */ 1654 #if defined(ND6_IFF_AUTO_LINKLOCAL) || \ 1655 defined(ND6_IFF_PERFORMNUD) || \ 1656 defined(ND6_IFF_ACCEPT_RTADV) || \ 1657 defined(ND6_IFF_OVERRIDE_RTADV) || \ 1658 defined(ND6_IFF_IFDISABLED) 1659 #define ND6_NDI_FLAGS 1660 #endif 1661 1662 void 1663 if_disable_rtadv(void) 1664 { 1665 #if defined(IPV6CTL_ACCEPT_RTADV) && !defined(ND6_IFF_ACCEPT_RTADV) 1666 int ra = get_inet6_sysctl(IPV6CTL_ACCEPT_RTADV); 1667 1668 if (ra == -1) { 1669 if (errno != ENOENT) 1670 logerr("IPV6CTL_ACCEPT_RTADV"); 1671 else if (ra != 0) 1672 if (set_inet6_sysctl(IPV6CTL_ACCEPT_RTADV, 0) == -1) 1673 logerr("IPV6CTL_ACCEPT_RTADV"); 1674 } 1675 #endif 1676 } 1677 1678 void 1679 if_setup_inet6(const struct interface *ifp) 1680 { 1681 struct priv *priv; 1682 int s; 1683 #ifdef ND6_NDI_FLAGS 1684 struct in6_ndireq nd; 1685 int flags; 1686 #endif 1687 1688 priv = (struct priv *)ifp->ctx->priv; 1689 s = priv->pf_inet6_fd; 1690 1691 #ifdef ND6_NDI_FLAGS 1692 memset(&nd, 0, sizeof(nd)); 1693 strlcpy(nd.ifname, ifp->name, sizeof(nd.ifname)); 1694 if (ioctl(s, SIOCGIFINFO_IN6, &nd) == -1) 1695 logerr("%s: SIOCGIFINFO_FLAGS", ifp->name); 1696 flags = (int)nd.ndi.flags; 1697 #endif 1698 1699 #ifdef ND6_IFF_AUTO_LINKLOCAL 1700 /* Unlike the kernel, 1701 * dhcpcd make make a stable private address. */ 1702 flags &= ~ND6_IFF_AUTO_LINKLOCAL; 1703 #endif 1704 1705 #ifdef ND6_IFF_PERFORMNUD 1706 /* NUD is kind of essential. */ 1707 flags |= ND6_IFF_PERFORMNUD; 1708 #endif 1709 1710 #ifdef ND6_IFF_IFDISABLED 1711 /* Ensure the interface is not disabled. */ 1712 flags &= ~ND6_IFF_IFDISABLED; 1713 #endif 1714 1715 /* 1716 * If not doing autoconf, don't disable the kernel from doing it. 1717 * If we need to, we should have another option actively disable it. 1718 */ 1719 #ifdef ND6_IFF_ACCEPT_RTADV 1720 if (ifp->options->options & DHCPCD_IPV6RS) 1721 flags &= ~ND6_IFF_ACCEPT_RTADV; 1722 #ifdef ND6_IFF_OVERRIDE_RTADV 1723 if (ifp->options->options & DHCPCD_IPV6RS) 1724 flags |= ND6_IFF_OVERRIDE_RTADV; 1725 #endif 1726 #endif 1727 1728 #ifdef ND6_NDI_FLAGS 1729 if (nd.ndi.flags != (uint32_t)flags) { 1730 nd.ndi.flags = (uint32_t)flags; 1731 if (ioctl(s, SIOCSIFINFO_FLAGS, &nd) == -1) 1732 logerr("%s: SIOCSIFINFO_FLAGS", ifp->name); 1733 } 1734 #endif 1735 1736 /* Enabling IPv6 by whatever means must be the 1737 * last action undertaken to ensure kernel RS and 1738 * LLADDR auto configuration are disabled where applicable. */ 1739 #ifdef SIOCIFAFATTACH 1740 if (af_attach(s, ifp, AF_INET6) == -1) 1741 logerr("%s: af_attach", ifp->name); 1742 #endif 1743 1744 #ifdef SIOCGIFXFLAGS 1745 if (set_ifxflags(s, ifp) == -1) 1746 logerr("%s: set_ifxflags", ifp->name); 1747 #endif 1748 1749 #if defined(IPV6CTL_ACCEPT_RTADV) || defined(ND6_IFF_ACCEPT_RTADV) 1750 /* Flush the kernel knowledge of advertised routers 1751 * and prefixes so the kernel does not expire prefixes 1752 * and default routes we are trying to own. */ 1753 if (ifp->options->options & DHCPCD_IPV6RS) { 1754 struct in6_ifreq ifr; 1755 1756 memset(&ifr, 0, sizeof(ifr)); 1757 strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); 1758 if (ioctl(s, SIOCSRTRFLUSH_IN6, &ifr) == -1 && 1759 errno != ENOTSUP) 1760 logwarn("SIOCSRTRFLUSH_IN6"); 1761 if (ioctl(s, SIOCSPFXFLUSH_IN6, &ifr) == -1 && 1762 errno != ENOTSUP) 1763 logwarn("SIOCSPFXFLUSH_IN6"); 1764 } 1765 #endif 1766 } 1767 #endif 1768