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