xref: /dragonfly/contrib/dhcpcd/src/if.c (revision c9c5aa9e)
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_DOWN ||
202 	     (ifp->options != NULL && !(ifp->options->options & DHCPCD_LINK)));
203 }
204 
205 int
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
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
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
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
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
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
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 *
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 		/* We reserve the 100 range for virtual interfaces, if and when
701 		 * we can work them out. */
702 		ifp->metric = 200 + ifp->index;
703 		if (if_getssid(ifp) != -1) {
704 			ifp->wireless = true;
705 			ifp->metric += 100;
706 		}
707 #endif
708 
709 		ifp->active = active;
710 		ifp->carrier = if_carrier(ifp, ifa->ifa_data);
711 		TAILQ_INSERT_TAIL(ifs, ifp, next);
712 	}
713 
714 	return ifs;
715 }
716 
717 /*
718  * eth0.100:2 OR eth0i100:2 (seems to be NetBSD xvif(4) only)
719  *
720  * drvname == eth
721  * devname == eth0.100 OR eth0i100
722  * ppa = 0
723  * lun = 2
724  */
725 int
726 if_nametospec(const char *ifname, struct if_spec *spec)
727 {
728 	char *ep, *pp;
729 	int e;
730 
731 	if (ifname == NULL || *ifname == '\0' ||
732 	    strlcpy(spec->ifname, ifname, sizeof(spec->ifname)) >=
733 	    sizeof(spec->ifname) ||
734 	    strlcpy(spec->drvname, ifname, sizeof(spec->drvname)) >=
735 	    sizeof(spec->drvname))
736 	{
737 		errno = EINVAL;
738 		return -1;
739 	}
740 
741 	/* :N is an alias */
742 	ep = strchr(spec->drvname, ':');
743 	if (ep) {
744 		spec->lun = (int)strtoi(ep + 1, NULL, 10, 0, INT_MAX, &e);
745 		if (e != 0) {
746 			errno = e;
747 			return -1;
748 		}
749 		*ep = '\0';
750 #ifdef __sun
751 		ep--;
752 #endif
753 	} else {
754 		spec->lun = -1;
755 #ifdef __sun
756 		ep = spec->drvname + strlen(spec->drvname) - 1;
757 #endif
758 	}
759 
760 	strlcpy(spec->devname, spec->drvname, sizeof(spec->devname));
761 #ifdef __sun
762 	/* Solaris has numbers in the driver name, such as e1000g */
763 	while (ep > spec->drvname && isdigit((int)*ep))
764 		ep--;
765 	if (*ep++ == ':') {
766 		errno = EINVAL;
767 		return -1;
768 	}
769 #else
770 	/* BSD and Linux no not have numbers in the driver name */
771 	for (ep = spec->drvname; *ep != '\0' && !isdigit((int)*ep); ep++) {
772 		if (*ep == ':') {
773 			errno = EINVAL;
774 			return -1;
775 		}
776 	}
777 #endif
778 	spec->ppa = (int)strtoi(ep, &pp, 10, 0, INT_MAX, &e);
779 	*ep = '\0';
780 
781 #ifndef __sun
782 	/*
783 	 * . is used for VLAN style names
784 	 * i is used on NetBSD for xvif interfaces
785 	 */
786 	if (pp != NULL && (*pp == '.' || *pp == 'i')) {
787 		spec->vlid = (int)strtoi(pp + 1, NULL, 10, 0, INT_MAX, &e);
788 		if (e)
789 			spec->vlid = -1;
790 	} else
791 #endif
792 		spec->vlid = -1;
793 
794 	return 0;
795 }
796 
797 static struct interface *
798 if_findindexname(struct if_head *ifaces, unsigned int idx, const char *name)
799 {
800 
801 	if (ifaces != NULL) {
802 		struct if_spec spec;
803 		struct interface *ifp;
804 
805 		if (name && if_nametospec(name, &spec) == -1)
806 			return NULL;
807 
808 		TAILQ_FOREACH(ifp, ifaces, next) {
809 			if ((name && strcmp(ifp->name, spec.devname) == 0) ||
810 			    (!name && ifp->index == idx))
811 				return ifp;
812 		}
813 	}
814 
815 	errno = ENXIO;
816 	return NULL;
817 }
818 
819 struct interface *
820 if_find(struct if_head *ifaces, const char *name)
821 {
822 
823 	return if_findindexname(ifaces, 0, name);
824 }
825 
826 struct interface *
827 if_findindex(struct if_head *ifaces, unsigned int idx)
828 {
829 
830 	return if_findindexname(ifaces, idx, NULL);
831 }
832 
833 struct interface *
834 if_loopback(struct dhcpcd_ctx *ctx)
835 {
836 	struct interface *ifp;
837 
838 	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
839 		if (ifp->flags & IFF_LOOPBACK)
840 			return ifp;
841 	}
842 	return NULL;
843 }
844 
845 int
846 if_domtu(const struct interface *ifp, short int mtu)
847 {
848 	int r;
849 	struct ifreq ifr;
850 
851 #ifdef __sun
852 	if (mtu == 0)
853 		return if_mtu_os(ifp);
854 #endif
855 
856 	memset(&ifr, 0, sizeof(ifr));
857 	strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
858 	ifr.ifr_mtu = mtu;
859 	if (mtu != 0)
860 		r = if_ioctl(ifp->ctx, SIOCSIFMTU, &ifr, sizeof(ifr));
861 	else
862 		r = pioctl(ifp->ctx, SIOCGIFMTU, &ifr, sizeof(ifr));
863 
864 	if (r == -1)
865 		return -1;
866 	return ifr.ifr_mtu;
867 }
868 
869 #ifdef ALIAS_ADDR
870 int
871 if_makealias(char *alias, size_t alias_len, const char *ifname, int lun)
872 {
873 
874 	if (lun == 0)
875 		return strlcpy(alias, ifname, alias_len);
876 	return snprintf(alias, alias_len, "%s:%u", ifname, lun);
877 }
878 #endif
879 
880 struct interface *
881 if_findifpfromcmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg, int *hoplimit)
882 {
883 	struct cmsghdr *cm;
884 	unsigned int ifindex = 0;
885 	struct interface *ifp;
886 #ifdef INET
887 #ifdef IP_RECVIF
888 	struct sockaddr_dl sdl;
889 #else
890 	struct in_pktinfo ipi;
891 #endif
892 #endif
893 #ifdef INET6
894 	struct in6_pktinfo ipi6;
895 #else
896 	UNUSED(hoplimit);
897 #endif
898 
899 	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(msg);
900 	     cm;
901 	     cm = (struct cmsghdr *)CMSG_NXTHDR(msg, cm))
902 	{
903 #ifdef INET
904 		if (cm->cmsg_level == IPPROTO_IP) {
905 			switch(cm->cmsg_type) {
906 #ifdef IP_RECVIF
907 			case IP_RECVIF:
908 				if (cm->cmsg_len <
909 				    offsetof(struct sockaddr_dl, sdl_index) +
910 				    sizeof(sdl.sdl_index))
911 					continue;
912 				memcpy(&sdl, CMSG_DATA(cm),
913 				    MIN(sizeof(sdl), cm->cmsg_len));
914 				ifindex = sdl.sdl_index;
915 				break;
916 #else
917 			case IP_PKTINFO:
918 				if (cm->cmsg_len != CMSG_LEN(sizeof(ipi)))
919 					continue;
920 				memcpy(&ipi, CMSG_DATA(cm), sizeof(ipi));
921 				ifindex = (unsigned int)ipi.ipi_ifindex;
922 				break;
923 #endif
924 			}
925 		}
926 #endif
927 #ifdef INET6
928 		if (cm->cmsg_level == IPPROTO_IPV6) {
929 			switch(cm->cmsg_type) {
930 			case IPV6_PKTINFO:
931 				if (cm->cmsg_len != CMSG_LEN(sizeof(ipi6)))
932 					continue;
933 				memcpy(&ipi6, CMSG_DATA(cm), sizeof(ipi6));
934 				ifindex = (unsigned int)ipi6.ipi6_ifindex;
935 				break;
936 			case IPV6_HOPLIMIT:
937 				if (cm->cmsg_len != CMSG_LEN(sizeof(int)))
938 					continue;
939 				if (hoplimit == NULL)
940 					break;
941 				memcpy(hoplimit, CMSG_DATA(cm), sizeof(int));
942 				break;
943 			}
944 		}
945 #endif
946 	}
947 
948 	/* Find the receiving interface */
949 	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
950 		if (ifp->index == ifindex)
951 			break;
952 	}
953 	if (ifp == NULL)
954 		errno = ESRCH;
955 	return ifp;
956 }
957 
958 int
959 xsocket(int domain, int type, int protocol)
960 {
961 	int s;
962 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK)
963 	int xflags, xtype = type;
964 #endif
965 
966 #ifndef HAVE_SOCK_CLOEXEC
967 	if (xtype & SOCK_CLOEXEC)
968 		type &= ~SOCK_CLOEXEC;
969 #endif
970 #ifndef HAVE_SOCK_NONBLOCK
971 	if (xtype & SOCK_NONBLOCK)
972 		type &= ~SOCK_NONBLOCK;
973 #endif
974 
975 	if ((s = socket(domain, type, protocol)) == -1)
976 		return -1;
977 
978 #ifndef HAVE_SOCK_CLOEXEC
979 	if ((xtype & SOCK_CLOEXEC) && ((xflags = fcntl(s, F_GETFD)) == -1 ||
980 	    fcntl(s, F_SETFD, xflags | FD_CLOEXEC) == -1))
981 		goto out;
982 #endif
983 #ifndef HAVE_SOCK_NONBLOCK
984 	if ((xtype & SOCK_NONBLOCK) && ((xflags = fcntl(s, F_GETFL)) == -1 ||
985 	    fcntl(s, F_SETFL, xflags | O_NONBLOCK) == -1))
986 		goto out;
987 #endif
988 
989 	return s;
990 
991 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK)
992 out:
993 	close(s);
994 	return -1;
995 #endif
996 }
997 
998 int
999 xsocketpair(int domain, int type, int protocol, int fd[2])
1000 {
1001 	int s;
1002 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK)
1003 	int xflags, xtype = type;
1004 #endif
1005 
1006 #ifndef HAVE_SOCK_CLOEXEC
1007 	if (xtype & SOCK_CLOEXEC)
1008 		type &= ~SOCK_CLOEXEC;
1009 #endif
1010 #ifndef HAVE_SOCK_NONBLOCK
1011 	if (xtype & SOCK_NONBLOCK)
1012 		type &= ~SOCK_NONBLOCK;
1013 #endif
1014 
1015 	if ((s = socketpair(domain, type, protocol, fd)) == -1)
1016 		return -1;
1017 
1018 #ifndef HAVE_SOCK_CLOEXEC
1019 	if ((xtype & SOCK_CLOEXEC) && ((xflags = fcntl(fd[0], F_GETFD)) == -1 ||
1020 	    fcntl(fd[0], F_SETFD, xflags | FD_CLOEXEC) == -1))
1021 		goto out;
1022 	if ((xtype & SOCK_CLOEXEC) && ((xflags = fcntl(fd[1], F_GETFD)) == -1 ||
1023 	    fcntl(fd[1], F_SETFD, xflags | FD_CLOEXEC) == -1))
1024 		goto out;
1025 #endif
1026 #ifndef HAVE_SOCK_NONBLOCK
1027 	if ((xtype & SOCK_NONBLOCK) && ((xflags = fcntl(fd[0], F_GETFL)) == -1 ||
1028 	    fcntl(fd[0], F_SETFL, xflags | O_NONBLOCK) == -1))
1029 		goto out;
1030 	if ((xtype & SOCK_NONBLOCK) && ((xflags = fcntl(fd[1], F_GETFL)) == -1 ||
1031 	    fcntl(fd[1], F_SETFL, xflags | O_NONBLOCK) == -1))
1032 		goto out;
1033 #endif
1034 
1035 	return s;
1036 
1037 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK)
1038 out:
1039 	close(fd[0]);
1040 	close(fd[1]);
1041 	return -1;
1042 #endif
1043 }
1044