• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * dhcpcd - DHCP client daemon
3  * Copyright (c) 2006-2015 Roy Marples <roy@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 /* TODO: We should decline dupliate addresses detected */
29 
30 #include <sys/stat.h>
31 #include <sys/utsname.h>
32 
33 #include <netinet/in.h>
34 
35 #include <ctype.h>
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <inttypes.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42 
43 #define ELOOP_QUEUE 4
44 #include "config.h"
45 #include "common.h"
46 #include "dhcp.h"
47 #include "dhcp6.h"
48 #include "duid.h"
49 #include "eloop.h"
50 #include "if.h"
51 #include "if-options.h"
52 #include "ipv6nd.h"
53 #include "rpc-interface.h"
54 #include "script.h"
55 
56 #ifndef __UNCONST
57 #define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
58 #endif
59 
60 /* DHCPCD Project has been assigned an IANA PEN of 40712 */
61 #define DHCPCD_IANA_PEN 40712
62 
63 /* Unsure if I want this */
64 //#define VENDOR_SPLIT
65 
66 /* Support older systems with different defines */
67 #if !defined(IPV6_RECVPKTINFO) && defined(IPV6_PKTINFO)
68 #define IPV6_RECVPKTINFO IPV6_PKTINFO
69 #endif
70 
71 struct dhcp6_op {
72 	uint16_t type;
73 	const char *name;
74 };
75 
76 static const struct dhcp6_op dhcp6_ops[] = {
77 	{ DHCP6_SOLICIT, "SOLICIT6" },
78 	{ DHCP6_ADVERTISE, "ADVERTISE6" },
79 	{ DHCP6_REQUEST, "REQUEST6" },
80 	{ DHCP6_REPLY, "REPLY6" },
81 	{ DHCP6_RENEW, "RENEW6" },
82 	{ DHCP6_REBIND, "REBIND6" },
83 	{ DHCP6_CONFIRM, "CONFIRM6" },
84 	{ DHCP6_INFORMATION_REQ, "INFORM6" },
85 	{ DHCP6_RELEASE, "RELEASE6" },
86 	{ DHCP6_RECONFIGURE, "RECONFIURE6" },
87 	{ 0, NULL }
88 };
89 
90 struct dhcp_compat {
91 	uint8_t dhcp_opt;
92 	uint16_t dhcp6_opt;
93 };
94 
95 const struct dhcp_compat dhcp_compats[] = {
96 	{ DHO_DNSSERVER,	D6_OPTION_DNS_SERVERS },
97 	{ DHO_HOSTNAME,		D6_OPTION_FQDN },
98 	{ DHO_DNSDOMAIN,	D6_OPTION_FQDN },
99 	{ DHO_NISSERVER,	D6_OPTION_NIS_SERVERS },
100 	{ DHO_NTPSERVER,	D6_OPTION_SNTP_SERVERS },
101 	{ DHO_RAPIDCOMMIT,	D6_OPTION_RAPID_COMMIT },
102 	{ DHO_FQDN,		D6_OPTION_FQDN },
103 	{ DHO_VIVCO,		D6_OPTION_VENDOR_CLASS },
104 	{ DHO_VIVSO,		D6_OPTION_VENDOR_OPTS },
105 	{ DHO_DNSSEARCH,	D6_OPTION_DOMAIN_LIST },
106 	{ 0, 0 }
107 };
108 
109 static const char * const dhcp6_statuses[] = {
110 	"Success",
111 	"Unspecified Failure",
112 	"No Addresses Available",
113 	"No Binding",
114 	"Not On Link",
115 	"Use Multicast"
116 };
117 
118 struct dhcp6_ia_addr {
119 	struct in6_addr addr;
120 	uint32_t pltime;
121 	uint32_t vltime;
122 } __packed;
123 
124 struct dhcp6_pd_addr {
125 	uint32_t pltime;
126 	uint32_t vltime;
127 	uint8_t prefix_len;
128 	struct in6_addr prefix;
129 } __packed;
130 
131 void
dhcp6_printoptions(const struct dhcpcd_ctx * ctx,const struct dhcp_opt * opts,size_t opts_len)132 dhcp6_printoptions(const struct dhcpcd_ctx *ctx,
133     const struct dhcp_opt *opts, size_t opts_len)
134 {
135 	size_t i, j;
136 	const struct dhcp_opt *opt, *opt2;
137 	int cols;
138 
139 	for (i = 0, opt = ctx->dhcp6_opts;
140 	    i < ctx->dhcp6_opts_len; i++, opt++)
141 	{
142 		for (j = 0, opt2 = opts; j < opts_len; j++, opt2++)
143 			if (opt2->option == opt->option)
144 				break;
145 		if (j == opts_len) {
146 			cols = printf("%05d %s", opt->option, opt->var);
147 			dhcp_print_option_encoding(opt, cols);
148 		}
149 	}
150 	for (i = 0, opt = opts; i < opts_len; i++, opt++) {
151 		cols = printf("%05d %s", opt->option, opt->var);
152 		dhcp_print_option_encoding(opt, cols);
153 	}
154 }
155 
156 static size_t
dhcp6_makevendor(struct dhcp6_option * o,const struct interface * ifp)157 dhcp6_makevendor(struct dhcp6_option *o, const struct interface *ifp)
158 {
159 	const struct if_options *ifo;
160 	size_t len, i;
161 	uint8_t *p;
162 	uint16_t u16;
163 	uint32_t u32;
164 	ssize_t vlen;
165 	const struct vivco *vivco;
166 	char vendor[VENDORCLASSID_MAX_LEN];
167 
168 	ifo = ifp->options;
169 	len = sizeof(uint32_t); /* IANA PEN */
170 	if (ifo->vivco_en) {
171 		for (i = 0, vivco = ifo->vivco;
172 		    i < ifo->vivco_len;
173 		    i++, vivco++)
174 			len += sizeof(uint16_t) + vivco->len;
175 		vlen = 0; /* silence bogus gcc warning */
176 	} else {
177 		vlen = dhcp_vendor(vendor, sizeof(vendor));
178 		if (vlen == -1)
179 			vlen = 0;
180 		else
181 			len += sizeof(uint16_t) + (size_t)vlen;
182 	}
183 
184 	if (len > UINT16_MAX) {
185 		logger(ifp->ctx, LOG_ERR,
186 		    "%s: DHCPv6 Vendor Class too big", ifp->name);
187 		return 0;
188 	}
189 
190 	if (o) {
191 		o->code = htons(D6_OPTION_VENDOR_CLASS);
192 		o->len = htons((uint16_t)len);
193 		p = D6_OPTION_DATA(o);
194 		u32 = htonl(ifo->vivco_en ? ifo->vivco_en : DHCPCD_IANA_PEN);
195 		memcpy(p, &u32, sizeof(u32));
196 		p += sizeof(u32);
197 		if (ifo->vivco_en) {
198 			for (i = 0, vivco = ifo->vivco;
199 			    i < ifo->vivco_len;
200 			    i++, vivco++)
201 			{
202 				u16 = htons((uint16_t)vivco->len);
203 				memcpy(p, &u16, sizeof(u16));
204 				p += sizeof(u16);
205 				memcpy(p, vivco->data, vivco->len);
206 				p += vivco->len;
207 			}
208 		} else if (vlen) {
209 			u16 = htons((uint16_t)vlen);
210 			memcpy(p, &u16, sizeof(u16));
211 			p += sizeof(u16);
212 			memcpy(p, vendor, (size_t)vlen);
213 		}
214 	}
215 
216 	return len;
217 }
218 
219 static const struct dhcp6_option *
dhcp6_findoption(uint16_t code,const uint8_t * d,size_t len)220 dhcp6_findoption(uint16_t code, const uint8_t *d, size_t len)
221 {
222 	const struct dhcp6_option *o;
223 	size_t ol;
224 
225 	code = htons(code);
226 	for (o = (const struct dhcp6_option *)d;
227 	    len >= sizeof(*o);
228 	    o = D6_CNEXT_OPTION(o))
229 	{
230 		ol = sizeof(*o) + ntohs(o->len);
231 		if (ol > len) {
232 			errno = EINVAL;
233 			return NULL;
234 		}
235 		if (o->code == code)
236 			return o;
237 		len -= ol;
238 	}
239 
240 	errno = ESRCH;
241 	return NULL;
242 }
243 
244 static const uint8_t *
dhcp6_getoption(struct dhcpcd_ctx * ctx,size_t * os,unsigned int * code,size_t * len,const uint8_t * od,size_t ol,struct dhcp_opt ** oopt)245 dhcp6_getoption(struct dhcpcd_ctx *ctx,
246     size_t *os, unsigned int *code, size_t *len,
247     const uint8_t *od, size_t ol, struct dhcp_opt **oopt)
248 {
249 	const struct dhcp6_option *o;
250 	size_t i;
251 	struct dhcp_opt *opt;
252 
253 	if (od) {
254 		*os = sizeof(*o);
255 		if (ol < *os) {
256 			errno = EINVAL;
257 			return NULL;
258 		}
259 		o = (const struct dhcp6_option *)od;
260 		*len = ntohs(o->len);
261 		if (*len > ol - *os) {
262 			errno = EINVAL;
263 			return NULL;
264 		}
265 		*code = ntohs(o->code);
266 	} else
267 		o = NULL;
268 
269 	*oopt = NULL;
270 	for (i = 0, opt = ctx->dhcp6_opts;
271 	    i < ctx->dhcp6_opts_len; i++, opt++)
272 	{
273 		if (opt->option == *code) {
274 			*oopt = opt;
275 			break;
276 		}
277 	}
278 
279 	if (o)
280 		return D6_COPTION_DATA(o);
281 	return NULL;
282 }
283 
284 static const struct dhcp6_option *
dhcp6_getmoption(uint16_t code,const struct dhcp6_message * m,size_t len)285 dhcp6_getmoption(uint16_t code, const struct dhcp6_message *m, size_t len)
286 {
287 
288 	if (len < sizeof(*m)) {
289 		errno = EINVAL;
290 		return NULL;
291 	}
292 	len -= sizeof(*m);
293 	return dhcp6_findoption(code,
294 	    (const uint8_t *)D6_CFIRST_OPTION(m), len);
295 }
296 
297 static int
dhcp6_updateelapsed(struct interface * ifp,struct dhcp6_message * m,size_t len)298 dhcp6_updateelapsed(struct interface *ifp, struct dhcp6_message *m, size_t len)
299 {
300 	struct dhcp6_state *state;
301 	const struct dhcp6_option *co;
302 	struct dhcp6_option *o;
303 	time_t up;
304 	uint16_t u16;
305 
306 	co = dhcp6_getmoption(D6_OPTION_ELAPSED, m, len);
307 	if (co == NULL)
308 		return -1;
309 
310 	o = __UNCONST(co);
311 	state = D6_STATE(ifp);
312 	up = uptime() - state->start_uptime;
313 	if (up < 0 || up > (time_t)UINT16_MAX)
314 		up = (time_t)UINT16_MAX;
315 	u16 = htons((uint16_t)up);
316 	memcpy(D6_OPTION_DATA(o), &u16, sizeof(u16));
317 	return 0;
318 }
319 
320 static void
dhcp6_newxid(const struct interface * ifp,struct dhcp6_message * m)321 dhcp6_newxid(const struct interface *ifp, struct dhcp6_message *m)
322 {
323 	uint32_t xid;
324 
325 	if (ifp->options->options & DHCPCD_XID_HWADDR &&
326 	    ifp->hwlen >= sizeof(xid))
327 		/* The lower bits are probably more unique on the network */
328 		memcpy(&xid, (ifp->hwaddr + ifp->hwlen) - sizeof(xid),
329 		    sizeof(xid));
330 	else
331 		xid = arc4random();
332 
333 	m->xid[0] = (xid >> 16) & 0xff;
334 	m->xid[1] = (xid >> 8) & 0xff;
335 	m->xid[2] = xid & 0xff;
336 }
337 
338 static const struct if_sla *
dhcp6_findselfsla(struct interface * ifp,const uint8_t * iaid)339 dhcp6_findselfsla(struct interface *ifp, const uint8_t *iaid)
340 {
341 	size_t i, j;
342 
343 	for (i = 0; i < ifp->options->ia_len; i++) {
344 		if (iaid == NULL ||
345 		    memcmp(&ifp->options->ia[i].iaid, iaid,
346 		    sizeof(ifp->options->ia[i].iaid)) == 0)
347 		{
348 			for (j = 0; j < ifp->options->ia[i].sla_len; j++) {
349 				if (strcmp(ifp->options->ia[i].sla[j].ifname,
350 				    ifp->name) == 0)
351 					return &ifp->options->ia[i].sla[j];
352 			}
353 		}
354 	}
355 	return NULL;
356 }
357 
358 
359 #ifndef ffs32
360 static int
ffs32(uint32_t n)361 ffs32(uint32_t n)
362 {
363 	int v;
364 
365 	if (!n)
366 		return 0;
367 
368 	v = 1;
369 	if ((n & 0x0000FFFFU) == 0) {
370 		n >>= 16;
371 		v += 16;
372 	}
373 	if ((n & 0x000000FFU) == 0) {
374 		n >>= 8;
375 		v += 8;
376 	}
377 	if ((n & 0x0000000FU) == 0) {
378 		n >>= 4;
379 		v += 4;
380 	}
381 	if ((n & 0x00000003U) == 0) {
382 		n >>= 2;
383 		v += 2;
384 	}
385 	if ((n & 0x00000001U) == 0)
386 		v += 1;
387 
388 	return v;
389 }
390 #endif
391 
392 static int
dhcp6_delegateaddr(struct in6_addr * addr,struct interface * ifp,const struct ipv6_addr * prefix,const struct if_sla * sla,struct if_ia * ia)393 dhcp6_delegateaddr(struct in6_addr *addr, struct interface *ifp,
394     const struct ipv6_addr *prefix, const struct if_sla *sla, struct if_ia *ia)
395 {
396 	struct dhcp6_state *state;
397 	struct if_sla asla;
398 	char sabuf[INET6_ADDRSTRLEN];
399 	const char *sa;
400 
401 	state = D6_STATE(ifp);
402 	if (state == NULL) {
403 		ifp->if_data[IF_DATA_DHCP6] = calloc(1, sizeof(*state));
404 		state = D6_STATE(ifp);
405 		if (state == NULL) {
406 			logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
407 			return -1;
408 		}
409 
410 		TAILQ_INIT(&state->addrs);
411 		state->state = DH6S_DELEGATED;
412 		state->reason = "DELEGATED6";
413 	}
414 
415 	if (sla == NULL || sla->sla_set == 0) {
416 		asla.sla = ifp->index;
417 		asla.prefix_len = 0;
418 		sla = &asla;
419 	} else if (sla->prefix_len == 0) {
420 		asla.sla = sla->sla;
421 		if (asla.sla == 0)
422 			asla.prefix_len = prefix->prefix_len;
423 		else
424 			asla.prefix_len = 0;
425 		sla = &asla;
426 	}
427 	if (sla->prefix_len == 0) {
428 		uint32_t sla_max;
429 		int bits;
430 
431 		if (ia->sla_max == 0) {
432 			const struct interface *ifi;
433 
434 			sla_max = 0;
435 			TAILQ_FOREACH(ifi, ifp->ctx->ifaces, next) {
436 				if (ifi != ifp && ifi->index > sla_max)
437 					sla_max = ifi->index;
438 			}
439 		} else
440 			sla_max = ia->sla_max;
441 
442 		bits = ffs32(sla_max);
443 
444 		if (prefix->prefix_len + bits > UINT8_MAX)
445 			asla.prefix_len = UINT8_MAX;
446 		else {
447 			asla.prefix_len = (uint8_t)(prefix->prefix_len + bits);
448 
449 			/* Make a 64 prefix by default, as this maks SLAAC
450 			 * possible. Otherwise round up to the nearest octet. */
451 			if (asla.prefix_len <= 64)
452 				asla.prefix_len = 64;
453 			else
454 				asla.prefix_len = (uint8_t)ROUNDUP8(asla.prefix_len);
455 
456 		}
457 
458 #define BIT(n) (1l << (n))
459 #define BIT_MASK(len) (BIT(len) - 1)
460 		if (ia->sla_max == 0)
461 			/* Work out the real sla_max from our bits used */
462 			ia->sla_max = (uint32_t)BIT_MASK(asla.prefix_len -
463 			    prefix->prefix_len);
464 	}
465 
466 	if (ipv6_userprefix(&prefix->prefix, prefix->prefix_len,
467 		sla->sla, addr, sla->prefix_len) == -1)
468 	{
469 		sa = inet_ntop(AF_INET6, &prefix->prefix,
470 		    sabuf, sizeof(sabuf));
471 		logger(ifp->ctx, LOG_ERR,
472 		    "%s: invalid prefix %s/%d + %d/%d: %m",
473 		    ifp->name, sa, prefix->prefix_len,
474 		    sla->sla, sla->prefix_len);
475 		return -1;
476 	}
477 
478 	if (prefix->prefix_exclude_len &&
479 	    IN6_ARE_ADDR_EQUAL(addr, &prefix->prefix_exclude))
480 	{
481 		sa = inet_ntop(AF_INET6, &prefix->prefix_exclude,
482 		    sabuf, sizeof(sabuf));
483 		logger(ifp->ctx, LOG_ERR,
484 		    "%s: cannot delegate excluded prefix %s/%d",
485 		    ifp->name, sa, prefix->prefix_exclude_len);
486 		return -1;
487 	}
488 
489 	return sla->prefix_len;
490 }
491 
492 int
dhcp6_has_public_addr(const struct interface * ifp)493 dhcp6_has_public_addr(const struct interface *ifp)
494 {
495 	const struct dhcp6_state *state = D6_CSTATE(ifp);
496 	const struct ipv6_addr *ia;
497 
498 	if (state == NULL)
499 		return 0;
500 	TAILQ_FOREACH(ia, &state->addrs, next) {
501 		if (ipv6_publicaddr(ia))
502 			return 1;
503 	}
504 	return 0;
505 }
506 
507 static int
dhcp6_makemessage(struct interface * ifp)508 dhcp6_makemessage(struct interface *ifp)
509 {
510 	struct dhcp6_state *state;
511 	struct dhcp6_message *m;
512 	struct dhcp6_option *o, *so, *eo;
513 	const struct dhcp6_option *si, *unicast;
514 	size_t l, n, len, ml;
515 	uint8_t u8, type;
516 	uint16_t u16, n_options, auth_len;
517 	struct if_options *ifo;
518 	const struct dhcp_opt *opt, *opt2;
519 	uint8_t IA, *p;
520 	const uint8_t *pp;
521 	uint32_t u32;
522 	const struct ipv6_addr *ap;
523 	char hbuf[HOSTNAME_MAX_LEN + 1];
524 	const char *hostname;
525 	int fqdn;
526 	struct dhcp6_ia_addr *iap;
527 	struct dhcp6_pd_addr *pdp;
528 
529 	state = D6_STATE(ifp);
530 	if (state->send) {
531 		free(state->send);
532 		state->send = NULL;
533 	}
534 
535 	ifo = ifp->options;
536 	fqdn = ifo->fqdn;
537 
538 	if (fqdn == FQDN_DISABLE && ifo->options & DHCPCD_HOSTNAME) {
539 		/* We're sending the DHCPv4 hostname option, so send FQDN as
540 		 * DHCPv6 has no FQDN option and DHCPv4 must not send
541 		 * hostname and FQDN according to RFC4702 */
542 		fqdn = FQDN_BOTH;
543 	}
544 	if (fqdn != FQDN_DISABLE) {
545 		if (ifo->hostname[0] == '\0')
546 			hostname = get_hostname(hbuf, sizeof(hbuf),
547 			    ifo->options & DHCPCD_HOSTNAME_SHORT ? 1 : 0);
548 		else
549 			hostname = ifo->hostname;
550 	} else
551 		hostname = NULL; /* appearse gcc */
552 
553 	/* Work out option size first */
554 	n_options = 0;
555 	len = 0;
556 	si = NULL;
557 	if (state->state != DH6S_RELEASE) {
558 		for (l = 0, opt = ifp->ctx->dhcp6_opts;
559 		    l < ifp->ctx->dhcp6_opts_len;
560 		    l++, opt++)
561 		{
562 			for (n = 0, opt2 = ifo->dhcp6_override;
563 			    n < ifo->dhcp6_override_len;
564 			    n++, opt2++)
565 			{
566 				if (opt->option == opt2->option)
567 					break;
568 			}
569 			if (n < ifo->dhcp6_override_len)
570 			    continue;
571 			if (!(opt->type & NOREQ) &&
572 			    (opt->type & REQUEST ||
573 			    has_option_mask(ifo->requestmask6, opt->option)))
574 			{
575 				n_options++;
576 				len += sizeof(u16);
577 			}
578 		}
579 		for (l = 0, opt = ifo->dhcp6_override;
580 		    l < ifo->dhcp6_override_len;
581 		    l++, opt++)
582 		{
583 			if (!(opt->type & NOREQ) &&
584 			    (opt->type & REQUEST ||
585 			    has_option_mask(ifo->requestmask6, opt->option)))
586 			{
587 				n_options++;
588 				len += sizeof(u16);
589 			}
590 		}
591 		if (dhcp6_findselfsla(ifp, NULL)) {
592 			n_options++;
593 			len += sizeof(u16);
594 		}
595 		if (len)
596 			len += sizeof(*o);
597 
598 		if (fqdn != FQDN_DISABLE)
599 			len += sizeof(*o) + 1 + encode_rfc1035(hostname, NULL);
600 
601 		if ((ifo->auth.options & DHCPCD_AUTH_SENDREQUIRE) !=
602 		    DHCPCD_AUTH_SENDREQUIRE)
603 			len += sizeof(*o); /* Reconfigure Accept */
604 	}
605 
606 	len += sizeof(*state->send);
607 	len += sizeof(*o) + ifp->ctx->duid_len;
608 	len += sizeof(*o) + sizeof(uint16_t); /* elapsed */
609 	len += sizeof(*o) + dhcp6_makevendor(NULL, ifp);
610 
611 	/* IA */
612 	m = NULL;
613 	ml = 0;
614 	switch(state->state) {
615 	case DH6S_REQUEST:
616 		m = state->recv;
617 		ml = state->recv_len;
618 		/* FALLTHROUGH */
619 	case DH6S_RELEASE:
620 		/* FALLTHROUGH */
621 	case DH6S_RENEW:
622 		if (m == NULL) {
623 			m = state->new;
624 			ml = state->new_len;
625 		}
626 		si = dhcp6_getmoption(D6_OPTION_SERVERID, m, ml);
627 		if (si == NULL) {
628 			errno = ESRCH;
629 			return -1;
630 		}
631 		len += sizeof(*si) + ntohs(si->len);
632 		/* FALLTHROUGH */
633 	case DH6S_REBIND:
634 		/* FALLTHROUGH */
635 	case DH6S_CONFIRM:
636 		/* FALLTHROUGH */
637 	case DH6S_DISCOVER:
638 		if (m == NULL) {
639 			m = state->new;
640 			ml = state->new_len;
641 		}
642 		TAILQ_FOREACH(ap, &state->addrs, next) {
643 			if (ap->prefix_vltime == 0 &&
644 			    !(ap->flags & IPV6_AF_REQUEST))
645 				continue;
646 			if (ap->ia_type == D6_OPTION_IA_PD) {
647 				if (!(ifo->options & DHCPCD_NOPFXDLG)) {
648 					len += sizeof(*o) + sizeof(u8) +
649 					    sizeof(u32) + sizeof(u32) +
650 					    sizeof(ap->prefix);
651 					if (ap->prefix_exclude_len)
652 						len += sizeof(*o) + 1 +
653 						    (uint8_t)((ap->prefix_exclude_len -
654 						    ap->prefix_len - 1) / NBBY)
655 						    + 1;
656 
657 				}
658 			} else if (!(ifo->options & DHCPCD_PFXDLGONLY))
659 				len += sizeof(*o) + sizeof(ap->addr) +
660 				    sizeof(u32) + sizeof(u32);
661 		}
662 		/* FALLTHROUGH */
663 	case DH6S_INIT:
664 		for (l = 0; l < ifo->ia_len; l++) {
665 			if (ifo->ia[l].ia_type == D6_OPTION_IA_PD) {
666 				if (ifo->options & DHCPCD_NOPFXDLG)
667 					continue;
668 			} else if (ifo->options & DHCPCD_PFXDLGONLY)
669 				continue;
670 			len += sizeof(*o) + (sizeof(u32) * 3);
671 		}
672 		IA = 1;
673 		break;
674 	default:
675 		IA = 0;
676 	}
677 
678 	if (state->state == DH6S_DISCOVER &&
679 	    !(ifp->ctx->options & DHCPCD_TEST) &&
680 	    has_option_mask(ifo->requestmask6, D6_OPTION_RAPID_COMMIT))
681 		len += sizeof(*o);
682 
683 	if (m == NULL) {
684 		m = state->new;
685 		ml = state->new_len;
686 	}
687 	unicast = NULL;
688 	/* Depending on state, get the unicast address */
689 	switch(state->state) {
690 		break;
691 	case DH6S_INIT: /* FALLTHROUGH */
692 	case DH6S_DISCOVER:
693 		type = DHCP6_SOLICIT;
694 		break;
695 	case DH6S_REQUEST:
696 		type = DHCP6_REQUEST;
697 		unicast = dhcp6_getmoption(D6_OPTION_UNICAST, m, ml);
698 		break;
699 	case DH6S_CONFIRM:
700 		type = DHCP6_CONFIRM;
701 		break;
702 	case DH6S_REBIND:
703 		type = DHCP6_REBIND;
704 		break;
705 	case DH6S_RENEW:
706 		type = DHCP6_RENEW;
707 		unicast = dhcp6_getmoption(D6_OPTION_UNICAST, m, ml);
708 		break;
709 	case DH6S_INFORM:
710 		type = DHCP6_INFORMATION_REQ;
711 		break;
712 	case DH6S_RELEASE:
713 		type = DHCP6_RELEASE;
714 		unicast = dhcp6_getmoption(D6_OPTION_UNICAST, m, ml);
715 		break;
716 	default:
717 		errno = EINVAL;
718 		return -1;
719 	}
720 
721 	auth_len = 0;
722 	if (ifo->auth.options & DHCPCD_AUTH_SEND) {
723 		ssize_t alen = dhcp_auth_encode(&ifo->auth,
724 		    state->auth.token, NULL, 0, 6, type, NULL, 0);
725 		if (alen != -1 && alen > UINT16_MAX) {
726 			errno = ERANGE;
727 			alen = -1;
728 		}
729 		if (alen == -1)
730 			logger(ifp->ctx, LOG_ERR,
731 			    "%s: dhcp_auth_encode: %m", ifp->name);
732 		else if (alen != 0) {
733 			auth_len = (uint16_t)alen;
734 			len += sizeof(*o) + auth_len;
735 		}
736 	}
737 
738 	state->send = malloc(len);
739 	if (state->send == NULL)
740 		return -1;
741 
742 	state->send_len = len;
743 	state->send->type = type;
744 
745 	/* If we found a unicast option, copy it to our state for sending */
746 	if (unicast && ntohs(unicast->len) == sizeof(state->unicast))
747 		memcpy(&state->unicast, D6_COPTION_DATA(unicast),
748 		    sizeof(state->unicast));
749 	else
750 		state->unicast = in6addr_any;
751 
752 	dhcp6_newxid(ifp, state->send);
753 
754 	o = D6_FIRST_OPTION(state->send);
755 	o->code = htons(D6_OPTION_CLIENTID);
756 	o->len = htons((uint16_t)ifp->ctx->duid_len);
757 	memcpy(D6_OPTION_DATA(o), ifp->ctx->duid, ifp->ctx->duid_len);
758 
759 	if (si) {
760 		o = D6_NEXT_OPTION(o);
761 		memcpy(o, si, sizeof(*si) + ntohs(si->len));
762 	}
763 
764 	o = D6_NEXT_OPTION(o);
765 	o->code = htons(D6_OPTION_ELAPSED);
766 	o->len = htons(sizeof(uint16_t));
767 	p = D6_OPTION_DATA(o);
768 	memset(p, 0, sizeof(uint16_t));
769 
770 	o = D6_NEXT_OPTION(o);
771 	dhcp6_makevendor(o, ifp);
772 
773 	if (state->state == DH6S_DISCOVER &&
774 	    !(ifp->ctx->options & DHCPCD_TEST) &&
775 	    has_option_mask(ifo->requestmask6, D6_OPTION_RAPID_COMMIT))
776 	{
777 		o = D6_NEXT_OPTION(o);
778 		o->code = htons(D6_OPTION_RAPID_COMMIT);
779 		o->len = 0;
780 	}
781 
782 	for (l = 0; IA && l < ifo->ia_len; l++) {
783 		if (ifo->ia[l].ia_type == D6_OPTION_IA_PD) {
784 			if (ifo->options & DHCPCD_NOPFXDLG)
785 				continue;
786 		} else if (ifo->options & DHCPCD_PFXDLGONLY)
787 			continue;
788 		o = D6_NEXT_OPTION(o);
789 		o->code = htons(ifo->ia[l].ia_type);
790 		o->len = htons(sizeof(u32) + sizeof(u32) + sizeof(u32));
791 		p = D6_OPTION_DATA(o);
792 		memcpy(p, ifo->ia[l].iaid, sizeof(u32));
793 		p += sizeof(u32);
794 		memset(p, 0, sizeof(u32) + sizeof(u32));
795 		TAILQ_FOREACH(ap, &state->addrs, next) {
796 			if (ap->prefix_vltime == 0 &&
797 			    !(ap->flags & IPV6_AF_REQUEST))
798 				continue;
799 			if (memcmp(ifo->ia[l].iaid, ap->iaid, sizeof(u32)))
800 				continue;
801 			so = D6_NEXT_OPTION(o);
802 			if (ap->ia_type == D6_OPTION_IA_PD) {
803 				so->code = htons(D6_OPTION_IAPREFIX);
804 				so->len = htons(sizeof(ap->prefix) +
805 				    sizeof(u32) + sizeof(u32) + sizeof(u8));
806 				pdp = (struct dhcp6_pd_addr *)
807 				    D6_OPTION_DATA(so);
808 				pdp->pltime = htonl(ap->prefix_pltime);
809 				pdp->vltime = htonl(ap->prefix_vltime);
810 				pdp->prefix_len = ap->prefix_len;
811 				pdp->prefix = ap->prefix;
812 
813 				/* RFC6603 Section 4.2 */
814 				if (ap->prefix_exclude_len) {
815 					n = (size_t)((ap->prefix_exclude_len -
816 					    ap->prefix_len - 1) / NBBY) + 1;
817 					eo = D6_NEXT_OPTION(so);
818 					eo->code = htons(D6_OPTION_PD_EXCLUDE);
819 					eo->len = (uint16_t)(n + 1);
820 					p = D6_OPTION_DATA(eo);
821 					*p++ = (uint8_t)ap->prefix_exclude_len;
822 					pp = ap->prefix_exclude.s6_addr;
823 					pp += (size_t)((ap->prefix_len - 1) / NBBY)
824 					    + (n - 1);
825 					u8 = ap->prefix_len % NBBY;
826 					if (u8)
827 						n--;
828 					while (n-- > 0)
829 						*p++ = *pp--;
830 					if (u8)
831 						*p = (uint8_t)(*pp << u8);
832 					u16 = (uint16_t)(ntohs(so->len) +
833 					    sizeof(*eo) + eo->len);
834 					so->len = htons(u16);
835 					eo->len = htons(eo->len);
836 				}
837 
838 				u16 = (uint16_t)(ntohs(o->len) + sizeof(*so)
839 				    + ntohs(so->len));
840 				o->len = htons(u16);
841 			} else {
842 				so->code = htons(D6_OPTION_IA_ADDR);
843 				so->len = sizeof(ap->addr) +
844 				    sizeof(u32) + sizeof(u32);
845 				iap = (struct dhcp6_ia_addr *)
846 				    D6_OPTION_DATA(so);
847 				iap->addr = ap->addr;
848 				iap->pltime = htonl(ap->prefix_pltime);
849 				iap->vltime = htonl(ap->prefix_vltime);
850 				u16 = (uint16_t)(ntohs(o->len) + sizeof(*so)
851 				    + so->len);
852 				so->len = htons(so->len);
853 				o->len = htons(u16);
854 			}
855 		}
856 	}
857 
858 	if (state->send->type != DHCP6_RELEASE) {
859 		if (fqdn != FQDN_DISABLE) {
860 			o = D6_NEXT_OPTION(o);
861 			o->code = htons(D6_OPTION_FQDN);
862 			p = D6_OPTION_DATA(o);
863 			switch (fqdn) {
864 			case FQDN_BOTH:
865 				*p = D6_FQDN_BOTH;
866 				break;
867 			case FQDN_PTR:
868 				*p = D6_FQDN_PTR;
869 				break;
870 			default:
871 				*p = D6_FQDN_NONE;
872 				break;
873 			}
874 			l = encode_rfc1035(hostname, p + 1);
875 			if (l == 0)
876 				*p = D6_FQDN_NONE;
877 			o->len = htons((uint16_t)(l + 1));
878 		}
879 
880 		if ((ifo->auth.options & DHCPCD_AUTH_SENDREQUIRE) !=
881 		    DHCPCD_AUTH_SENDREQUIRE)
882 		{
883 			o = D6_NEXT_OPTION(o);
884 			o->code = htons(D6_OPTION_RECONF_ACCEPT);
885 			o->len = 0;
886 		}
887 
888 		if (n_options) {
889 			o = D6_NEXT_OPTION(o);
890 			o->code = htons(D6_OPTION_ORO);
891 			o->len = 0;
892 			p = D6_OPTION_DATA(o);
893 			for (l = 0, opt = ifp->ctx->dhcp6_opts;
894 			    l < ifp->ctx->dhcp6_opts_len;
895 			    l++, opt++)
896 			{
897 				for (n = 0, opt2 = ifo->dhcp6_override;
898 				    n < ifo->dhcp6_override_len;
899 				    n++, opt2++)
900 				{
901 					if (opt->option == opt2->option)
902 						break;
903 				}
904 				if (n < ifo->dhcp6_override_len)
905 				    continue;
906 				if (!(opt->type & NOREQ) &&
907 				    (opt->type & REQUEST ||
908 				    has_option_mask(ifo->requestmask6,
909 				        opt->option)))
910 				{
911 					u16 = htons((uint16_t)opt->option);
912 					memcpy(p, &u16, sizeof(u16));
913 					p += sizeof(u16);
914 					o->len = (uint16_t)(o->len + sizeof(u16));
915 				}
916 			}
917 			for (l = 0, opt = ifo->dhcp6_override;
918 			    l < ifo->dhcp6_override_len;
919 			    l++, opt++)
920 			{
921 				if (!(opt->type & NOREQ) &&
922 				    (opt->type & REQUEST ||
923 				    has_option_mask(ifo->requestmask6,
924 				        opt->option)))
925 				{
926 					u16 = htons((uint16_t)opt->option);
927 					memcpy(p, &u16, sizeof(u16));
928 					p += sizeof(u16);
929 					o->len = (uint16_t)(o->len + sizeof(u16));
930 				}
931 			}
932 			if (dhcp6_findselfsla(ifp, NULL)) {
933 				u16 = htons(D6_OPTION_PD_EXCLUDE);
934 				memcpy(p, &u16, sizeof(u16));
935 				o->len = (uint16_t)(o->len + sizeof(u16));
936 			}
937 			o->len = htons(o->len);
938 		}
939 	}
940 
941 	/* This has to be the last option */
942 	if (ifo->auth.options & DHCPCD_AUTH_SEND && auth_len != 0) {
943 		o = D6_NEXT_OPTION(o);
944 		o->code = htons(D6_OPTION_AUTH);
945 		o->len = htons((uint16_t)auth_len);
946 		/* data will be filled at send message time */
947 	}
948 
949 	return 0;
950 }
951 
952 static const char *
dhcp6_get_op(uint16_t type)953 dhcp6_get_op(uint16_t type)
954 {
955 	const struct dhcp6_op *d;
956 
957 	for (d = dhcp6_ops; d->name; d++)
958 		if (d->type == type)
959 			return d->name;
960 	return NULL;
961 }
962 
963 static void
dhcp6_freedrop_addrs(struct interface * ifp,int drop,const struct interface * ifd)964 dhcp6_freedrop_addrs(struct interface *ifp, int drop,
965     const struct interface *ifd)
966 {
967 	struct dhcp6_state *state;
968 
969 	state = D6_STATE(ifp);
970 	if (state) {
971 		ipv6_freedrop_addrs(&state->addrs, drop, ifd);
972 		if (drop)
973 			ipv6_buildroutes(ifp->ctx);
974 	}
975 }
976 
dhcp6_delete_delegates(struct interface * ifp)977 static void dhcp6_delete_delegates(struct interface *ifp)
978 {
979 	struct interface *ifp0;
980 
981 	if (ifp->ctx->ifaces) {
982 		TAILQ_FOREACH(ifp0, ifp->ctx->ifaces, next) {
983 			if (ifp0 != ifp)
984 				dhcp6_freedrop_addrs(ifp0, 1, ifp);
985 		}
986 	}
987 }
988 
989 static ssize_t
dhcp6_update_auth(struct interface * ifp,struct dhcp6_message * m,size_t len)990 dhcp6_update_auth(struct interface *ifp, struct dhcp6_message *m, size_t len)
991 {
992 	struct dhcp6_state *state;
993 	const struct dhcp6_option *co;
994 	struct dhcp6_option *o;
995 
996 	co = dhcp6_getmoption(D6_OPTION_AUTH, m, len);
997 	if (co == NULL)
998 		return -1;
999 
1000 	o = __UNCONST(co);
1001 	state = D6_STATE(ifp);
1002 
1003 	return dhcp_auth_encode(&ifp->options->auth, state->auth.token,
1004 	    (uint8_t *)state->send, state->send_len,
1005 	    6, state->send->type,
1006 	    D6_OPTION_DATA(o), ntohs(o->len));
1007 }
1008 
1009 static int
dhcp6_sendmessage(struct interface * ifp,void (* callback)(void *))1010 dhcp6_sendmessage(struct interface *ifp, void (*callback)(void *))
1011 {
1012 	struct dhcp6_state *state;
1013 	struct ipv6_ctx *ctx;
1014 	struct sockaddr_in6 dst;
1015 	struct cmsghdr *cm;
1016 	struct in6_pktinfo pi;
1017 	struct timespec RTprev;
1018 	double rnd;
1019 	time_t ms;
1020 	uint8_t neg;
1021 	const char *broad_uni;
1022 	const struct in6_addr alldhcp = IN6ADDR_LINKLOCAL_ALLDHCP_INIT;
1023 
1024 	memset(&dst, 0, sizeof(dst));
1025 	dst.sin6_family = AF_INET6;
1026 	dst.sin6_port = htons(DHCP6_SERVER_PORT);
1027 #ifdef SIN6_LEN
1028 	dst.sin6_len = sizeof(dst);
1029 #endif
1030 
1031 	state = D6_STATE(ifp);
1032 	/* We need to ensure we have sufficient scope to unicast the address */
1033 	/* XXX FIXME: We should check any added addresses we have like from
1034 	 * a Router Advertisement */
1035 	if (IN6_IS_ADDR_UNSPECIFIED(&state->unicast) ||
1036 	    (state->state == DH6S_REQUEST &&
1037 	    (!IN6_IS_ADDR_LINKLOCAL(&state->unicast) || !ipv6_linklocal(ifp))))
1038 	{
1039 		dst.sin6_addr = alldhcp;
1040 		broad_uni = "broadcasting";
1041 	} else {
1042 		dst.sin6_addr = state->unicast;
1043 		broad_uni = "unicasting";
1044 	}
1045 
1046 	if (!callback)
1047 		logger(ifp->ctx, LOG_DEBUG,
1048 		    "%s: %s %s with xid 0x%02x%02x%02x",
1049 		    ifp->name,
1050 		    broad_uni,
1051 		    dhcp6_get_op(state->send->type),
1052 		    state->send->xid[0],
1053 		    state->send->xid[1],
1054 		    state->send->xid[2]);
1055 	else {
1056 		if (state->IMD) {
1057 			/* Some buggy PPP servers close the link too early
1058 			 * after sending an invalid status in their reply
1059 			 * which means this host won't see it.
1060 			 * 1 second grace seems to be the sweet spot. */
1061 			if (ifp->flags & IFF_POINTOPOINT)
1062 				state->RT.tv_sec = 1;
1063 			else
1064 				state->RT.tv_sec = 0;
1065 			state->RT.tv_nsec = (suseconds_t)arc4random_uniform(
1066 			    (uint32_t)(state->IMD * NSEC_PER_SEC));
1067 			timespecnorm(&state->RT);
1068 			broad_uni = "delaying";
1069 			goto logsend;
1070 		}
1071 		if (state->RTC == 0) {
1072 			RTprev.tv_sec = state->IRT;
1073 			RTprev.tv_nsec = 0;
1074 			state->RT.tv_sec = RTprev.tv_sec;
1075 			state->RT.tv_nsec = 0;
1076 		} else {
1077 			RTprev = state->RT;
1078 			timespecadd(&state->RT, &state->RT, &state->RT);
1079 		}
1080 
1081 		rnd = DHCP6_RAND_MIN;
1082 		rnd += (suseconds_t)arc4random_uniform(
1083 		    DHCP6_RAND_MAX - DHCP6_RAND_MIN);
1084 		rnd /= MSEC_PER_SEC;
1085 		neg = (rnd < 0.0);
1086 		if (neg)
1087 			rnd = -rnd;
1088 		ts_to_ms(ms, &RTprev);
1089 		ms = (time_t)((double)ms * rnd);
1090 		ms_to_ts(&RTprev, ms);
1091 		if (neg)
1092 			timespecsub(&state->RT, &RTprev, &state->RT);
1093 		else
1094 			timespecadd(&state->RT, &RTprev, &state->RT);
1095 
1096 		if (state->RT.tv_sec > state->MRT) {
1097 			RTprev.tv_sec = state->MRT;
1098 			RTprev.tv_nsec = 0;
1099 			state->RT.tv_sec = state->MRT;
1100 			state->RT.tv_nsec = 0;
1101 			ts_to_ms(ms, &RTprev);
1102 			ms = (time_t)((double)ms * rnd);
1103 			ms_to_ts(&RTprev, ms);
1104 			if (neg)
1105 				timespecsub(&state->RT, &RTprev, &state->RT);
1106 			else
1107 				timespecadd(&state->RT, &RTprev, &state->RT);
1108 		}
1109 
1110 logsend:
1111 		logger(ifp->ctx, LOG_DEBUG,
1112 		    "%s: %s %s (xid 0x%02x%02x%02x),"
1113 		    " next in %0.1f seconds",
1114 		    ifp->name,
1115 		    broad_uni,
1116 		    dhcp6_get_op(state->send->type),
1117 		    state->send->xid[0],
1118 		    state->send->xid[1],
1119 		    state->send->xid[2],
1120 		    timespec_to_double(&state->RT));
1121 
1122 		/* Wait the initial delay */
1123 		if (state->IMD) {
1124 			state->IMD = 0;
1125 			eloop_timeout_add_tv(ifp->ctx->eloop,
1126 			    &state->RT, callback, ifp);
1127 			return 0;
1128 		}
1129 	}
1130 
1131 	/* Update the elapsed time */
1132 	dhcp6_updateelapsed(ifp, state->send, state->send_len);
1133 	if (ifp->options->auth.options & DHCPCD_AUTH_SEND &&
1134 	    dhcp6_update_auth(ifp, state->send, state->send_len) == -1)
1135 	{
1136 		logger(ifp->ctx, LOG_ERR,
1137 		    "%s: dhcp6_updateauth: %m", ifp->name);
1138 		if (errno != ESRCH)
1139 			return -1;
1140 	}
1141 
1142 	ctx = ifp->ctx->ipv6;
1143 	dst.sin6_scope_id = ifp->index;
1144 	ctx->sndhdr.msg_name = (void *)&dst;
1145 	ctx->sndhdr.msg_iov[0].iov_base = state->send;
1146 	ctx->sndhdr.msg_iov[0].iov_len = state->send_len;
1147 
1148 	/* Set the outbound interface */
1149 	cm = CMSG_FIRSTHDR(&ctx->sndhdr);
1150 	if (cm == NULL) /* unlikely */
1151 		return -1;
1152 	cm->cmsg_level = IPPROTO_IPV6;
1153 	cm->cmsg_type = IPV6_PKTINFO;
1154 	cm->cmsg_len = CMSG_LEN(sizeof(pi));
1155 	memset(&pi, 0, sizeof(pi));
1156 	pi.ipi6_ifindex = ifp->index;
1157 	memcpy(CMSG_DATA(cm), &pi, sizeof(pi));
1158 
1159 	if (sendmsg(ctx->dhcp_fd, &ctx->sndhdr, 0) == -1) {
1160 		logger(ifp->ctx, LOG_ERR,
1161 		    "%s: %s: sendmsg: %m", ifp->name, __func__);
1162 		ifp->options->options &= ~DHCPCD_IPV6;
1163 		dhcp6_drop(ifp, "EXPIRE6");
1164 		return -1;
1165 	}
1166 
1167 	state->RTC++;
1168 	if (callback) {
1169 		if (state->MRC == 0 || state->RTC < state->MRC)
1170 			eloop_timeout_add_tv(ifp->ctx->eloop,
1171 			    &state->RT, callback, ifp);
1172 		else if (state->MRC != 0 && state->MRCcallback)
1173 			eloop_timeout_add_tv(ifp->ctx->eloop,
1174 			    &state->RT, state->MRCcallback, ifp);
1175 		else
1176 			logger(ifp->ctx, LOG_WARNING,
1177 			    "%s: sent %d times with no reply",
1178 			    ifp->name, state->RTC);
1179 	}
1180 	return 0;
1181 }
1182 
1183 static void
dhcp6_sendinform(void * arg)1184 dhcp6_sendinform(void *arg)
1185 {
1186 
1187 	dhcp6_sendmessage(arg, dhcp6_sendinform);
1188 }
1189 
1190 static void
dhcp6_senddiscover(void * arg)1191 dhcp6_senddiscover(void *arg)
1192 {
1193 
1194 	dhcp6_sendmessage(arg, dhcp6_senddiscover);
1195 }
1196 
1197 static void
dhcp6_sendrequest(void * arg)1198 dhcp6_sendrequest(void *arg)
1199 {
1200 
1201 	dhcp6_sendmessage(arg, dhcp6_sendrequest);
1202 }
1203 
1204 static void
dhcp6_sendrebind(void * arg)1205 dhcp6_sendrebind(void *arg)
1206 {
1207 
1208 	dhcp6_sendmessage(arg, dhcp6_sendrebind);
1209 }
1210 
1211 static void
dhcp6_sendrenew(void * arg)1212 dhcp6_sendrenew(void *arg)
1213 {
1214 
1215 	dhcp6_sendmessage(arg, dhcp6_sendrenew);
1216 }
1217 
1218 static void
dhcp6_sendconfirm(void * arg)1219 dhcp6_sendconfirm(void *arg)
1220 {
1221 
1222 	dhcp6_sendmessage(arg, dhcp6_sendconfirm);
1223 }
1224 
1225 /*
1226 static void
1227 dhcp6_sendrelease(void *arg)
1228 {
1229 
1230 	dhcp6_sendmessage(arg, dhcp6_sendrelease);
1231 }
1232 */
1233 
1234 static void
dhcp6_startrenew(void * arg)1235 dhcp6_startrenew(void *arg)
1236 {
1237 	struct interface *ifp;
1238 	struct dhcp6_state *state;
1239 
1240 	ifp = arg;
1241 	state = D6_STATE(ifp);
1242 	state->state = DH6S_RENEW;
1243 	state->start_uptime = uptime();
1244 	state->RTC = 0;
1245 	state->IRT = REN_TIMEOUT;
1246 	state->MRT = REN_MAX_RT;
1247 	state->MRC = 0;
1248 
1249 	if (dhcp6_makemessage(ifp) == -1)
1250 		logger(ifp->ctx, LOG_ERR,
1251 		    "%s: dhcp6_makemessage: %m", ifp->name);
1252 	else
1253 		dhcp6_sendrenew(ifp);
1254 }
1255 
1256 int
dhcp6_dadcompleted(const struct interface * ifp)1257 dhcp6_dadcompleted(const struct interface *ifp)
1258 {
1259 	const struct dhcp6_state *state;
1260 	const struct ipv6_addr *ap;
1261 
1262 	state = D6_CSTATE(ifp);
1263 	TAILQ_FOREACH(ap, &state->addrs, next) {
1264 		if (ap->flags & IPV6_AF_ADDED &&
1265 		    !(ap->flags & IPV6_AF_DADCOMPLETED))
1266 			return 0;
1267 	}
1268 	return 1;
1269 }
1270 
1271 static void
dhcp6_dadcallback(void * arg)1272 dhcp6_dadcallback(void *arg)
1273 {
1274 	struct ipv6_addr *ap = arg;
1275 	struct interface *ifp;
1276 	struct dhcp6_state *state;
1277 	int wascompleted, valid;
1278 
1279 	wascompleted = (ap->flags & IPV6_AF_DADCOMPLETED);
1280 	ap->flags |= IPV6_AF_DADCOMPLETED;
1281 	if (ap->flags & IPV6_AF_DUPLICATED)
1282 		/* XXX FIXME
1283 		 * We should decline the address */
1284 		logger(ap->iface->ctx, LOG_WARNING, "%s: DAD detected %s",
1285 		    ap->iface->name, ap->saddr);
1286 
1287 	if (!wascompleted) {
1288 		ifp = ap->iface;
1289 		state = D6_STATE(ifp);
1290 		if (state->state == DH6S_BOUND ||
1291 		    state->state == DH6S_DELEGATED)
1292 		{
1293 			struct ipv6_addr *ap2;
1294 
1295 			valid = (ap->delegating_iface == NULL);
1296 			TAILQ_FOREACH(ap2, &state->addrs, next) {
1297 				if (ap2->flags & IPV6_AF_ADDED &&
1298 				    !(ap2->flags & IPV6_AF_DADCOMPLETED))
1299 				{
1300 					wascompleted = 1;
1301 					break;
1302 				}
1303 			}
1304 			if (!wascompleted) {
1305 				logger(ap->iface->ctx, LOG_DEBUG,
1306 				    "%s: DHCPv6 DAD completed", ifp->name);
1307 				script_runreason(ifp,
1308 				    ap->delegating_iface ?
1309 				    "DELEGATED6" : state->reason);
1310 				if (valid)
1311 					dhcpcd_daemonise(ifp->ctx);
1312 			}
1313 		}
1314 	}
1315 }
1316 
1317 static void
dhcp6_addrequestedaddrs(struct interface * ifp)1318 dhcp6_addrequestedaddrs(struct interface *ifp)
1319 {
1320 	struct dhcp6_state *state;
1321 	size_t i;
1322 	struct if_ia *ia;
1323 	struct ipv6_addr *a;
1324 	char iabuf[INET6_ADDRSTRLEN];
1325 	const char *iap;
1326 
1327 	state = D6_STATE(ifp);
1328 	/* Add any requested prefixes / addresses */
1329 	for (i = 0; i < ifp->options->ia_len; i++) {
1330 		ia = &ifp->options->ia[i];
1331 		if (!((ia->ia_type == D6_OPTION_IA_PD && ia->prefix_len) ||
1332 		    !IN6_IS_ADDR_UNSPECIFIED(&ia->addr)))
1333 			continue;
1334 		a = calloc(1, sizeof(*a));
1335 		if (a == NULL) {
1336 			logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
1337 			return;
1338 		}
1339 		a->flags = IPV6_AF_REQUEST;
1340 		a->iface = ifp;
1341 		a->dadcallback = dhcp6_dadcallback;
1342 		memcpy(&a->iaid, &ia->iaid, sizeof(a->iaid));
1343 		a->ia_type = ia->ia_type;
1344 		//a->prefix_pltime = 0;
1345 		//a->prefix_vltime = 0;
1346 
1347 		if (ia->ia_type == D6_OPTION_IA_PD) {
1348 			memcpy(&a->prefix, &ia->addr, sizeof(a->addr));
1349 			a->prefix_len = ia->prefix_len;
1350 			iap = inet_ntop(AF_INET6, &a->prefix,
1351 			    iabuf, sizeof(iabuf));
1352 		} else {
1353 			memcpy(&a->addr, &ia->addr, sizeof(a->addr));
1354 			/*
1355 			 * RFC 5942 Section 5
1356 			 * We cannot assume any prefix length, nor tie the
1357 			 * address to an existing one as it could expire
1358 			 * before the address.
1359 			 * As such we just give it a 128 prefix.
1360 			 */
1361 			a->prefix_len = 128;
1362 			ipv6_makeprefix(&a->prefix, &a->addr, a->prefix_len);
1363 			iap = inet_ntop(AF_INET6, &a->addr,
1364 			    iabuf, sizeof(iabuf));
1365 		}
1366 		snprintf(a->saddr, sizeof(a->saddr),
1367 		    "%s/%d", iap, a->prefix_len);
1368 		TAILQ_INSERT_TAIL(&state->addrs, a, next);
1369 	}
1370 }
1371 
1372 static void
dhcp6_startdiscover(void * arg)1373 dhcp6_startdiscover(void *arg)
1374 {
1375 	struct interface *ifp;
1376 	struct dhcp6_state *state;
1377 
1378 	rpc_signal_status("Discover6");
1379 	ifp = arg;
1380 	dhcp6_delete_delegates(ifp);
1381 	logger(ifp->ctx, LOG_INFO, "%s: soliciting a DHCPv6 lease", ifp->name);
1382 	state = D6_STATE(ifp);
1383 	state->state = DH6S_DISCOVER;
1384 	state->start_uptime = uptime();
1385 	state->RTC = 0;
1386 	state->IMD = SOL_MAX_DELAY;
1387 	state->IRT = SOL_TIMEOUT;
1388 	state->MRT = state->sol_max_rt;
1389 	state->MRC = 0;
1390 
1391 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1392 	free(state->new);
1393 	state->new = NULL;
1394 	state->new_len = 0;
1395 
1396 	dhcp6_freedrop_addrs(ifp, 0, NULL);
1397 	unlink(state->leasefile);
1398 
1399 	dhcp6_addrequestedaddrs(ifp);
1400 
1401 	if (dhcp6_makemessage(ifp) == -1)
1402 		logger(ifp->ctx, LOG_ERR,
1403 		    "%s: dhcp6_makemessage: %m", ifp->name);
1404 	else
1405 		dhcp6_senddiscover(ifp);
1406 }
1407 
1408 static void
dhcp6_failconfirm(void * arg)1409 dhcp6_failconfirm(void *arg)
1410 {
1411 	struct interface *ifp;
1412 
1413 	ifp = arg;
1414 	logger(ifp->ctx, LOG_ERR,
1415 	    "%s: failed to confirm prior address", ifp->name);
1416 	/* Section 18.1.2 says that we SHOULD use the last known
1417 	 * IP address(s) and lifetimes if we didn't get a reply.
1418 	 * I disagree with this. */
1419 	dhcp6_startdiscover(ifp);
1420 }
1421 
1422 static void
dhcp6_failrequest(void * arg)1423 dhcp6_failrequest(void *arg)
1424 {
1425 	struct interface *ifp;
1426 
1427 	ifp = arg;
1428 	logger(ifp->ctx, LOG_ERR, "%s: failed to request address", ifp->name);
1429 	/* Section 18.1.1 says that client local policy dictates
1430 	 * what happens if a REQUEST fails.
1431 	 * Of the possible scenarios listed, moving back to the
1432 	 * DISCOVER phase makes more sense for us. */
1433 	dhcp6_startdiscover(ifp);
1434 }
1435 
1436 static void
dhcp6_failrebind(void * arg)1437 dhcp6_failrebind(void *arg)
1438 {
1439 	struct interface *ifp;
1440 
1441 	ifp = arg;
1442 	logger(ifp->ctx, LOG_ERR,
1443 	    "%s: failed to rebind prior delegation", ifp->name);
1444 	dhcp6_delete_delegates(ifp);
1445 	/* Section 18.1.2 says that we SHOULD use the last known
1446 	 * IP address(s) and lifetimes if we didn't get a reply.
1447 	 * I disagree with this. */
1448 	dhcp6_startdiscover(ifp);
1449 }
1450 
1451 
1452 static int
dhcp6_hasprefixdelegation(struct interface * ifp)1453 dhcp6_hasprefixdelegation(struct interface *ifp)
1454 {
1455 	size_t i;
1456 	uint16_t t;
1457 
1458 	if (ifp->options->options & DHCPCD_NOPFXDLG)
1459 		return 0;
1460 
1461 	t = 0;
1462 	for (i = 0; i < ifp->options->ia_len; i++) {
1463 		if (t && t != ifp->options->ia[i].ia_type) {
1464 			if (t == D6_OPTION_IA_PD ||
1465 			    ifp->options->ia[i].ia_type == D6_OPTION_IA_PD)
1466 				return 2;
1467 		}
1468 		t = ifp->options->ia[i].ia_type;
1469 	}
1470 	return t == D6_OPTION_IA_PD ? 1 : 0;
1471 }
1472 
1473 static void
dhcp6_startrebind(void * arg)1474 dhcp6_startrebind(void *arg)
1475 {
1476 	struct interface *ifp;
1477 	struct dhcp6_state *state;
1478 	int pd;
1479 
1480 	rpc_signal_status("Rebind6");
1481 	ifp = arg;
1482 	eloop_timeout_delete(ifp->ctx->eloop, dhcp6_sendrenew, ifp);
1483 	state = D6_STATE(ifp);
1484 	if (state->state == DH6S_RENEW)
1485 		logger(ifp->ctx, LOG_WARNING,
1486 		    "%s: failed to renew DHCPv6, rebinding", ifp->name);
1487 	else
1488 		logger(ifp->ctx, LOG_INFO,
1489 		    "%s: rebinding prior DHCPv6 lease", ifp->name);
1490 	state->state = DH6S_REBIND;
1491 	state->RTC = 0;
1492 	state->MRC = 0;
1493 
1494 	/* RFC 3633 section 12.1 */
1495 	pd = dhcp6_hasprefixdelegation(ifp);
1496 	if (pd) {
1497 		state->IMD = CNF_MAX_DELAY;
1498 		state->IRT = CNF_TIMEOUT;
1499 		state->MRT = CNF_MAX_RT;
1500 	} else {
1501 		state->IRT = REB_TIMEOUT;
1502 		state->MRT = REB_MAX_RT;
1503 	}
1504 
1505 	if (dhcp6_makemessage(ifp) == -1)
1506 		logger(ifp->ctx, LOG_ERR,
1507 		    "%s: dhcp6_makemessage: %m", ifp->name);
1508 	else
1509 		dhcp6_sendrebind(ifp);
1510 
1511 	/* RFC 3633 section 12.1 */
1512 	if (pd)
1513 		eloop_timeout_add_sec(ifp->ctx->eloop,
1514 		    CNF_MAX_RD, dhcp6_failrebind, ifp);
1515 }
1516 
1517 
1518 static void
dhcp6_startrequest(struct interface * ifp)1519 dhcp6_startrequest(struct interface *ifp)
1520 {
1521 	struct dhcp6_state *state;
1522 
1523 	rpc_signal_status("Request6");
1524 	eloop_timeout_delete(ifp->ctx->eloop, dhcp6_senddiscover, ifp);
1525 	state = D6_STATE(ifp);
1526 	state->state = DH6S_REQUEST;
1527 	state->RTC = 0;
1528 	state->IRT = REQ_TIMEOUT;
1529 	state->MRT = REQ_MAX_RT;
1530 	state->MRC = REQ_MAX_RC;
1531 	state->MRCcallback = dhcp6_failrequest;
1532 
1533 	if (dhcp6_makemessage(ifp) == -1) {
1534 		logger(ifp->ctx, LOG_ERR,
1535 		    "%s: dhcp6_makemessage: %m", ifp->name);
1536 		return;
1537 	}
1538 
1539 	dhcp6_sendrequest(ifp);
1540 }
1541 
1542 static void
dhcp6_startconfirm(struct interface * ifp)1543 dhcp6_startconfirm(struct interface *ifp)
1544 {
1545 	struct dhcp6_state *state;
1546 
1547 	rpc_signal_status("Confirm6");
1548 	state = D6_STATE(ifp);
1549 	state->state = DH6S_CONFIRM;
1550 	state->start_uptime = uptime();
1551 	state->RTC = 0;
1552 	state->IMD = CNF_MAX_DELAY;
1553 	state->IRT = CNF_TIMEOUT;
1554 	state->MRT = CNF_MAX_RT;
1555 	state->MRC = 0;
1556 
1557 	logger(ifp->ctx, LOG_INFO,
1558 	    "%s: confirming prior DHCPv6 lease", ifp->name);
1559 	if (dhcp6_makemessage(ifp) == -1) {
1560 		logger(ifp->ctx, LOG_ERR,
1561 		    "%s: dhcp6_makemessage: %m", ifp->name);
1562 		return;
1563 	}
1564 	dhcp6_sendconfirm(ifp);
1565 	eloop_timeout_add_sec(ifp->ctx->eloop,
1566 	    CNF_MAX_RD, dhcp6_failconfirm, ifp);
1567 }
1568 
1569 static void
dhcp6_startinform(void * arg)1570 dhcp6_startinform(void *arg)
1571 {
1572 	struct interface *ifp;
1573 	struct dhcp6_state *state;
1574 
1575 	rpc_signal_status("Inform6");
1576 	ifp = arg;
1577 	state = D6_STATE(ifp);
1578 	if (state->new == NULL || ifp->options->options & DHCPCD_DEBUG)
1579 		logger(ifp->ctx, LOG_INFO,
1580 		    "%s: requesting DHCPv6 information", ifp->name);
1581 	state->state = DH6S_INFORM;
1582 	state->start_uptime = uptime();
1583 	state->RTC = 0;
1584 	state->IMD = INF_MAX_DELAY;
1585 	state->IRT = INF_TIMEOUT;
1586 	state->MRT = state->inf_max_rt;
1587 	state->MRC = 0;
1588 
1589 	if (dhcp6_makemessage(ifp) == -1)
1590 		logger(ifp->ctx, LOG_ERR,
1591 		    "%s: dhcp6_makemessage: %m", ifp->name);
1592 	else
1593 		dhcp6_sendinform(ifp);
1594 }
1595 
1596 static void
dhcp6_startexpire(void * arg)1597 dhcp6_startexpire(void *arg)
1598 {
1599 	struct interface *ifp;
1600 
1601 	rpc_signal_status("Expire6");
1602 	ifp = arg;
1603 	eloop_timeout_delete(ifp->ctx->eloop, dhcp6_sendrebind, ifp);
1604 
1605 	logger(ifp->ctx, LOG_ERR, "%s: DHCPv6 lease expired", ifp->name);
1606 	dhcp6_freedrop_addrs(ifp, 1, NULL);
1607 	dhcp6_delete_delegates(ifp);
1608 	script_runreason(ifp, "EXPIRE6");
1609 	if (ipv6nd_hasradhcp(ifp) || dhcp6_hasprefixdelegation(ifp))
1610 		dhcp6_startdiscover(ifp);
1611 	else
1612 		logger(ifp->ctx, LOG_WARNING,
1613 		    "%s: no advertising IPv6 router wants DHCP", ifp->name);
1614 }
1615 
1616 static void
dhcp6_startrelease(struct interface * ifp)1617 dhcp6_startrelease(struct interface *ifp)
1618 {
1619 	struct dhcp6_state *state;
1620 
1621 	state = D6_STATE(ifp);
1622 	if (state->state != DH6S_BOUND)
1623 		return;
1624 
1625 	rpc_signal_status("Release6");
1626 	state->state = DH6S_RELEASE;
1627 	state->start_uptime = uptime();
1628 	state->RTC = 0;
1629 	state->IRT = REL_TIMEOUT;
1630 	state->MRT = 0;
1631 	state->MRC = REL_MAX_RC;
1632 	//state->MRCcallback = dhcp6_failrelease;
1633 	state->MRCcallback = NULL;
1634 
1635 	if (dhcp6_makemessage(ifp) == -1)
1636 		logger(ifp->ctx, LOG_ERR,
1637 		    "%s: dhcp6_makemessage: %m", ifp->name);
1638 	else
1639 		/* XXX: We should loop a few times
1640 		 * Luckily RFC3315 section 18.1.6 says this is optional */
1641 		//dhcp6_sendrelease(ifp);
1642 		dhcp6_sendmessage(ifp, NULL);
1643 }
1644 
1645 static int
dhcp6_checkstatusok(const struct interface * ifp,const struct dhcp6_message * m,const uint8_t * p,size_t len)1646 dhcp6_checkstatusok(const struct interface *ifp,
1647     const struct dhcp6_message *m, const uint8_t *p, size_t len)
1648 {
1649 	const struct dhcp6_option *o;
1650 	uint16_t code;
1651 	char *status;
1652 
1653 	if (p)
1654 		o = dhcp6_findoption(D6_OPTION_STATUS_CODE, p, len);
1655 	else
1656 		o = dhcp6_getmoption(D6_OPTION_STATUS_CODE, m, len);
1657 	if (o == NULL) {
1658 		//logger(ifp->ctx, LOG_DEBUG, "%s: no status", ifp->name);
1659 		return 0;
1660 	}
1661 
1662 	len = ntohs(o->len);
1663 	if (len < sizeof(code)) {
1664 		logger(ifp->ctx, LOG_ERR, "%s: status truncated", ifp->name);
1665 		return -1;
1666 	}
1667 
1668 	p = D6_COPTION_DATA(o);
1669 	memcpy(&code, p, sizeof(code));
1670 	code = ntohs(code);
1671 	if (code == D6_STATUS_OK)
1672 		return 1;
1673 
1674 	len -= sizeof(code);
1675 
1676 	if (len == 0) {
1677 		if (code < sizeof(dhcp6_statuses) / sizeof(char *)) {
1678 			p = (const uint8_t *)dhcp6_statuses[code];
1679 			len = strlen((const char *)p);
1680 		} else
1681 			p = NULL;
1682 	} else
1683 		p += sizeof(code);
1684 
1685 	status = malloc(len + 1);
1686 	if (status == NULL) {
1687 		logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
1688 		return -1;
1689 	}
1690 	if (p)
1691 		memcpy(status, p, len);
1692 	status[len] = '\0';
1693 	logger(ifp->ctx, LOG_ERR, "%s: DHCPv6 REPLY: %s", ifp->name, status);
1694 	free(status);
1695 	return -1;
1696 }
1697 
1698 static struct ipv6_addr *
dhcp6_iffindaddr(struct interface * ifp,const struct in6_addr * addr,short flags)1699 dhcp6_iffindaddr(struct interface *ifp, const struct in6_addr *addr,
1700     short flags)
1701 {
1702 	struct dhcp6_state *state;
1703 	struct ipv6_addr *ap;
1704 
1705 	state = D6_STATE(ifp);
1706 	if (state) {
1707 		TAILQ_FOREACH(ap, &state->addrs, next) {
1708 			if (addr == NULL) {
1709 				if ((ap->flags &
1710 				    (IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED)) ==
1711 				    (IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED))
1712 					return ap;
1713 			} else if (ap->prefix_vltime &&
1714 			    IN6_ARE_ADDR_EQUAL(&ap->addr, addr) &&
1715 			    (!flags || ap->flags & flags))
1716 				return ap;
1717 		}
1718 	}
1719 	return NULL;
1720 }
1721 
1722 struct ipv6_addr *
dhcp6_findaddr(struct dhcpcd_ctx * ctx,const struct in6_addr * addr,short flags)1723 dhcp6_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr,
1724     short flags)
1725 {
1726 	struct interface *ifp;
1727 	struct ipv6_addr *ap;
1728 
1729 	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
1730 		ap = dhcp6_iffindaddr(ifp, addr, flags);
1731 		if (ap)
1732 			return ap;
1733 	}
1734 	return NULL;
1735 }
1736 
1737 static int
dhcp6_findna(struct interface * ifp,uint16_t ot,const uint8_t * iaid,const uint8_t * d,size_t l,const struct timespec * acquired)1738 dhcp6_findna(struct interface *ifp, uint16_t ot, const uint8_t *iaid,
1739     const uint8_t *d, size_t l, const struct timespec *acquired)
1740 {
1741 	struct dhcp6_state *state;
1742 	const struct dhcp6_option *o;
1743 	struct ipv6_addr *a;
1744 	char iabuf[INET6_ADDRSTRLEN];
1745 	const char *ia;
1746 	int i;
1747 	uint32_t u32;
1748 	size_t off;
1749 	const struct dhcp6_ia_addr *iap;
1750 
1751 	i = 0;
1752 	state = D6_STATE(ifp);
1753 	while ((o = dhcp6_findoption(D6_OPTION_IA_ADDR, d, l))) {
1754 		off = (size_t)((const uint8_t *)o - d);
1755 		l -= off;
1756 		d += off;
1757 		u32 = ntohs(o->len);
1758 		l -= sizeof(*o) + u32;
1759 		d += sizeof(*o) + u32;
1760 		if (u32 < 24) {
1761 			errno = EINVAL;
1762 			logger(ifp->ctx, LOG_ERR,
1763 			    "%s: IA Address option truncated", ifp->name);
1764 			continue;
1765 		}
1766 		iap = (const struct dhcp6_ia_addr *)D6_COPTION_DATA(o);
1767 		a = dhcp6_iffindaddr(ifp, &iap->addr, 0);
1768 		if (a == NULL) {
1769 			a = calloc(1, sizeof(*a));
1770 			if (a == NULL) {
1771 				logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
1772 				break;
1773 			}
1774 			a->iface = ifp;
1775 			a->flags = IPV6_AF_NEW | IPV6_AF_ONLINK;
1776 			a->dadcallback = dhcp6_dadcallback;
1777 			a->ia_type = ot;
1778 			memcpy(a->iaid, iaid, sizeof(a->iaid));
1779 			a->addr = iap->addr;
1780 			a->created = *acquired;
1781 
1782 			/*
1783 			 * RFC 5942 Section 5
1784 			 * We cannot assume any prefix length, nor tie the
1785 			 * address to an existing one as it could expire
1786 			 * before the address.
1787 			 * As such we just give it a 128 prefix.
1788 			 */
1789 			a->prefix_len = 128;
1790 			ipv6_makeprefix(&a->prefix, &a->addr, a->prefix_len);
1791 			ia = inet_ntop(AF_INET6, &a->addr,
1792 			    iabuf, sizeof(iabuf));
1793 			snprintf(a->saddr, sizeof(a->saddr),
1794 			    "%s/%d", ia, a->prefix_len);
1795 
1796 			TAILQ_INSERT_TAIL(&state->addrs, a, next);
1797 		} else {
1798 			if (!(a->flags & IPV6_AF_ONLINK))
1799 				a->flags |= IPV6_AF_ONLINK | IPV6_AF_NEW;
1800 			a->flags &= ~IPV6_AF_STALE;
1801 		}
1802 		a->acquired = *acquired;
1803 		a->prefix_pltime = ntohl(iap->pltime);
1804 		u32 = ntohl(iap->vltime);
1805 		if (a->prefix_vltime != u32) {
1806 			a->flags |= IPV6_AF_NEW;
1807 			a->prefix_vltime = u32;
1808 		}
1809 		if (a->prefix_pltime && a->prefix_pltime < state->lowpl)
1810 		    state->lowpl = a->prefix_pltime;
1811 		if (a->prefix_vltime && a->prefix_vltime > state->expire)
1812 		    state->expire = a->prefix_vltime;
1813 		i++;
1814 	}
1815 	return i;
1816 }
1817 
1818 static int
dhcp6_findpd(struct interface * ifp,const uint8_t * iaid,const uint8_t * d,size_t l,const struct timespec * acquired)1819 dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
1820     const uint8_t *d, size_t l, const struct timespec *acquired)
1821 {
1822 	struct dhcp6_state *state;
1823 	const struct dhcp6_option *o, *ex;
1824 	const uint8_t *p, *op;
1825 	struct ipv6_addr *a;
1826 	char iabuf[INET6_ADDRSTRLEN];
1827 	const char *ia;
1828 	int i;
1829 	uint8_t u8, *pw;
1830 	size_t off;
1831 	uint16_t ol;
1832 	const struct dhcp6_pd_addr *pdp;
1833 
1834 	i = 0;
1835 	state = D6_STATE(ifp);
1836 	while ((o = dhcp6_findoption(D6_OPTION_IAPREFIX, d, l))) {
1837 		off = (size_t)((const uint8_t *)o - d);
1838 		l -= off;
1839 		d += off;
1840 		ol = ntohs(o->len);
1841 		l -= sizeof(*o) + ol;
1842 		d += sizeof(*o) + ol;
1843 		if (ol < sizeof(*pdp)) {
1844 			errno = EINVAL;
1845 			logger(ifp->ctx, LOG_ERR,
1846 			    "%s: IA Prefix option truncated", ifp->name);
1847 			continue;
1848 		}
1849 
1850 		pdp = (const struct dhcp6_pd_addr *)D6_COPTION_DATA(o);
1851 		TAILQ_FOREACH(a, &state->addrs, next) {
1852 			if (IN6_ARE_ADDR_EQUAL(&a->prefix, &pdp->prefix))
1853 				break;
1854 		}
1855 		if (a == NULL) {
1856 			a = calloc(1, sizeof(*a));
1857 			if (a == NULL) {
1858 				logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
1859 				break;
1860 			}
1861 			a->iface = ifp;
1862 			a->flags = IPV6_AF_NEW | IPV6_AF_DELEGATEDPFX;
1863 			a->created = *acquired;
1864 			a->dadcallback = dhcp6_dadcallback;
1865 			a->ia_type = D6_OPTION_IA_PD;
1866 			memcpy(a->iaid, iaid, sizeof(a->iaid));
1867 			a->prefix = pdp->prefix;
1868 			a->prefix_len = pdp->prefix_len;
1869 			ia = inet_ntop(AF_INET6, &a->prefix,
1870 			    iabuf, sizeof(iabuf));
1871 			snprintf(a->saddr, sizeof(a->saddr),
1872 			    "%s/%d", ia, a->prefix_len);
1873 			TAILQ_INSERT_TAIL(&state->addrs, a, next);
1874 		} else {
1875 			if (!(a->flags & IPV6_AF_DELEGATEDPFX))
1876 				a->flags |= IPV6_AF_NEW | IPV6_AF_DELEGATEDPFX;
1877 			a->flags &= ~(IPV6_AF_STALE | IPV6_AF_REQUEST);
1878 			if (a->prefix_vltime != ntohl(pdp->vltime))
1879 				a->flags |= IPV6_AF_NEW;
1880 		}
1881 
1882 		a->acquired = *acquired;
1883 		a->prefix_pltime = ntohl(pdp->pltime);
1884 		a->prefix_vltime = ntohl(pdp->vltime);
1885 
1886 		if (a->prefix_pltime && a->prefix_pltime < state->lowpl)
1887 			state->lowpl = a->prefix_pltime;
1888 		if (a->prefix_vltime && a->prefix_vltime > state->expire)
1889 			state->expire = a->prefix_vltime;
1890 		i++;
1891 
1892 		p = D6_COPTION_DATA(o) + sizeof(pdp);
1893 		ol = (uint16_t)(ol - sizeof(pdp));
1894 		ex = dhcp6_findoption(D6_OPTION_PD_EXCLUDE, p, ol);
1895 		a->prefix_exclude_len = 0;
1896 		memset(&a->prefix_exclude, 0, sizeof(a->prefix_exclude));
1897 #if 0
1898 		if (ex == NULL) {
1899 			struct dhcp6_option *w;
1900 			uint8_t *wp;
1901 
1902 			w = calloc(1, 128);
1903 			w->len = htons(2);
1904 			wp = D6_OPTION_DATA(w);
1905 			*wp++ = 64;
1906 			*wp++ = 0x78;
1907 			ex = w;
1908 		}
1909 #endif
1910 		if (ex == NULL)
1911 			continue;
1912 		ol = ntohs(ex->len);
1913 		if (ol < 2) {
1914 			logger(ifp->ctx, LOG_ERR,
1915 			    "%s: truncated PD Exclude", ifp->name);
1916 			continue;
1917 		}
1918 		op = D6_COPTION_DATA(ex);
1919 		a->prefix_exclude_len = *op++;
1920 		ol--;
1921 		if (((a->prefix_exclude_len - a->prefix_len - 1) / NBBY) + 1
1922 		    != ol)
1923 		{
1924 			logger(ifp->ctx, LOG_ERR,
1925 			    "%s: PD Exclude length mismatch", ifp->name);
1926 			a->prefix_exclude_len = 0;
1927 			continue;
1928 		}
1929 		u8 = a->prefix_len % NBBY;
1930 		memcpy(&a->prefix_exclude, &a->prefix,
1931 		    sizeof(a->prefix_exclude));
1932 		if (u8)
1933 			ol--;
1934 		pw = a->prefix_exclude.s6_addr +
1935 		    (a->prefix_exclude_len / NBBY) - 1;
1936 		while (ol-- > 0)
1937 			*pw-- = *op++;
1938 		if (u8)
1939 			*pw = (uint8_t)(*pw | (*op >> u8));
1940 	}
1941 	return i;
1942 }
1943 
1944 static int
dhcp6_findia(struct interface * ifp,const struct dhcp6_message * m,size_t l,const char * sfrom,const struct timespec * acquired)1945 dhcp6_findia(struct interface *ifp, const struct dhcp6_message *m, size_t l,
1946     const char *sfrom, const struct timespec *acquired)
1947 {
1948 	struct dhcp6_state *state;
1949 	const struct if_options *ifo;
1950 	const struct dhcp6_option *o;
1951 	const uint8_t *p;
1952 	int i, e;
1953 	size_t j;
1954 	uint32_t u32, renew, rebind;
1955 	uint16_t code, ol;
1956 	uint8_t iaid[4];
1957 	char buf[sizeof(iaid) * 3];
1958 	struct ipv6_addr *ap, *nap;
1959 
1960 	if (l < sizeof(*m)) {
1961 		/* Should be impossible with guards at packet in
1962 		 * and reading leases */
1963 		errno = EINVAL;
1964 		return -1;
1965 	}
1966 
1967 	ifo = ifp->options;
1968 	i = e = 0;
1969 	state = D6_STATE(ifp);
1970 	TAILQ_FOREACH(ap, &state->addrs, next) {
1971 		ap->flags |= IPV6_AF_STALE;
1972 	}
1973 	l -= sizeof(*m);
1974 	for (o = D6_CFIRST_OPTION(m); l > sizeof(*o); o = D6_CNEXT_OPTION(o)) {
1975 		ol = ntohs(o->len);
1976 		if (sizeof(*o) + ol > l) {
1977 			errno = EINVAL;
1978 			logger(ifp->ctx, LOG_ERR,
1979 			    "%s: option overflow", ifp->name);
1980 			break;
1981 		}
1982 		l -= sizeof(*o) + ol;
1983 
1984 		code = ntohs(o->code);
1985 		switch(code) {
1986 		case D6_OPTION_IA_TA:
1987 			u32 = 4;
1988 			break;
1989 		case D6_OPTION_IA_NA:
1990 		case D6_OPTION_IA_PD:
1991 			u32 = 12;
1992 			break;
1993 		default:
1994 			continue;
1995 		}
1996 		if (ol < u32) {
1997 			errno = EINVAL;
1998 			logger(ifp->ctx, LOG_ERR,
1999 			    "%s: IA option truncated", ifp->name);
2000 			continue;
2001 		}
2002 
2003 		p = D6_COPTION_DATA(o);
2004 		memcpy(iaid, p, sizeof(iaid));
2005 		p += sizeof(iaid);
2006 		ol = (uint16_t)(ol - sizeof(iaid));
2007 
2008 		for (j = 0; j < ifo->ia_len; j++) {
2009 			if (memcmp(&ifo->ia[j].iaid, iaid, sizeof(iaid)) == 0)
2010 				break;
2011 		}
2012 		if (j == ifo->ia_len &&
2013 		    !(ifo->ia_len == 0 && ifp->ctx->options & DHCPCD_DUMPLEASE))
2014 		{
2015 			logger(ifp->ctx, LOG_DEBUG,
2016 			    "%s: ignoring unrequested IAID %s",
2017 			    ifp->name,
2018 			    hwaddr_ntoa(iaid, sizeof(iaid), buf, sizeof(buf)));
2019 			continue;
2020 		}
2021 		if ( j < ifo->ia_len && ifo->ia[j].ia_type != code) {
2022 			logger(ifp->ctx, LOG_ERR,
2023 			    "%s: IAID %s: option type mismatch",
2024 			    ifp->name,
2025 			    hwaddr_ntoa(iaid, sizeof(iaid), buf, sizeof(buf)));
2026 			continue;
2027 		}
2028 
2029 		if (code != D6_OPTION_IA_TA) {
2030 			memcpy(&u32, p, sizeof(u32));
2031 			renew = ntohl(u32);
2032 			p += sizeof(u32);
2033 			ol = (uint16_t)(ol - sizeof(u32));
2034 			memcpy(&u32, p, sizeof(u32));
2035 			rebind = ntohl(u32);
2036 			p += sizeof(u32);
2037 			ol = (uint16_t)(ol - sizeof(u32));
2038 		} else
2039 			renew = rebind = 0; /* appease gcc */
2040 		if (dhcp6_checkstatusok(ifp, NULL, p, ol) == -1) {
2041 			e = 1;
2042 			continue;
2043 		}
2044 		if (code == D6_OPTION_IA_PD) {
2045 			if (!(ifo->options & DHCPCD_NOPFXDLG) &&
2046 			    dhcp6_findpd(ifp, iaid, p, ol, acquired) == 0)
2047 			{
2048 				logger(ifp->ctx, LOG_WARNING,
2049 				    "%s: %s: DHCPv6 REPLY missing Prefix",
2050 				    ifp->name, sfrom);
2051 				continue;
2052 			}
2053 		} else if (!(ifo->options & DHCPCD_PFXDLGONLY)) {
2054 			if (dhcp6_findna(ifp, code, iaid, p, ol, acquired) == 0)
2055 			{
2056 				logger(ifp->ctx, LOG_WARNING,
2057 				    "%s: %s: DHCPv6 REPLY missing IA Address",
2058 				    ifp->name, sfrom);
2059 				continue;
2060 			}
2061 		}
2062 		if (code != D6_OPTION_IA_TA) {
2063 			if (renew > rebind && rebind > 0) {
2064 				if (sfrom)
2065 				    logger(ifp->ctx, LOG_WARNING,
2066 					"%s: T1 (%d) > T2 (%d) from %s",
2067 					ifp->name, renew, rebind, sfrom);
2068 				renew = 0;
2069 				rebind = 0;
2070 			}
2071 			if (renew != 0 &&
2072 			    (renew < state->renew || state->renew == 0))
2073 				state->renew = renew;
2074 			if (rebind != 0 &&
2075 			    (rebind < state->rebind || state->rebind == 0))
2076 				state->rebind = rebind;
2077 		}
2078 		i++;
2079 	}
2080 	TAILQ_FOREACH_SAFE(ap, &state->addrs, next, nap) {
2081 		if (ap->flags & IPV6_AF_STALE) {
2082 			eloop_q_timeout_delete(ifp->ctx->eloop, 0, NULL, ap);
2083 			if (ap->flags & IPV6_AF_REQUEST) {
2084 				ap->prefix_vltime = ap->prefix_pltime = 0;
2085 			} else {
2086 				TAILQ_REMOVE(&state->addrs, ap, next);
2087 				free(ap);
2088 			}
2089 		}
2090 	}
2091 	if (i == 0 && e)
2092 		return -1;
2093 	return i;
2094 }
2095 
2096 static int
dhcp6_validatelease(struct interface * ifp,const struct dhcp6_message * m,size_t len,const char * sfrom,const struct timespec * acquired)2097 dhcp6_validatelease(struct interface *ifp,
2098     const struct dhcp6_message *m, size_t len,
2099     const char *sfrom, const struct timespec *acquired)
2100 {
2101 	struct dhcp6_state *state;
2102 	int nia;
2103 	struct timespec aq;
2104 
2105 	if (len <= sizeof(*m)) {
2106 		logger(ifp->ctx, LOG_ERR,
2107 		    "%s: DHCPv6 lease truncated", ifp->name);
2108 		return -1;
2109 	}
2110 
2111 	state = D6_STATE(ifp);
2112 	if (dhcp6_checkstatusok(ifp, m, NULL, len) == -1)
2113 		return -1;
2114 
2115 	state->renew = state->rebind = state->expire = 0;
2116 	state->lowpl = ND6_INFINITE_LIFETIME;
2117 	if (!acquired) {
2118 		get_monotonic(&aq);
2119 		acquired = &aq;
2120 	}
2121 	nia = dhcp6_findia(ifp, m, len, sfrom, acquired);
2122 	if (nia == 0) {
2123 		logger(ifp->ctx, LOG_ERR,
2124 		    "%s: no useable IA found in lease", ifp->name);
2125 		return -1;
2126 	}
2127 	return nia;
2128 }
2129 
2130 static ssize_t
dhcp6_writelease(const struct interface * ifp)2131 dhcp6_writelease(const struct interface *ifp)
2132 {
2133 	const struct dhcp6_state *state;
2134 	int fd;
2135 	ssize_t bytes;
2136 
2137 	state = D6_CSTATE(ifp);
2138 	logger(ifp->ctx, LOG_DEBUG,
2139 	    "%s: writing lease `%s'", ifp->name, state->leasefile);
2140 
2141 	fd = open(state->leasefile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
2142 	if (fd == -1) {
2143 		logger(ifp->ctx, LOG_ERR, "%s: dhcp6_writelease: %m", ifp->name);
2144 		return -1;
2145 	}
2146 	bytes = write(fd, state->new, state->new_len);
2147 	close(fd);
2148 	return bytes;
2149 }
2150 
2151 static int
dhcp6_readlease(struct interface * ifp,int validate)2152 dhcp6_readlease(struct interface *ifp, int validate)
2153 {
2154 	struct dhcp6_state *state;
2155 	struct stat st;
2156 	int fd;
2157 	ssize_t bytes;
2158 	const struct dhcp6_option *o;
2159 	struct timespec acquired;
2160 	time_t now;
2161 	int retval;
2162 
2163 	state = D6_STATE(ifp);
2164 	if (stat(state->leasefile, &st) == -1)
2165 		return -1;
2166 	logger(ifp->ctx, LOG_DEBUG, "%s: reading lease `%s'",
2167 	    ifp->name, state->leasefile);
2168 	if (st.st_size > UINT32_MAX) {
2169 		errno = E2BIG;
2170 		return -1;
2171 	}
2172 	if ((fd = open(state->leasefile, O_RDONLY)) == -1)
2173 		return -1;
2174 	if ((state->new = malloc((size_t)st.st_size)) == NULL)
2175 		return -1;
2176 	retval = -1;
2177 	state->new_len = (size_t)st.st_size;
2178 	bytes = read(fd, state->new, state->new_len);
2179 	close(fd);
2180 	if (bytes != (ssize_t)state->new_len)
2181 		goto ex;
2182 
2183 	/* If not validating IA's and if they have expired,
2184 	 * skip to the auth check. */
2185 	if (!validate) {
2186 		fd = 0;
2187 		goto auth;
2188 	}
2189 
2190 	if ((now = time(NULL)) == -1)
2191 		goto ex;
2192 
2193 	get_monotonic(&acquired);
2194 	acquired.tv_sec -= now - st.st_mtime;
2195 
2196 	/* Check to see if the lease is still valid */
2197 	fd = dhcp6_validatelease(ifp, state->new, state->new_len, NULL,
2198 	    &acquired);
2199 	if (fd == -1)
2200 		goto ex;
2201 
2202 	if (!(ifp->ctx->options & DHCPCD_DUMPLEASE) &&
2203 	    state->expire != ND6_INFINITE_LIFETIME)
2204 	{
2205 		if ((time_t)state->expire < now - st.st_mtime) {
2206 			logger(ifp->ctx,
2207 			    LOG_DEBUG,"%s: discarding expired lease",
2208 			    ifp->name);
2209 			retval = 0;
2210 			goto ex;
2211 		}
2212 	}
2213 
2214 auth:
2215 
2216 	retval = 0;
2217 	/* Authenticate the message */
2218 	o = dhcp6_getmoption(D6_OPTION_AUTH, state->new, state->new_len);
2219 	if (o) {
2220 		if (dhcp_auth_validate(&state->auth, &ifp->options->auth,
2221 		    (uint8_t *)state->new, state->new_len, 6, state->new->type,
2222 		    D6_COPTION_DATA(o), ntohs(o->len)) == NULL)
2223 		{
2224 			logger(ifp->ctx, LOG_DEBUG,
2225 			    "%s: dhcp_auth_validate: %m", ifp->name);
2226 			logger(ifp->ctx, LOG_ERR,
2227 			    "%s: authentication failed", ifp->name);
2228 			goto ex;
2229 		}
2230 		if (state->auth.token)
2231 			logger(ifp->ctx, LOG_DEBUG,
2232 			    "%s: validated using 0x%08" PRIu32,
2233 			    ifp->name, state->auth.token->secretid);
2234 		else
2235 			logger(ifp->ctx, LOG_DEBUG,
2236 			    "%s: accepted reconfigure key", ifp->name);
2237 	} else if (ifp->options->auth.options & DHCPCD_AUTH_REQUIRE) {
2238 		logger(ifp->ctx, LOG_ERR,
2239 		    "%s: authentication now required", ifp->name);
2240 		goto ex;
2241 	}
2242 
2243 	return fd;
2244 
2245 ex:
2246 	dhcp6_freedrop_addrs(ifp, 0, NULL);
2247 	free(state->new);
2248 	state->new = NULL;
2249 	state->new_len = 0;
2250 	if (!(ifp->ctx->options & DHCPCD_DUMPLEASE))
2251 		unlink(state->leasefile);
2252 	return retval;
2253 }
2254 
2255 static void
dhcp6_startinit(struct interface * ifp)2256 dhcp6_startinit(struct interface *ifp)
2257 {
2258 	struct dhcp6_state *state;
2259 	int r;
2260 	uint8_t has_ta, has_non_ta;
2261 	size_t i;
2262 
2263 	state = D6_STATE(ifp);
2264 	state->state = DH6S_INIT;
2265 	state->expire = ND6_INFINITE_LIFETIME;
2266 	state->lowpl = ND6_INFINITE_LIFETIME;
2267 
2268 	dhcp6_addrequestedaddrs(ifp);
2269 	has_ta = has_non_ta = 0;
2270 	for (i = 0; i < ifp->options->ia_len; i++) {
2271 		switch (ifp->options->ia[i].ia_type) {
2272 		case D6_OPTION_IA_TA:
2273 			has_ta = 1;
2274 			break;
2275 		default:
2276 			has_non_ta = 1;
2277 		}
2278 	}
2279 
2280 	if (!(ifp->ctx->options & DHCPCD_TEST) &&
2281 	    !(has_ta && !has_non_ta) &&
2282 	    ifp->options->reboot != 0)
2283 	{
2284 		r = dhcp6_readlease(ifp, 1);
2285 		if (r == -1) {
2286 			if (errno != ENOENT)
2287 				logger(ifp->ctx, LOG_ERR,
2288 				    "%s: dhcp6_readlease: %s: %m",
2289 				    ifp->name, state->leasefile);
2290 		} else if (r != 0) {
2291 			/* RFC 3633 section 12.1 */
2292 			if (dhcp6_hasprefixdelegation(ifp))
2293 				dhcp6_startrebind(ifp);
2294 			else
2295 				dhcp6_startconfirm(ifp);
2296 			return;
2297 		}
2298 	}
2299 	dhcp6_startdiscover(ifp);
2300 }
2301 
2302 static struct ipv6_addr *
dhcp6_ifdelegateaddr(struct interface * ifp,struct ipv6_addr * prefix,const struct if_sla * sla,struct if_ia * ia,struct interface * ifs)2303 dhcp6_ifdelegateaddr(struct interface *ifp, struct ipv6_addr *prefix,
2304     const struct if_sla *sla, struct if_ia *ia, struct interface *ifs)
2305 {
2306 	struct dhcp6_state *state;
2307 	struct in6_addr addr;
2308 	struct ipv6_addr *a, *ap, *apn;
2309 	char sabuf[INET6_ADDRSTRLEN];
2310 	const char *sa;
2311 	int pfxlen;
2312 
2313 	/* RFC6603 Section 4.2 */
2314 	if (strcmp(ifp->name, ifs->name) == 0) {
2315 		if (prefix->prefix_exclude_len == 0) {
2316 			/* Don't spam the log automatically */
2317 			if (sla)
2318 				logger(ifp->ctx, LOG_WARNING,
2319 				    "%s: DHCPv6 server does not support "
2320 				    "OPTION_PD_EXCLUDE",
2321 				    ifp->name);
2322 			return NULL;
2323 		}
2324 		pfxlen = prefix->prefix_exclude_len;
2325 		memcpy(&addr, &prefix->prefix_exclude, sizeof(addr));
2326 	} else if ((pfxlen = dhcp6_delegateaddr(&addr, ifp, prefix,
2327 	    sla, ia)) == -1)
2328 		return NULL;
2329 
2330 
2331 	a = calloc(1, sizeof(*a));
2332 	if (a == NULL) {
2333 		logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
2334 		return NULL;
2335 	}
2336 	a->iface = ifp;
2337 	a->flags = IPV6_AF_NEW | IPV6_AF_ONLINK;
2338 	a->dadcallback = dhcp6_dadcallback;
2339 	a->delegating_iface = ifs;
2340 	memcpy(&a->iaid, &prefix->iaid, sizeof(a->iaid));
2341 	a->created = a->acquired = prefix->acquired;
2342 	a->prefix_pltime = prefix->prefix_pltime;
2343 	a->prefix_vltime = prefix->prefix_vltime;
2344 	a->prefix = addr;
2345 	a->prefix_len = (uint8_t)pfxlen;
2346 
2347 	/* Wang a 1 at the end as the prefix could be >64
2348 	 * making SLAAC impossible. */
2349 	a->addr = a->prefix;
2350 	a->addr.s6_addr[sizeof(a->addr.s6_addr) - 1] =
2351 	    (uint8_t)(a->addr.s6_addr[sizeof(a->addr.s6_addr) - 1] + 1);
2352 
2353 	state = D6_STATE(ifp);
2354 	/* Remove any exiting address */
2355 	TAILQ_FOREACH_SAFE(ap, &state->addrs, next, apn) {
2356 		if (IN6_ARE_ADDR_EQUAL(&ap->addr, &a->addr)) {
2357 			TAILQ_REMOVE(&state->addrs, ap, next);
2358 			/* Keep our flags */
2359 			a->flags |= ap->flags;
2360 			a->flags &= ~IPV6_AF_NEW;
2361 			a->created = ap->created;
2362 			ipv6_freeaddr(ap);
2363 		}
2364 	}
2365 
2366 	sa = inet_ntop(AF_INET6, &a->addr, sabuf, sizeof(sabuf));
2367 	snprintf(a->saddr, sizeof(a->saddr), "%s/%d", sa, a->prefix_len);
2368 	TAILQ_INSERT_TAIL(&state->addrs, a, next);
2369 	return a;
2370 }
2371 
2372 static void
dhcp6_script_try_run(struct interface * ifp,int delegated)2373 dhcp6_script_try_run(struct interface *ifp, int delegated)
2374 {
2375 	struct dhcp6_state *state;
2376 	struct ipv6_addr *ap;
2377 	int completed;
2378 
2379 	state = D6_STATE(ifp);
2380 	completed = 1;
2381 	/* If all addresses have completed DAD run the script */
2382 	TAILQ_FOREACH(ap, &state->addrs, next) {
2383 		if (!(ap->flags & IPV6_AF_ADDED))
2384 			continue;
2385 		if (ap->flags & IPV6_AF_ONLINK) {
2386 			if (!(ap->flags & IPV6_AF_DADCOMPLETED) &&
2387 			    ipv6_iffindaddr(ap->iface, &ap->addr))
2388 				ap->flags |= IPV6_AF_DADCOMPLETED;
2389 			if ((ap->flags & IPV6_AF_DADCOMPLETED) == 0 &&
2390 			    ((delegated && ap->delegating_iface) ||
2391 			    (!delegated && !ap->delegating_iface)))
2392 			{
2393 				completed = 0;
2394 				break;
2395 			}
2396 		}
2397 	}
2398 	if (completed) {
2399 		script_runreason(ifp, delegated ? "DELEGATED6" : state->reason);
2400 		if (!delegated)
2401 			dhcpcd_daemonise(ifp->ctx);
2402 	} else
2403 		logger(ifp->ctx, LOG_DEBUG,
2404 		    "%s: waiting for DHCPv6 DAD to complete", ifp->name);
2405 }
2406 
2407 static void
dhcp6_delegate_prefix(struct interface * ifp)2408 dhcp6_delegate_prefix(struct interface *ifp)
2409 {
2410 	struct if_options *ifo;
2411 	struct dhcp6_state *state, *ifd_state;
2412 	struct ipv6_addr *ap;
2413 	size_t i, j, k;
2414 	struct if_ia *ia;
2415 	struct if_sla *sla;
2416 	struct interface *ifd;
2417 	uint8_t carrier_warned, abrt;
2418 
2419 	ifo = ifp->options;
2420 	state = D6_STATE(ifp);
2421 
2422 	/* Try to load configured interfaces for delegation that do not exist */
2423 	for (i = 0; i < ifo->ia_len; i++) {
2424 		ia = &ifo->ia[i];
2425 		for (j = 0; j < ia->sla_len; j++) {
2426 			sla = &ia->sla[j];
2427 			for (k = 0; k < i; j++)
2428 				if (strcmp(sla->ifname, ia->sla[j].ifname) == 0)
2429 					break;
2430 			if (j >= i &&
2431 			    if_find(ifp->ctx->ifaces, sla->ifname) == NULL)
2432 			{
2433 				logger(ifp->ctx, LOG_INFO,
2434 				    "%s: loading for delegation", sla->ifname);
2435 				if (dhcpcd_handleinterface(ifp->ctx, 2,
2436 				    sla->ifname) == -1)
2437 					logger(ifp->ctx, LOG_ERR,
2438 					    "%s: interface does not exist"
2439 					    " for delegation",
2440 					    sla->ifname);
2441 			}
2442 		}
2443 	}
2444 
2445 	TAILQ_FOREACH(ifd, ifp->ctx->ifaces, next) {
2446 		if (ifd->options->options & DHCPCD_NOPFXDLG)
2447 			continue;
2448 		k = 0;
2449 		carrier_warned = abrt = 0;
2450 		TAILQ_FOREACH(ap, &state->addrs, next) {
2451 			if (!(ap->flags & IPV6_AF_DELEGATEDPFX))
2452 				continue;
2453 			if (ap->flags & IPV6_AF_NEW) {
2454 				ap->flags &= ~IPV6_AF_NEW;
2455 				logger(ifp->ctx, LOG_DEBUG,
2456 				    "%s: delegated prefix %s",
2457 				    ifp->name, ap->saddr);
2458 			}
2459 			for (i = 0; i < ifo->ia_len; i++) {
2460 				ia = &ifo->ia[i];
2461 				if (memcmp(ia->iaid, ap->iaid,
2462 				    sizeof(ia->iaid)))
2463 					continue;
2464 				if (ia->sla_len == 0) {
2465 					/* no SLA configured, so lets
2466 					 * automate it */
2467 					if (ifd->carrier != LINK_UP) {
2468 						logger(ifp->ctx, LOG_DEBUG,
2469 						    "%s: has no carrier, cannot"
2470 						    " delegate addresses",
2471 						    ifd->name);
2472 						carrier_warned = 1;
2473 						break;
2474 					}
2475 					if (dhcp6_ifdelegateaddr(ifd, ap,
2476 					    NULL, ia, ifp))
2477 						k++;
2478 				}
2479 				for (j = 0; j < ia->sla_len; j++) {
2480 					sla = &ia->sla[j];
2481 					if (sla->sla_set && sla->sla == 0)
2482 						ap->flags |=
2483 						    IPV6_AF_DELEGATEDZERO;
2484 					if (strcmp(ifd->name, sla->ifname))
2485 						continue;
2486 					if (ifd->carrier != LINK_UP) {
2487 						logger(ifp->ctx, LOG_DEBUG,
2488 						    "%s: has no carrier, cannot"
2489 						    " delegate addresses",
2490 						    ifd->name);
2491 						carrier_warned = 1;
2492 						break;
2493 					}
2494 					if (dhcp6_ifdelegateaddr(ifd, ap,
2495 					    sla, ia, ifp))
2496 						k++;
2497 				}
2498 				if (carrier_warned ||abrt)
2499 					break;
2500 			}
2501 			if (carrier_warned || abrt)
2502 				break;
2503 		}
2504 		if (k && !carrier_warned) {
2505 			ifd_state = D6_STATE(ifd);
2506 			ipv6_addaddrs(&ifd_state->addrs);
2507 			if_initrt6(ifd);
2508 			dhcp6_script_try_run(ifd, 1);
2509 		}
2510 	}
2511 }
2512 
2513 static void
dhcp6_find_delegates1(void * arg)2514 dhcp6_find_delegates1(void *arg)
2515 {
2516 
2517 	dhcp6_find_delegates(arg);
2518 }
2519 
2520 size_t
dhcp6_find_delegates(struct interface * ifp)2521 dhcp6_find_delegates(struct interface *ifp)
2522 {
2523 	struct if_options *ifo;
2524 	struct dhcp6_state *state;
2525 	struct ipv6_addr *ap;
2526 	size_t i, j, k;
2527 	struct if_ia *ia;
2528 	struct if_sla *sla;
2529 	struct interface *ifd;
2530 
2531 	k = 0;
2532 	TAILQ_FOREACH(ifd, ifp->ctx->ifaces, next) {
2533 		ifo = ifd->options;
2534 		state = D6_STATE(ifd);
2535 		if (state == NULL || state->state != DH6S_BOUND)
2536 			continue;
2537 		TAILQ_FOREACH(ap, &state->addrs, next) {
2538 			if (!(ap->flags & IPV6_AF_DELEGATEDPFX))
2539 				continue;
2540 			for (i = 0; i < ifo->ia_len; i++) {
2541 				ia = &ifo->ia[i];
2542 				if (memcmp(ia->iaid, ap->iaid,
2543 				    sizeof(ia->iaid)))
2544 					continue;
2545 				for (j = 0; j < ia->sla_len; j++) {
2546 					sla = &ia->sla[j];
2547 					if (strcmp(ifp->name, sla->ifname))
2548 						continue;
2549 					if (ipv6_linklocal(ifp) == NULL) {
2550 						logger(ifp->ctx, LOG_DEBUG,
2551 						    "%s: delaying adding"
2552 						    " delegated addresses for"
2553 						    " LL address",
2554 						    ifp->name);
2555 						ipv6_addlinklocalcallback(ifp,
2556 						    dhcp6_find_delegates1, ifp);
2557 						return 1;
2558 					}
2559 					if (dhcp6_ifdelegateaddr(ifp, ap,
2560 					    sla, ia, ifd))
2561 					    k++;
2562 				}
2563 			}
2564 		}
2565 	}
2566 
2567 	if (k) {
2568 		logger(ifp->ctx, LOG_INFO,
2569 		    "%s: adding delegated prefixes", ifp->name);
2570 		state = D6_STATE(ifp);
2571 		state->state = DH6S_DELEGATED;
2572 		ipv6_addaddrs(&state->addrs);
2573 		if_initrt6(ifp);
2574 		ipv6_buildroutes(ifp->ctx);
2575 		dhcp6_script_try_run(ifp, 1);
2576 	}
2577 	return k;
2578 }
2579 
2580 static struct interface *
dhcp6_findpfxdlgif(struct interface * ifp)2581 dhcp6_findpfxdlgif(struct interface *ifp)
2582 {
2583 	struct interface *ifn;
2584 
2585 	if (ifp->options && ifp->options->options & DHCPCD_PFXDLGONLY)
2586 		return NULL;
2587 
2588 	if (ifp->ctx && ifp->ctx->ifaces) {
2589 		TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
2590 			if (strcmp(ifn->name, ifp->name) == 0 &&
2591 			    ifn->options->options & DHCPCD_PFXDLGONLY)
2592 				return ifn;
2593 		}
2594 	}
2595 	return NULL;
2596 }
2597 
2598 /* ARGSUSED */
2599 static void
dhcp6_handledata(void * arg)2600 dhcp6_handledata(void *arg)
2601 {
2602 	struct dhcpcd_ctx *dctx;
2603 	struct ipv6_ctx *ctx;
2604 	size_t i, len;
2605 	ssize_t bytes;
2606 	struct cmsghdr *cm;
2607 	struct in6_pktinfo pkt;
2608 	struct interface *ifp, *ifpx;
2609 	const char *op;
2610 	struct dhcp6_message *r;
2611 	struct dhcp6_state *state;
2612 	const struct dhcp6_option *o, *auth;
2613 	const struct dhcp_opt *opt;
2614 	const struct if_options *ifo;
2615 	struct ipv6_addr *ap;
2616 	uint8_t has_new;
2617 	int error;
2618 	uint32_t u32;
2619 
2620 	dctx = arg;
2621 	ctx = dctx->ipv6;
2622 	ctx->rcvhdr.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
2623 	bytes = recvmsg(ctx->dhcp_fd, &ctx->rcvhdr, 0);
2624 	if (bytes == -1) {
2625 		logger(dctx, LOG_ERR, "%s: recvmsg: %m", __func__);
2626 		close(ctx->dhcp_fd);
2627 		eloop_event_delete(dctx->eloop, ctx->dhcp_fd, 0);
2628 		ctx->dhcp_fd = -1;
2629 		return;
2630 	}
2631 	len = (size_t)bytes;
2632 	ctx->sfrom = inet_ntop(AF_INET6, &ctx->from.sin6_addr,
2633 	    ctx->ntopbuf, sizeof(ctx->ntopbuf));
2634 	if (len < sizeof(struct dhcp6_message)) {
2635 		logger(dctx, LOG_ERR,
2636 		    "DHCPv6 packet too short from %s", ctx->sfrom);
2637 		return;
2638 	}
2639 
2640 	pkt.ipi6_ifindex = 0;
2641 	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&ctx->rcvhdr);
2642 	     cm;
2643 	     cm = (struct cmsghdr *)CMSG_NXTHDR(&ctx->rcvhdr, cm))
2644 	{
2645 		if (cm->cmsg_level != IPPROTO_IPV6)
2646 			continue;
2647 		switch(cm->cmsg_type) {
2648 		case IPV6_PKTINFO:
2649 			if (cm->cmsg_len == CMSG_LEN(sizeof(pkt)))
2650 				memcpy(&pkt, CMSG_DATA(cm), sizeof(pkt));
2651 			break;
2652 		}
2653 	}
2654 	if (pkt.ipi6_ifindex == 0) {
2655 		logger(dctx, LOG_ERR,
2656 		    "DHCPv6 reply did not contain index from %s", ctx->sfrom);
2657 		return;
2658 	}
2659 
2660 	TAILQ_FOREACH(ifp, dctx->ifaces, next) {
2661 		/* Ensure we work on the master interface */
2662 		if (ifp->index == (unsigned int)pkt.ipi6_ifindex &&
2663 		    !(ifp->options->options & DHCPCD_PFXDLGONLY))
2664 			break;
2665 	}
2666 	if (ifp == NULL) {
2667 		logger(dctx, LOG_DEBUG,
2668 		    "DHCPv6 reply for unexpected interface from %s",
2669 		    ctx->sfrom);
2670 		return;
2671 	}
2672 
2673 	r = (struct dhcp6_message *)ctx->rcvhdr.msg_iov[0].iov_base;
2674 
2675 	/* Which interface state is the IAID for? */
2676 	ifpx = dhcp6_findpfxdlgif(ifp);
2677 	if (ifpx && D6_STATE(ifpx)) {
2678 		state = D6_STATE(ifpx);
2679 		if (r->xid[0] == state->send->xid[0] &&
2680 		    r->xid[1] == state->send->xid[1] &&
2681 		    r->xid[2] == state->send->xid[2])
2682 			ifp = ifpx;
2683 	}
2684 
2685 	state = D6_STATE(ifp);
2686 	if (state == NULL || state->send == NULL) {
2687 		logger(ifp->ctx, LOG_DEBUG,
2688 		    "%s: DHCPv6 reply received but not running", ifp->name);
2689 		return;
2690 	}
2691 
2692 	/* We're already bound and this message is for another machine */
2693 	/* XXX DELEGATED? */
2694 	if (r->type != DHCP6_RECONFIGURE &&
2695 	    (state->state == DH6S_BOUND || state->state == DH6S_INFORMED))
2696 	{
2697 		logger(ifp->ctx, LOG_DEBUG,
2698 		    "%s: DHCPv6 reply received but already bound", ifp->name);
2699 		return;
2700 	}
2701 
2702 	if (r->type != DHCP6_RECONFIGURE &&
2703 	    (r->xid[0] != state->send->xid[0] ||
2704 	    r->xid[1] != state->send->xid[1] ||
2705 	    r->xid[2] != state->send->xid[2]))
2706 	{
2707 		logger(dctx, LOG_DEBUG,
2708 		    "%s: wrong xid 0x%02x%02x%02x"
2709 		    " (expecting 0x%02x%02x%02x) from %s",
2710 		    ifp->name,
2711 		    r->xid[0], r->xid[1], r->xid[2],
2712 		    state->send->xid[0], state->send->xid[1],
2713 		    state->send->xid[2],
2714 		    ctx->sfrom);
2715 		return;
2716 	}
2717 
2718 	if (dhcp6_getmoption(D6_OPTION_SERVERID, r, len) == NULL) {
2719 		logger(ifp->ctx, LOG_DEBUG, "%s: no DHCPv6 server ID from %s",
2720 		    ifp->name, ctx->sfrom);
2721 		return;
2722 	}
2723 
2724 	o = dhcp6_getmoption(D6_OPTION_CLIENTID, r, len);
2725 	if (o == NULL || ntohs(o->len) != dctx->duid_len ||
2726 	    memcmp(D6_COPTION_DATA(o), dctx->duid, dctx->duid_len) != 0)
2727 	{
2728 		logger(ifp->ctx, LOG_DEBUG, "%s: incorrect client ID from %s",
2729 		    ifp->name, ctx->sfrom);
2730 		return;
2731 	}
2732 
2733 	ifo = ifp->options;
2734 	for (i = 0, opt = dctx->dhcp6_opts;
2735 	    i < dctx->dhcp6_opts_len;
2736 	    i++, opt++)
2737 	{
2738 		if (has_option_mask(ifo->requiremask6, opt->option) &&
2739 		    dhcp6_getmoption((uint16_t)opt->option, r, len) == NULL)
2740 		{
2741 			logger(ifp->ctx, LOG_WARNING,
2742 			    "%s: reject DHCPv6 (no option %s) from %s",
2743 			    ifp->name, opt->var, ctx->sfrom);
2744 			return;
2745 		}
2746 		if (has_option_mask(ifo->rejectmask6, opt->option) &&
2747 		    dhcp6_getmoption((uint16_t)opt->option, r, len))
2748 		{
2749 			logger(ifp->ctx, LOG_WARNING,
2750 			    "%s: reject DHCPv6 (option %s) from %s",
2751 			    ifp->name, opt->var, ctx->sfrom);
2752 			return;
2753 		}
2754 	}
2755 
2756 	/* Authenticate the message */
2757 	auth = dhcp6_getmoption(D6_OPTION_AUTH, r, len);
2758 	if (auth) {
2759 		if (dhcp_auth_validate(&state->auth, &ifo->auth,
2760 		    (uint8_t *)r, len, 6, r->type,
2761 		    D6_COPTION_DATA(auth), ntohs(auth->len)) == NULL)
2762 		{
2763 			logger(ifp->ctx, LOG_DEBUG, "dhcp_auth_validate: %m");
2764 			logger(ifp->ctx, LOG_ERR,
2765 			    "%s: authentication failed from %s",
2766 			    ifp->name, ctx->sfrom);
2767 			return;
2768 		}
2769 		if (state->auth.token)
2770 			logger(ifp->ctx, LOG_DEBUG,
2771 			    "%s: validated using 0x%08" PRIu32,
2772 			    ifp->name, state->auth.token->secretid);
2773 		else
2774 			logger(ifp->ctx, LOG_DEBUG,
2775 			    "%s: accepted reconfigure key", ifp->name);
2776 	} else if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
2777 		logger(ifp->ctx, LOG_ERR,
2778 		    "%s: no authentication from %s", ifp->name, ctx->sfrom);
2779 		return;
2780 	} else if (ifo->auth.options & DHCPCD_AUTH_SEND)
2781 		logger(ifp->ctx, LOG_WARNING,
2782 		    "%s: no authentication from %s", ifp->name, ctx->sfrom);
2783 
2784 	op = dhcp6_get_op(r->type);
2785 	switch(r->type) {
2786 	case DHCP6_REPLY:
2787 		switch(state->state) {
2788 		case DH6S_INFORM:
2789 			if (dhcp6_checkstatusok(ifp, r, NULL, len) == -1)
2790 				return;
2791 			/* RFC4242 */
2792 			o = dhcp6_getmoption(D6_OPTION_INFO_REFRESH_TIME,
2793 			    r, len);
2794 			if (o == NULL || ntohs(o->len) != sizeof(u32))
2795 				state->renew = IRT_DEFAULT;
2796 			else {
2797 				memcpy(&u32, D6_COPTION_DATA(o), sizeof(u32));
2798 				state->renew = ntohl(u32);
2799 				if (state->renew < IRT_MINIMUM)
2800 					state->renew = IRT_MINIMUM;
2801 			}
2802 			break;
2803 		case DH6S_CONFIRM:
2804 			error = dhcp6_checkstatusok(ifp, r, NULL, len);
2805 			/* If we got an OK status the chances are that we
2806 			 * didn't get the IA's returned, so preserve them
2807 			 * from our saved response */
2808 			if (error == 1)
2809 				goto recv;
2810 			if (error == -1 ||
2811 			    dhcp6_validatelease(ifp, r, len,
2812 			    ctx->sfrom, NULL) == -1)
2813 			{
2814 				dhcp6_startdiscover(ifp);
2815 				return;
2816 			}
2817 			break;
2818 		case DH6S_DISCOVER:
2819 			if (has_option_mask(ifo->requestmask6,
2820 			    D6_OPTION_RAPID_COMMIT) &&
2821 			    dhcp6_getmoption(D6_OPTION_RAPID_COMMIT, r, len))
2822 				state->state = DH6S_REQUEST;
2823 			else
2824 				op = NULL;
2825 		case DH6S_REQUEST: /* FALLTHROUGH */
2826 		case DH6S_RENEW: /* FALLTHROUGH */
2827 		case DH6S_REBIND:
2828 			if (dhcp6_validatelease(ifp, r, len,
2829 			    ctx->sfrom, NULL) == -1)
2830 			{
2831 				/* PD doesn't use CONFIRM, so REBIND could
2832 				 * throw up an invalid prefix if we
2833 				 * changed link */
2834 				if (dhcp6_hasprefixdelegation(ifp))
2835 					dhcp6_startdiscover(ifp);
2836 				return;
2837 			}
2838 			break;
2839 		default:
2840 			op = NULL;
2841 		}
2842 		break;
2843 	case DHCP6_ADVERTISE:
2844 		if (state->state != DH6S_DISCOVER) {
2845 			op = NULL;
2846 			break;
2847 		}
2848 		/* RFC7083 */
2849 		o = dhcp6_getmoption(D6_OPTION_SOL_MAX_RT, r, len);
2850 		if (o && ntohs(o->len) >= sizeof(u32)) {
2851 			memcpy(&u32, D6_COPTION_DATA(o), sizeof(u32));
2852 			u32 = ntohl(u32);
2853 			if (u32 >= 60 && u32 <= 86400) {
2854 				logger(ifp->ctx, LOG_DEBUG,
2855 				    "%s: SOL_MAX_RT %llu -> %d", ifp->name,
2856 				    (unsigned long long)state->sol_max_rt, u32);
2857 				state->sol_max_rt = (time_t)u32;
2858 			} else
2859 				logger(ifp->ctx, LOG_ERR,
2860 				    "%s: invalid SOL_MAX_RT %d",
2861 				    ifp->name, u32);
2862 		}
2863 		o = dhcp6_getmoption(D6_OPTION_INF_MAX_RT, r, len);
2864 		if (o && ntohs(o->len) >= sizeof(u32)) {
2865 			memcpy(&u32, D6_COPTION_DATA(o), sizeof(u32));
2866 			u32 = ntohl(u32);
2867 			if (u32 >= 60 && u32 <= 86400) {
2868 				logger(ifp->ctx, LOG_DEBUG,
2869 				    "%s: INF_MAX_RT %llu -> %d",
2870 				    ifp->name,
2871 				    (unsigned long long)state->inf_max_rt, u32);
2872 				state->inf_max_rt = (time_t)u32;
2873 			} else
2874 				logger(ifp->ctx, LOG_ERR,
2875 				    "%s: invalid INF_MAX_RT %d",
2876 				    ifp->name, u32);
2877 		}
2878 		if (dhcp6_validatelease(ifp, r, len, ctx->sfrom, NULL) == -1)
2879 			return;
2880 		break;
2881 	case DHCP6_RECONFIGURE:
2882 		if (auth == NULL) {
2883 			logger(ifp->ctx, LOG_ERR,
2884 			    "%s: unauthenticated %s from %s",
2885 			    ifp->name, op, ctx->sfrom);
2886 			return;
2887 		}
2888 		logger(ifp->ctx, LOG_INFO, "%s: %s from %s",
2889 		    ifp->name, op, ctx->sfrom);
2890 		o = dhcp6_getmoption(D6_OPTION_RECONF_MSG, r, len);
2891 		if (o == NULL) {
2892 			logger(ifp->ctx, LOG_ERR,
2893 			    "%s: missing Reconfigure Message option",
2894 			    ifp->name);
2895 			return;
2896 		}
2897 		if (ntohs(o->len) != 1) {
2898 			logger(ifp->ctx, LOG_ERR,
2899 			    "%s: missing Reconfigure Message type", ifp->name);
2900 			return;
2901 		}
2902 		switch(*D6_COPTION_DATA(o)) {
2903 		case DHCP6_RENEW:
2904 			if (state->state != DH6S_BOUND) {
2905 				logger(ifp->ctx, LOG_ERR,
2906 				    "%s: not bound, ignoring %s",
2907 				    ifp->name, op);
2908 				return;
2909 			}
2910 			eloop_timeout_delete(ifp->ctx->eloop,
2911 			    dhcp6_startrenew, ifp);
2912 			dhcp6_startrenew(ifp);
2913 			break;
2914 		case DHCP6_INFORMATION_REQ:
2915 			if (state->state != DH6S_INFORMED) {
2916 				logger(ifp->ctx, LOG_ERR,
2917 				    "%s: not informed, ignoring %s",
2918 				    ifp->name, op);
2919 				return;
2920 			}
2921 			eloop_timeout_delete(ifp->ctx->eloop,
2922 			    dhcp6_sendinform, ifp);
2923 			dhcp6_startinform(ifp);
2924 			break;
2925 		default:
2926 			logger(ifp->ctx, LOG_ERR,
2927 			    "%s: unsupported %s type %d",
2928 			    ifp->name, op, *D6_COPTION_DATA(o));
2929 			break;
2930 		}
2931 		return;
2932 	default:
2933 		logger(ifp->ctx, LOG_ERR, "%s: invalid DHCP6 type %s (%d)",
2934 		    ifp->name, op, r->type);
2935 		return;
2936 	}
2937 	if (op == NULL) {
2938 		logger(ifp->ctx, LOG_WARNING,
2939 		    "%s: invalid state for DHCP6 type %s (%d)",
2940 		    ifp->name, op, r->type);
2941 		return;
2942 	}
2943 
2944 	if (state->recv_len < (size_t)len) {
2945 		free(state->recv);
2946 		state->recv = malloc(len);
2947 		if (state->recv == NULL) {
2948 			logger(ifp->ctx, LOG_ERR,
2949 			    "%s: malloc recv: %m", ifp->name);
2950 			return;
2951 		}
2952 	}
2953 	memcpy(state->recv, r, len);
2954 	state->recv_len = len;
2955 
2956 	switch(r->type) {
2957 	case DHCP6_ADVERTISE:
2958 		if (state->state == DH6S_REQUEST) /* rapid commit */
2959 			break;
2960 		ap = TAILQ_FIRST(&state->addrs);
2961 		logger(ifp->ctx, LOG_INFO, "%s: ADV %s from %s",
2962 		    ifp->name, ap->saddr, ctx->sfrom);
2963 		if (ifp->ctx->options & DHCPCD_TEST)
2964 			break;
2965 		dhcp6_startrequest(ifp);
2966 		return;
2967 	}
2968 
2969 recv:
2970 	has_new = 0;
2971 	TAILQ_FOREACH(ap, &state->addrs, next) {
2972 		if (ap->flags & IPV6_AF_NEW) {
2973 			has_new = 1;
2974 			break;
2975 		}
2976 	}
2977 	logger(ifp->ctx, has_new ? LOG_INFO : LOG_DEBUG,
2978 	    "%s: %s received from %s", ifp->name, op, ctx->sfrom);
2979 
2980 	state->reason = NULL;
2981 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
2982 	switch(state->state) {
2983 	case DH6S_INFORM:
2984 		state->rebind = 0;
2985 		state->expire = ND6_INFINITE_LIFETIME;
2986 		state->lowpl = ND6_INFINITE_LIFETIME;
2987 		state->reason = "INFORM6";
2988 		break;
2989 	case DH6S_REQUEST:
2990 		if (state->reason == NULL)
2991 			state->reason = "BOUND6";
2992 		/* FALLTHROUGH */
2993 	case DH6S_RENEW:
2994 		if (state->reason == NULL)
2995 			state->reason = "RENEW6";
2996 		/* FALLTHROUGH */
2997 	case DH6S_REBIND:
2998 		if (state->reason == NULL)
2999 			state->reason = "REBIND6";
3000 		/* FALLTHROUGH */
3001 	case DH6S_CONFIRM:
3002 		if (state->reason == NULL)
3003 			state->reason = "REBOOT6";
3004 		if (state->renew == 0) {
3005 			if (state->expire == ND6_INFINITE_LIFETIME)
3006 				state->renew = ND6_INFINITE_LIFETIME;
3007 			else if (state->lowpl != ND6_INFINITE_LIFETIME)
3008 				state->renew = (uint32_t)(state->lowpl * 0.5);
3009 		}
3010 		if (state->rebind == 0) {
3011 			if (state->expire == ND6_INFINITE_LIFETIME)
3012 				state->rebind = ND6_INFINITE_LIFETIME;
3013 			else if (state->lowpl != ND6_INFINITE_LIFETIME)
3014 				state->rebind = (uint32_t)(state->lowpl * 0.8);
3015 		}
3016 		break;
3017 	default:
3018 		state->reason = "UNKNOWN6";
3019 		break;
3020 	}
3021 
3022 	if (state->state != DH6S_CONFIRM) {
3023 		free(state->old);
3024 		state->old = state->new;
3025 		state->old_len = state->new_len;
3026 		state->new = state->recv;
3027 		state->new_len = state->recv_len;
3028 		state->recv = NULL;
3029 		state->recv_len = 0;
3030 	}
3031 
3032 	if (ifp->ctx->options & DHCPCD_TEST)
3033 		script_runreason(ifp, "TEST");
3034 	else {
3035 		if (state->state == DH6S_INFORM)
3036 			state->state = DH6S_INFORMED;
3037 		else
3038 			state->state = DH6S_BOUND;
3039 		if (state->renew && state->renew != ND6_INFINITE_LIFETIME)
3040 			eloop_timeout_add_sec(ifp->ctx->eloop,
3041 			    (time_t)state->renew,
3042 			    state->state == DH6S_INFORMED ?
3043 			    dhcp6_startinform : dhcp6_startrenew, ifp);
3044 		if (state->rebind && state->rebind != ND6_INFINITE_LIFETIME)
3045 			eloop_timeout_add_sec(ifp->ctx->eloop,
3046 			    (time_t)state->rebind, dhcp6_startrebind, ifp);
3047 		if (state->expire != ND6_INFINITE_LIFETIME)
3048 			eloop_timeout_add_sec(ifp->ctx->eloop,
3049 			    (time_t)state->expire, dhcp6_startexpire, ifp);
3050 
3051 #ifndef PASSIVE_MODE
3052 		ipv6nd_runignoredra(ifp);
3053 		ipv6_addaddrs(&state->addrs);
3054 		dhcp6_delegate_prefix(ifp);
3055 #else
3056 		rpc_update_ipv6(ifp);
3057 #endif  /* PASSIVE_MODE */
3058 
3059 		if (state->state == DH6S_INFORMED)
3060 			logger(ifp->ctx, has_new ? LOG_INFO : LOG_DEBUG,
3061 			    "%s: refresh in %"PRIu32" seconds",
3062 			    ifp->name, state->renew);
3063 		else if (state->renew || state->rebind)
3064 			logger(ifp->ctx, has_new ? LOG_INFO : LOG_DEBUG,
3065 			    "%s: renew in %"PRIu32" seconds,"
3066 			    " rebind in %"PRIu32" seconds",
3067 			    ifp->name, state->renew, state->rebind);
3068 		else if (state->expire == 0)
3069 			logger(ifp->ctx, has_new ? LOG_INFO : LOG_DEBUG,
3070 			    "%s: will expire", ifp->name);
3071 		if_initrt6(ifp);
3072 		ipv6_buildroutes(ifp->ctx);
3073 		dhcp6_writelease(ifp);
3074 		dhcp6_script_try_run(ifp, 0);
3075 	}
3076 
3077 	if (ifp->ctx->options & DHCPCD_TEST ||
3078 	    (ifp->options->options & DHCPCD_INFORM &&
3079 	    !(ifp->ctx->options & DHCPCD_MASTER)))
3080 	{
3081 		eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
3082 	}
3083 }
3084 
3085 static int
dhcp6_open(struct dhcpcd_ctx * dctx)3086 dhcp6_open(struct dhcpcd_ctx *dctx)
3087 {
3088 	struct ipv6_ctx *ctx;
3089 	struct sockaddr_in6 sa;
3090 	int n;
3091 
3092 	memset(&sa, 0, sizeof(sa));
3093 	sa.sin6_family = AF_INET6;
3094 	sa.sin6_port = htons(DHCP6_CLIENT_PORT);
3095 #ifdef BSD
3096 	sa.sin6_len = sizeof(sa);
3097 #endif
3098 
3099 	ctx = dctx->ipv6;
3100 #ifdef SOCK_CLOEXEC
3101 	ctx->dhcp_fd = socket(PF_INET6,
3102 	    SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
3103 	    IPPROTO_UDP);
3104 	if (ctx->dhcp_fd == -1)
3105 		return -1;
3106 #else
3107 	if ((ctx->dhcp_fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1)
3108 		return -1;
3109 	if ((n = fcntl(ctx->dhcp_fd, F_GETFD, 0)) == -1 ||
3110 	    fcntl(ctx->dhcp_fd, F_SETFD, n | FD_CLOEXEC) == -1)
3111 	{
3112 		close(ctx->dhcp_fd);
3113 		ctx->dhcp_fd = -1;
3114 	        return -1;
3115 	}
3116 	if ((n = fcntl(ctx->dhcp_fd, F_GETFL, 0)) == -1 ||
3117 	    fcntl(ctx->dhcp_fd, F_SETFL, n | O_NONBLOCK) == -1)
3118 	{
3119 		close(ctx->dhcp_fd);
3120 		ctx->dhcp_fd = -1;
3121 	        return -1;
3122 	}
3123 #endif
3124 
3125 	n = 1;
3126 	if (setsockopt(ctx->dhcp_fd, SOL_SOCKET, SO_REUSEADDR,
3127 	    &n, sizeof(n)) == -1)
3128 		goto errexit;
3129 
3130 	n = 1;
3131 	if (setsockopt(ctx->dhcp_fd, SOL_SOCKET, SO_BROADCAST,
3132 	    &n, sizeof(n)) == -1)
3133 		goto errexit;
3134 
3135 #ifdef SO_REUSEPORT
3136 	n = 1;
3137 	if (setsockopt(ctx->dhcp_fd, SOL_SOCKET, SO_REUSEPORT,
3138 	    &n, sizeof(n)) == -1)
3139 		logger(dctx, LOG_WARNING, "setsockopt: SO_REUSEPORT: %m");
3140 #endif
3141 
3142 	if (bind(ctx->dhcp_fd, (struct sockaddr *)&sa, sizeof(sa)) == -1)
3143 		goto errexit;
3144 
3145 	n = 1;
3146 	if (setsockopt(ctx->dhcp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
3147 	    &n, sizeof(n)) == -1)
3148 		goto errexit;
3149 
3150 	eloop_event_add(dctx->eloop, ctx->dhcp_fd,
3151 	    dhcp6_handledata, dctx, NULL, NULL);
3152 	return 0;
3153 
3154 errexit:
3155 	close(ctx->dhcp_fd);
3156 	ctx->dhcp_fd = -1;
3157 	return -1;
3158 }
3159 
3160 static void
dhcp6_start1(void * arg)3161 dhcp6_start1(void *arg)
3162 {
3163 	struct interface *ifp = arg;
3164 	struct if_options *ifo = ifp->options;
3165 	struct dhcp6_state *state;
3166 	size_t i;
3167 	const struct dhcp_compat *dhc;
3168 
3169 	state = D6_STATE(ifp);
3170 	/* Match any DHCPv4 opton to DHCPv6 options if given for easy
3171 	 * configuration */
3172 	for (i = 0; i < sizeof(ifo->requestmask6); i++) {
3173 		if (ifo->requestmask6[i] != '\0')
3174 			break;
3175 	}
3176 	if (i == sizeof(ifo->requestmask6)) {
3177 		for (dhc = dhcp_compats; dhc->dhcp_opt; dhc++) {
3178 			if (has_option_mask(ifo->requestmask, dhc->dhcp_opt))
3179 				add_option_mask(ifo->requestmask6,
3180 				    dhc->dhcp6_opt);
3181 		}
3182 		if (ifo->fqdn != FQDN_DISABLE ||
3183 		    ifo->options & DHCPCD_HOSTNAME)
3184 			add_option_mask(ifo->requestmask6, D6_OPTION_FQDN);
3185 	}
3186 
3187 	/* Rapid commit won't wor with Prefix Delegation Exclusion */
3188 	if (dhcp6_findselfsla(ifp, NULL))
3189 		del_option_mask(ifo->requestmask6, D6_OPTION_RAPID_COMMIT);
3190 
3191 	/* Create a 2nd interface to handle the PD state */
3192 	if (!(ifo->options & (DHCPCD_PFXDLGONLY | DHCPCD_PFXDLGMIX)) &&
3193 	    dhcp6_hasprefixdelegation(ifp) > 1)
3194 	{
3195 		const char * const argv[] = { ifp->name };
3196 		struct if_head *ifs;
3197 		struct interface *ifn;
3198 
3199 		ifn = dhcp6_findpfxdlgif(ifp);
3200 		if (ifn == NULL) {
3201 			ifs = if_discover(ifp->ctx, -1, UNCONST(argv));
3202 			if (ifs) {
3203 				ifn = TAILQ_FIRST(ifs);
3204 				if (ifn) {
3205 					logger(ifp->ctx, LOG_INFO,
3206 					    "%s: creating pseudo interface"
3207 					    " to handle Prefix Delegation",
3208 					    ifp->name);
3209 					ifp->options->options |=
3210 					    DHCPCD_NOPFXDLG;
3211 					/*
3212 					 * Maintain the same lease identifier
3213 					 * for the pseudo interface for
3214 					 * obtaining prefix delegation.
3215 					 */
3216 					strlcpy(ifn->lease_identifier,
3217 					        ifp->lease_identifier,
3218 					        sizeof(ifn->lease_identifier));
3219 					TAILQ_REMOVE(ifs, ifn, next);
3220 					TAILQ_INSERT_AFTER(ifp->ctx->ifaces,
3221 					    ifp, ifn, next);
3222 					dhcpcd_initstate(ifn,
3223 					    DHCPCD_PFXDLGONLY);
3224 					eloop_timeout_add_sec(ifp->ctx->eloop,
3225 					    0, dhcpcd_startinterface, ifn);
3226 				}
3227 				while ((ifn = TAILQ_FIRST(ifs))) {
3228 					TAILQ_REMOVE(ifs, ifn, next);
3229 					if_free(ifn);
3230 				}
3231 				free(ifs);
3232 			}
3233 		}
3234 	}
3235 
3236 	if (state->state == DH6S_INFORM) {
3237 		add_option_mask(ifo->requestmask6, D6_OPTION_INFO_REFRESH_TIME);
3238 		dhcp6_startinform(ifp);
3239 	} else {
3240 		del_option_mask(ifo->requestmask6, D6_OPTION_INFO_REFRESH_TIME);
3241 		dhcp6_startinit(ifp);
3242 	}
3243 }
3244 
3245 int
dhcp6_start(struct interface * ifp,enum DH6S init_state)3246 dhcp6_start(struct interface *ifp, enum DH6S init_state)
3247 {
3248 	struct dhcp6_state *state;
3249 
3250 	state = D6_STATE(ifp);
3251 	if (state) {
3252 		if (state->state == DH6S_INFORMED &&
3253 		    init_state == DH6S_INFORM)
3254 		{
3255 			dhcp6_startinform(ifp);
3256 			return 0;
3257 		}
3258 		if (init_state == DH6S_INIT &&
3259 		    ifp->options->options & DHCPCD_DHCP6 &&
3260 		    (state->state == DH6S_INFORM ||
3261 		    state->state == DH6S_INFORMED ||
3262 		    state->state == DH6S_DELEGATED))
3263 		{
3264 			/* Change from stateless to stateful */
3265 			goto gogogo;
3266 		}
3267 		/* We're already running DHCP6 */
3268 		/* XXX: What if the managed flag vanishes from all RA? */
3269 		return 0;
3270 	}
3271 
3272 	if (!(ifp->options->options & DHCPCD_DHCP6))
3273 		return 0;
3274 
3275 	if (ifp->ctx->ipv6->dhcp_fd == -1 && dhcp6_open(ifp->ctx) == -1)
3276 		return -1;
3277 
3278 	ifp->if_data[IF_DATA_DHCP6] = calloc(1, sizeof(*state));
3279 	state = D6_STATE(ifp);
3280 	if (state == NULL)
3281 		return -1;
3282 
3283 	state->sol_max_rt = SOL_MAX_RT;
3284 	state->inf_max_rt = INF_MAX_RT;
3285 	TAILQ_INIT(&state->addrs);
3286 
3287 gogogo:
3288 	state->state = init_state;
3289 	dhcp_set_leasefile(state->leasefile, sizeof(state->leasefile),
3290 	    AF_INET6, ifp,
3291 	    ifp->options->options & DHCPCD_PFXDLGONLY ? ".pd" : "");
3292 	if (ipv6_linklocal(ifp) == NULL) {
3293 		logger(ifp->ctx, LOG_DEBUG,
3294 		    "%s: delaying DHCPv6 soliciation for LL address",
3295 		    ifp->name);
3296 		ipv6_addlinklocalcallback(ifp, dhcp6_start1, ifp);
3297 		return 0;
3298 	}
3299 
3300 	dhcp6_start1(ifp);
3301 	return 0;
3302 }
3303 
3304 void
dhcp6_reboot(struct interface * ifp)3305 dhcp6_reboot(struct interface *ifp)
3306 {
3307 	struct dhcp6_state *state;
3308 
3309 	state = D6_STATE(ifp);
3310 	if (state) {
3311 		switch (state->state) {
3312 		case DH6S_BOUND:
3313 			dhcp6_startrebind(ifp);
3314 			break;
3315 		case DH6S_INFORMED:
3316 			dhcp6_startinform(ifp);
3317 			break;
3318 		default:
3319 			dhcp6_startdiscover(ifp);
3320 			break;
3321 		}
3322 	}
3323 }
3324 
3325 static void
dhcp6_freedrop(struct interface * ifp,int drop,const char * reason)3326 dhcp6_freedrop(struct interface *ifp, int drop, const char *reason)
3327 {
3328 	struct interface *ifpx;
3329 	struct dhcp6_state *state;
3330 	struct dhcpcd_ctx *ctx;
3331 	unsigned long long options;
3332 	int dropdele;
3333 
3334 	/*
3335 	 * As the interface is going away from dhcpcd we need to
3336 	 * remove the delegated addresses, otherwise we lose track
3337 	 * of which interface is delegating as we remeber it by pointer.
3338 	 * So if we need to change this behaviour, we need to change
3339 	 * how we remember which interface delegated.
3340 	 *
3341 	 * XXX The below is no longer true due to the change of the
3342 	 * default IAID, but do PPP links have stable ethernet
3343 	 * addresses?
3344 	 *
3345 	 * To make it more interesting, on some OS's with PPP links
3346 	 * there is no guarantee the delegating interface will have
3347 	 * the same name or index so think very hard before changing
3348 	 * this.
3349 	 */
3350 	if (ifp->options)
3351 		options = ifp->options->options;
3352 	else
3353 		options = 0;
3354 	dropdele = (options & (DHCPCD_STOPPING | DHCPCD_RELEASE) &&
3355 	    (options &
3356 	    (DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
3357 	    (DHCPCD_EXITING | DHCPCD_PERSISTENT));
3358 
3359 	ifpx = dhcp6_findpfxdlgif(ifp);
3360 	if (ifpx) {
3361 		if (options & DHCPCD_EXITING)
3362 			ifpx->options->options |= DHCPCD_EXITING;
3363 		dhcp6_freedrop(ifpx, dropdele ? 1 : drop, reason);
3364 		TAILQ_REMOVE(ifp->ctx->ifaces, ifpx, next);
3365 		if_free(ifpx);
3366 	}
3367 
3368 	if (ifp->ctx->eloop)
3369 		eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
3370 
3371 	if (dropdele)
3372 		dhcp6_delete_delegates(ifp);
3373 
3374 	state = D6_STATE(ifp);
3375 	if (state) {
3376 		dhcp_auth_reset(&state->auth);
3377 		if (drop && options & DHCPCD_RELEASE) {
3378 			if (ifp->carrier == LINK_UP)
3379 				dhcp6_startrelease(ifp);
3380 			unlink(state->leasefile);
3381 		}
3382 		dhcp6_freedrop_addrs(ifp, drop, NULL);
3383 		free(state->old);
3384 		state->old = state->new;
3385 		state->old_len = state->new_len;
3386 		state->new = NULL;
3387 		state->new_len = 0;
3388 		if (drop && state->old &&
3389 		    (options &
3390 		    (DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
3391 		    (DHCPCD_EXITING | DHCPCD_PERSISTENT))
3392 		{
3393 			if (reason == NULL)
3394 				reason = "STOP6";
3395 			script_runreason(ifp, reason);
3396 		}
3397 		free(state->old);
3398 		free(state->send);
3399 		free(state->recv);
3400 		free(state);
3401 		ifp->if_data[IF_DATA_DHCP6] = NULL;
3402 	}
3403 
3404 	/* If we don't have any more DHCP6 enabled interfaces,
3405 	 * close the global socket and release resources */
3406 	ctx = ifp->ctx;
3407 	if (ctx->ifaces) {
3408 		TAILQ_FOREACH(ifp, ctx->ifaces, next) {
3409 			if (D6_STATE(ifp))
3410 				break;
3411 		}
3412 	}
3413 	if (ifp == NULL && ctx->ipv6) {
3414 		if (ctx->ipv6->dhcp_fd != -1) {
3415 			eloop_event_delete(ctx->eloop, ctx->ipv6->dhcp_fd, 0);
3416 			close(ctx->ipv6->dhcp_fd);
3417 			ctx->ipv6->dhcp_fd = -1;
3418 		}
3419 	}
3420 }
3421 
3422 void
dhcp6_drop(struct interface * ifp,const char * reason)3423 dhcp6_drop(struct interface *ifp, const char *reason)
3424 {
3425 
3426 	dhcp6_freedrop(ifp, 1, reason);
3427 }
3428 
3429 void
dhcp6_free(struct interface * ifp)3430 dhcp6_free(struct interface *ifp)
3431 {
3432 
3433 	dhcp6_freedrop(ifp, 0, NULL);
3434 }
3435 
3436 void
dhcp6_handleifa(struct dhcpcd_ctx * ctx,int cmd,const char * ifname,const struct in6_addr * addr,int flags)3437 dhcp6_handleifa(struct dhcpcd_ctx *ctx, int cmd, const char *ifname,
3438     const struct in6_addr *addr, int flags)
3439 {
3440 	struct interface *ifp;
3441 	struct dhcp6_state *state;
3442 
3443 	if (ctx->ifaces == NULL)
3444 		return;
3445 
3446 	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
3447 		state = D6_STATE(ifp);
3448 		if (state == NULL || strcmp(ifp->name, ifname))
3449 			continue;
3450 		ipv6_handleifa_addrs(cmd, &state->addrs, addr, flags);
3451 	}
3452 
3453 }
3454 
3455 ssize_t
dhcp6_env(char ** env,const char * prefix,const struct interface * ifp,const struct dhcp6_message * m,size_t len)3456 dhcp6_env(char **env, const char *prefix, const struct interface *ifp,
3457     const struct dhcp6_message *m, size_t len)
3458 {
3459 	const struct if_options *ifo;
3460 	struct dhcp_opt *opt, *vo;
3461 	const struct dhcp6_option *o;
3462 	size_t i, n;
3463 	uint16_t ol, oc;
3464 	char *pfx;
3465 	uint32_t en;
3466 	const struct dhcpcd_ctx *ctx;
3467 	const struct dhcp6_state *state;
3468 	const struct ipv6_addr *ap;
3469 	char *v, *val;
3470 
3471 	n = 0;
3472 	if (m == NULL)
3473 		goto delegated;
3474 
3475 	if (len < sizeof(*m)) {
3476 		/* Should be impossible with guards at packet in
3477 		 * and reading leases */
3478 		errno = EINVAL;
3479 		return -1;
3480 	}
3481 
3482 	ifo = ifp->options;
3483 	ctx = ifp->ctx;
3484 
3485 	/* Zero our indexes */
3486 	if (env) {
3487 		for (i = 0, opt = ctx->dhcp6_opts;
3488 		    i < ctx->dhcp6_opts_len;
3489 		    i++, opt++)
3490 			dhcp_zero_index(opt);
3491 		for (i = 0, opt = ifp->options->dhcp6_override;
3492 		    i < ifp->options->dhcp6_override_len;
3493 		    i++, opt++)
3494 			dhcp_zero_index(opt);
3495 		for (i = 0, opt = ctx->vivso;
3496 		    i < ctx->vivso_len;
3497 		    i++, opt++)
3498 			dhcp_zero_index(opt);
3499 		i = strlen(prefix) + strlen("_dhcp6") + 1;
3500 		pfx = malloc(i);
3501 		if (pfx == NULL) {
3502 			logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
3503 			return -1;
3504 		}
3505 		snprintf(pfx, i, "%s_dhcp6", prefix);
3506 	} else
3507 		pfx = NULL;
3508 
3509 	/* Unlike DHCP, DHCPv6 options *may* occur more than once.
3510 	 * There is also no provision for option concatenation unlike DHCP. */
3511 	for (o = D6_CFIRST_OPTION(m);
3512 	    len > (ssize_t)sizeof(*o);
3513 	    o = D6_CNEXT_OPTION(o))
3514 	{
3515 		ol = ntohs(o->len);
3516 		if (sizeof(*o) + ol > len) {
3517 			errno =	EINVAL;
3518 			break;
3519 		}
3520 		len -= sizeof(*o) + ol;
3521 		oc = ntohs(o->code);
3522 		if (has_option_mask(ifo->nomask6, oc))
3523 			continue;
3524 		for (i = 0, opt = ifo->dhcp6_override;
3525 		    i < ifo->dhcp6_override_len;
3526 		    i++, opt++)
3527 			if (opt->option == oc)
3528 				break;
3529 		if (i == ifo->dhcp6_override_len &&
3530 		    oc == D6_OPTION_VENDOR_OPTS &&
3531 		    ol > sizeof(en))
3532 		{
3533 			memcpy(&en, D6_COPTION_DATA(o), sizeof(en));
3534 			en = ntohl(en);
3535 			vo = vivso_find(en, ifp);
3536 		} else
3537 			vo = NULL;
3538 		if (i == ifo->dhcp6_override_len) {
3539 			for (i = 0, opt = ctx->dhcp6_opts;
3540 			    i < ctx->dhcp6_opts_len;
3541 			    i++, opt++)
3542 				if (opt->option == oc)
3543 					break;
3544 			if (i == ctx->dhcp6_opts_len)
3545 				opt = NULL;
3546 		}
3547 		if (opt) {
3548 			n += dhcp_envoption(ifp->ctx,
3549 			    env == NULL ? NULL : &env[n],
3550 			    pfx, ifp->name,
3551 			    opt, dhcp6_getoption, D6_COPTION_DATA(o), ol);
3552 		}
3553 		if (vo) {
3554 			n += dhcp_envoption(ifp->ctx,
3555 			    env == NULL ? NULL : &env[n],
3556 			    pfx, ifp->name,
3557 			    vo, dhcp6_getoption,
3558 			    D6_COPTION_DATA(o) + sizeof(en),
3559 			    ol - sizeof(en));
3560 		}
3561 	}
3562 	free(pfx);
3563 
3564 delegated:
3565         /* Needed for Delegated Prefixes */
3566 	state = D6_CSTATE(ifp);
3567 	i = 0;
3568 	TAILQ_FOREACH(ap, &state->addrs, next) {
3569 		if (ap->delegating_iface) {
3570 			i += strlen(ap->saddr) + 1;
3571 		}
3572 	}
3573 	if (env && i) {
3574 		i += strlen(prefix) + strlen("_delegated_dhcp6_prefix=");
3575                 v = val = env[n] = malloc(i);
3576 		if (v == NULL) {
3577 			logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
3578 			return -1;
3579 		}
3580 		v += snprintf(val, i, "%s_delegated_dhcp6_prefix=", prefix);
3581 		TAILQ_FOREACH(ap, &state->addrs, next) {
3582 			if (ap->delegating_iface) {
3583 				/* Can't use stpcpy(3) due to "security" */
3584 				const char *sap = ap->saddr;
3585 
3586 				do
3587 					*v++ = *sap;
3588 				while (*++sap != '\0');
3589 				*v++ = ' ';
3590 			}
3591 		}
3592 		*--v = '\0';
3593         }
3594 	if (i)
3595 		n++;
3596 
3597 	return (ssize_t)n;
3598 }
3599 
3600 int
dhcp6_dump(struct interface * ifp)3601 dhcp6_dump(struct interface *ifp)
3602 {
3603 	struct dhcp6_state *state;
3604 
3605 	ifp->if_data[IF_DATA_DHCP6] = state = calloc(1, sizeof(*state));
3606 	if (state == NULL) {
3607 		logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
3608 		return -1;
3609 	}
3610 	TAILQ_INIT(&state->addrs);
3611 	dhcp_set_leasefile(state->leasefile, sizeof(state->leasefile),
3612 	    AF_INET6, ifp,
3613 	    ifp->options->options & DHCPCD_PFXDLGONLY ? ".pd" : "");
3614 	if (dhcp6_readlease(ifp, 0) == -1) {
3615 		logger(ifp->ctx, LOG_ERR, "%s: %s: %m",
3616 		    *ifp->name ? ifp->name : state->leasefile, __func__);
3617 		return -1;
3618 	}
3619 	state->reason = "DUMP6";
3620 	return script_runreason(ifp, state->reason);
3621 }
3622