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