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