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