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