1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3 * dhcpcd - DHCP client daemon
4 * Copyright (c) 2006-2021 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 #ifdef PRIVSEP_GETIFADDRS
361 if (IN_PRIVSEP(ctx))
362 free(*ifaddrs);
363 else
364 #endif
365 freeifaddrs(*ifaddrs);
366 *ifaddrs = NULL;
367 }
368
369 void
if_deletestaleaddrs(struct if_head * ifs)370 if_deletestaleaddrs(struct if_head *ifs)
371 {
372 struct interface *ifp;
373
374 TAILQ_FOREACH(ifp, ifs, next) {
375 #ifdef INET
376 ipv4_deletestaleaddrs(ifp);
377 #endif
378 #ifdef INET6
379 ipv6_deletestaleaddrs(ifp);
380 #endif
381 }
382 }
383
384 bool
if_valid_hwaddr(const uint8_t * hwaddr,size_t hwlen)385 if_valid_hwaddr(const uint8_t *hwaddr, size_t hwlen)
386 {
387 size_t i;
388 bool all_zeros, all_ones;
389
390 all_zeros = all_ones = true;
391 for (i = 0; i < hwlen; i++) {
392 if (hwaddr[i] != 0x00)
393 all_zeros = false;
394 if (hwaddr[i] != 0xff)
395 all_ones = false;
396 if (!all_zeros && !all_ones)
397 return true;
398 }
399 return false;
400 }
401
402 #if defined(AF_PACKET) && !defined(AF_LINK)
403 static unsigned int
if_check_arphrd(struct interface * ifp,unsigned int active,bool if_noconf)404 if_check_arphrd(struct interface *ifp, unsigned int active, bool if_noconf)
405 {
406
407 switch(ifp->hwtype) {
408 case ARPHRD_ETHER: /* FALLTHROUGH */
409 case ARPHRD_IEEE1394: /* FALLTHROUGH */
410 case ARPHRD_INFINIBAND: /* FALLTHROUGH */
411 case ARPHRD_NONE: /* FALLTHROUGH */
412 break;
413 case ARPHRD_LOOPBACK:
414 case ARPHRD_PPP:
415 if (if_noconf && active) {
416 logdebugx("%s: ignoring due to interface type and"
417 " no config",
418 ifp->name);
419 active = IF_INACTIVE;
420 }
421 break;
422 default:
423 if (active) {
424 int i;
425
426 if (if_noconf)
427 active = IF_INACTIVE;
428 i = active ? LOG_WARNING : LOG_DEBUG;
429 logmessage(i, "%s: unsupported"
430 " interface type 0x%.2x",
431 ifp->name, ifp->hwtype);
432 }
433 break;
434 }
435
436 return active;
437 }
438 #endif
439
440 struct if_head *
if_discover(struct dhcpcd_ctx * ctx,struct ifaddrs ** ifaddrs,int argc,char * const * argv)441 if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs,
442 int argc, char * const *argv)
443 {
444 struct ifaddrs *ifa;
445 int i;
446 unsigned int active;
447 struct if_head *ifs;
448 struct interface *ifp;
449 struct if_spec spec;
450 bool if_noconf;
451 #ifdef AF_LINK
452 const struct sockaddr_dl *sdl;
453 #ifdef IFLR_ACTIVE
454 struct if_laddrreq iflr = { .flags = IFLR_PREFIX };
455 #endif
456 #elif defined(AF_PACKET)
457 const struct sockaddr_ll *sll;
458 #endif
459 #if defined(SIOCGIFPRIORITY)
460 struct ifreq ifr;
461 #endif
462
463 if ((ifs = malloc(sizeof(*ifs))) == NULL) {
464 logerr(__func__);
465 return NULL;
466 }
467 TAILQ_INIT(ifs);
468
469 #ifdef PRIVSEP_GETIFADDRS
470 if (ctx->options & DHCPCD_PRIVSEP) {
471 if (ps_root_getifaddrs(ctx, ifaddrs) == -1) {
472 logerr("ps_root_getifaddrs");
473 free(ifs);
474 return NULL;
475 }
476 } else
477 #endif
478 if (getifaddrs(ifaddrs) == -1) {
479 logerr("getifaddrs");
480 free(ifs);
481 return NULL;
482 }
483
484 for (ifa = *ifaddrs; ifa; ifa = ifa->ifa_next) {
485 if (ifa->ifa_addr != NULL) {
486 #ifdef AF_LINK
487 if (ifa->ifa_addr->sa_family != AF_LINK)
488 continue;
489 #elif defined(AF_PACKET)
490 if (ifa->ifa_addr->sa_family != AF_PACKET)
491 continue;
492 #endif
493 }
494 if (if_nametospec(ifa->ifa_name, &spec) != 0)
495 continue;
496
497 /* It's possible for an interface to have >1 AF_LINK.
498 * For our purposes, we use the first one. */
499 TAILQ_FOREACH(ifp, ifs, next) {
500 if (strcmp(ifp->name, spec.devname) == 0)
501 break;
502 }
503 if (ifp)
504 continue;
505
506 if (argc > 0) {
507 for (i = 0; i < argc; i++) {
508 if (strcmp(argv[i], spec.devname) == 0)
509 break;
510 }
511 active = (i == argc) ? IF_INACTIVE : IF_ACTIVE_USER;
512 } else {
513 /* -1 means we're discovering against a specific
514 * interface, but we still need the below rules
515 * to apply. */
516 if (argc == -1 && strcmp(argv[0], spec.devname) != 0)
517 continue;
518 active = ctx->options & DHCPCD_INACTIVE ?
519 IF_INACTIVE: IF_ACTIVE_USER;
520 }
521
522 for (i = 0; i < ctx->ifdc; i++)
523 if (fnmatch(ctx->ifdv[i], spec.devname, 0) == 0)
524 break;
525 if (i < ctx->ifdc)
526 active = IF_INACTIVE;
527 for (i = 0; i < ctx->ifc; i++)
528 if (fnmatch(ctx->ifv[i], spec.devname, 0) == 0)
529 break;
530 if (ctx->ifc && i == ctx->ifc)
531 active = IF_INACTIVE;
532 for (i = 0; i < ctx->ifac; i++)
533 if (fnmatch(ctx->ifav[i], spec.devname, 0) == 0)
534 break;
535 if (ctx->ifac && i == ctx->ifac)
536 active = IF_INACTIVE;
537
538 #ifdef PLUGIN_DEV
539 /* Ensure that the interface name has settled */
540 if (!dev_initialised(ctx, spec.devname)) {
541 logdebugx("%s: waiting for interface to initialise",
542 spec.devname);
543 continue;
544 }
545 #endif
546
547 if (if_vimaster(ctx, spec.devname) == 1) {
548 int loglevel = argc != 0 ? LOG_ERR : LOG_DEBUG;
549 logmessage(loglevel,
550 "%s: is a Virtual Interface Master, skipping",
551 spec.devname);
552 continue;
553 }
554
555 if_noconf = ((argc == 0 || argc == -1) && ctx->ifac == 0 &&
556 !if_hasconf(ctx, spec.devname));
557
558 /* Don't allow some reserved interface names unless explicit. */
559 if (if_noconf && if_ignore(ctx, spec.devname)) {
560 logdebugx("%s: ignoring due to interface type and"
561 " no config", spec.devname);
562 active = IF_INACTIVE;
563 }
564
565 ifp = calloc(1, sizeof(*ifp));
566 if (ifp == NULL) {
567 logerr(__func__);
568 break;
569 }
570 ifp->ctx = ctx;
571 strlcpy(ifp->name, spec.devname, sizeof(ifp->name));
572 ifp->flags = ifa->ifa_flags;
573
574 if (ifa->ifa_addr != NULL) {
575 #ifdef AF_LINK
576 sdl = (const void *)ifa->ifa_addr;
577
578 #ifdef IFLR_ACTIVE
579 /* We need to check for active address */
580 strlcpy(iflr.iflr_name, ifp->name,
581 sizeof(iflr.iflr_name));
582 memcpy(&iflr.addr, ifa->ifa_addr,
583 MIN(ifa->ifa_addr->sa_len, sizeof(iflr.addr)));
584 iflr.flags = IFLR_PREFIX;
585 iflr.prefixlen = (unsigned int)sdl->sdl_alen * NBBY;
586 if (ioctl(ctx->pf_link_fd, SIOCGLIFADDR, &iflr) == -1 ||
587 !(iflr.flags & IFLR_ACTIVE))
588 {
589 if_free(ifp);
590 continue;
591 }
592 #endif
593
594 ifp->index = sdl->sdl_index;
595 switch(sdl->sdl_type) {
596 #ifdef IFT_BRIDGE
597 case IFT_BRIDGE: /* FALLTHROUGH */
598 #endif
599 #ifdef IFT_PROPVIRTUAL
600 case IFT_PROPVIRTUAL: /* FALLTHROUGH */
601 #endif
602 #ifdef IFT_TUNNEL
603 case IFT_TUNNEL: /* FALLTHROUGH */
604 #endif
605 case IFT_LOOP: /* FALLTHROUGH */
606 case IFT_PPP:
607 /* Don't allow unless explicit */
608 if (if_noconf && active) {
609 logdebugx("%s: ignoring due to"
610 " interface type and"
611 " no config",
612 ifp->name);
613 active = IF_INACTIVE;
614 }
615 __fallthrough; /* appease gcc */
616 /* FALLTHROUGH */
617 #ifdef IFT_L2VLAN
618 case IFT_L2VLAN: /* FALLTHROUGH */
619 #endif
620 #ifdef IFT_L3IPVLAN
621 case IFT_L3IPVLAN: /* FALLTHROUGH */
622 #endif
623 case IFT_ETHER:
624 ifp->hwtype = ARPHRD_ETHER;
625 break;
626 #ifdef IFT_IEEE1394
627 case IFT_IEEE1394:
628 ifp->hwtype = ARPHRD_IEEE1394;
629 break;
630 #endif
631 #ifdef IFT_INFINIBAND
632 case IFT_INFINIBAND:
633 ifp->hwtype = ARPHRD_INFINIBAND;
634 break;
635 #endif
636 default:
637 /* Don't allow unless explicit */
638 if (active) {
639 if (if_noconf)
640 active = IF_INACTIVE;
641 i = active ? LOG_WARNING : LOG_DEBUG;
642 logmessage(i, "%s: unsupported"
643 " interface type 0x%.2x",
644 ifp->name, sdl->sdl_type);
645 }
646 /* Pretend it's ethernet */
647 ifp->hwtype = ARPHRD_ETHER;
648 break;
649 }
650 ifp->hwlen = sdl->sdl_alen;
651 memcpy(ifp->hwaddr, CLLADDR(sdl), ifp->hwlen);
652 #elif defined(AF_PACKET)
653 sll = (const void *)ifa->ifa_addr;
654 ifp->index = (unsigned int)sll->sll_ifindex;
655 ifp->hwtype = sll->sll_hatype;
656 ifp->hwlen = sll->sll_halen;
657 if (ifp->hwlen != 0)
658 memcpy(ifp->hwaddr, sll->sll_addr, ifp->hwlen);
659 active = if_check_arphrd(ifp, active, if_noconf);
660 #endif
661 }
662 #ifdef __linux__
663 else {
664 struct ifreq ifr = { .ifr_flags = 0 };
665
666 /* This is a huge bug in getifaddrs(3) as there
667 * is no reason why this can't be returned in
668 * ifa_addr. */
669 strlcpy(ifr.ifr_name, ifa->ifa_name,
670 sizeof(ifr.ifr_name));
671 if (ioctl(ctx->pf_inet_fd, SIOCGIFHWADDR, &ifr) == -1)
672 logerr("%s: SIOCGIFHWADDR", ifa->ifa_name);
673 ifp->hwtype = ifr.ifr_hwaddr.sa_family;
674 if (ioctl(ctx->pf_inet_fd, SIOCGIFINDEX, &ifr) == -1)
675 logerr("%s: SIOCGIFINDEX", ifa->ifa_name);
676 ifp->index = (unsigned int)ifr.ifr_ifindex;
677 if_check_arphrd(ifp, active, if_noconf);
678 }
679 #endif
680
681 if (!(ctx->options & (DHCPCD_DUMPLEASE | DHCPCD_TEST))) {
682 /* Handle any platform init for the interface */
683 if (active != IF_INACTIVE && if_init(ifp) == -1) {
684 logerr("%s: if_init", ifp->name);
685 if_free(ifp);
686 continue;
687 }
688 }
689
690 ifp->vlanid = if_vlanid(ifp);
691
692 #ifdef SIOCGIFPRIORITY
693 /* Respect the interface priority */
694 memset(&ifr, 0, sizeof(ifr));
695 strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
696 if (pioctl(ctx, SIOCGIFPRIORITY, &ifr, sizeof(ifr)) == 0)
697 ifp->metric = (unsigned int)ifr.ifr_metric;
698 if_getssid(ifp);
699 #else
700 /* Leave a low portion for user config */
701 ifp->metric = RTMETRIC_BASE + ifp->index;
702 if (if_getssid(ifp) != -1) {
703 ifp->wireless = true;
704 ifp->metric += RTMETRIC_WIRELESS;
705 }
706 #endif
707
708 ifp->active = active;
709 ifp->carrier = if_carrier(ifp, ifa->ifa_data);
710 TAILQ_INSERT_TAIL(ifs, ifp, next);
711 }
712
713 return ifs;
714 }
715
716 /*
717 * eth0.100:2 OR eth0i100:2 (seems to be NetBSD xvif(4) only)
718 *
719 * drvname == eth
720 * devname == eth0.100 OR eth0i100
721 * ppa = 0
722 * lun = 2
723 */
724 int
if_nametospec(const char * ifname,struct if_spec * spec)725 if_nametospec(const char *ifname, struct if_spec *spec)
726 {
727 char *ep, *pp;
728 int e;
729
730 if (ifname == NULL || *ifname == '\0' ||
731 strlcpy(spec->ifname, ifname, sizeof(spec->ifname)) >=
732 sizeof(spec->ifname) ||
733 strlcpy(spec->drvname, ifname, sizeof(spec->drvname)) >=
734 sizeof(spec->drvname))
735 {
736 errno = EINVAL;
737 return -1;
738 }
739
740 /* :N is an alias */
741 ep = strchr(spec->drvname, ':');
742 if (ep) {
743 spec->lun = (int)strtoi(ep + 1, NULL, 10, 0, INT_MAX, &e);
744 if (e != 0) {
745 errno = e;
746 return -1;
747 }
748 *ep = '\0';
749 #ifdef __sun
750 ep--;
751 #endif
752 } else {
753 spec->lun = -1;
754 #ifdef __sun
755 ep = spec->drvname + strlen(spec->drvname) - 1;
756 #endif
757 }
758
759 strlcpy(spec->devname, spec->drvname, sizeof(spec->devname));
760 #ifdef __sun
761 /* Solaris has numbers in the driver name, such as e1000g */
762 while (ep > spec->drvname && isdigit((int)*ep))
763 ep--;
764 if (*ep++ == ':') {
765 errno = EINVAL;
766 return -1;
767 }
768 #else
769 /* BSD and Linux no not have numbers in the driver name */
770 for (ep = spec->drvname; *ep != '\0' && !isdigit((int)*ep); ep++) {
771 if (*ep == ':') {
772 errno = EINVAL;
773 return -1;
774 }
775 }
776 #endif
777 spec->ppa = (int)strtoi(ep, &pp, 10, 0, INT_MAX, &e);
778 *ep = '\0';
779
780 #ifndef __sun
781 /*
782 * . is used for VLAN style names
783 * i is used on NetBSD for xvif interfaces
784 */
785 if (pp != NULL && (*pp == '.' || *pp == 'i')) {
786 spec->vlid = (int)strtoi(pp + 1, NULL, 10, 0, INT_MAX, &e);
787 if (e)
788 spec->vlid = -1;
789 } else
790 #endif
791 spec->vlid = -1;
792
793 return 0;
794 }
795
796 static struct interface *
if_findindexname(struct if_head * ifaces,unsigned int idx,const char * name)797 if_findindexname(struct if_head *ifaces, unsigned int idx, const char *name)
798 {
799
800 if (ifaces != NULL) {
801 struct if_spec spec;
802 struct interface *ifp;
803
804 if (name && if_nametospec(name, &spec) == -1)
805 return NULL;
806
807 TAILQ_FOREACH(ifp, ifaces, next) {
808 if ((name && strcmp(ifp->name, spec.devname) == 0) ||
809 (!name && ifp->index == idx))
810 return ifp;
811 }
812 }
813
814 errno = ENXIO;
815 return NULL;
816 }
817
818 struct interface *
if_find(struct if_head * ifaces,const char * name)819 if_find(struct if_head *ifaces, const char *name)
820 {
821
822 return if_findindexname(ifaces, 0, name);
823 }
824
825 struct interface *
if_findindex(struct if_head * ifaces,unsigned int idx)826 if_findindex(struct if_head *ifaces, unsigned int idx)
827 {
828
829 return if_findindexname(ifaces, idx, NULL);
830 }
831
832 struct interface *
if_loopback(struct dhcpcd_ctx * ctx)833 if_loopback(struct dhcpcd_ctx *ctx)
834 {
835 struct interface *ifp;
836
837 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
838 if (ifp->flags & IFF_LOOPBACK)
839 return ifp;
840 }
841 return NULL;
842 }
843
844 int
if_domtu(const struct interface * ifp,short int mtu)845 if_domtu(const struct interface *ifp, short int mtu)
846 {
847 int r;
848 struct ifreq ifr;
849
850 #ifdef __sun
851 if (mtu == 0)
852 return if_mtu_os(ifp);
853 #endif
854
855 memset(&ifr, 0, sizeof(ifr));
856 strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
857 ifr.ifr_mtu = mtu;
858 if (mtu != 0)
859 r = if_ioctl(ifp->ctx, SIOCSIFMTU, &ifr, sizeof(ifr));
860 else
861 r = pioctl(ifp->ctx, SIOCGIFMTU, &ifr, sizeof(ifr));
862
863 if (r == -1)
864 return -1;
865 return ifr.ifr_mtu;
866 }
867
868 #ifdef ALIAS_ADDR
869 int
if_makealias(char * alias,size_t alias_len,const char * ifname,int lun)870 if_makealias(char *alias, size_t alias_len, const char *ifname, int lun)
871 {
872
873 if (lun == 0)
874 return strlcpy(alias, ifname, alias_len);
875 return snprintf(alias, alias_len, "%s:%u", ifname, lun);
876 }
877 #endif
878
879 struct interface *
if_findifpfromcmsg(struct dhcpcd_ctx * ctx,struct msghdr * msg,int * hoplimit)880 if_findifpfromcmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg, int *hoplimit)
881 {
882 struct cmsghdr *cm;
883 unsigned int ifindex = 0;
884 struct interface *ifp;
885 #ifdef INET
886 #ifdef IP_RECVIF
887 struct sockaddr_dl sdl;
888 #else
889 struct in_pktinfo ipi;
890 #endif
891 #endif
892 #ifdef INET6
893 struct in6_pktinfo ipi6;
894 #else
895 UNUSED(hoplimit);
896 #endif
897
898 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(msg);
899 cm;
900 cm = (struct cmsghdr *)CMSG_NXTHDR(msg, cm))
901 {
902 #ifdef INET
903 if (cm->cmsg_level == IPPROTO_IP) {
904 switch(cm->cmsg_type) {
905 #ifdef IP_RECVIF
906 case IP_RECVIF:
907 if (cm->cmsg_len <
908 offsetof(struct sockaddr_dl, sdl_index) +
909 sizeof(sdl.sdl_index))
910 continue;
911 memcpy(&sdl, CMSG_DATA(cm),
912 MIN(sizeof(sdl), cm->cmsg_len));
913 ifindex = sdl.sdl_index;
914 break;
915 #else
916 case IP_PKTINFO:
917 if (cm->cmsg_len != CMSG_LEN(sizeof(ipi)))
918 continue;
919 memcpy(&ipi, CMSG_DATA(cm), sizeof(ipi));
920 ifindex = (unsigned int)ipi.ipi_ifindex;
921 break;
922 #endif
923 }
924 }
925 #endif
926 #ifdef INET6
927 if (cm->cmsg_level == IPPROTO_IPV6) {
928 switch(cm->cmsg_type) {
929 case IPV6_PKTINFO:
930 if (cm->cmsg_len != CMSG_LEN(sizeof(ipi6)))
931 continue;
932 memcpy(&ipi6, CMSG_DATA(cm), sizeof(ipi6));
933 ifindex = (unsigned int)ipi6.ipi6_ifindex;
934 break;
935 case IPV6_HOPLIMIT:
936 if (cm->cmsg_len != CMSG_LEN(sizeof(int)))
937 continue;
938 if (hoplimit == NULL)
939 break;
940 memcpy(hoplimit, CMSG_DATA(cm), sizeof(int));
941 break;
942 }
943 }
944 #endif
945 }
946
947 /* Find the receiving interface */
948 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
949 if (ifp->index == ifindex)
950 break;
951 }
952 if (ifp == NULL)
953 errno = ESRCH;
954 return ifp;
955 }
956
957 int
xsocket(int domain,int type,int protocol)958 xsocket(int domain, int type, int protocol)
959 {
960 int s;
961 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK)
962 int xflags, xtype = type;
963 #endif
964
965 #ifndef HAVE_SOCK_CLOEXEC
966 if (xtype & SOCK_CLOEXEC)
967 type &= ~SOCK_CLOEXEC;
968 #endif
969 #ifndef HAVE_SOCK_NONBLOCK
970 if (xtype & SOCK_NONBLOCK)
971 type &= ~SOCK_NONBLOCK;
972 #endif
973
974 if ((s = socket(domain, type, protocol)) == -1)
975 return -1;
976
977 #ifndef HAVE_SOCK_CLOEXEC
978 if ((xtype & SOCK_CLOEXEC) && ((xflags = fcntl(s, F_GETFD)) == -1 ||
979 fcntl(s, F_SETFD, xflags | FD_CLOEXEC) == -1))
980 goto out;
981 #endif
982 #ifndef HAVE_SOCK_NONBLOCK
983 if ((xtype & SOCK_NONBLOCK) && ((xflags = fcntl(s, F_GETFL)) == -1 ||
984 fcntl(s, F_SETFL, xflags | O_NONBLOCK) == -1))
985 goto out;
986 #endif
987
988 return s;
989
990 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK)
991 out:
992 close(s);
993 return -1;
994 #endif
995 }
996
997 int
xsocketpair(int domain,int type,int protocol,int fd[2])998 xsocketpair(int domain, int type, int protocol, int fd[2])
999 {
1000 int s;
1001 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK)
1002 int xflags, xtype = type;
1003 #endif
1004
1005 #ifndef HAVE_SOCK_CLOEXEC
1006 if (xtype & SOCK_CLOEXEC)
1007 type &= ~SOCK_CLOEXEC;
1008 #endif
1009 #ifndef HAVE_SOCK_NONBLOCK
1010 if (xtype & SOCK_NONBLOCK)
1011 type &= ~SOCK_NONBLOCK;
1012 #endif
1013
1014 if ((s = socketpair(domain, type, protocol, fd)) == -1)
1015 return -1;
1016
1017 #ifndef HAVE_SOCK_CLOEXEC
1018 if ((xtype & SOCK_CLOEXEC) && ((xflags = fcntl(fd[0], F_GETFD)) == -1 ||
1019 fcntl(fd[0], F_SETFD, xflags | FD_CLOEXEC) == -1))
1020 goto out;
1021 if ((xtype & SOCK_CLOEXEC) && ((xflags = fcntl(fd[1], F_GETFD)) == -1 ||
1022 fcntl(fd[1], F_SETFD, xflags | FD_CLOEXEC) == -1))
1023 goto out;
1024 #endif
1025 #ifndef HAVE_SOCK_NONBLOCK
1026 if ((xtype & SOCK_NONBLOCK) && ((xflags = fcntl(fd[0], F_GETFL)) == -1 ||
1027 fcntl(fd[0], F_SETFL, xflags | O_NONBLOCK) == -1))
1028 goto out;
1029 if ((xtype & SOCK_NONBLOCK) && ((xflags = fcntl(fd[1], F_GETFL)) == -1 ||
1030 fcntl(fd[1], F_SETFL, xflags | O_NONBLOCK) == -1))
1031 goto out;
1032 #endif
1033
1034 return s;
1035
1036 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK)
1037 out:
1038 close(fd[0]);
1039 close(fd[1]);
1040 return -1;
1041 #endif
1042 }
1043