Home | History | Annotate | Download | only in dhcpcd-6.8.2
      1 /*
      2  * dhcpcd - DHCP client daemon
      3  * Copyright (c) 2006-2015 Roy Marples <roy (at) marples.name>
      4  * All rights reserved
      5 
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     25  * SUCH DAMAGE.
     26  */
     27 
     28 #include <sys/ioctl.h>
     29 #include <sys/param.h>
     30 #include <sys/socket.h>
     31 #include <sys/stat.h>
     32 #include <sys/sysctl.h>
     33 #include <sys/time.h>
     34 #include <sys/types.h>
     35 #include <sys/uio.h>
     36 #include <sys/utsname.h>
     37 
     38 #include <arpa/inet.h>
     39 #include <net/bpf.h>
     40 #include <net/if.h>
     41 #include <net/if_dl.h>
     42 #ifdef __FreeBSD__ /* Needed so that including netinet6/in6_var.h works */
     43 #  include <net/if_var.h>
     44 #endif
     45 #include <net/if_media.h>
     46 #include <net/route.h>
     47 #include <netinet/if_ether.h>
     48 #include <netinet/in.h>
     49 #include <netinet/in_var.h>
     50 #include <netinet6/in6_var.h>
     51 #include <netinet6/nd6.h>
     52 #ifdef __DragonFly__
     53 #  include <netproto/802_11/ieee80211_ioctl.h>
     54 #elif __APPLE__
     55   /* FIXME: Add apple includes so we can work out SSID */
     56 #else
     57 #  include <net80211/ieee80211.h>
     58 #  include <net80211/ieee80211_ioctl.h>
     59 #endif
     60 
     61 #include <errno.h>
     62 #include <fcntl.h>
     63 #include <fnmatch.h>
     64 #include <paths.h>
     65 #include <stddef.h>
     66 #include <stdio.h>
     67 #include <stdlib.h>
     68 #include <string.h>
     69 #include <unistd.h>
     70 
     71 #if defined(OpenBSD) && OpenBSD >= 201411
     72 /* OpenBSD dropped the global setting from sysctl but left the #define
     73  * which causes a EPERM error when trying to use it.
     74  * I think both the error and keeping the define are wrong, so we #undef it. */
     75 #undef IPV6CTL_ACCEPT_RTADV
     76 #endif
     77 
     78 #include "config.h"
     79 #include "common.h"
     80 #include "dhcp.h"
     81 #include "if.h"
     82 #include "if-options.h"
     83 #include "ipv4.h"
     84 #include "ipv6.h"
     85 #include "ipv6nd.h"
     86 
     87 #include "bpf-filter.h"
     88 
     89 #ifndef RT_ROUNDUP
     90 #define RT_ROUNDUP(a)							      \
     91 	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
     92 #define RT_ADVANCE(x, n) (x += RT_ROUNDUP((n)->sa_len))
     93 #endif
     94 
     95 #define COPYOUT(sin, sa) do {						      \
     96 	if ((sa) && ((sa)->sa_family == AF_INET || (sa)->sa_family == 255))   \
     97 		(sin) = ((struct sockaddr_in*)(void *)(sa))->sin_addr;	      \
     98 	} while (0)
     99 
    100 #define COPYOUT6(sin, sa) do {						      \
    101 	if ((sa) && ((sa)->sa_family == AF_INET6 || (sa)->sa_family == 255))  \
    102 		(sin) = ((struct sockaddr_in6*)(void *)(sa))->sin6_addr;      \
    103 	} while (0)
    104 
    105 #ifndef CLLADDR
    106 #  define CLLADDR(s) ((const char *)((s)->sdl_data + (s)->sdl_nlen))
    107 #endif
    108 
    109 int
    110 if_init(__unused struct interface *iface)
    111 {
    112 	/* BSD promotes secondary address by default */
    113 	return 0;
    114 }
    115 
    116 int
    117 if_conf(__unused struct interface *iface)
    118 {
    119 	/* No extra checks needed on BSD */
    120 	return 0;
    121 }
    122 
    123 int
    124 if_openlinksocket(void)
    125 {
    126 
    127 #ifdef SOCK_CLOEXEC
    128 	return socket(PF_ROUTE, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
    129 #else
    130 	int s, flags;
    131 
    132 	if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -1)
    133 		return -1;
    134 	if ((flags = fcntl(s, F_GETFD, 0)) == -1 ||
    135 	    fcntl(s, F_SETFD, flags | FD_CLOEXEC) == -1)
    136 	{
    137 		close(s);
    138 	        return -1;
    139 	}
    140 	if ((flags = fcntl(s, F_GETFL, 0)) == -1 ||
    141 	    fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1)
    142 	{
    143 		close(s);
    144 	        return -1;
    145 	}
    146 	return s;
    147 #endif
    148 }
    149 
    150 #if defined(INET) || defined(INET6)
    151 static void
    152 if_linkaddr(struct sockaddr_dl *sdl, const struct interface *ifp)
    153 {
    154 
    155 	memset(sdl, 0, sizeof(*sdl));
    156 	sdl->sdl_family = AF_LINK;
    157 	sdl->sdl_len = sizeof(*sdl);
    158 	sdl->sdl_nlen = sdl->sdl_alen = sdl->sdl_slen = 0;
    159 	sdl->sdl_index = (unsigned short)ifp->index;
    160 }
    161 #endif
    162 
    163 static int
    164 if_getssid1(const char *ifname, uint8_t *ssid)
    165 {
    166 	int s, retval = -1;
    167 #if defined(SIOCG80211NWID)
    168 	struct ifreq ifr;
    169 	struct ieee80211_nwid nwid;
    170 #elif defined(IEEE80211_IOC_SSID)
    171 	struct ieee80211req ireq;
    172 	char nwid[IEEE80211_NWID_LEN + 1];
    173 #endif
    174 
    175 	if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
    176 		return -1;
    177 
    178 #if defined(SIOCG80211NWID) /* NetBSD */
    179 	memset(&ifr, 0, sizeof(ifr));
    180 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
    181 	memset(&nwid, 0, sizeof(nwid));
    182 	ifr.ifr_data = (void *)&nwid;
    183 	if (ioctl(s, SIOCG80211NWID, &ifr) == 0) {
    184 		if (ssid == NULL)
    185 			retval = nwid.i_len;
    186 		else if (nwid.i_len > IF_SSIDSIZE) {
    187 			errno = ENOBUFS;
    188 			retval = -1;
    189 		} else {
    190 			retval = nwid.i_len;
    191 			memcpy(ssid, nwid.i_nwid, nwid.i_len);
    192 			ssid[nwid.i_len] = '\0';
    193 		}
    194 	}
    195 #elif defined(IEEE80211_IOC_SSID) /* FreeBSD */
    196 	memset(&ireq, 0, sizeof(ireq));
    197 	strlcpy(ireq.i_name, ifname, sizeof(ireq.i_name));
    198 	ireq.i_type = IEEE80211_IOC_SSID;
    199 	ireq.i_val = -1;
    200 	memset(nwid, 0, sizeof(nwid));
    201 	ireq.i_data = &nwid;
    202 	if (ioctl(s, SIOCG80211, &ireq) == 0) {
    203 		if (ssid == NULL)
    204 			retval = ireq.i_len;
    205 		else if (ireq.i_len > IF_SSIDSIZE) {
    206 			errno = ENOBUFS;
    207 			retval = -1;
    208 		} else  {
    209 			retval = ireq.i_len;
    210 			memcpy(ssid, nwid, ireq.i_len);
    211 			ssid[ireq.i_len] = '\0';
    212 		}
    213 	}
    214 #endif
    215 
    216 	close(s);
    217 	return retval;
    218 }
    219 
    220 int
    221 if_getssid(struct interface *ifp)
    222 {
    223 	int r;
    224 
    225 	r = if_getssid1(ifp->name, ifp->ssid);
    226 	if (r != -1)
    227 		ifp->ssid_len = (unsigned int)r;
    228 	return r;
    229 }
    230 
    231 /*
    232  * FreeBSD allows for Virtual Access Points
    233  * We need to check if the interface is a Virtual Interface Master
    234  * and if so, don't use it.
    235  * This check is made by virtue of being a IEEE80211 device but
    236  * returning the SSID gives an error.
    237  */
    238 int
    239 if_vimaster(const char *ifname)
    240 {
    241 	int s, r;
    242 	struct ifmediareq ifmr;
    243 
    244 	if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
    245 		return -1;
    246 	memset(&ifmr, 0, sizeof(ifmr));
    247 	strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
    248 	r = ioctl(s, SIOCGIFMEDIA, &ifmr);
    249 	close(s);
    250 	if (r == -1)
    251 		return -1;
    252 	if (ifmr.ifm_status & IFM_AVALID &&
    253 	    IFM_TYPE(ifmr.ifm_active) == IFM_IEEE80211)
    254 	{
    255 		if (if_getssid1(ifname, NULL) == -1)
    256 			return 1;
    257 	}
    258 	return 0;
    259 }
    260 
    261 static void
    262 get_addrs(int type, char *cp, struct sockaddr **sa)
    263 {
    264 	int i;
    265 
    266 	for (i = 0; i < RTAX_MAX; i++) {
    267 		if (type & (1 << i)) {
    268 			sa[i] = (struct sockaddr *)cp;
    269 			RT_ADVANCE(cp, sa[i]);
    270 		} else
    271 			sa[i] = NULL;
    272 	}
    273 }
    274 
    275 #if defined(INET) || defined(INET6)
    276 static struct interface *
    277 if_findsdl(struct dhcpcd_ctx *ctx, struct sockaddr_dl *sdl)
    278 {
    279 
    280 	if (sdl->sdl_nlen) {
    281 		char ifname[IF_NAMESIZE];
    282 		memcpy(ifname, sdl->sdl_data, sdl->sdl_nlen);
    283 		ifname[sdl->sdl_nlen] = '\0';
    284 		return if_find(ctx->ifaces, ifname);
    285 	}
    286 	return NULL;
    287 }
    288 #endif
    289 
    290 #ifdef INET
    291 const char *if_pfname = "Berkley Packet Filter";
    292 
    293 int
    294 if_openrawsocket(struct interface *ifp, uint16_t protocol)
    295 {
    296 	struct dhcp_state *state;
    297 	int fd = -1;
    298 	struct ifreq ifr;
    299 	int ibuf_len = 0;
    300 	size_t buf_len;
    301 	struct bpf_version pv;
    302 	struct bpf_program pf;
    303 #ifdef BIOCIMMEDIATE
    304 	int flags;
    305 #endif
    306 #ifdef _PATH_BPF
    307 	fd = open(_PATH_BPF, O_RDWR | O_CLOEXEC | O_NONBLOCK);
    308 #else
    309 	char device[32];
    310 	int n = 0;
    311 
    312 	do {
    313 		snprintf(device, sizeof(device), "/dev/bpf%d", n++);
    314 		fd = open(device, O_RDWR | O_CLOEXEC | O_NONBLOCK);
    315 	} while (fd == -1 && errno == EBUSY);
    316 #endif
    317 
    318 	if (fd == -1)
    319 		return -1;
    320 
    321 	state = D_STATE(ifp);
    322 
    323 	memset(&pv, 0, sizeof(pv));
    324 	if (ioctl(fd, BIOCVERSION, &pv) == -1)
    325 		goto eexit;
    326 	if (pv.bv_major != BPF_MAJOR_VERSION ||
    327 	    pv.bv_minor < BPF_MINOR_VERSION) {
    328 		logger(ifp->ctx, LOG_ERR, "BPF version mismatch - recompile");
    329 		goto eexit;
    330 	}
    331 
    332 	memset(&ifr, 0, sizeof(ifr));
    333 	strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
    334 	if (ioctl(fd, BIOCSETIF, &ifr) == -1)
    335 		goto eexit;
    336 
    337 	/* Get the required BPF buffer length from the kernel. */
    338 	if (ioctl(fd, BIOCGBLEN, &ibuf_len) == -1)
    339 		goto eexit;
    340 	buf_len = (size_t)ibuf_len;
    341 	if (state->buffer_size != buf_len) {
    342 		free(state->buffer);
    343 		state->buffer = malloc(buf_len);
    344 		if (state->buffer == NULL)
    345 			goto eexit;
    346 		state->buffer_size = buf_len;
    347 		state->buffer_len = state->buffer_pos = 0;
    348 	}
    349 
    350 #ifdef BIOCIMMEDIATE
    351 	flags = 1;
    352 	if (ioctl(fd, BIOCIMMEDIATE, &flags) == -1)
    353 		goto eexit;
    354 #endif
    355 
    356 	/* Install the DHCP filter */
    357 	memset(&pf, 0, sizeof(pf));
    358 	if (protocol == ETHERTYPE_ARP) {
    359 		pf.bf_insns = UNCONST(arp_bpf_filter);
    360 		pf.bf_len = arp_bpf_filter_len;
    361 	} else {
    362 		pf.bf_insns = UNCONST(dhcp_bpf_filter);
    363 		pf.bf_len = dhcp_bpf_filter_len;
    364 	}
    365 	if (ioctl(fd, BIOCSETF, &pf) == -1)
    366 		goto eexit;
    367 
    368 	return fd;
    369 
    370 eexit:
    371 	free(state->buffer);
    372 	state->buffer = NULL;
    373 	close(fd);
    374 	return -1;
    375 }
    376 
    377 ssize_t
    378 if_sendrawpacket(const struct interface *ifp, uint16_t protocol,
    379     const void *data, size_t len, const uint8_t *dest_hw_addr)
    380 {
    381 	struct iovec iov[2];
    382 	struct ether_header hw;
    383 	int fd;
    384 	const struct dhcp_state *state;
    385 
    386 	memset(&hw, 0, ETHER_HDR_LEN);
    387 	if (dest_hw_addr)
    388 		memcpy(&hw.ether_dhost, dest_hw_addr, ETHER_ADDR_LEN);
    389 	else
    390 		memset(&hw.ether_dhost, 0xff, ETHER_ADDR_LEN);
    391 	hw.ether_type = htons(protocol);
    392 	iov[0].iov_base = &hw;
    393 	iov[0].iov_len = ETHER_HDR_LEN;
    394 	iov[1].iov_base = UNCONST(data);
    395 	iov[1].iov_len = len;
    396 	state = D_CSTATE(ifp);
    397 	if (protocol == ETHERTYPE_ARP)
    398 		fd = state->arp_fd;
    399 	else
    400 		fd = state->raw_fd;
    401 	return writev(fd, iov, 2);
    402 }
    403 
    404 /* BPF requires that we read the entire buffer.
    405  * So we pass the buffer in the API so we can loop on >1 packet. */
    406 ssize_t
    407 if_readrawpacket(struct interface *ifp, uint16_t protocol,
    408     void *data, size_t len, int *flags)
    409 {
    410 	int fd;
    411 	struct bpf_hdr packet;
    412 	ssize_t bytes;
    413 	const unsigned char *payload;
    414 	struct dhcp_state *state;
    415 
    416 	state = D_STATE(ifp);
    417 	if (protocol == ETHERTYPE_ARP)
    418 		fd = state->arp_fd;
    419 	else
    420 		fd = state->raw_fd;
    421 
    422 	*flags = 0;
    423 	for (;;) {
    424 		if (state->buffer_len == 0) {
    425 			bytes = read(fd, state->buffer, state->buffer_size);
    426 			if (bytes == -1 || bytes == 0)
    427 				return bytes;
    428 			state->buffer_len = (size_t)bytes;
    429 			state->buffer_pos = 0;
    430 		}
    431 		bytes = -1;
    432 		memcpy(&packet, state->buffer + state->buffer_pos,
    433 		    sizeof(packet));
    434 		if (packet.bh_caplen != packet.bh_datalen)
    435 			goto next; /* Incomplete packet, drop. */
    436 		if (state->buffer_pos + packet.bh_caplen + packet.bh_hdrlen >
    437 		    state->buffer_len)
    438 			goto next; /* Packet beyond buffer, drop. */
    439 		payload = state->buffer + state->buffer_pos +
    440 		    packet.bh_hdrlen + ETHER_HDR_LEN;
    441 		bytes = (ssize_t)packet.bh_caplen - ETHER_HDR_LEN;
    442 		if ((size_t)bytes > len)
    443 			bytes = (ssize_t)len;
    444 		memcpy(data, payload, (size_t)bytes);
    445 next:
    446 		state->buffer_pos += BPF_WORDALIGN(packet.bh_hdrlen +
    447 		    packet.bh_caplen);
    448 		if (state->buffer_pos >= state->buffer_len) {
    449 			state->buffer_len = state->buffer_pos = 0;
    450 			*flags |= RAW_EOF;
    451 		}
    452 		if (bytes != -1)
    453 			return bytes;
    454 	}
    455 }
    456 
    457 int
    458 if_address(const struct interface *ifp, const struct in_addr *address,
    459     const struct in_addr *netmask, const struct in_addr *broadcast,
    460     int action)
    461 {
    462 	int s, r;
    463 	struct in_aliasreq ifra;
    464 
    465 	if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
    466 		return -1;
    467 
    468 	memset(&ifra, 0, sizeof(ifra));
    469 	strlcpy(ifra.ifra_name, ifp->name, sizeof(ifra.ifra_name));
    470 
    471 #define ADDADDR(var, addr) do {						      \
    472 		(var)->sin_family = AF_INET;				      \
    473 		(var)->sin_len = sizeof(*(var));			      \
    474 		(var)->sin_addr = *(addr);				      \
    475 	} while (/*CONSTCOND*/0)
    476 	ADDADDR(&ifra.ifra_addr, address);
    477 	ADDADDR(&ifra.ifra_mask, netmask);
    478 	if (action >= 0 && broadcast)
    479 		ADDADDR(&ifra.ifra_broadaddr, broadcast);
    480 #undef ADDADDR
    481 
    482 	r = ioctl(s,
    483 	    action < 0 ? SIOCDIFADDR : SIOCAIFADDR, &ifra);
    484 	close(s);
    485 	return r;
    486 }
    487 
    488 static int
    489 if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct rt_msghdr *rtm)
    490 {
    491 	char *cp;
    492 	struct sockaddr *sa, *rti_info[RTAX_MAX];
    493 
    494 	cp = (char *)(void *)(rtm + 1);
    495 	sa = (struct sockaddr *)(void *)cp;
    496 	if (sa->sa_family != AF_INET)
    497 		return -1;
    498 	if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY))
    499 		return -1;
    500 #ifdef RTF_CLONED
    501 	if (rtm->rtm_flags & RTF_CLONED)
    502 		return -1;
    503 #endif
    504 #ifdef RTF_LOCAL
    505 	if (rtm->rtm_flags & RTF_LOCAL)
    506 		return -1;
    507 #endif
    508 #ifdef RTF_BROADCAST
    509 	if (rtm->rtm_flags & RTF_BROADCAST)
    510 		return -1;
    511 #endif
    512 
    513 	get_addrs(rtm->rtm_addrs, cp, rti_info);
    514 	memset(rt, 0, sizeof(*rt));
    515 	COPYOUT(rt->dest, rti_info[RTAX_DST]);
    516 	if (rtm->rtm_addrs & RTA_NETMASK)
    517 		COPYOUT(rt->net, rti_info[RTAX_NETMASK]);
    518 	else
    519 		rt->net.s_addr = INADDR_BROADCAST;
    520 	COPYOUT(rt->gate, rti_info[RTAX_GATEWAY]);
    521 
    522 	if (rtm->rtm_index)
    523 		rt->iface = if_findindex(ctx->ifaces, rtm->rtm_index);
    524 	else if (rtm->rtm_addrs & RTA_IFP) {
    525 		struct sockaddr_dl *sdl;
    526 
    527 		sdl = (struct sockaddr_dl *)(void *)rti_info[RTAX_IFP];
    528 		rt->iface = if_findsdl(ctx, sdl);
    529 	}
    530 	/* If we don't have an interface and it's a host route, it maybe
    531 	 * to a local ip via the loopback interface. */
    532 	if (rt->iface == NULL &&
    533 	    !(~rtm->rtm_flags & (RTF_HOST | RTF_GATEWAY)))
    534 	{
    535 		struct ipv4_addr *ia;
    536 
    537 		if ((ia = ipv4_findaddr(ctx, &rt->dest)))
    538 			rt->iface = ia->iface;
    539 	}
    540 
    541 	return 0;
    542 }
    543 
    544 int
    545 if_route(unsigned char cmd, const struct rt *rt)
    546 {
    547 	const struct dhcp_state *state;
    548 	union sockunion {
    549 		struct sockaddr sa;
    550 		struct sockaddr_in sin;
    551 		struct sockaddr_dl sdl;
    552 	} su;
    553 	struct rtm
    554 	{
    555 		struct rt_msghdr hdr;
    556 		char buffer[sizeof(su) * RTAX_MAX];
    557 	} rtm;
    558 	char *bp = rtm.buffer;
    559 	size_t l;
    560 	int s, retval;
    561 
    562 	if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -1)
    563 		return -1;
    564 
    565 #define ADDSU {								      \
    566 		l = RT_ROUNDUP(su.sa.sa_len);				      \
    567 		memcpy(bp, &su, l);					      \
    568 		bp += l;						      \
    569 	}
    570 #define ADDADDR(addr) {							      \
    571 		memset(&su, 0, sizeof(su));				      \
    572 		su.sin.sin_family = AF_INET;				      \
    573 		su.sin.sin_len = sizeof(su.sin);			      \
    574 		(&su.sin)->sin_addr = *addr;				      \
    575 		ADDSU;							      \
    576 	}
    577 
    578 	if (cmd != RTM_DELETE)
    579 		state = D_CSTATE(rt->iface);
    580 	else	/* appease GCC */
    581 		state = NULL;
    582 	memset(&rtm, 0, sizeof(rtm));
    583 	rtm.hdr.rtm_version = RTM_VERSION;
    584 	rtm.hdr.rtm_seq = 1;
    585 	rtm.hdr.rtm_type = cmd;
    586 	rtm.hdr.rtm_addrs = RTA_DST;
    587 	if (cmd == RTM_ADD || cmd == RTM_CHANGE)
    588 		rtm.hdr.rtm_addrs |= RTA_GATEWAY;
    589 	rtm.hdr.rtm_flags = RTF_UP;
    590 #ifdef RTF_PINNED
    591 	if (cmd != RTM_ADD)
    592 		rtm.hdr.rtm_flags |= RTF_PINNED;
    593 #endif
    594 
    595 	if (cmd != RTM_DELETE) {
    596 		rtm.hdr.rtm_addrs |= RTA_IFA | RTA_IFP;
    597 		/* None interface subnet routes are static. */
    598 		if (rt->gate.s_addr != INADDR_ANY ||
    599 		    rt->net.s_addr != state->net.s_addr ||
    600 		    rt->dest.s_addr != (state->addr.s_addr & state->net.s_addr))
    601 			rtm.hdr.rtm_flags |= RTF_STATIC;
    602 		else {
    603 #ifdef RTF_CLONING
    604 			rtm.hdr.rtm_flags |= RTF_CLONING;
    605 #endif
    606 #ifdef RTP_CONNECTED
    607 			rtm.hdr.rtm_priority = RTP_CONNECTED;
    608 #endif
    609 		}
    610 	}
    611 	if (rt->net.s_addr == htonl(INADDR_BROADCAST) &&
    612 	    rt->gate.s_addr == htonl(INADDR_ANY))
    613 	{
    614 #ifdef RTF_CLONING
    615 		/* We add a cloning network route for a single host.
    616 		 * Traffic to the host will generate a cloned route and the
    617 		 * hardware address will resolve correctly.
    618 		 * It might be more correct to use RTF_HOST instead of
    619 		 * RTF_CLONING, and that does work, but some OS generate
    620 		 * an arp warning diagnostic which we don't want to do. */
    621 		rtm.hdr.rtm_flags |= RTF_CLONING;
    622 		rtm.hdr.rtm_addrs |= RTA_NETMASK;
    623 #else
    624 		rtm.hdr.rtm_flags |= RTF_HOST;
    625 #endif
    626 	} else if (rt->gate.s_addr == htonl(INADDR_LOOPBACK) &&
    627 	    rt->net.s_addr == htonl(INADDR_BROADCAST))
    628 	{
    629 		rtm.hdr.rtm_flags |= RTF_HOST | RTF_GATEWAY;
    630 		/* Going via lo0 so remove the interface flags */
    631 		if (cmd == RTM_ADD)
    632 			rtm.hdr.rtm_addrs &= ~(RTA_IFA | RTA_IFP);
    633 	} else {
    634 		rtm.hdr.rtm_addrs |= RTA_NETMASK;
    635 		if (rtm.hdr.rtm_flags & RTF_STATIC)
    636 			rtm.hdr.rtm_flags |= RTF_GATEWAY;
    637 	}
    638 	if ((cmd == RTM_ADD || cmd == RTM_CHANGE) &&
    639 	    !(rtm.hdr.rtm_flags & RTF_GATEWAY))
    640 		rtm.hdr.rtm_addrs |= RTA_IFA | RTA_IFP;
    641 
    642 	ADDADDR(&rt->dest);
    643 	if (rtm.hdr.rtm_addrs & RTA_GATEWAY) {
    644 #ifdef RTF_CLONING
    645 		if ((rtm.hdr.rtm_flags & (RTF_HOST | RTF_CLONING) &&
    646 #else
    647 		if ((rtm.hdr.rtm_flags & RTF_HOST &&
    648 #endif
    649 		    rt->gate.s_addr != htonl(INADDR_LOOPBACK)) ||
    650 		    !(rtm.hdr.rtm_flags & RTF_STATIC))
    651 		{
    652 			if_linkaddr(&su.sdl, rt->iface);
    653 			ADDSU;
    654 		} else
    655 			ADDADDR(&rt->gate);
    656 	}
    657 
    658 	if (rtm.hdr.rtm_addrs & RTA_NETMASK)
    659 		ADDADDR(&rt->net);
    660 
    661 	if ((cmd == RTM_ADD || cmd == RTM_CHANGE) &&
    662 	    (rtm.hdr.rtm_addrs & (RTA_IFP | RTA_IFA)))
    663 	{
    664 		rtm.hdr.rtm_index = (unsigned short)rt->iface->index;
    665 		if (rtm.hdr.rtm_addrs & RTA_IFP) {
    666 			if_linkaddr(&su.sdl, rt->iface);
    667 			ADDSU;
    668 		}
    669 
    670 		if (rtm.hdr.rtm_addrs & RTA_IFA)
    671 			ADDADDR(&state->addr);
    672 	}
    673 
    674 #undef ADDADDR
    675 #undef ADDSU
    676 
    677 	rtm.hdr.rtm_msglen = (unsigned short)(bp - (char *)&rtm);
    678 	retval = write(s, &rtm, rtm.hdr.rtm_msglen) == -1 ? -1 : 0;
    679 	close(s);
    680 	return retval;
    681 }
    682 
    683 int
    684 if_initrt(struct interface *ifp)
    685 {
    686 	struct rt_msghdr *rtm;
    687 	int mib[6];
    688 	size_t needed;
    689 	char *buf, *p, *end;
    690 	struct rt rt;
    691 
    692 	ipv4_freerts(ifp->ctx->ipv4_kroutes);
    693 
    694 	mib[0] = CTL_NET;
    695 	mib[1] = PF_ROUTE;
    696 	mib[2] = 0;
    697 	mib[3] = AF_INET;
    698 	mib[4] = NET_RT_DUMP;
    699 	mib[5] = 0;
    700 
    701 	if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1)
    702 		return -1;
    703 	if (needed == 0)
    704 		return 0;
    705 	if ((buf = malloc(needed)) == NULL)
    706 		return -1;
    707 	if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1)
    708 		return -1;
    709 
    710 	end = buf + needed;
    711 	for (p = buf; p < end; p += rtm->rtm_msglen) {
    712 		rtm = (struct rt_msghdr *)(void *)p;
    713 		if (if_copyrt(ifp->ctx, &rt, rtm) == 0)
    714 			ipv4_handlert(ifp->ctx, RTM_ADD, &rt);
    715 	}
    716 	free(buf);
    717 	return 0;
    718 }
    719 
    720 #ifdef SIOCGIFAFLAG_IN
    721 int
    722 if_addrflags(const struct in_addr *addr, const struct interface *ifp)
    723 {
    724 	int s, flags;
    725 	struct ifreq ifr;
    726 	struct sockaddr_in *sin;
    727 
    728 	s = socket(PF_INET, SOCK_DGRAM, 0);
    729 	flags = -1;
    730 	if (s != -1) {
    731 		memset(&ifr, 0, sizeof(ifr));
    732 		strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
    733 		sin = (struct sockaddr_in *)(void *)&ifr.ifr_addr;
    734 		sin->sin_family = AF_INET;
    735 		sin->sin_addr = *addr;
    736 		if (ioctl(s, SIOCGIFAFLAG_IN, &ifr) != -1)
    737 			flags = ifr.ifr_addrflags;
    738 		close(s);
    739 	}
    740 	return flags;
    741 }
    742 #else
    743 int
    744 if_addrflags(__unused const struct in_addr *addr,
    745     __unused const struct interface *ifp)
    746 {
    747 
    748 	errno = ENOTSUP;
    749 	return 0;
    750 }
    751 #endif
    752 #endif /* INET */
    753 
    754 #ifdef INET6
    755 static void
    756 ifa_scope(struct sockaddr_in6 *sin, unsigned int ifindex)
    757 {
    758 
    759 #ifdef __KAME__
    760 	/* KAME based systems want to store the scope inside the sin6_addr
    761 	 * for link local addreses */
    762 	if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) {
    763 		uint16_t scope = htons((uint16_t)ifindex);
    764 		memcpy(&sin->sin6_addr.s6_addr[2], &scope,
    765 		    sizeof(scope));
    766 	}
    767 	sin->sin6_scope_id = 0;
    768 #else
    769 	if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr))
    770 		sin->sin6_scope_id = ifindex;
    771 	else
    772 		sin->sin6_scope_id = 0;
    773 #endif
    774 }
    775 
    776 #ifdef __KAME__
    777 #define DESCOPE(ia6) do {						      \
    778 	if (IN6_IS_ADDR_LINKLOCAL((ia6)))				      \
    779 		(ia6)->s6_addr[2] = (ia6)->s6_addr[3] = '\0';		      \
    780 	} while (/*CONSTCOND */0)
    781 #else
    782 #define DESCOPE(ia6)
    783 #endif
    784 
    785 int
    786 if_address6(const struct ipv6_addr *a, int action)
    787 {
    788 	int s, r;
    789 	struct in6_aliasreq ifa;
    790 	struct in6_addr mask;
    791 
    792 	if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) == -1)
    793 		return -1;
    794 
    795 	memset(&ifa, 0, sizeof(ifa));
    796 	strlcpy(ifa.ifra_name, a->iface->name, sizeof(ifa.ifra_name));
    797 	/*
    798 	 * We should not set IN6_IFF_TENTATIVE as the kernel should be
    799 	 * able to work out if it's a new address or not.
    800 	 *
    801 	 * We should set IN6_IFF_AUTOCONF, but the kernel won't let us.
    802 	 * This is probably a safety measure, but still it's not entirely right
    803 	 * either.
    804 	 */
    805 #if 0
    806 	if (a->autoconf)
    807 		ifa.ifra_flags |= IN6_IFF_AUTOCONF;
    808 #endif
    809 #ifdef IPV6_MANGETEMPADDR
    810 	if (a->flags & IPV6_AF_TEMPORARY)
    811 		ifa.ifra_flags |= IN6_IFF_TEMPORARY;
    812 #endif
    813 
    814 #define ADDADDR(v, addr) {						      \
    815 		(v)->sin6_family = AF_INET6;				      \
    816 		(v)->sin6_len = sizeof(*v);				      \
    817 		(v)->sin6_addr = *addr;					      \
    818 	}
    819 
    820 	ADDADDR(&ifa.ifra_addr, &a->addr);
    821 	ifa_scope(&ifa.ifra_addr, a->iface->index);
    822 	ipv6_mask(&mask, a->prefix_len);
    823 	ADDADDR(&ifa.ifra_prefixmask, &mask);
    824 	ifa.ifra_lifetime.ia6t_vltime = a->prefix_vltime;
    825 	ifa.ifra_lifetime.ia6t_pltime = a->prefix_pltime;
    826 #undef ADDADDR
    827 
    828 	r = ioctl(s, action < 0 ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa);
    829 	close(s);
    830 	return r;
    831 }
    832 
    833 
    834 static int
    835 if_copyrt6(struct dhcpcd_ctx *ctx, struct rt6 *rt, struct rt_msghdr *rtm)
    836 {
    837 	char *cp;
    838 	struct sockaddr *sa, *rti_info[RTAX_MAX];
    839 
    840 	cp = (char *)(void *)(rtm + 1);
    841 	sa = (struct sockaddr *)(void *)cp;
    842 	if (sa->sa_family != AF_INET6)
    843 		return -1;
    844 	if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY))
    845 		return -1;
    846 #ifdef RTF_CLONED
    847 	if (rtm->rtm_flags & (RTF_CLONED | RTF_HOST))
    848 		return -1;
    849 #else
    850 	if (rtm->rtm_flags & RTF_HOST)
    851 		return -1;
    852 #endif
    853 #ifdef RTF_LOCAL
    854 	if (rtm->rtm_flags & RTF_LOCAL)
    855 		return -1;
    856 #endif
    857 
    858 	get_addrs(rtm->rtm_addrs, cp, rti_info);
    859 	memset(rt, 0, sizeof(*rt));
    860 	rt->flags = (unsigned int)rtm->rtm_flags;
    861 	COPYOUT6(rt->dest, rti_info[RTAX_DST]);
    862 	if (rtm->rtm_addrs & RTA_NETMASK) {
    863 		/*
    864 		 * We need to zero out the struct beyond sin6_len and
    865 		 * ensure it's valid.
    866 		 * I have no idea what the invalid data is for, could be
    867 		 * a kernel bug or actually used for something.
    868 		 * Either way it needs to be zeroed out.
    869 		 */
    870 		struct sockaddr_in6 *sin6;
    871 		size_t e, i, len = 0, final = 0;
    872 
    873 		sin6 = (struct sockaddr_in6 *)(void *)rti_info[RTAX_NETMASK];
    874 		rt->net = sin6->sin6_addr;
    875 		e = sin6->sin6_len - offsetof(struct sockaddr_in6, sin6_addr);
    876 		if (e > sizeof(struct in6_addr))
    877 			e = sizeof(struct in6_addr);
    878 		for (i = 0; i < e; i++) {
    879 			switch (rt->net.s6_addr[i] & 0xff) {
    880 			case 0xff:
    881 				/* We don't really want the length,
    882 				 * just that it's valid */
    883 				len++;
    884 				break;
    885 			case 0xfe:
    886 			case 0xfc:
    887 			case 0xf8:
    888 			case 0xf0:
    889 			case 0xe0:
    890 			case 0xc0:
    891 			case 0x80:
    892 				len++;
    893 				final = 1;
    894 				break;
    895 			default:
    896 				rt->net.s6_addr[i] = 0x00;
    897 				final = 1;
    898 				break;
    899 			}
    900 			if (final)
    901 				break;
    902 		}
    903 		if (len == 0)
    904 			i = 0;
    905 		while (i < sizeof(rt->net.s6_addr))
    906 			rt->net.s6_addr[i++] = 0x00;
    907 	} else
    908 		ipv6_mask(&rt->net, 128);
    909 	COPYOUT6(rt->gate, rti_info[RTAX_GATEWAY]);
    910 
    911 	if (rtm->rtm_index)
    912 		rt->iface = if_findindex(ctx->ifaces, rtm->rtm_index);
    913 	else if (rtm->rtm_addrs & RTA_IFP) {
    914 		struct sockaddr_dl *sdl;
    915 
    916 		sdl = (struct sockaddr_dl *)(void *)rti_info[RTAX_IFP];
    917 		rt->iface = if_findsdl(ctx, sdl);
    918 	}
    919 	/* If we don't have an interface and it's a host route, it maybe
    920 	 * to a local ip via the loopback interface. */
    921 	if (rt->iface == NULL &&
    922 	    !(~rtm->rtm_flags & (RTF_HOST | RTF_GATEWAY)))
    923 	{
    924 		struct ipv6_addr *ia;
    925 
    926 		if ((ia = ipv6_findaddr(ctx, &rt->dest, 0)))
    927 			rt->iface = ia->iface;
    928 	}
    929 
    930 	return 0;
    931 }
    932 
    933 int
    934 if_route6(unsigned char cmd, const struct rt6 *rt)
    935 {
    936 	union sockunion {
    937 		struct sockaddr sa;
    938 		struct sockaddr_in6 sin;
    939 		struct sockaddr_dl sdl;
    940 	} su;
    941 	struct rtm
    942 	{
    943 		struct rt_msghdr hdr;
    944 		char buffer[sizeof(su) * RTAX_MAX];
    945 	} rtm;
    946 	char *bp = rtm.buffer;
    947 	size_t l;
    948 	int s, retval;
    949 
    950 	if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -1)
    951 		return -1;
    952 
    953 #define ADDSU {								      \
    954 		l = RT_ROUNDUP(su.sa.sa_len);				      \
    955 		memcpy(bp, &su, l);					      \
    956 		bp += l;						      \
    957 	}
    958 #define ADDADDRS(addr, scope) {						      \
    959 		memset(&su, 0, sizeof(su));				      \
    960 		su.sin.sin6_family = AF_INET6;				      \
    961 		su.sin.sin6_len = sizeof(su.sin);			      \
    962 		(&su.sin)->sin6_addr = *addr;				      \
    963 		if (scope)						      \
    964 			ifa_scope(&su.sin, scope);			      \
    965 		ADDSU;							      \
    966 	}
    967 #define ADDADDR(addr) ADDADDRS(addr, 0)
    968 
    969 	memset(&rtm, 0, sizeof(rtm));
    970 	rtm.hdr.rtm_version = RTM_VERSION;
    971 	rtm.hdr.rtm_seq = 1;
    972 	rtm.hdr.rtm_type = cmd;
    973 	rtm.hdr.rtm_flags = RTF_UP | (int)rt->flags;
    974 #ifdef RTF_PINNED
    975 	if (rtm.hdr.rtm_type != RTM_ADD)
    976 		rtm.hdr.rtm_flags |= RTF_PINNED;
    977 #endif
    978 	rtm.hdr.rtm_addrs = RTA_DST | RTA_NETMASK;
    979 	/* None interface subnet routes are static. */
    980 	if (IN6_IS_ADDR_UNSPECIFIED(&rt->gate)) {
    981 #ifdef RTF_CLONING
    982 		rtm.hdr.rtm_flags |= RTF_CLONING;
    983 #endif
    984 #ifdef RTP_CONNECTED
    985 		rtm.hdr.rtm_priority = RTP_CONNECTED;
    986 #endif
    987 	} else
    988 		rtm.hdr.rtm_flags |= RTF_GATEWAY | RTF_STATIC;
    989 
    990 	if (cmd == RTM_ADD)
    991 		rtm.hdr.rtm_addrs |= RTA_GATEWAY;
    992 	if (cmd == RTM_ADD && !(rtm.hdr.rtm_flags & RTF_REJECT))
    993 		rtm.hdr.rtm_addrs |= RTA_IFP | RTA_IFA;
    994 
    995 	ADDADDR(&rt->dest);
    996 	if (rtm.hdr.rtm_addrs & RTA_GATEWAY) {
    997 		if (IN6_IS_ADDR_UNSPECIFIED(&rt->gate)) {
    998 			if_linkaddr(&su.sdl, rt->iface);
    999 			ADDSU;
   1000 		} else {
   1001 			ADDADDRS(&rt->gate, rt->iface->index);
   1002 		}
   1003 	}
   1004 
   1005 	if (rtm.hdr.rtm_addrs & RTA_NETMASK)
   1006 		ADDADDR(&rt->net);
   1007 
   1008 	if ((cmd == RTM_ADD || cmd == RTM_CHANGE) &&
   1009 	    (rtm.hdr.rtm_addrs & (RTA_IFP | RTA_IFA)))
   1010 	{
   1011 		rtm.hdr.rtm_index = (unsigned short)rt->iface->index;
   1012 		if (rtm.hdr.rtm_addrs & RTA_IFP) {
   1013 			if_linkaddr(&su.sdl, rt->iface);
   1014 			ADDSU;
   1015 		}
   1016 
   1017 		if (rtm.hdr.rtm_addrs & RTA_IFA) {
   1018 			const struct ipv6_addr *lla;
   1019 
   1020 			lla = ipv6_linklocal(rt->iface);
   1021 			if (lla == NULL) /* unlikely */
   1022 					return -1;
   1023 			ADDADDRS(&lla->addr, rt->iface->index);
   1024 		}
   1025 
   1026 		if (rt->mtu) {
   1027 			rtm.hdr.rtm_inits |= RTV_MTU;
   1028 			rtm.hdr.rtm_rmx.rmx_mtu = rt->mtu;
   1029 		}
   1030 	}
   1031 
   1032 #undef ADDADDR
   1033 #undef ADDSU
   1034 
   1035 	rtm.hdr.rtm_msglen = (unsigned short)(bp - (char *)&rtm);
   1036 	retval = write(s, &rtm, rtm.hdr.rtm_msglen) == -1 ? -1 : 0;
   1037 	close(s);
   1038 	return retval;
   1039 }
   1040 
   1041 int
   1042 if_initrt6(struct interface *ifp)
   1043 {
   1044 	struct rt_msghdr *rtm;
   1045 	int mib[6];
   1046 	size_t needed;
   1047 	char *buf, *p, *end;
   1048 	struct rt6 rt;
   1049 
   1050 	ipv6_freerts(&ifp->ctx->ipv6->kroutes);
   1051 
   1052 	mib[0] = CTL_NET;
   1053 	mib[1] = PF_ROUTE;
   1054 	mib[2] = 0;
   1055 	mib[3] = AF_INET6;
   1056 	mib[4] = NET_RT_DUMP;
   1057 	mib[5] = 0;
   1058 
   1059 	if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1)
   1060 		return -1;
   1061 	if (needed == 0)
   1062 		return 0;
   1063 	if ((buf = malloc(needed)) == NULL)
   1064 		return -1;
   1065 	if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1)
   1066 		return -1;
   1067 
   1068 	end = buf + needed;
   1069 	for (p = buf; p < end; p += rtm->rtm_msglen) {
   1070 		rtm = (struct rt_msghdr *)(void *)p;
   1071 		if (if_copyrt6(ifp->ctx, &rt, rtm) == 0)
   1072 			ipv6_handlert(ifp->ctx, RTM_ADD, &rt);
   1073 	}
   1074 	free(buf);
   1075 	return 0;
   1076 }
   1077 
   1078 int
   1079 if_addrflags6(const struct in6_addr *addr, const struct interface *ifp)
   1080 {
   1081 	int s, flags;
   1082 	struct in6_ifreq ifr6;
   1083 
   1084 	s = socket(PF_INET6, SOCK_DGRAM, 0);
   1085 	flags = -1;
   1086 	if (s != -1) {
   1087 		memset(&ifr6, 0, sizeof(ifr6));
   1088 		strlcpy(ifr6.ifr_name, ifp->name, sizeof(ifr6.ifr_name));
   1089 		ifr6.ifr_addr.sin6_family = AF_INET6;
   1090 		ifr6.ifr_addr.sin6_addr = *addr;
   1091 		ifa_scope(&ifr6.ifr_addr, ifp->index);
   1092 		if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) != -1)
   1093 			flags = ifr6.ifr_ifru.ifru_flags6;
   1094 		close(s);
   1095 	}
   1096 	return flags;
   1097 }
   1098 
   1099 int
   1100 if_getlifetime6(struct ipv6_addr *ia)
   1101 {
   1102 	int s, r;
   1103 	struct in6_ifreq ifr6;
   1104 
   1105 	s = socket(PF_INET6, SOCK_DGRAM, 0);
   1106 	r = -1;
   1107 	if (s != -1) {
   1108 		memset(&ifr6, 0, sizeof(ifr6));
   1109 		strlcpy(ifr6.ifr_name, ia->iface->name, sizeof(ifr6.ifr_name));
   1110 		ifr6.ifr_addr.sin6_family = AF_INET6;
   1111 		ifr6.ifr_addr.sin6_addr = ia->addr;
   1112 		ifa_scope(&ifr6.ifr_addr, ia->iface->index);
   1113 		if (ioctl(s, SIOCGIFALIFETIME_IN6, &ifr6) != -1) {
   1114 			time_t t;
   1115 			struct in6_addrlifetime *lifetime;
   1116 
   1117 			t = time(NULL);
   1118 			lifetime = &ifr6.ifr_ifru.ifru_lifetime;
   1119 
   1120 			if (lifetime->ia6t_preferred)
   1121 				ia->prefix_pltime =
   1122 				    (uint32_t)(lifetime->ia6t_preferred -
   1123 				    MIN(t, lifetime->ia6t_preferred));
   1124 			else
   1125 				ia->prefix_pltime = ND6_INFINITE_LIFETIME;
   1126 			if (lifetime->ia6t_expire) {
   1127 				ia->prefix_vltime =
   1128 				    (uint32_t)(lifetime->ia6t_expire -
   1129 				    MIN(t, lifetime->ia6t_expire));
   1130 				/* Calculate the created time */
   1131 				get_monotonic(&ia->created);
   1132 				ia->created.tv_sec -=
   1133 				    lifetime->ia6t_vltime - ia->prefix_vltime;
   1134 			} else
   1135 				ia->prefix_vltime = ND6_INFINITE_LIFETIME;
   1136 
   1137 			r = 0;
   1138 		}
   1139 		close(s);
   1140 	}
   1141 	return r;
   1142 }
   1143 #endif
   1144 
   1145 int
   1146 if_managelink(struct dhcpcd_ctx *ctx)
   1147 {
   1148 	/* route and ifwatchd like a msg buf size of 2048 */
   1149 	char msg[2048], *p, *e, *cp;
   1150 	ssize_t bytes;
   1151 	struct rt_msghdr *rtm;
   1152 	struct if_announcemsghdr *ifan;
   1153 	struct if_msghdr *ifm;
   1154 	struct ifa_msghdr *ifam;
   1155 	struct sockaddr *sa, *rti_info[RTAX_MAX];
   1156 	int len;
   1157 	struct sockaddr_dl sdl;
   1158 	struct interface *ifp;
   1159 #ifdef INET
   1160 	struct rt rt;
   1161 #endif
   1162 #ifdef INET6
   1163 	struct rt6 rt6;
   1164 	struct in6_addr ia6, net6;
   1165 	struct sockaddr_in6 *sin6;
   1166 #endif
   1167 #if (defined(INET) && defined(IN_IFF_TENTATIVE)) || defined(INET6)
   1168 	int ifa_flags;
   1169 #endif
   1170 
   1171 	if ((bytes = read(ctx->link_fd, msg, sizeof(msg))) == -1)
   1172 		return -1;
   1173 	e = msg + bytes;
   1174 	for (p = msg; p < e; p += rtm->rtm_msglen) {
   1175 		rtm = (struct rt_msghdr *)(void *)p;
   1176 		// Ignore messages generated by us
   1177 		if (rtm->rtm_pid == getpid())
   1178 			break;
   1179 		switch(rtm->rtm_type) {
   1180 #ifdef RTM_IFANNOUNCE
   1181 		case RTM_IFANNOUNCE:
   1182 			ifan = (struct if_announcemsghdr *)(void *)p;
   1183 			switch(ifan->ifan_what) {
   1184 			case IFAN_ARRIVAL:
   1185 				dhcpcd_handleinterface(ctx, 1,
   1186 				    ifan->ifan_name);
   1187 				break;
   1188 			case IFAN_DEPARTURE:
   1189 				dhcpcd_handleinterface(ctx, -1,
   1190 				    ifan->ifan_name);
   1191 				break;
   1192 			}
   1193 			break;
   1194 #endif
   1195 		case RTM_IFINFO:
   1196 			ifm = (struct if_msghdr *)(void *)p;
   1197 			ifp = if_findindex(ctx->ifaces, ifm->ifm_index);
   1198 			if (ifp == NULL)
   1199 				break;
   1200 			switch (ifm->ifm_data.ifi_link_state) {
   1201 			case LINK_STATE_DOWN:
   1202 				len = LINK_DOWN;
   1203 				break;
   1204 			case LINK_STATE_UP:
   1205 				len = LINK_UP;
   1206 				break;
   1207 			default:
   1208 				/* handle_carrier will re-load
   1209 				 * the interface flags and check for
   1210 				 * IFF_RUNNING as some drivers that
   1211 				 * don't handle link state also don't
   1212 				 * set IFF_RUNNING when this routing
   1213 				 * message is generated.
   1214 				 * As such, it is a race ...*/
   1215 				len = LINK_UNKNOWN;
   1216 				break;
   1217 			}
   1218 			dhcpcd_handlecarrier(ctx, len,
   1219 			    (unsigned int)ifm->ifm_flags, ifp->name);
   1220 			break;
   1221 		case RTM_ADD:
   1222 		case RTM_CHANGE:
   1223 		case RTM_DELETE:
   1224 			cp = (char *)(void *)(rtm + 1);
   1225 			sa = (struct sockaddr *)(void *)cp;
   1226 			switch (sa->sa_family) {
   1227 #ifdef INET
   1228 			case AF_INET:
   1229 				if (if_copyrt(ctx, &rt, rtm) == 0)
   1230 					ipv4_handlert(ctx, rtm->rtm_type, &rt);
   1231 				break;
   1232 #endif
   1233 #ifdef INET6
   1234 			case AF_INET6:
   1235 				if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY))
   1236 					break;
   1237 				/*
   1238 				 * BSD caches host routes in the
   1239 				 * routing table.
   1240 				 * As such, we should be notified of
   1241 				 * reachability by its existance
   1242 				 * with a hardware address
   1243 				 */
   1244 				if (rtm->rtm_flags & (RTF_HOST)) {
   1245 					get_addrs(rtm->rtm_addrs, cp, rti_info);
   1246 					COPYOUT6(ia6, rti_info[RTAX_DST]);
   1247 					DESCOPE(&ia6);
   1248 					if (rti_info[RTAX_GATEWAY]->sa_family
   1249 					    == AF_LINK)
   1250 						memcpy(&sdl,
   1251 						    rti_info[RTAX_GATEWAY],
   1252 						    sizeof(sdl));
   1253 					else
   1254 						sdl.sdl_alen = 0;
   1255 					ipv6nd_neighbour(ctx, &ia6,
   1256 					    rtm->rtm_type != RTM_DELETE &&
   1257 					    sdl.sdl_alen ?
   1258 					    IPV6ND_REACHABLE : 0);
   1259 					break;
   1260 				}
   1261 
   1262 				if (if_copyrt6(ctx, &rt6, rtm) == 0)
   1263 					ipv6_handlert(ctx, rtm->rtm_type, &rt6);
   1264 				break;
   1265 #endif
   1266 			}
   1267 			break;
   1268 #ifdef RTM_CHGADDR
   1269 		case RTM_CHGADDR:	/* FALLTHROUGH */
   1270 #endif
   1271 		case RTM_DELADDR:	/* FALLTHROUGH */
   1272 		case RTM_NEWADDR:
   1273 			ifam = (struct ifa_msghdr *)(void *)p;
   1274 			ifp = if_findindex(ctx->ifaces, ifam->ifam_index);
   1275 			if (ifp == NULL)
   1276 				break;
   1277 			cp = (char *)(void *)(ifam + 1);
   1278 			get_addrs(ifam->ifam_addrs, cp, rti_info);
   1279 			if (rti_info[RTAX_IFA] == NULL)
   1280 				break;
   1281 			switch (rti_info[RTAX_IFA]->sa_family) {
   1282 			case AF_LINK:
   1283 #ifdef RTM_CHGADDR
   1284 				if (rtm->rtm_type != RTM_CHGADDR)
   1285 					break;
   1286 #else
   1287 				if (rtm->rtm_type != RTM_NEWADDR)
   1288 					break;
   1289 #endif
   1290 				memcpy(&sdl, rti_info[RTAX_IFA],
   1291 				    rti_info[RTAX_IFA]->sa_len);
   1292 				dhcpcd_handlehwaddr(ctx, ifp->name,
   1293 				    (const unsigned char*)CLLADDR(&sdl),
   1294 				    sdl.sdl_alen);
   1295 				break;
   1296 #ifdef INET
   1297 			case AF_INET:
   1298 			case 255: /* FIXME: Why 255? */
   1299 				COPYOUT(rt.dest, rti_info[RTAX_IFA]);
   1300 				COPYOUT(rt.net, rti_info[RTAX_NETMASK]);
   1301 				COPYOUT(rt.gate, rti_info[RTAX_BRD]);
   1302 				if (rtm->rtm_type == RTM_NEWADDR) {
   1303 					ifa_flags = if_addrflags(&rt.dest, ifp);
   1304 					if (ifa_flags == -1)
   1305 						break;
   1306 				} else
   1307 					ifa_flags = 0;
   1308 				ipv4_handleifa(ctx, rtm->rtm_type,
   1309 				    NULL, ifp->name,
   1310 				    &rt.dest, &rt.net, &rt.gate, ifa_flags);
   1311 				break;
   1312 #endif
   1313 #ifdef INET6
   1314 			case AF_INET6:
   1315 				sin6 = (struct sockaddr_in6*)(void *)
   1316 				    rti_info[RTAX_IFA];
   1317 				ia6 = sin6->sin6_addr;
   1318 				DESCOPE(&ia6);
   1319 				sin6 = (struct sockaddr_in6*)(void *)
   1320 				    rti_info[RTAX_NETMASK];
   1321 				net6 = sin6->sin6_addr;
   1322 				DESCOPE(&net6);
   1323 				if (rtm->rtm_type == RTM_NEWADDR) {
   1324 					ifa_flags = if_addrflags6(&ia6, ifp);
   1325 					if (ifa_flags == -1)
   1326 						break;
   1327 				} else
   1328 					ifa_flags = 0;
   1329 				ipv6_handleifa(ctx, rtm->rtm_type, NULL,
   1330 				    ifp->name, &ia6, ipv6_prefixlen(&net6),
   1331 				    ifa_flags);
   1332 				break;
   1333 #endif
   1334 			}
   1335 			break;
   1336 		}
   1337 	}
   1338 	return 0;
   1339 }
   1340 
   1341 #ifndef SYS_NMLN	/* OSX */
   1342 #  define SYS_NMLN 256
   1343 #endif
   1344 #ifndef HW_MACHINE_ARCH
   1345 #  ifdef HW_MODEL	/* OpenBSD */
   1346 #    define HW_MACHINE_ARCH HW_MODEL
   1347 #  endif
   1348 #endif
   1349 int
   1350 if_machinearch(char *str, size_t len)
   1351 {
   1352 	int mib[2] = { CTL_HW, HW_MACHINE_ARCH };
   1353 	char march[SYS_NMLN];
   1354 	size_t marchlen = sizeof(march);
   1355 
   1356 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
   1357 	    march, &marchlen, NULL, 0) != 0)
   1358 		return -1;
   1359 	return snprintf(str, len, ":%s", march);
   1360 }
   1361 
   1362 #ifdef INET6
   1363 #ifdef IPV6CTL_ACCEPT_RTADV
   1364 #define get_inet6_sysctl(code) inet6_sysctl(code, 0, 0)
   1365 #define set_inet6_sysctl(code, val) inet6_sysctl(code, val, 1)
   1366 static int
   1367 inet6_sysctl(int code, int val, int action)
   1368 {
   1369 	int mib[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, 0 };
   1370 	size_t size;
   1371 
   1372 	mib[3] = code;
   1373 	size = sizeof(val);
   1374 	if (action) {
   1375 		if (sysctl(mib, sizeof(mib)/sizeof(mib[0]),
   1376 		    NULL, 0, &val, size) == -1)
   1377 			return -1;
   1378 		return 0;
   1379 	}
   1380 	if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &val, &size, NULL, 0) == -1)
   1381 		return -1;
   1382 	return val;
   1383 }
   1384 #endif
   1385 
   1386 #ifdef IPV6_MANAGETEMPADDR
   1387 #ifndef IPV6CTL_TEMPVLTIME
   1388 #define get_inet6_sysctlbyname(code) inet6_sysctlbyname(code, 0, 0)
   1389 #define set_inet6_sysctlbyname(code, val) inet6_sysctlbyname(code, val, 1)
   1390 static int
   1391 inet6_sysctlbyname(const char *name, int val, int action)
   1392 {
   1393 	size_t size;
   1394 
   1395 	size = sizeof(val);
   1396 	if (action) {
   1397 		if (sysctlbyname(name, NULL, 0, &val, size) == -1)
   1398 			return -1;
   1399 		return 0;
   1400 	}
   1401 	if (sysctlbyname(name, &val, &size, NULL, 0) == -1)
   1402 		return -1;
   1403 	return val;
   1404 }
   1405 #endif
   1406 
   1407 int
   1408 ip6_use_tempaddr(__unused const char *ifname)
   1409 {
   1410 	int val;
   1411 
   1412 #ifdef IPV6CTL_USETEMPADDR
   1413 	val = get_inet6_sysctl(IPV6CTL_USETEMPADDR);
   1414 #else
   1415 	val = get_inet6_sysctlbyname("net.inet6.ip6.use_tempaddr");
   1416 #endif
   1417 	return val == -1 ? 0 : val;
   1418 }
   1419 
   1420 int
   1421 ip6_temp_preferred_lifetime(__unused const char *ifname)
   1422 {
   1423 	int val;
   1424 
   1425 #ifdef IPV6CTL_TEMPPLTIME
   1426 	val = get_inet6_sysctl(IPV6CTL_TEMPPLTIME);
   1427 #else
   1428 	val = get_inet6_sysctlbyname("net.inet6.ip6.temppltime");
   1429 #endif
   1430 	return val < 0 ? TEMP_PREFERRED_LIFETIME : val;
   1431 }
   1432 
   1433 int
   1434 ip6_temp_valid_lifetime(__unused const char *ifname)
   1435 {
   1436 	int val;
   1437 
   1438 #ifdef IPV6CTL_TEMPVLTIME
   1439 	val = get_inet6_sysctl(IPV6CTL_TEMPVLTIME);
   1440 #else
   1441 	val = get_inet6_sysctlbyname("net.inet6.ip6.tempvltime");
   1442 #endif
   1443 	return val < 0 ? TEMP_VALID_LIFETIME : val;
   1444 }
   1445 #endif
   1446 
   1447 #define del_if_nd6_flag(s, ifname, flag) if_nd6_flag((s), (ifp), (flag), -1)
   1448 #define get_if_nd6_flag(s, ifname, flag) if_nd6_flag((s), (ifp), (flag),  0)
   1449 #define set_if_nd6_flag(s, ifname, flag) if_nd6_flag((s), (ifp), (flag),  1)
   1450 static int
   1451 if_nd6_flag(int s, const struct interface *ifp, unsigned int flag, int set)
   1452 {
   1453 	struct in6_ndireq nd;
   1454 	unsigned int oflags;
   1455 
   1456 	memset(&nd, 0, sizeof(nd));
   1457 	strlcpy(nd.ifname, ifp->name, sizeof(nd.ifname));
   1458 	if (ioctl(s, SIOCGIFINFO_IN6, &nd) == -1)
   1459 		return -1;
   1460 	if (set == 0)
   1461 		return nd.ndi.flags & flag ? 1 : 0;
   1462 
   1463 	oflags = nd.ndi.flags;
   1464 	if (set == -1)
   1465 		nd.ndi.flags &= ~flag;
   1466 	else
   1467 		nd.ndi.flags |= flag;
   1468 	if (oflags == nd.ndi.flags)
   1469 		return 0;
   1470 	return ioctl(s, SIOCSIFINFO_FLAGS, &nd);
   1471 }
   1472 
   1473 static int
   1474 if_raflush(int s)
   1475 {
   1476 	char dummy[IFNAMSIZ + 8];
   1477 
   1478 	strlcpy(dummy, "lo0", sizeof(dummy));
   1479 	if (ioctl(s, SIOCSRTRFLUSH_IN6, (void *)&dummy) == -1 ||
   1480 	    ioctl(s, SIOCSPFXFLUSH_IN6, (void *)&dummy) == -1)
   1481 		return -1;
   1482 	return 0;
   1483 }
   1484 
   1485 #ifdef SIOCIFAFATTACH
   1486 static int
   1487 af_attach(int s, const struct interface *ifp, int af)
   1488 {
   1489 	struct if_afreq ifar;
   1490 
   1491 	strlcpy(ifar.ifar_name, ifp->name, sizeof(ifar.ifar_name));
   1492 	ifar.ifar_af = af;
   1493 	return ioctl(s, SIOCIFAFATTACH, (void *)&ifar);
   1494 }
   1495 #endif
   1496 
   1497 #ifdef SIOCGIFXFLAGS
   1498 static int
   1499 set_ifxflags(int s, const struct interface *ifp, int own)
   1500 {
   1501 	struct ifreq ifr;
   1502 	int flags;
   1503 
   1504 #ifndef IFXF_NOINET6
   1505 	/* No point in removing the no inet6 flag if it doesn't
   1506 	 * exist and we're not owning inet6. */
   1507 	if (! own)
   1508 		return 0;
   1509 #endif
   1510 
   1511 	strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
   1512 	if (ioctl(s, SIOCGIFXFLAGS, (void *)&ifr) == -1)
   1513 		return -1;
   1514 	flags = ifr.ifr_flags;
   1515 #ifdef IFXF_NOINET6
   1516 	flags &= ~IFXF_NOINET6;
   1517 #endif
   1518 	if (own)
   1519 		flags &= ~IFXF_AUTOCONF6;
   1520 	if (ifr.ifr_flags == flags)
   1521 		return 0;
   1522 	ifr.ifr_flags = flags;
   1523 	return ioctl(s, SIOCSIFXFLAGS, (void *)&ifr);
   1524 }
   1525 #endif
   1526 
   1527 static int
   1528 _if_checkipv6(int s, struct dhcpcd_ctx *ctx,
   1529     const struct interface *ifp, int own)
   1530 {
   1531 	int ra;
   1532 
   1533 	if (ifp) {
   1534 #ifdef ND6_IFF_OVERRIDE_RTADV
   1535 		int override;
   1536 #endif
   1537 
   1538 #ifdef ND6_IFF_IFDISABLED
   1539 		if (del_if_nd6_flag(s, ifp, ND6_IFF_IFDISABLED) == -1) {
   1540 			logger(ifp->ctx, LOG_ERR,
   1541 			    "%s: del_if_nd6_flag: ND6_IFF_IFDISABLED: %m",
   1542 			    ifp->name);
   1543 			return -1;
   1544 		}
   1545 #endif
   1546 
   1547 #ifdef ND6_IFF_PERFORMNUD
   1548 		if (set_if_nd6_flag(s, ifp, ND6_IFF_PERFORMNUD) == -1) {
   1549 			logger(ifp->ctx, LOG_ERR,
   1550 			    "%s: set_if_nd6_flag: ND6_IFF_PERFORMNUD: %m",
   1551 			    ifp->name);
   1552 			return -1;
   1553 		}
   1554 #endif
   1555 
   1556 #ifdef ND6_IFF_AUTO_LINKLOCAL
   1557 		if (own) {
   1558 			int all;
   1559 
   1560 			all = get_if_nd6_flag(s, ifp, ND6_IFF_AUTO_LINKLOCAL);
   1561 			if (all == -1)
   1562 				logger(ifp->ctx, LOG_ERR,
   1563 				    "%s: get_if_nd6_flag: "
   1564 				    "ND6_IFF_AUTO_LINKLOCAL: %m",
   1565 				    ifp->name);
   1566 			else if (all != 0) {
   1567 				logger(ifp->ctx, LOG_DEBUG,
   1568 				    "%s: disabling Kernel IPv6 "
   1569 				    "auto link-local support",
   1570 				    ifp->name);
   1571 				if (del_if_nd6_flag(s, ifp,
   1572 				    ND6_IFF_AUTO_LINKLOCAL) == -1)
   1573 				{
   1574 					logger(ifp->ctx, LOG_ERR,
   1575 					    "%s: del_if_nd6_flag: "
   1576 					    "ND6_IFF_AUTO_LINKLOCAL: %m",
   1577 					    ifp->name);
   1578 					return -1;
   1579 				}
   1580 			}
   1581 		}
   1582 #endif
   1583 
   1584 #ifdef SIOCIFAFATTACH
   1585 		if (af_attach(s, ifp, AF_INET6) == -1) {
   1586 			logger(ifp->ctx, LOG_ERR,
   1587 			    "%s: af_attach: %m", ifp->name);
   1588 			return 1;
   1589 		}
   1590 #endif
   1591 
   1592 #ifdef SIOCGIFXFLAGS
   1593 		if (set_ifxflags(s, ifp, own) == -1) {
   1594 			logger(ifp->ctx, LOG_ERR,
   1595 			    "%s: set_ifxflags: %m", ifp->name);
   1596 			return -1;
   1597 		}
   1598 #endif
   1599 
   1600 #ifdef ND6_IFF_OVERRIDE_RTADV
   1601 		override = get_if_nd6_flag(s, ifp, ND6_IFF_OVERRIDE_RTADV);
   1602 		if (override == -1)
   1603 			logger(ifp->ctx, LOG_ERR,
   1604 			    "%s: get_if_nd6_flag: ND6_IFF_OVERRIDE_RTADV: %m",
   1605 			    ifp->name);
   1606 		else if (override == 0 && own) {
   1607 			if (set_if_nd6_flag(s, ifp, ND6_IFF_OVERRIDE_RTADV)
   1608 			    == -1)
   1609 				logger(ifp->ctx, LOG_ERR,
   1610 				    "%s: set_if_nd6_flag: "
   1611 				    "ND6_IFF_OVERRIDE_RTADV: %m",
   1612 				    ifp->name);
   1613 			else
   1614 				override = 1;
   1615 		}
   1616 #endif
   1617 
   1618 #ifdef ND6_IFF_ACCEPT_RTADV
   1619 		ra = get_if_nd6_flag(s, ifp, ND6_IFF_ACCEPT_RTADV);
   1620 		if (ra == -1)
   1621 			logger(ifp->ctx, LOG_ERR,
   1622 			    "%s: get_if_nd6_flag: ND6_IFF_ACCEPT_RTADV: %m",
   1623 			    ifp->name);
   1624 		else if (ra != 0 && own) {
   1625 			logger(ifp->ctx, LOG_DEBUG,
   1626 			    "%s: disabling Kernel IPv6 RA support",
   1627 			    ifp->name);
   1628 			if (del_if_nd6_flag(s, ifp, ND6_IFF_ACCEPT_RTADV)
   1629 			    == -1)
   1630 				logger(ifp->ctx, LOG_ERR,
   1631 				    "%s: del_if_nd6_flag: "
   1632 				    "ND6_IFF_ACCEPT_RTADV: %m",
   1633 				    ifp->name);
   1634 			else
   1635 				ra = 0;
   1636 		} else if (ra == 0 && !own)
   1637 			logger(ifp->ctx, LOG_WARNING,
   1638 			    "%s: IPv6 kernel autoconf disabled", ifp->name);
   1639 #ifdef ND6_IFF_OVERRIDE_RTADV
   1640 		if (override == 0 && ra)
   1641 			return ctx->ra_global;
   1642 #endif
   1643 		return ra;
   1644 #else
   1645 		return ctx->ra_global;
   1646 #endif
   1647 	}
   1648 
   1649 #ifdef IPV6CTL_ACCEPT_RTADV
   1650 	ra = get_inet6_sysctl(IPV6CTL_ACCEPT_RTADV);
   1651 	if (ra == -1)
   1652 		/* The sysctl probably doesn't exist, but this isn't an
   1653 		 * error as such so just log it and continue */
   1654 		logger(ifp->ctx, errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
   1655 		    "IPV6CTL_ACCEPT_RTADV: %m");
   1656 	else if (ra != 0 && own) {
   1657 		logger(ifp->ctx, LOG_DEBUG, "disabling Kernel IPv6 RA support");
   1658 		if (set_inet6_sysctl(IPV6CTL_ACCEPT_RTADV, 0) == -1) {
   1659 			logger(ifp->ctx, LOG_ERR, "IPV6CTL_ACCEPT_RTADV: %m");
   1660 			return ra;
   1661 		}
   1662 		ra = 0;
   1663 #else
   1664 	ra = 0;
   1665 	if (own) {
   1666 #endif
   1667 		/* Flush the kernel knowledge of advertised routers
   1668 		 * and prefixes so the kernel does not expire prefixes
   1669 		 * and default routes we are trying to own. */
   1670 		if (if_raflush(s) == -1)
   1671 			logger(ctx, LOG_WARNING, "if_raflush: %m");
   1672 	}
   1673 
   1674 	ctx->ra_global = ra;
   1675 	return ra;
   1676 }
   1677 
   1678 int
   1679 if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own)
   1680 {
   1681 	int s, r;
   1682 
   1683 	if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) == -1)
   1684 		return -1;
   1685 	r = _if_checkipv6(s, ctx, ifp, own);
   1686 	close(s);
   1687 	return r;
   1688 }
   1689 #endif
   1690