"Fossies" - the Fresh Open Source Software Archive 
Member "dhcpcd-9.4.1/src/dhcp6.c" (22 Oct 2021, 104279 Bytes) of package /linux/misc/dhcpcd-9.4.1.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "dhcp6.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
9.4.0_vs_9.4.1.
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3 * dhcpcd - DHCP client daemon
4 * Copyright (c) 2006-2021 Roy Marples <roy@marples.name>
5 * All rights reserved
6
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <sys/utsname.h>
30 #include <sys/types.h>
31
32 #include <netinet/in.h>
33 #include <netinet/ip6.h>
34
35 #include <assert.h>
36 #include <ctype.h>
37 #include <errno.h>
38 #include <fcntl.h>
39 #include <inttypes.h>
40 #include <stdbool.h>
41 #include <stddef.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <unistd.h>
45 #include <fcntl.h>
46 #include <syslog.h>
47
48 #define ELOOP_QUEUE ELOOP_DHCP6
49 #include "config.h"
50 #include "common.h"
51 #include "dhcp.h"
52 #include "dhcp6.h"
53 #include "duid.h"
54 #include "eloop.h"
55 #include "if.h"
56 #include "if-options.h"
57 #include "ipv6nd.h"
58 #include "logerr.h"
59 #include "privsep.h"
60 #include "script.h"
61
62 #ifdef HAVE_SYS_BITOPS_H
63 #include <sys/bitops.h>
64 #else
65 #include "compat/bitops.h"
66 #endif
67
68 /* DHCPCD Project has been assigned an IANA PEN of 40712 */
69 #define DHCPCD_IANA_PEN 40712
70
71 /* Unsure if I want this */
72 //#define VENDOR_SPLIT
73
74 /* Support older systems with different defines */
75 #if !defined(IPV6_RECVPKTINFO) && defined(IPV6_PKTINFO)
76 #define IPV6_RECVPKTINFO IPV6_PKTINFO
77 #endif
78
79 #ifdef DHCP6
80
81 /* Assert the correct structure size for on wire */
82 struct dhcp6_message {
83 uint8_t type;
84 uint8_t xid[3];
85 /* followed by options */
86 };
87 __CTASSERT(sizeof(struct dhcp6_message) == 4);
88
89 struct dhcp6_option {
90 uint16_t code;
91 uint16_t len;
92 /* followed by data */
93 };
94 __CTASSERT(sizeof(struct dhcp6_option) == 4);
95
96 struct dhcp6_ia_na {
97 uint8_t iaid[4];
98 uint32_t t1;
99 uint32_t t2;
100 };
101 __CTASSERT(sizeof(struct dhcp6_ia_na) == 12);
102
103 struct dhcp6_ia_ta {
104 uint8_t iaid[4];
105 };
106 __CTASSERT(sizeof(struct dhcp6_ia_ta) == 4);
107
108 struct dhcp6_ia_addr {
109 struct in6_addr addr;
110 uint32_t pltime;
111 uint32_t vltime;
112 };
113 __CTASSERT(sizeof(struct dhcp6_ia_addr) == 16 + 8);
114
115 /* XXX FIXME: This is the only packed structure and it does not align.
116 * Maybe manually decode it? */
117 struct dhcp6_pd_addr {
118 uint32_t pltime;
119 uint32_t vltime;
120 uint8_t prefix_len;
121 struct in6_addr prefix;
122 } __packed;
123 __CTASSERT(sizeof(struct dhcp6_pd_addr) == 8 + 1 + 16);
124
125 struct dhcp6_op {
126 uint16_t type;
127 const char *name;
128 };
129
130 static const struct dhcp6_op dhcp6_ops[] = {
131 { DHCP6_SOLICIT, "SOLICIT6" },
132 { DHCP6_ADVERTISE, "ADVERTISE6" },
133 { DHCP6_REQUEST, "REQUEST6" },
134 { DHCP6_REPLY, "REPLY6" },
135 { DHCP6_RENEW, "RENEW6" },
136 { DHCP6_REBIND, "REBIND6" },
137 { DHCP6_CONFIRM, "CONFIRM6" },
138 { DHCP6_INFORMATION_REQ, "INFORM6" },
139 { DHCP6_RELEASE, "RELEASE6" },
140 { DHCP6_RECONFIGURE, "RECONFIGURE6" },
141 { DHCP6_DECLINE, "DECLINE6" },
142 { 0, NULL }
143 };
144
145 struct dhcp_compat {
146 uint8_t dhcp_opt;
147 uint16_t dhcp6_opt;
148 };
149
150 static const struct dhcp_compat dhcp_compats[] = {
151 { DHO_DNSSERVER, D6_OPTION_DNS_SERVERS },
152 { DHO_HOSTNAME, D6_OPTION_FQDN },
153 { DHO_DNSDOMAIN, D6_OPTION_FQDN },
154 { DHO_NISSERVER, D6_OPTION_NIS_SERVERS },
155 { DHO_NTPSERVER, D6_OPTION_SNTP_SERVERS },
156 { DHO_RAPIDCOMMIT, D6_OPTION_RAPID_COMMIT },
157 { DHO_FQDN, D6_OPTION_FQDN },
158 { DHO_VIVCO, D6_OPTION_VENDOR_CLASS },
159 { DHO_VIVSO, D6_OPTION_VENDOR_OPTS },
160 { DHO_DNSSEARCH, D6_OPTION_DOMAIN_LIST },
161 { 0, 0 }
162 };
163
164 static const char * const dhcp6_statuses[] = {
165 "Success",
166 "Unspecified Failure",
167 "No Addresses Available",
168 "No Binding",
169 "Not On Link",
170 "Use Multicast",
171 "No Prefix Available"
172 };
173
174 static void dhcp6_bind(struct interface *, const char *, const char *);
175 static void dhcp6_failinform(void *);
176 static void dhcp6_recvaddr(void *);
177 static void dhcp6_startdecline(struct interface *);
178
179 #ifdef SMALL
180 #define dhcp6_hasprefixdelegation(a) (0)
181 #else
182 static int dhcp6_hasprefixdelegation(struct interface *);
183 #endif
184
185 #define DECLINE_IA(ia) \
186 ((ia)->addr_flags & IN6_IFF_DUPLICATED && \
187 (ia)->ia_type != 0 && (ia)->ia_type != D6_OPTION_IA_PD && \
188 !((ia)->flags & IPV6_AF_STALE) && \
189 (ia)->prefix_vltime != 0)
190
191 void
192 dhcp6_printoptions(const struct dhcpcd_ctx *ctx,
193 const struct dhcp_opt *opts, size_t opts_len)
194 {
195 size_t i, j;
196 const struct dhcp_opt *opt, *opt2;
197 int cols;
198
199 for (i = 0, opt = ctx->dhcp6_opts;
200 i < ctx->dhcp6_opts_len; i++, opt++)
201 {
202 for (j = 0, opt2 = opts; j < opts_len; j++, opt2++)
203 if (opt2->option == opt->option)
204 break;
205 if (j == opts_len) {
206 cols = printf("%05d %s", opt->option, opt->var);
207 dhcp_print_option_encoding(opt, cols);
208 }
209 }
210 for (i = 0, opt = opts; i < opts_len; i++, opt++) {
211 cols = printf("%05d %s", opt->option, opt->var);
212 dhcp_print_option_encoding(opt, cols);
213 }
214 }
215
216 static size_t
217 dhcp6_makeuser(void *data, const struct interface *ifp)
218 {
219 const struct if_options *ifo = ifp->options;
220 struct dhcp6_option o;
221 uint8_t *p;
222 const uint8_t *up, *ue;
223 uint16_t ulen, unlen;
224 size_t olen;
225
226 /* Convert the DHCPv4 user class option to DHCPv6 */
227 up = ifo->userclass;
228 ulen = *up++;
229 if (ulen == 0)
230 return 0;
231
232 p = data;
233 olen = 0;
234 if (p != NULL)
235 p += sizeof(o);
236
237 ue = up + ulen;
238 for (; up < ue; up += ulen) {
239 ulen = *up++;
240 olen += sizeof(ulen) + ulen;
241 if (data == NULL)
242 continue;
243 unlen = htons(ulen);
244 memcpy(p, &unlen, sizeof(unlen));
245 p += sizeof(unlen);
246 memcpy(p, up, ulen);
247 p += ulen;
248 }
249 if (data != NULL) {
250 o.code = htons(D6_OPTION_USER_CLASS);
251 o.len = htons((uint16_t)olen);
252 memcpy(data, &o, sizeof(o));
253 }
254
255 return sizeof(o) + olen;
256 }
257
258 static size_t
259 dhcp6_makevendor(void *data, const struct interface *ifp)
260 {
261 const struct if_options *ifo;
262 size_t len, vlen, i;
263 uint8_t *p;
264 const struct vivco *vivco;
265 struct dhcp6_option o;
266
267 ifo = ifp->options;
268 len = sizeof(uint32_t); /* IANA PEN */
269 if (ifo->vivco_en) {
270 vlen = 0;
271 for (i = 0, vivco = ifo->vivco;
272 i < ifo->vivco_len;
273 i++, vivco++)
274 vlen += sizeof(uint16_t) + vivco->len;
275 len += vlen;
276 } else if (ifo->vendorclassid[0] != '\0') {
277 /* dhcpcd owns DHCPCD_IANA_PEN.
278 * If you need your own string, get your own IANA PEN. */
279 vlen = strlen(ifp->ctx->vendor);
280 len += sizeof(uint16_t) + vlen;
281 } else
282 return 0;
283
284 if (len > UINT16_MAX) {
285 logerrx("%s: DHCPv6 Vendor Class too big", ifp->name);
286 return 0;
287 }
288
289 if (data != NULL) {
290 uint32_t pen;
291 uint16_t hvlen;
292
293 p = data;
294 o.code = htons(D6_OPTION_VENDOR_CLASS);
295 o.len = htons((uint16_t)len);
296 memcpy(p, &o, sizeof(o));
297 p += sizeof(o);
298 pen = htonl(ifo->vivco_en ? ifo->vivco_en : DHCPCD_IANA_PEN);
299 memcpy(p, &pen, sizeof(pen));
300 p += sizeof(pen);
301
302 if (ifo->vivco_en) {
303 for (i = 0, vivco = ifo->vivco;
304 i < ifo->vivco_len;
305 i++, vivco++)
306 {
307 hvlen = htons((uint16_t)vivco->len);
308 memcpy(p, &hvlen, sizeof(hvlen));
309 p += sizeof(hvlen);
310 memcpy(p, vivco->data, vivco->len);
311 p += vivco->len;
312 }
313 } else if (ifo->vendorclassid[0] != '\0') {
314 hvlen = htons((uint16_t)vlen);
315 memcpy(p, &hvlen, sizeof(hvlen));
316 p += sizeof(hvlen);
317 memcpy(p, ifp->ctx->vendor, vlen);
318 }
319 }
320
321 return sizeof(o) + len;
322 }
323
324 static void *
325 dhcp6_findoption(void *data, size_t data_len, uint16_t code, uint16_t *len)
326 {
327 uint8_t *d;
328 struct dhcp6_option o;
329
330 code = htons(code);
331 for (d = data; data_len != 0; d += o.len, data_len -= o.len) {
332 if (data_len < sizeof(o)) {
333 errno = EINVAL;
334 return NULL;
335 }
336 memcpy(&o, d, sizeof(o));
337 d += sizeof(o);
338 data_len -= sizeof(o);
339 o.len = htons(o.len);
340 if (data_len < o.len) {
341 errno = EINVAL;
342 return NULL;
343 }
344 if (o.code == code) {
345 if (len != NULL)
346 *len = o.len;
347 return d;
348 }
349 }
350
351 errno = ENOENT;
352 return NULL;
353 }
354
355 static void *
356 dhcp6_findmoption(void *data, size_t data_len, uint16_t code,
357 uint16_t *len)
358 {
359 uint8_t *d;
360
361 if (data_len < sizeof(struct dhcp6_message)) {
362 errno = EINVAL;
363 return false;
364 }
365 d = data;
366 d += sizeof(struct dhcp6_message);
367 data_len -= sizeof(struct dhcp6_message);
368 return dhcp6_findoption(d, data_len, code, len);
369 }
370
371 static const uint8_t *
372 dhcp6_getoption(struct dhcpcd_ctx *ctx,
373 size_t *os, unsigned int *code, size_t *len,
374 const uint8_t *od, size_t ol, struct dhcp_opt **oopt)
375 {
376 struct dhcp6_option o;
377 size_t i;
378 struct dhcp_opt *opt;
379
380 if (od != NULL) {
381 *os = sizeof(o);
382 if (ol < *os) {
383 errno = EINVAL;
384 return NULL;
385 }
386 memcpy(&o, od, sizeof(o));
387 *len = ntohs(o.len);
388 if (*len > ol - *os) {
389 errno = ERANGE;
390 return NULL;
391 }
392 *code = ntohs(o.code);
393 }
394
395 *oopt = NULL;
396 for (i = 0, opt = ctx->dhcp6_opts;
397 i < ctx->dhcp6_opts_len; i++, opt++)
398 {
399 if (opt->option == *code) {
400 *oopt = opt;
401 break;
402 }
403 }
404
405 if (od != NULL)
406 return od + sizeof(o);
407 return NULL;
408 }
409
410 static bool
411 dhcp6_updateelapsed(struct interface *ifp, struct dhcp6_message *m, size_t len)
412 {
413 uint8_t *opt;
414 uint16_t opt_len;
415 struct dhcp6_state *state;
416 struct timespec tv;
417 unsigned long long hsec;
418 uint16_t sec;
419
420 opt = dhcp6_findmoption(m, len, D6_OPTION_ELAPSED, &opt_len);
421 if (opt == NULL)
422 return false;
423 if (opt_len != sizeof(sec)) {
424 errno = EINVAL;
425 return false;
426 }
427
428 state = D6_STATE(ifp);
429 clock_gettime(CLOCK_MONOTONIC, &tv);
430 if (state->RTC == 0) {
431 /* An RTC of zero means we're the first message
432 * out of the door, so the elapsed time is zero. */
433 state->started = tv;
434 hsec = 0;
435 } else {
436 unsigned long long secs;
437 unsigned int nsecs;
438
439 secs = eloop_timespec_diff(&tv, &state->started, &nsecs);
440 /* Elapsed time is measured in centiseconds.
441 * We need to be sure it will not potentially overflow. */
442 if (secs >= (UINT16_MAX / CSEC_PER_SEC) + 1)
443 hsec = UINT16_MAX;
444 else {
445 hsec = (secs * CSEC_PER_SEC) +
446 (nsecs / NSEC_PER_CSEC);
447 if (hsec > UINT16_MAX)
448 hsec = UINT16_MAX;
449 }
450 }
451 sec = htons((uint16_t)hsec);
452 memcpy(opt, &sec, sizeof(sec));
453 return true;
454 }
455
456 static void
457 dhcp6_newxid(const struct interface *ifp, struct dhcp6_message *m)
458 {
459 const struct interface *ifp1;
460 const struct dhcp6_state *state1;
461 uint32_t xid;
462
463 if (ifp->options->options & DHCPCD_XID_HWADDR &&
464 ifp->hwlen >= sizeof(xid))
465 /* The lower bits are probably more unique on the network */
466 memcpy(&xid, (ifp->hwaddr + ifp->hwlen) - sizeof(xid),
467 sizeof(xid));
468 else {
469 again:
470 xid = arc4random();
471 }
472
473 m->xid[0] = (xid >> 16) & 0xff;
474 m->xid[1] = (xid >> 8) & 0xff;
475 m->xid[2] = xid & 0xff;
476
477 /* Ensure it's unique */
478 TAILQ_FOREACH(ifp1, ifp->ctx->ifaces, next) {
479 if (ifp == ifp1)
480 continue;
481 if ((state1 = D6_CSTATE(ifp1)) == NULL)
482 continue;
483 if (state1->send != NULL &&
484 state1->send->xid[0] == m->xid[0] &&
485 state1->send->xid[1] == m->xid[1] &&
486 state1->send->xid[2] == m->xid[2])
487 break;
488 }
489
490 if (ifp1 != NULL) {
491 if (ifp->options->options & DHCPCD_XID_HWADDR &&
492 ifp->hwlen >= sizeof(xid))
493 {
494 logerrx("%s: duplicate xid on %s",
495 ifp->name, ifp1->name);
496 return;
497 }
498 goto again;
499 }
500 }
501
502 #ifndef SMALL
503 static const struct if_sla *
504 dhcp6_findselfsla(struct interface *ifp)
505 {
506 size_t i, j;
507 struct if_ia *ia;
508
509 for (i = 0; i < ifp->options->ia_len; i++) {
510 ia = &ifp->options->ia[i];
511 if (ia->ia_type != D6_OPTION_IA_PD)
512 continue;
513 for (j = 0; j < ia->sla_len; j++) {
514 if (strcmp(ia->sla[j].ifname, ifp->name) == 0)
515 return &ia->sla[j];
516 }
517 }
518 return NULL;
519 }
520
521 static int
522 dhcp6_delegateaddr(struct in6_addr *addr, struct interface *ifp,
523 const struct ipv6_addr *prefix, const struct if_sla *sla, struct if_ia *ia)
524 {
525 struct dhcp6_state *state;
526 struct if_sla asla;
527 char sabuf[INET6_ADDRSTRLEN];
528 const char *sa;
529
530 state = D6_STATE(ifp);
531 if (state == NULL) {
532 ifp->if_data[IF_DATA_DHCP6] = calloc(1, sizeof(*state));
533 state = D6_STATE(ifp);
534 if (state == NULL) {
535 logerr(__func__);
536 return -1;
537 }
538
539 TAILQ_INIT(&state->addrs);
540 state->state = DH6S_DELEGATED;
541 state->reason = "DELEGATED6";
542 }
543
544 if (sla == NULL || !sla->sla_set) {
545 /* No SLA set, so make an assumption of
546 * desired SLA and prefix length. */
547 asla.sla = ifp->index;
548 asla.prefix_len = 0;
549 asla.sla_set = false;
550 sla = &asla;
551 } else if (sla->prefix_len == 0) {
552 /* An SLA was given, but prefix length was not.
553 * We need to work out a suitable prefix length for
554 * potentially more than one interface. */
555 asla.sla = sla->sla;
556 asla.prefix_len = 0;
557 asla.sla_set = sla->sla_set;
558 sla = &asla;
559 }
560
561 if (sla->prefix_len == 0) {
562 uint32_t sla_max;
563 int bits;
564
565 sla_max = ia->sla_max;
566 if (sla_max == 0 && (sla == NULL || !sla->sla_set)) {
567 const struct interface *ifi;
568
569 TAILQ_FOREACH(ifi, ifp->ctx->ifaces, next) {
570 if (ifi->index > sla_max)
571 sla_max = ifi->index;
572 }
573 }
574
575 bits = fls32(sla_max);
576
577 if (prefix->prefix_len + bits > (int)UINT8_MAX)
578 asla.prefix_len = UINT8_MAX;
579 else {
580 asla.prefix_len = (uint8_t)(prefix->prefix_len + bits);
581
582 /* Make a 64 prefix by default, as this makes SLAAC
583 * possible.
584 * Otherwise round up to the nearest 4 bits. */
585 if (asla.prefix_len <= 64)
586 asla.prefix_len = 64;
587 else
588 asla.prefix_len =
589 (uint8_t)ROUNDUP4(asla.prefix_len);
590 }
591
592 #define BIT(n) (1UL << (n))
593 #define BIT_MASK(len) (BIT(len) - 1)
594 if (ia->sla_max == 0) {
595 /* Work out the real sla_max from our bits used */
596 bits = asla.prefix_len - prefix->prefix_len;
597 /* Make static analysis happy.
598 * Bits cannot be bigger than 32 thanks to fls32. */
599 assert(bits <= 32);
600 ia->sla_max = (uint32_t)BIT_MASK(bits);
601 }
602 }
603
604 if (ipv6_userprefix(&prefix->prefix, prefix->prefix_len,
605 sla->sla, addr, sla->prefix_len) == -1)
606 {
607 sa = inet_ntop(AF_INET6, &prefix->prefix,
608 sabuf, sizeof(sabuf));
609 logerr("%s: invalid prefix %s/%d + %d/%d",
610 ifp->name, sa, prefix->prefix_len,
611 sla->sla, sla->prefix_len);
612 return -1;
613 }
614
615 if (prefix->prefix_exclude_len &&
616 IN6_ARE_ADDR_EQUAL(addr, &prefix->prefix_exclude))
617 {
618 sa = inet_ntop(AF_INET6, &prefix->prefix_exclude,
619 sabuf, sizeof(sabuf));
620 logerrx("%s: cannot delegate excluded prefix %s/%d",
621 ifp->name, sa, prefix->prefix_exclude_len);
622 return -1;
623 }
624
625 return sla->prefix_len;
626 }
627 #endif
628
629 static int
630 dhcp6_makemessage(struct interface *ifp)
631 {
632 struct dhcp6_state *state;
633 struct dhcp6_message *m;
634 struct dhcp6_option o;
635 uint8_t *p, *si, *unicast, IA;
636 size_t n, l, len, ml, hl;
637 uint8_t type;
638 uint16_t si_len, uni_len, n_options;
639 uint8_t *o_lenp;
640 struct if_options *ifo = ifp->options;
641 const struct dhcp_opt *opt, *opt2;
642 const struct ipv6_addr *ap;
643 char hbuf[HOSTNAME_MAX_LEN + 1];
644 const char *hostname;
645 int fqdn;
646 struct dhcp6_ia_na ia_na;
647 uint16_t ia_na_len;
648 struct if_ia *ifia;
649 #ifdef AUTH
650 uint16_t auth_len;
651 #endif
652 uint8_t duid[DUID_LEN];
653 size_t duid_len = 0;
654
655 state = D6_STATE(ifp);
656 if (state->send) {
657 free(state->send);
658 state->send = NULL;
659 }
660
661 switch(state->state) {
662 case DH6S_INIT: /* FALLTHROUGH */
663 case DH6S_DISCOVER:
664 type = DHCP6_SOLICIT;
665 break;
666 case DH6S_REQUEST:
667 type = DHCP6_REQUEST;
668 break;
669 case DH6S_CONFIRM:
670 type = DHCP6_CONFIRM;
671 break;
672 case DH6S_REBIND:
673 type = DHCP6_REBIND;
674 break;
675 case DH6S_RENEW:
676 type = DHCP6_RENEW;
677 break;
678 case DH6S_INFORM:
679 type = DHCP6_INFORMATION_REQ;
680 break;
681 case DH6S_RELEASE:
682 type = DHCP6_RELEASE;
683 break;
684 case DH6S_DECLINE:
685 type = DHCP6_DECLINE;
686 break;
687 default:
688 errno = EINVAL;
689 return -1;
690 }
691
692 /* RFC 4704 Section 5 says we can only send FQDN for these
693 * message types. */
694 switch(type) {
695 case DHCP6_SOLICIT:
696 case DHCP6_REQUEST:
697 case DHCP6_RENEW:
698 case DHCP6_REBIND:
699 fqdn = ifo->fqdn;
700 break;
701 default:
702 fqdn = FQDN_DISABLE;
703 break;
704 }
705
706 if (fqdn == FQDN_DISABLE && ifo->options & DHCPCD_HOSTNAME) {
707 /* We're sending the DHCPv4 hostname option, so send FQDN as
708 * DHCPv6 has no FQDN option and DHCPv4 must not send
709 * hostname and FQDN according to RFC4702 */
710 fqdn = FQDN_BOTH;
711 }
712 if (fqdn != FQDN_DISABLE)
713 hostname = dhcp_get_hostname(hbuf, sizeof(hbuf), ifo);
714 else
715 hostname = NULL; /* appearse gcc */
716
717 /* Work out option size first */
718 n_options = 0;
719 len = 0;
720 si = NULL;
721 hl = 0; /* Appease gcc */
722 if (state->state != DH6S_RELEASE && state->state != DH6S_DECLINE) {
723 for (l = 0, opt = ifp->ctx->dhcp6_opts;
724 l < ifp->ctx->dhcp6_opts_len;
725 l++, opt++)
726 {
727 for (n = 0, opt2 = ifo->dhcp6_override;
728 n < ifo->dhcp6_override_len;
729 n++, opt2++)
730 {
731 if (opt->option == opt2->option)
732 break;
733 }
734 if (n < ifo->dhcp6_override_len)
735 continue;
736 if (!DHC_REQOPT(opt, ifo->requestmask6, ifo->nomask6))
737 continue;
738 n_options++;
739 len += sizeof(o.len);
740 }
741 #ifndef SMALL
742 for (l = 0, opt = ifo->dhcp6_override;
743 l < ifo->dhcp6_override_len;
744 l++, opt++)
745 {
746 if (!DHC_REQOPT(opt, ifo->requestmask6, ifo->nomask6))
747 continue;
748 n_options++;
749 len += sizeof(o.len);
750 }
751 if (dhcp6_findselfsla(ifp)) {
752 n_options++;
753 len += sizeof(o.len);
754 }
755 #endif
756 if (len)
757 len += sizeof(o);
758
759 if (fqdn != FQDN_DISABLE) {
760 hl = encode_rfc1035(hostname, NULL);
761 len += sizeof(o) + 1 + hl;
762 }
763
764 if (!has_option_mask(ifo->nomask6, D6_OPTION_MUDURL) &&
765 ifo->mudurl[0])
766 len += sizeof(o) + ifo->mudurl[0];
767
768 #ifdef AUTH
769 if ((ifo->auth.options & DHCPCD_AUTH_SENDREQUIRE) !=
770 DHCPCD_AUTH_SENDREQUIRE &&
771 DHC_REQ(ifo->requestmask6, ifo->nomask6,
772 D6_OPTION_RECONF_ACCEPT))
773 len += sizeof(o); /* Reconfigure Accept */
774 #endif
775 }
776
777 len += sizeof(*state->send);
778 len += sizeof(o) + sizeof(uint16_t); /* elapsed */
779
780 if (ifo->options & DHCPCD_ANONYMOUS) {
781 duid_len = duid_make(duid, ifp, DUID_LL);
782 len += sizeof(o) + duid_len;
783 } else {
784 len += sizeof(o) + ifp->ctx->duid_len;
785 }
786
787 if (!has_option_mask(ifo->nomask6, D6_OPTION_USER_CLASS))
788 len += dhcp6_makeuser(NULL, ifp);
789 if (!has_option_mask(ifo->nomask6, D6_OPTION_VENDOR_CLASS))
790 len += dhcp6_makevendor(NULL, ifp);
791
792 /* IA */
793 m = NULL;
794 ml = 0;
795 switch(state->state) {
796 case DH6S_REQUEST:
797 m = state->recv;
798 ml = state->recv_len;
799 /* FALLTHROUGH */
800 case DH6S_DECLINE:
801 /* FALLTHROUGH */
802 case DH6S_RELEASE:
803 /* FALLTHROUGH */
804 case DH6S_RENEW:
805 if (m == NULL) {
806 m = state->new;
807 ml = state->new_len;
808 }
809 si = dhcp6_findmoption(m, ml, D6_OPTION_SERVERID, &si_len);
810 if (si == NULL)
811 return -1;
812 len += sizeof(o) + si_len;
813 /* FALLTHROUGH */
814 case DH6S_REBIND:
815 /* FALLTHROUGH */
816 case DH6S_CONFIRM:
817 /* FALLTHROUGH */
818 case DH6S_DISCOVER:
819 if (m == NULL) {
820 m = state->new;
821 ml = state->new_len;
822 }
823 TAILQ_FOREACH(ap, &state->addrs, next) {
824 if (ap->flags & IPV6_AF_STALE)
825 continue;
826 if (!(ap->flags & IPV6_AF_REQUEST) &&
827 (ap->prefix_vltime == 0 ||
828 state->state == DH6S_DISCOVER))
829 continue;
830 if (DECLINE_IA(ap) && state->state != DH6S_DECLINE)
831 continue;
832 if (ap->ia_type == D6_OPTION_IA_PD) {
833 #ifndef SMALL
834 len += sizeof(o) + sizeof(struct dhcp6_pd_addr);
835 if (ap->prefix_exclude_len)
836 len += sizeof(o) + 1 +
837 (uint8_t)((ap->prefix_exclude_len -
838 ap->prefix_len - 1) / NBBY) + 1;
839 #endif
840 } else
841 len += sizeof(o) + sizeof(struct dhcp6_ia_addr);
842 }
843 /* FALLTHROUGH */
844 case DH6S_INIT:
845 for (l = 0; l < ifo->ia_len; l++) {
846 len += sizeof(o) + sizeof(uint32_t); /* IAID */
847 /* IA_TA does not have T1 or T2 timers */
848 if (ifo->ia[l].ia_type != D6_OPTION_IA_TA)
849 len += sizeof(uint32_t) + sizeof(uint32_t);
850 }
851 IA = 1;
852 break;
853 default:
854 IA = 0;
855 }
856
857 if (state->state == DH6S_DISCOVER &&
858 !(ifp->ctx->options & DHCPCD_TEST) &&
859 DHC_REQ(ifo->requestmask6, ifo->nomask6, D6_OPTION_RAPID_COMMIT))
860 len += sizeof(o);
861
862 if (m == NULL) {
863 m = state->new;
864 ml = state->new_len;
865 }
866
867 switch(state->state) {
868 case DH6S_REQUEST: /* FALLTHROUGH */
869 case DH6S_RENEW: /* FALLTHROUGH */
870 case DH6S_RELEASE:
871 if (has_option_mask(ifo->nomask6, D6_OPTION_UNICAST)) {
872 unicast = NULL;
873 break;
874 }
875 unicast = dhcp6_findmoption(m, ml, D6_OPTION_UNICAST, &uni_len);
876 break;
877 default:
878 unicast = NULL;
879 break;
880 }
881
882 /* In non manager mode we listen and send from fixed addresses.
883 * We should try and match an address we have to unicast to,
884 * but for now this is the safest policy. */
885 if (unicast != NULL && !(ifp->ctx->options & DHCPCD_MANAGER)) {
886 logdebugx("%s: ignoring unicast option as not manager",
887 ifp->name);
888 unicast = NULL;
889 }
890
891 #ifdef AUTH
892 auth_len = 0;
893 if (ifo->auth.options & DHCPCD_AUTH_SEND) {
894 ssize_t alen = dhcp_auth_encode(ifp->ctx, &ifo->auth,
895 state->auth.token, NULL, 0, 6, type, NULL, 0);
896 if (alen != -1 && alen > UINT16_MAX) {
897 errno = ERANGE;
898 alen = -1;
899 }
900 if (alen == -1)
901 logerr("%s: %s: dhcp_auth_encode", __func__, ifp->name);
902 else if (alen != 0) {
903 auth_len = (uint16_t)alen;
904 len += sizeof(o) + auth_len;
905 }
906 }
907 #endif
908
909 state->send = malloc(len);
910 if (state->send == NULL)
911 return -1;
912
913 state->send_len = len;
914 state->send->type = type;
915
916 /* If we found a unicast option, copy it to our state for sending */
917 if (unicast && uni_len == sizeof(state->unicast))
918 memcpy(&state->unicast, unicast, sizeof(state->unicast));
919 else
920 state->unicast = in6addr_any;
921
922 dhcp6_newxid(ifp, state->send);
923
924 #define COPYIN1(_code, _len) { \
925 o.code = htons((_code)); \
926 o.len = htons((_len)); \
927 memcpy(p, &o, sizeof(o)); \
928 p += sizeof(o); \
929 }
930 #define COPYIN(_code, _data, _len) do { \
931 COPYIN1((_code), (_len)); \
932 if ((_len) != 0) { \
933 memcpy(p, (_data), (_len)); \
934 p += (_len); \
935 } \
936 } while (0 /* CONSTCOND */)
937 #define NEXTLEN (p + offsetof(struct dhcp6_option, len))
938
939 /* Options are listed in numerical order as per RFC 7844 Section 4.1
940 * XXX: They should be randomised. */
941
942 p = (uint8_t *)state->send + sizeof(*state->send);
943 if (ifo->options & DHCPCD_ANONYMOUS)
944 COPYIN(D6_OPTION_CLIENTID, duid,
945 (uint16_t)duid_len);
946 else
947 COPYIN(D6_OPTION_CLIENTID, ifp->ctx->duid,
948 (uint16_t)ifp->ctx->duid_len);
949
950 if (si != NULL)
951 COPYIN(D6_OPTION_SERVERID, si, si_len);
952
953 for (l = 0; IA && l < ifo->ia_len; l++) {
954 ifia = &ifo->ia[l];
955 o_lenp = NEXTLEN;
956 /* TA structure is the same as the others,
957 * it just lacks the T1 and T2 timers.
958 * These happen to be at the end of the struct,
959 * so we just don't copy them in. */
960 if (ifia->ia_type == D6_OPTION_IA_TA)
961 ia_na_len = sizeof(struct dhcp6_ia_ta);
962 else
963 ia_na_len = sizeof(ia_na);
964 memcpy(ia_na.iaid, ifia->iaid, sizeof(ia_na.iaid));
965 ia_na.t1 = 0;
966 ia_na.t2 = 0;
967 COPYIN(ifia->ia_type, &ia_na, ia_na_len);
968 TAILQ_FOREACH(ap, &state->addrs, next) {
969 if (ap->flags & IPV6_AF_STALE)
970 continue;
971 if (!(ap->flags & IPV6_AF_REQUEST) &&
972 (ap->prefix_vltime == 0 ||
973 state->state == DH6S_DISCOVER))
974 continue;
975 if (DECLINE_IA(ap) && state->state != DH6S_DECLINE)
976 continue;
977 if (ap->ia_type != ifia->ia_type)
978 continue;
979 if (memcmp(ap->iaid, ifia->iaid, sizeof(ap->iaid)))
980 continue;
981 if (ap->ia_type == D6_OPTION_IA_PD) {
982 #ifndef SMALL
983 struct dhcp6_pd_addr pdp;
984
985 pdp.pltime = htonl(ap->prefix_pltime);
986 pdp.vltime = htonl(ap->prefix_vltime);
987 pdp.prefix_len = ap->prefix_len;
988 /* pdp.prefix is not aligned, so copy it in. */
989 memcpy(&pdp.prefix, &ap->prefix, sizeof(pdp.prefix));
990 COPYIN(D6_OPTION_IAPREFIX, &pdp, sizeof(pdp));
991 ia_na_len = (uint16_t)
992 (ia_na_len + sizeof(o) + sizeof(pdp));
993
994 /* RFC6603 Section 4.2 */
995 if (ap->prefix_exclude_len) {
996 uint8_t exb[16], *ep, u8;
997 const uint8_t *pp;
998
999 n = (size_t)((ap->prefix_exclude_len -
1000 ap->prefix_len - 1) / NBBY) + 1;
1001 ep = exb;
1002 *ep++ = (uint8_t)ap->prefix_exclude_len;
1003 pp = ap->prefix_exclude.s6_addr;
1004 pp += (size_t)
1005 ((ap->prefix_len - 1) / NBBY) +
1006 (n - 1);
1007 u8 = ap->prefix_len % NBBY;
1008 if (u8)
1009 n--;
1010 while (n-- > 0)
1011 *ep++ = *pp--;
1012 if (u8)
1013 *ep = (uint8_t)(*pp << u8);
1014 n++;
1015 COPYIN(D6_OPTION_PD_EXCLUDE, exb,
1016 (uint16_t)n);
1017 ia_na_len = (uint16_t)
1018 (ia_na_len + sizeof(o) + n);
1019 }
1020 #endif
1021 } else {
1022 struct dhcp6_ia_addr ia;
1023
1024 ia.addr = ap->addr;
1025 ia.pltime = htonl(ap->prefix_pltime);
1026 ia.vltime = htonl(ap->prefix_vltime);
1027 COPYIN(D6_OPTION_IA_ADDR, &ia, sizeof(ia));
1028 ia_na_len = (uint16_t)
1029 (ia_na_len + sizeof(o) + sizeof(ia));
1030 }
1031 }
1032
1033 /* Update the total option lenth. */
1034 ia_na_len = htons(ia_na_len);
1035 memcpy(o_lenp, &ia_na_len, sizeof(ia_na_len));
1036 }
1037
1038 if (state->send->type != DHCP6_RELEASE &&
1039 state->send->type != DHCP6_DECLINE &&
1040 n_options)
1041 {
1042 o_lenp = NEXTLEN;
1043 o.len = 0;
1044 COPYIN1(D6_OPTION_ORO, 0);
1045 for (l = 0, opt = ifp->ctx->dhcp6_opts;
1046 l < ifp->ctx->dhcp6_opts_len;
1047 l++, opt++)
1048 {
1049 #ifndef SMALL
1050 for (n = 0, opt2 = ifo->dhcp6_override;
1051 n < ifo->dhcp6_override_len;
1052 n++, opt2++)
1053 {
1054 if (opt->option == opt2->option)
1055 break;
1056 }
1057 if (n < ifo->dhcp6_override_len)
1058 continue;
1059 #endif
1060 if (!DHC_REQOPT(opt, ifo->requestmask6, ifo->nomask6))
1061 continue;
1062 o.code = htons((uint16_t)opt->option);
1063 memcpy(p, &o.code, sizeof(o.code));
1064 p += sizeof(o.code);
1065 o.len = (uint16_t)(o.len + sizeof(o.code));
1066 }
1067 #ifndef SMALL
1068 for (l = 0, opt = ifo->dhcp6_override;
1069 l < ifo->dhcp6_override_len;
1070 l++, opt++)
1071 {
1072 if (!DHC_REQOPT(opt, ifo->requestmask6, ifo->nomask6))
1073 continue;
1074 o.code = htons((uint16_t)opt->option);
1075 memcpy(p, &o.code, sizeof(o.code));
1076 p += sizeof(o.code);
1077 o.len = (uint16_t)(o.len + sizeof(o.code));
1078 }
1079 if (dhcp6_findselfsla(ifp)) {
1080 o.code = htons(D6_OPTION_PD_EXCLUDE);
1081 memcpy(p, &o.code, sizeof(o.code));
1082 p += sizeof(o.code);
1083 o.len = (uint16_t)(o.len + sizeof(o.code));
1084 }
1085 #endif
1086 o.len = htons(o.len);
1087 memcpy(o_lenp, &o.len, sizeof(o.len));
1088 }
1089
1090 si_len = 0;
1091 COPYIN(D6_OPTION_ELAPSED, &si_len, sizeof(si_len));
1092
1093 if (state->state == DH6S_DISCOVER &&
1094 !(ifp->ctx->options & DHCPCD_TEST) &&
1095 DHC_REQ(ifo->requestmask6, ifo->nomask6, D6_OPTION_RAPID_COMMIT))
1096 COPYIN1(D6_OPTION_RAPID_COMMIT, 0);
1097
1098 if (!has_option_mask(ifo->nomask6, D6_OPTION_USER_CLASS))
1099 p += dhcp6_makeuser(p, ifp);
1100 if (!has_option_mask(ifo->nomask6, D6_OPTION_VENDOR_CLASS))
1101 p += dhcp6_makevendor(p, ifp);
1102
1103 if (state->send->type != DHCP6_RELEASE &&
1104 state->send->type != DHCP6_DECLINE)
1105 {
1106 if (fqdn != FQDN_DISABLE) {
1107 o_lenp = NEXTLEN;
1108 COPYIN1(D6_OPTION_FQDN, 0);
1109 if (hl == 0)
1110 *p = D6_FQDN_NONE;
1111 else {
1112 switch (fqdn) {
1113 case FQDN_BOTH:
1114 *p = D6_FQDN_BOTH;
1115 break;
1116 case FQDN_PTR:
1117 *p = D6_FQDN_PTR;
1118 break;
1119 default:
1120 *p = D6_FQDN_NONE;
1121 break;
1122 }
1123 }
1124 p++;
1125 encode_rfc1035(hostname, p);
1126 p += hl;
1127 o.len = htons((uint16_t)(hl + 1));
1128 memcpy(o_lenp, &o.len, sizeof(o.len));
1129 }
1130
1131 if (!has_option_mask(ifo->nomask6, D6_OPTION_MUDURL) &&
1132 ifo->mudurl[0])
1133 COPYIN(D6_OPTION_MUDURL,
1134 ifo->mudurl + 1, ifo->mudurl[0]);
1135
1136 #ifdef AUTH
1137 if ((ifo->auth.options & DHCPCD_AUTH_SENDREQUIRE) !=
1138 DHCPCD_AUTH_SENDREQUIRE &&
1139 DHC_REQ(ifo->requestmask6, ifo->nomask6,
1140 D6_OPTION_RECONF_ACCEPT))
1141 COPYIN1(D6_OPTION_RECONF_ACCEPT, 0);
1142 #endif
1143
1144 }
1145
1146 #ifdef AUTH
1147 /* This has to be the last option */
1148 if (ifo->auth.options & DHCPCD_AUTH_SEND && auth_len != 0) {
1149 COPYIN1(D6_OPTION_AUTH, auth_len);
1150 /* data will be filled at send message time */
1151 }
1152 #endif
1153
1154 return 0;
1155 }
1156
1157 static const char *
1158 dhcp6_get_op(uint16_t type)
1159 {
1160 const struct dhcp6_op *d;
1161
1162 for (d = dhcp6_ops; d->name; d++)
1163 if (d->type == type)
1164 return d->name;
1165 return NULL;
1166 }
1167
1168 static void
1169 dhcp6_freedrop_addrs(struct interface *ifp, int drop,
1170 const struct interface *ifd)
1171 {
1172 struct dhcp6_state *state;
1173
1174 state = D6_STATE(ifp);
1175 if (state) {
1176 ipv6_freedrop_addrs(&state->addrs, drop, ifd);
1177 if (drop)
1178 rt_build(ifp->ctx, AF_INET6);
1179 }
1180 }
1181
1182 #ifndef SMALL
1183 static void dhcp6_delete_delegates(struct interface *ifp)
1184 {
1185 struct interface *ifp0;
1186
1187 if (ifp->ctx->ifaces) {
1188 TAILQ_FOREACH(ifp0, ifp->ctx->ifaces, next) {
1189 if (ifp0 != ifp)
1190 dhcp6_freedrop_addrs(ifp0, 1, ifp);
1191 }
1192 }
1193 }
1194 #endif
1195
1196 #ifdef AUTH
1197 static ssize_t
1198 dhcp6_update_auth(struct interface *ifp, struct dhcp6_message *m, size_t len)
1199 {
1200 struct dhcp6_state *state;
1201 uint8_t *opt;
1202 uint16_t opt_len;
1203
1204 opt = dhcp6_findmoption(m, len, D6_OPTION_AUTH, &opt_len);
1205 if (opt == NULL)
1206 return -1;
1207
1208 state = D6_STATE(ifp);
1209 return dhcp_auth_encode(ifp->ctx, &ifp->options->auth,
1210 state->auth.token, (uint8_t *)state->send, state->send_len, 6,
1211 state->send->type, opt, opt_len);
1212 }
1213 #endif
1214
1215 static const struct in6_addr alldhcp = IN6ADDR_LINKLOCAL_ALLDHCP_INIT;
1216 static int
1217 dhcp6_sendmessage(struct interface *ifp, void (*callback)(void *))
1218 {
1219 struct dhcp6_state *state = D6_STATE(ifp);
1220 struct dhcpcd_ctx *ctx = ifp->ctx;
1221 unsigned int RT;
1222 bool broadcast = true;
1223 struct sockaddr_in6 dst = {
1224 .sin6_family = AF_INET6,
1225 /* Setting the port on Linux gives EINVAL when sending.
1226 * This looks like a kernel bug as the equivalent works
1227 * fine with the DHCP counterpart. */
1228 #ifndef __linux__
1229 .sin6_port = htons(DHCP6_SERVER_PORT),
1230 #endif
1231 };
1232 struct udphdr udp = {
1233 .uh_sport = htons(DHCP6_CLIENT_PORT),
1234 .uh_dport = htons(DHCP6_SERVER_PORT),
1235 .uh_ulen = htons((uint16_t)(sizeof(udp) + state->send_len)),
1236 };
1237 struct iovec iov[] = {
1238 { .iov_base = &udp, .iov_len = sizeof(udp), },
1239 { .iov_base = state->send, .iov_len = state->send_len, },
1240 };
1241 union {
1242 struct cmsghdr hdr;
1243 uint8_t buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
1244 } cmsgbuf = { .buf = { 0 } };
1245 struct msghdr msg = {
1246 .msg_name = &dst, .msg_namelen = sizeof(dst),
1247 .msg_iov = iov, .msg_iovlen = __arraycount(iov),
1248 };
1249 char uaddr[INET6_ADDRSTRLEN];
1250
1251 if (!callback && !if_is_link_up(ifp))
1252 return 0;
1253
1254 if (!IN6_IS_ADDR_UNSPECIFIED(&state->unicast)) {
1255 switch (state->send->type) {
1256 case DHCP6_SOLICIT: /* FALLTHROUGH */
1257 case DHCP6_CONFIRM: /* FALLTHROUGH */
1258 case DHCP6_REBIND:
1259 /* Unicasting is denied for these types. */
1260 break;
1261 default:
1262 broadcast = false;
1263 inet_ntop(AF_INET6, &state->unicast, uaddr,
1264 sizeof(uaddr));
1265 break;
1266 }
1267 }
1268 dst.sin6_addr = broadcast ? alldhcp : state->unicast;
1269
1270 if (!callback) {
1271 logdebugx("%s: %s %s with xid 0x%02x%02x%02x%s%s",
1272 ifp->name,
1273 broadcast ? "broadcasting" : "unicasting",
1274 dhcp6_get_op(state->send->type),
1275 state->send->xid[0],
1276 state->send->xid[1],
1277 state->send->xid[2],
1278 !broadcast ? " " : "",
1279 !broadcast ? uaddr : "");
1280 RT = 0;
1281 } else {
1282 if (state->IMD &&
1283 !(ifp->options->options & DHCPCD_INITIAL_DELAY))
1284 state->IMD = 0;
1285 if (state->IMD) {
1286 state->RT = state->IMD * MSEC_PER_SEC;
1287 /* Some buggy PPP servers close the link too early
1288 * after sending an invalid status in their reply
1289 * which means this host won't see it.
1290 * 1 second grace seems to be the sweet spot. */
1291 if (ifp->flags & IFF_POINTOPOINT)
1292 state->RT += MSEC_PER_SEC;
1293 } else if (state->RTC == 0)
1294 state->RT = state->IRT * MSEC_PER_SEC;
1295
1296 if (state->MRT != 0) {
1297 unsigned int mrt = state->MRT * MSEC_PER_SEC;
1298
1299 if (state->RT > mrt)
1300 state->RT = mrt;
1301 }
1302
1303 /* Add -.1 to .1 * RT randomness as per RFC8415 section 15 */
1304 uint32_t lru = arc4random_uniform(
1305 state->RTC == 0 ? DHCP6_RAND_MAX
1306 : DHCP6_RAND_MAX - DHCP6_RAND_MIN);
1307 int lr = (int)lru - (state->RTC == 0 ? 0 : DHCP6_RAND_MAX);
1308 RT = state->RT
1309 + (unsigned int)((float)state->RT
1310 * ((float)lr / DHCP6_RAND_DIV));
1311
1312 if (if_is_link_up(ifp))
1313 logdebugx("%s: %s %s (xid 0x%02x%02x%02x)%s%s,"
1314 " next in %0.1f seconds",
1315 ifp->name,
1316 state->IMD != 0 ? "delaying" :
1317 broadcast ? "broadcasting" : "unicasting",
1318 dhcp6_get_op(state->send->type),
1319 state->send->xid[0],
1320 state->send->xid[1],
1321 state->send->xid[2],
1322 state->IMD == 0 && !broadcast ? " " : "",
1323 state->IMD == 0 && !broadcast ? uaddr : "",
1324 (float)RT / MSEC_PER_SEC);
1325
1326 /* Wait the initial delay */
1327 if (state->IMD != 0) {
1328 state->IMD = 0;
1329 eloop_timeout_add_msec(ctx->eloop, RT, callback, ifp);
1330 return 0;
1331 }
1332 }
1333
1334 if (!if_is_link_up(ifp))
1335 return 0;
1336
1337 /* Update the elapsed time */
1338 dhcp6_updateelapsed(ifp, state->send, state->send_len);
1339 #ifdef AUTH
1340 if (ifp->options->auth.options & DHCPCD_AUTH_SEND &&
1341 dhcp6_update_auth(ifp, state->send, state->send_len) == -1)
1342 {
1343 logerr("%s: %s: dhcp6_updateauth", __func__, ifp->name);
1344 if (errno != ESRCH)
1345 return -1;
1346 }
1347 #endif
1348
1349 /* Set the outbound interface */
1350 if (broadcast) {
1351 struct cmsghdr *cm;
1352 struct in6_pktinfo pi = { .ipi6_ifindex = ifp->index };
1353
1354 dst.sin6_scope_id = ifp->index;
1355 msg.msg_control = cmsgbuf.buf;
1356 msg.msg_controllen = sizeof(cmsgbuf.buf);
1357 cm = CMSG_FIRSTHDR(&msg);
1358 if (cm == NULL) /* unlikely */
1359 return -1;
1360 cm->cmsg_level = IPPROTO_IPV6;
1361 cm->cmsg_type = IPV6_PKTINFO;
1362 cm->cmsg_len = CMSG_LEN(sizeof(pi));
1363 memcpy(CMSG_DATA(cm), &pi, sizeof(pi));
1364 }
1365
1366 #ifdef PRIVSEP
1367 if (IN_PRIVSEP(ifp->ctx)) {
1368 if (ps_inet_senddhcp6(ifp, &msg) == -1)
1369 logerr(__func__);
1370 goto sent;
1371 }
1372 #endif
1373
1374 if (sendmsg(ctx->dhcp6_wfd, &msg, 0) == -1) {
1375 logerr("%s: %s: sendmsg", __func__, ifp->name);
1376 /* Allow DHCPv6 to continue .... the errors
1377 * would be rate limited by the protocol.
1378 * Generally the error is ENOBUFS when struggling to
1379 * associate with an access point. */
1380 }
1381
1382 #ifdef PRIVSEP
1383 sent:
1384 #endif
1385 state->RTC++;
1386 if (callback) {
1387 state->RT = RT * 2;
1388 if (state->RT < RT) /* Check overflow */
1389 state->RT = RT;
1390 if (state->MRC == 0 || state->RTC < state->MRC)
1391 eloop_timeout_add_msec(ctx->eloop,
1392 RT, callback, ifp);
1393 else if (state->MRC != 0 && state->MRCcallback)
1394 eloop_timeout_add_msec(ctx->eloop,
1395 RT, state->MRCcallback, ifp);
1396 else
1397 logwarnx("%s: sent %d times with no reply",
1398 ifp->name, state->RTC);
1399 }
1400 return 0;
1401 }
1402
1403 static void
1404 dhcp6_sendinform(void *arg)
1405 {
1406
1407 dhcp6_sendmessage(arg, dhcp6_sendinform);
1408 }
1409
1410 static void
1411 dhcp6_senddiscover(void *arg)
1412 {
1413
1414 dhcp6_sendmessage(arg, dhcp6_senddiscover);
1415 }
1416
1417 static void
1418 dhcp6_sendrequest(void *arg)
1419 {
1420
1421 dhcp6_sendmessage(arg, dhcp6_sendrequest);
1422 }
1423
1424 static void
1425 dhcp6_sendrebind(void *arg)
1426 {
1427
1428 dhcp6_sendmessage(arg, dhcp6_sendrebind);
1429 }
1430
1431 static void
1432 dhcp6_sendrenew(void *arg)
1433 {
1434
1435 dhcp6_sendmessage(arg, dhcp6_sendrenew);
1436 }
1437
1438 static void
1439 dhcp6_sendconfirm(void *arg)
1440 {
1441
1442 dhcp6_sendmessage(arg, dhcp6_sendconfirm);
1443 }
1444
1445 static void
1446 dhcp6_senddecline(void *arg)
1447 {
1448
1449 dhcp6_sendmessage(arg, dhcp6_senddecline);
1450 }
1451
1452 static void
1453 dhcp6_sendrelease(void *arg)
1454 {
1455
1456 dhcp6_sendmessage(arg, dhcp6_sendrelease);
1457 }
1458
1459 static void
1460 dhcp6_startrenew(void *arg)
1461 {
1462 struct interface *ifp;
1463 struct dhcp6_state *state;
1464
1465 ifp = arg;
1466 if ((state = D6_STATE(ifp)) == NULL)
1467 return;
1468
1469 /* Only renew in the bound or renew states */
1470 if (state->state != DH6S_BOUND &&
1471 state->state != DH6S_RENEW)
1472 return;
1473
1474 /* Remove the timeout as the renew may have been forced. */
1475 eloop_timeout_delete(ifp->ctx->eloop, dhcp6_startrenew, ifp);
1476
1477 state->state = DH6S_RENEW;
1478 state->RTC = 0;
1479 state->IMD = REN_MAX_DELAY;
1480 state->IRT = REN_TIMEOUT;
1481 state->MRT = REN_MAX_RT;
1482 state->MRC = 0;
1483
1484 if (dhcp6_makemessage(ifp) == -1)
1485 logerr("%s: %s", __func__, ifp->name);
1486 else
1487 dhcp6_sendrenew(ifp);
1488 }
1489
1490 void dhcp6_renew(struct interface *ifp)
1491 {
1492
1493 dhcp6_startrenew(ifp);
1494 }
1495
1496 bool
1497 dhcp6_dadcompleted(const struct interface *ifp)
1498 {
1499 const struct dhcp6_state *state;
1500 const struct ipv6_addr *ap;
1501
1502 state = D6_CSTATE(ifp);
1503 TAILQ_FOREACH(ap, &state->addrs, next) {
1504 if (ap->flags & IPV6_AF_ADDED &&
1505 !(ap->flags & IPV6_AF_DADCOMPLETED))
1506 return false;
1507 }
1508 return true;
1509 }
1510
1511 static void
1512 dhcp6_dadcallback(void *arg)
1513 {
1514 struct ipv6_addr *ia = arg;
1515 struct interface *ifp;
1516 struct dhcp6_state *state;
1517 struct ipv6_addr *ia2;
1518 bool completed, valid, oneduplicated;
1519
1520 completed = (ia->flags & IPV6_AF_DADCOMPLETED);
1521 ia->flags |= IPV6_AF_DADCOMPLETED;
1522 if (ia->addr_flags & IN6_IFF_DUPLICATED)
1523 logwarnx("%s: DAD detected %s", ia->iface->name, ia->saddr);
1524
1525 #ifdef ND6_ADVERTISE
1526 else
1527 ipv6nd_advertise(ia);
1528 #endif
1529 if (completed)
1530 return;
1531
1532 ifp = ia->iface;
1533 state = D6_STATE(ifp);
1534 if (state->state != DH6S_BOUND && state->state != DH6S_DELEGATED)
1535 return;
1536
1537 #ifdef SMALL
1538 valid = true;
1539 #else
1540 valid = (ia->delegating_prefix == NULL);
1541 #endif
1542 completed = true;
1543 oneduplicated = false;
1544 TAILQ_FOREACH(ia2, &state->addrs, next) {
1545 if (ia2->flags & IPV6_AF_ADDED &&
1546 !(ia2->flags & IPV6_AF_DADCOMPLETED))
1547 {
1548 completed = false;
1549 break;
1550 }
1551 if (DECLINE_IA(ia))
1552 oneduplicated = true;
1553 }
1554 if (!completed)
1555 return;
1556
1557 logdebugx("%s: DHCPv6 DAD completed", ifp->name);
1558
1559 if (oneduplicated && state->state == DH6S_BOUND) {
1560 dhcp6_startdecline(ifp);
1561 return;
1562 }
1563
1564 script_runreason(ifp,
1565 #ifndef SMALL
1566 ia->delegating_prefix ? "DELEGATED6" :
1567 #endif
1568 state->reason);
1569 if (valid)
1570 dhcpcd_daemonise(ifp->ctx);
1571 }
1572
1573 static void
1574 dhcp6_addrequestedaddrs(struct interface *ifp)
1575 {
1576 struct dhcp6_state *state;
1577 size_t i;
1578 struct if_ia *ia;
1579 struct ipv6_addr *a;
1580
1581 state = D6_STATE(ifp);
1582 /* Add any requested prefixes / addresses */
1583 for (i = 0; i < ifp->options->ia_len; i++) {
1584 ia = &ifp->options->ia[i];
1585 if (!((ia->ia_type == D6_OPTION_IA_PD && ia->prefix_len) ||
1586 !IN6_IS_ADDR_UNSPECIFIED(&ia->addr)))
1587 continue;
1588 a = ipv6_newaddr(ifp, &ia->addr,
1589 /*
1590 * RFC 5942 Section 5
1591 * We cannot assume any prefix length, nor tie the
1592 * address to an existing one as it could expire
1593 * before the address.
1594 * As such we just give it a 128 prefix.
1595 */
1596 ia->ia_type == D6_OPTION_IA_PD ? ia->prefix_len : 128,
1597 IPV6_AF_REQUEST);
1598 if (a == NULL)
1599 continue;
1600 a->dadcallback = dhcp6_dadcallback;
1601 memcpy(&a->iaid, &ia->iaid, sizeof(a->iaid));
1602 a->ia_type = ia->ia_type;
1603 TAILQ_INSERT_TAIL(&state->addrs, a, next);
1604 }
1605 }
1606
1607 static void
1608 dhcp6_startdiscover(void *arg)
1609 {
1610 struct interface *ifp;
1611 struct dhcp6_state *state;
1612 int llevel;
1613
1614 ifp = arg;
1615 state = D6_STATE(ifp);
1616 #ifndef SMALL
1617 if (state->reason == NULL || strcmp(state->reason, "TIMEOUT6") != 0)
1618 dhcp6_delete_delegates(ifp);
1619 #endif
1620 if (state->new == NULL && !state->failed)
1621 llevel = LOG_INFO;
1622 else
1623 llevel = LOG_DEBUG;
1624 logmessage(llevel, "%s: soliciting a DHCPv6 lease", ifp->name);
1625 state->state = DH6S_DISCOVER;
1626 state->RTC = 0;
1627 state->IMD = SOL_MAX_DELAY;
1628 state->IRT = SOL_TIMEOUT;
1629 state->MRT = state->sol_max_rt;
1630 state->MRC = SOL_MAX_RC;
1631
1632 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1633 free(state->new);
1634 state->new = NULL;
1635 state->new_len = 0;
1636
1637 if (dhcp6_makemessage(ifp) == -1)
1638 logerr("%s: %s", __func__, ifp->name);
1639 else
1640 dhcp6_senddiscover(ifp);
1641 }
1642
1643 static void
1644 dhcp6_startinform(void *arg)
1645 {
1646 struct interface *ifp;
1647 struct dhcp6_state *state;
1648 int llevel;
1649
1650 ifp = arg;
1651 state = D6_STATE(ifp);
1652 if (state->new_start || (state->new == NULL && !state->failed))
1653 llevel = LOG_INFO;
1654 else
1655 llevel = LOG_DEBUG;
1656 logmessage(llevel, "%s: requesting DHCPv6 information", ifp->name);
1657 state->state = DH6S_INFORM;
1658 state->RTC = 0;
1659 state->IMD = INF_MAX_DELAY;
1660 state->IRT = INF_TIMEOUT;
1661 state->MRT = state->inf_max_rt;
1662 state->MRC = 0;
1663
1664 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1665 if (dhcp6_makemessage(ifp) == -1) {
1666 logerr("%s: %s", __func__, ifp->name);
1667 return;
1668 }
1669 dhcp6_sendinform(ifp);
1670 /* RFC3315 18.1.2 says that if CONFIRM failed then the prior addresses
1671 * SHOULD be used. The wording here is poor, because the addresses are
1672 * merely one facet of the lease as a whole.
1673 * This poor wording might explain the lack of similar text for INFORM
1674 * in 18.1.5 because there are no addresses in the INFORM message. */
1675 eloop_timeout_add_sec(ifp->ctx->eloop,
1676 INF_MAX_RD, dhcp6_failinform, ifp);
1677 }
1678
1679 static bool
1680 dhcp6_startdiscoinform(struct interface *ifp)
1681 {
1682 unsigned long long opts = ifp->options->options;
1683
1684 if (opts & DHCPCD_IA_FORCED || ipv6nd_hasradhcp(ifp, true))
1685 dhcp6_startdiscover(ifp);
1686 else if (opts & DHCPCD_INFORM6 || ipv6nd_hasradhcp(ifp, false))
1687 dhcp6_startinform(ifp);
1688 else
1689 return false;
1690 return true;
1691 }
1692
1693 static void
1694 dhcp6_leaseextend(struct interface *ifp)
1695 {
1696 struct dhcp6_state *state = D6_STATE(ifp);
1697 struct ipv6_addr *ia;
1698
1699 logwarnx("%s: extending DHCPv6 lease", ifp->name);
1700 TAILQ_FOREACH(ia, &state->addrs, next) {
1701 ia->flags |= IPV6_AF_EXTENDED;
1702 /* Set infinite lifetimes. */
1703 ia->prefix_pltime = ND6_INFINITE_LIFETIME;
1704 ia->prefix_vltime = ND6_INFINITE_LIFETIME;
1705 }
1706 }
1707
1708 static void
1709 dhcp6_fail(struct interface *ifp)
1710 {
1711 struct dhcp6_state *state = D6_STATE(ifp);
1712
1713 state->failed = true;
1714
1715 /* RFC3315 18.1.2 says that prior addresses SHOULD be used on failure.
1716 * RFC2131 3.2.3 says that MAY chose to use the prior address.
1717 * Because dhcpcd was written first for RFC2131, we have the LASTLEASE
1718 * option which defaults to off as that makes the most sense for
1719 * mobile clients.
1720 * dhcpcd also has LASTLEASE_EXTEND to extend this lease past it's
1721 * expiry, but this is strictly not RFC compliant in any way or form. */
1722 if (state->new != NULL &&
1723 ifp->options->options & DHCPCD_LASTLEASE_EXTEND)
1724 {
1725 dhcp6_leaseextend(ifp);
1726 dhcp6_bind(ifp, NULL, NULL);
1727 } else {
1728 dhcp6_freedrop_addrs(ifp, 1, NULL);
1729 #ifndef SMALL
1730 dhcp6_delete_delegates(ifp);
1731 #endif
1732 free(state->old);
1733 state->old = state->new;
1734 state->old_len = state->new_len;
1735 state->new = NULL;
1736 state->new_len = 0;
1737 if (state->old != NULL)
1738 script_runreason(ifp, "EXPIRE6");
1739 dhcp_unlink(ifp->ctx, state->leasefile);
1740 dhcp6_addrequestedaddrs(ifp);
1741 }
1742
1743 if (!dhcp6_startdiscoinform(ifp)) {
1744 logwarnx("%s: no advertising IPv6 router wants DHCP",ifp->name);
1745 state->state = DH6S_INIT;
1746 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1747 }
1748 }
1749
1750 static int
1751 dhcp6_failloglevel(struct interface *ifp)
1752 {
1753 const struct dhcp6_state *state = D6_CSTATE(ifp);
1754
1755 return state->failed ? LOG_DEBUG : LOG_ERR;
1756 }
1757
1758 static void
1759 dhcp6_failconfirm(void *arg)
1760 {
1761 struct interface *ifp = arg;
1762 int llevel = dhcp6_failloglevel(ifp);
1763
1764 logmessage(llevel, "%s: failed to confirm prior DHCPv6 address",
1765 ifp->name);
1766 dhcp6_fail(ifp);
1767 }
1768
1769 static void
1770 dhcp6_failrequest(void *arg)
1771 {
1772 struct interface *ifp = arg;
1773 int llevel = dhcp6_failloglevel(ifp);
1774
1775 logmessage(llevel, "%s: failed to request DHCPv6 address", ifp->name);
1776 dhcp6_fail(ifp);
1777 }
1778
1779 static void
1780 dhcp6_failinform(void *arg)
1781 {
1782 struct interface *ifp = arg;
1783 int llevel = dhcp6_failloglevel(ifp);
1784
1785 logmessage(llevel, "%s: failed to request DHCPv6 information",
1786 ifp->name);
1787 dhcp6_fail(ifp);
1788 }
1789
1790 #ifndef SMALL
1791 static void
1792 dhcp6_failrebind(void *arg)
1793 {
1794 struct interface *ifp = arg;
1795
1796 logerrx("%s: failed to rebind prior DHCPv6 delegation", ifp->name);
1797 dhcp6_fail(ifp);
1798 }
1799
1800 static int
1801 dhcp6_hasprefixdelegation(struct interface *ifp)
1802 {
1803 size_t i;
1804 uint16_t t;
1805
1806 t = 0;
1807 for (i = 0; i < ifp->options->ia_len; i++) {
1808 if (t && t != ifp->options->ia[i].ia_type) {
1809 if (t == D6_OPTION_IA_PD ||
1810 ifp->options->ia[i].ia_type == D6_OPTION_IA_PD)
1811 return 2;
1812 }
1813 t = ifp->options->ia[i].ia_type;
1814 }
1815 return t == D6_OPTION_IA_PD ? 1 : 0;
1816 }
1817 #endif
1818
1819 static void
1820 dhcp6_startrebind(void *arg)
1821 {
1822 struct interface *ifp;
1823 struct dhcp6_state *state;
1824 #ifndef SMALL
1825 int pd;
1826 #endif
1827
1828 ifp = arg;
1829 eloop_timeout_delete(ifp->ctx->eloop, dhcp6_sendrenew, ifp);
1830 state = D6_STATE(ifp);
1831 if (state->state == DH6S_RENEW)
1832 logwarnx("%s: failed to renew DHCPv6, rebinding", ifp->name);
1833 else
1834 loginfox("%s: rebinding prior DHCPv6 lease", ifp->name);
1835 state->state = DH6S_REBIND;
1836 state->RTC = 0;
1837 state->MRC = 0;
1838
1839 #ifndef SMALL
1840 /* RFC 3633 section 12.1 */
1841 pd = dhcp6_hasprefixdelegation(ifp);
1842 if (pd) {
1843 state->IMD = CNF_MAX_DELAY;
1844 state->IRT = CNF_TIMEOUT;
1845 state->MRT = CNF_MAX_RT;
1846 } else
1847 #endif
1848 {
1849 state->IMD = REB_MAX_DELAY;
1850 state->IRT = REB_TIMEOUT;
1851 state->MRT = REB_MAX_RT;
1852 }
1853
1854 if (dhcp6_makemessage(ifp) == -1)
1855 logerr("%s: %s", __func__, ifp->name);
1856 else
1857 dhcp6_sendrebind(ifp);
1858
1859 #ifndef SMALL
1860 /* RFC 3633 section 12.1 */
1861 if (pd)
1862 eloop_timeout_add_sec(ifp->ctx->eloop,
1863 CNF_MAX_RD, dhcp6_failrebind, ifp);
1864 #endif
1865 }
1866
1867
1868 static void
1869 dhcp6_startrequest(struct interface *ifp)
1870 {
1871 struct dhcp6_state *state;
1872
1873 eloop_timeout_delete(ifp->ctx->eloop, dhcp6_senddiscover, ifp);
1874 state = D6_STATE(ifp);
1875 state->state = DH6S_REQUEST;
1876 state->RTC = 0;
1877 state->IMD = 0;
1878 state->IRT = REQ_TIMEOUT;
1879 state->MRT = REQ_MAX_RT;
1880 state->MRC = REQ_MAX_RC;
1881 state->MRCcallback = dhcp6_failrequest;
1882
1883 if (dhcp6_makemessage(ifp) == -1) {
1884 logerr("%s: %s", __func__, ifp->name);
1885 return;
1886 }
1887
1888 dhcp6_sendrequest(ifp);
1889 }
1890
1891 static void
1892 dhcp6_startconfirm(struct interface *ifp)
1893 {
1894 struct dhcp6_state *state;
1895 struct ipv6_addr *ia;
1896
1897 state = D6_STATE(ifp);
1898
1899 TAILQ_FOREACH(ia, &state->addrs, next) {
1900 if (!DECLINE_IA(ia))
1901 continue;
1902 logerrx("%s: prior DHCPv6 has a duplicated address", ifp->name);
1903 dhcp6_startdecline(ifp);
1904 return;
1905 }
1906
1907 state->state = DH6S_CONFIRM;
1908 state->RTC = 0;
1909 state->IMD = CNF_MAX_DELAY;
1910 state->IRT = CNF_TIMEOUT;
1911 state->MRT = CNF_MAX_RT;
1912 state->MRC = CNF_MAX_RC;
1913
1914 loginfox("%s: confirming prior DHCPv6 lease", ifp->name);
1915
1916 if (dhcp6_makemessage(ifp) == -1) {
1917 logerr("%s: %s", __func__, ifp->name);
1918 return;
1919 }
1920 dhcp6_sendconfirm(ifp);
1921 eloop_timeout_add_sec(ifp->ctx->eloop,
1922 CNF_MAX_RD, dhcp6_failconfirm, ifp);
1923 }
1924
1925 static void
1926 dhcp6_startexpire(void *arg)
1927 {
1928 struct interface *ifp;
1929
1930 ifp = arg;
1931 eloop_timeout_delete(ifp->ctx->eloop, dhcp6_sendrebind, ifp);
1932
1933 logerrx("%s: DHCPv6 lease expired", ifp->name);
1934 dhcp6_fail(ifp);
1935 }
1936
1937 static void
1938 dhcp6_faildecline(void *arg)
1939 {
1940 struct interface *ifp = arg;
1941
1942 logerrx("%s: failed to decline duplicated DHCPv6 addresses", ifp->name);
1943 dhcp6_fail(ifp);
1944 }
1945
1946 static void
1947 dhcp6_startdecline(struct interface *ifp)
1948 {
1949 struct dhcp6_state *state;
1950
1951 state = D6_STATE(ifp);
1952 loginfox("%s: declining failed DHCPv6 addresses", ifp->name);
1953 state->state = DH6S_DECLINE;
1954 state->RTC = 0;
1955 state->IMD = 0;
1956 state->IRT = DEC_TIMEOUT;
1957 state->MRT = 0;
1958 state->MRC = DEC_MAX_RC;
1959 state->MRCcallback = dhcp6_faildecline;
1960
1961 if (dhcp6_makemessage(ifp) == -1)
1962 logerr("%s: %s", __func__, ifp->name);
1963 else
1964 dhcp6_senddecline(ifp);
1965 }
1966
1967 static void
1968 dhcp6_finishrelease(void *arg)
1969 {
1970 struct interface *ifp;
1971 struct dhcp6_state *state;
1972
1973 ifp = (struct interface *)arg;
1974 if ((state = D6_STATE(ifp)) != NULL) {
1975 state->state = DH6S_RELEASED;
1976 dhcp6_drop(ifp, "RELEASE6");
1977 }
1978 }
1979
1980 static void
1981 dhcp6_startrelease(struct interface *ifp)
1982 {
1983 struct dhcp6_state *state;
1984
1985 state = D6_STATE(ifp);
1986 if (state->state != DH6S_BOUND)
1987 return;
1988
1989 state->state = DH6S_RELEASE;
1990 state->RTC = 0;
1991 state->IMD = REL_MAX_DELAY;
1992 state->IRT = REL_TIMEOUT;
1993 state->MRT = REL_MAX_RT;
1994 /* MRC of REL_MAX_RC is optional in RFC 3315 18.1.6 */
1995 #if 0
1996 state->MRC = REL_MAX_RC;
1997 state->MRCcallback = dhcp6_finishrelease;
1998 #else
1999 state->MRC = 0;
2000 state->MRCcallback = NULL;
2001 #endif
2002
2003 if (dhcp6_makemessage(ifp) == -1)
2004 logerr("%s: %s", __func__, ifp->name);
2005 else {
2006 dhcp6_sendrelease(ifp);
2007 dhcp6_finishrelease(ifp);
2008 }
2009 }
2010
2011 static int
2012 dhcp6_checkstatusok(const struct interface *ifp,
2013 struct dhcp6_message *m, uint8_t *p, size_t len)
2014 {
2015 struct dhcp6_state *state;
2016 uint8_t *opt;
2017 uint16_t opt_len, code;
2018 size_t mlen;
2019 void * (*f)(void *, size_t, uint16_t, uint16_t *), *farg;
2020 char buf[32], *sbuf;
2021 const char *status;
2022 int loglevel;
2023
2024 state = D6_STATE(ifp);
2025 f = p ? dhcp6_findoption : dhcp6_findmoption;
2026 if (p)
2027 farg = p;
2028 else
2029 farg = m;
2030 if ((opt = f(farg, len, D6_OPTION_STATUS_CODE, &opt_len)) == NULL) {
2031 //logdebugx("%s: no status", ifp->name);
2032 state->lerror = 0;
2033 errno = ESRCH;
2034 return 0;
2035 }
2036
2037 if (opt_len < sizeof(code)) {
2038 logerrx("%s: status truncated", ifp->name);
2039 return -1;
2040 }
2041 memcpy(&code, opt, sizeof(code));
2042 code = ntohs(code);
2043 if (code == D6_STATUS_OK) {
2044 state->lerror = 0;
2045 errno = 0;
2046 return 0;
2047 }
2048
2049 /* Anything after the code is a message. */
2050 opt += sizeof(code);
2051 mlen = opt_len - sizeof(code);
2052 if (mlen == 0) {
2053 sbuf = NULL;
2054 if (code < sizeof(dhcp6_statuses) / sizeof(char *))
2055 status = dhcp6_statuses[code];
2056 else {
2057 snprintf(buf, sizeof(buf), "Unknown Status (%d)", code);
2058 status = buf;
2059 }
2060 } else {
2061 if ((sbuf = malloc(mlen + 1)) == NULL) {
2062 logerr(__func__);
2063 return -1;
2064 }
2065 memcpy(sbuf, opt, mlen);
2066 sbuf[mlen] = '\0';
2067 status = sbuf;
2068 }
2069
2070 if (state->lerror == code || state->state == DH6S_INIT)
2071 loglevel = LOG_DEBUG;
2072 else
2073 loglevel = LOG_ERR;
2074 logmessage(loglevel, "%s: DHCPv6 REPLY: %s", ifp->name, status);
2075 free(sbuf);
2076 state->lerror = code;
2077 errno = 0;
2078
2079 /* code cannot be D6_STATUS_OK, so there is a failure */
2080 if (ifp->ctx->options & DHCPCD_TEST)
2081 eloop_exit(ifp->ctx->eloop, EXIT_FAILURE);
2082
2083 return (int)code;
2084 }
2085
2086 const struct ipv6_addr *
2087 dhcp6_iffindaddr(const struct interface *ifp, const struct in6_addr *addr,
2088 unsigned int flags)
2089 {
2090 const struct dhcp6_state *state;
2091 const struct ipv6_addr *ap;
2092
2093 if ((state = D6_STATE(ifp)) != NULL) {
2094 TAILQ_FOREACH(ap, &state->addrs, next) {
2095 if (ipv6_findaddrmatch(ap, addr, flags))
2096 return ap;
2097 }
2098 }
2099 return NULL;
2100 }
2101
2102 struct ipv6_addr *
2103 dhcp6_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr,
2104 unsigned int flags)
2105 {
2106 struct interface *ifp;
2107 struct ipv6_addr *ap;
2108 struct dhcp6_state *state;
2109
2110 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
2111 if ((state = D6_STATE(ifp)) != NULL) {
2112 TAILQ_FOREACH(ap, &state->addrs, next) {
2113 if (ipv6_findaddrmatch(ap, addr, flags))
2114 return ap;
2115 }
2116 }
2117 }
2118 return NULL;
2119 }
2120
2121 static int
2122 dhcp6_findna(struct interface *ifp, uint16_t ot, const uint8_t *iaid,
2123 uint8_t *d, size_t l, const struct timespec *acquired)
2124 {
2125 struct dhcp6_state *state;
2126 uint8_t *o, *nd;
2127 uint16_t ol;
2128 struct ipv6_addr *a;
2129 int i;
2130 struct dhcp6_ia_addr ia;
2131
2132 i = 0;
2133 state = D6_STATE(ifp);
2134 while ((o = dhcp6_findoption(d, l, D6_OPTION_IA_ADDR, &ol))) {
2135 /* Set d and l first to ensure we find the next option. */
2136 nd = o + ol;
2137 l -= (size_t)(nd - d);
2138 d = nd;
2139 if (ol < sizeof(ia)) {
2140 errno = EINVAL;
2141 logerrx("%s: IA Address option truncated", ifp->name);
2142 continue;
2143 }
2144 memcpy(&ia, o, sizeof(ia));
2145 ia.pltime = ntohl(ia.pltime);
2146 ia.vltime = ntohl(ia.vltime);
2147 /* RFC 3315 22.6 */
2148 if (ia.pltime > ia.vltime) {
2149 errno = EINVAL;
2150 logerr("%s: IA Address pltime %"PRIu32
2151 " > vltime %"PRIu32,
2152 ifp->name, ia.pltime, ia.vltime);
2153 continue;
2154 }
2155 TAILQ_FOREACH(a, &state->addrs, next) {
2156 if (ipv6_findaddrmatch(a, &ia.addr, 0))
2157 break;
2158 }
2159 if (a == NULL) {
2160 /*
2161 * RFC 5942 Section 5
2162 * We cannot assume any prefix length, nor tie the
2163 * address to an existing one as it could expire
2164 * before the address.
2165 * As such we just give it a 128 prefix.
2166 */
2167 a = ipv6_newaddr(ifp, &ia.addr, 128, IPV6_AF_ONLINK);
2168 a->dadcallback = dhcp6_dadcallback;
2169 a->ia_type = ot;
2170 memcpy(a->iaid, iaid, sizeof(a->iaid));
2171 a->created = *acquired;
2172
2173 TAILQ_INSERT_TAIL(&state->addrs, a, next);
2174 } else {
2175 if (!(a->flags & IPV6_AF_ONLINK))
2176 a->flags |= IPV6_AF_ONLINK | IPV6_AF_NEW;
2177 a->flags &= ~(IPV6_AF_STALE | IPV6_AF_EXTENDED);
2178 }
2179 a->acquired = *acquired;
2180 a->prefix_pltime = ia.pltime;
2181 if (a->prefix_vltime != ia.vltime) {
2182 a->flags |= IPV6_AF_NEW;
2183 a->prefix_vltime = ia.vltime;
2184 }
2185 if (a->prefix_pltime && a->prefix_pltime < state->lowpl)
2186 state->lowpl = a->prefix_pltime;
2187 if (a->prefix_vltime && a->prefix_vltime > state->expire)
2188 state->expire = a->prefix_vltime;
2189 i++;
2190 }
2191 return i;
2192 }
2193
2194 #ifndef SMALL
2195 static int
2196 dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
2197 uint8_t *d, size_t l, const struct timespec *acquired)
2198 {
2199 struct dhcp6_state *state;
2200 uint8_t *o, *nd;
2201 struct ipv6_addr *a;
2202 int i;
2203 uint8_t nb, *pw;
2204 uint16_t ol;
2205 struct dhcp6_pd_addr pdp;
2206 struct in6_addr pdp_prefix;
2207
2208 i = 0;
2209 state = D6_STATE(ifp);
2210 while ((o = dhcp6_findoption(d, l, D6_OPTION_IAPREFIX, &ol))) {
2211 /* Set d and l first to ensure we find the next option. */
2212 nd = o + ol;
2213 l -= (size_t)(nd - d);
2214 d = nd;
2215 if (ol < sizeof(pdp)) {
2216 errno = EINVAL;
2217 logerrx("%s: IA Prefix option truncated", ifp->name);
2218 continue;
2219 }
2220
2221 memcpy(&pdp, o, sizeof(pdp));
2222 pdp.pltime = ntohl(pdp.pltime);
2223 pdp.vltime = ntohl(pdp.vltime);
2224 /* RFC 3315 22.6 */
2225 if (pdp.pltime > pdp.vltime) {
2226 errno = EINVAL;
2227 logerrx("%s: IA Prefix pltime %"PRIu32
2228 " > vltime %"PRIu32,
2229 ifp->name, pdp.pltime, pdp.vltime);
2230 continue;
2231 }
2232
2233 o += sizeof(pdp);
2234 ol = (uint16_t)(ol - sizeof(pdp));
2235
2236 /* pdp.prefix is not aligned so copy it out. */
2237 memcpy(&pdp_prefix, &pdp.prefix, sizeof(pdp_prefix));
2238 TAILQ_FOREACH(a, &state->addrs, next) {
2239 if (IN6_ARE_ADDR_EQUAL(&a->prefix, &pdp_prefix))
2240 break;
2241 }
2242
2243 if (a == NULL) {
2244 a = ipv6_newaddr(ifp, &pdp_prefix, pdp.prefix_len,
2245 IPV6_AF_DELEGATEDPFX);
2246 if (a == NULL)
2247 break;
2248 a->created = *acquired;
2249 a->dadcallback = dhcp6_dadcallback;
2250 a->ia_type = D6_OPTION_IA_PD;
2251 memcpy(a->iaid, iaid, sizeof(a->iaid));
2252 TAILQ_INSERT_TAIL(&state->addrs, a, next);
2253 } else {
2254 if (!(a->flags & IPV6_AF_DELEGATEDPFX))
2255 a->flags |= IPV6_AF_NEW | IPV6_AF_DELEGATEDPFX;
2256 a->flags &= ~(IPV6_AF_STALE |
2257 IPV6_AF_EXTENDED |
2258 IPV6_AF_REQUEST);
2259 if (a->prefix_vltime != pdp.vltime)
2260 a->flags |= IPV6_AF_NEW;
2261 }
2262
2263 a->acquired = *acquired;
2264 a->prefix_pltime = pdp.pltime;
2265 a->prefix_vltime = pdp.vltime;
2266
2267 if (a->prefix_pltime && a->prefix_pltime < state->lowpl)
2268 state->lowpl = a->prefix_pltime;
2269 if (a->prefix_vltime && a->prefix_vltime > state->expire)
2270 state->expire = a->prefix_vltime;
2271 i++;
2272
2273 a->prefix_exclude_len = 0;
2274 memset(&a->prefix_exclude, 0, sizeof(a->prefix_exclude));
2275 o = dhcp6_findoption(o, ol, D6_OPTION_PD_EXCLUDE, &ol);
2276 if (o == NULL)
2277 continue;
2278
2279 /* RFC 6603 4.2 says option length MUST be between 2 and 17.
2280 * This allows 1 octet for prefix length and 16 for the
2281 * subnet ID. */
2282 if (ol < 2 || ol > 17) {
2283 logerrx("%s: invalid PD Exclude option", ifp->name);
2284 continue;
2285 }
2286
2287 /* RFC 6603 4.2 says prefix length MUST be between the
2288 * length of the IAPREFIX prefix length + 1 and 128. */
2289 if (*o < a->prefix_len + 1 || *o > 128) {
2290 logerrx("%s: invalid PD Exclude length", ifp->name);
2291 continue;
2292 }
2293
2294 ol--;
2295 /* Check option length matches prefix length. */
2296 if (((*o - a->prefix_len - 1) / NBBY) + 1 != ol) {
2297 logerrx("%s: PD Exclude length mismatch", ifp->name);
2298 continue;
2299 }
2300 a->prefix_exclude_len = *o++;
2301
2302 memcpy(&a->prefix_exclude, &a->prefix,
2303 sizeof(a->prefix_exclude));
2304 nb = a->prefix_len % NBBY;
2305 if (nb)
2306 ol--;
2307 pw = a->prefix_exclude.s6_addr +
2308 (a->prefix_exclude_len / NBBY) - 1;
2309 while (ol-- > 0)
2310 *pw-- = *o++;
2311 if (nb)
2312 *pw = (uint8_t)(*pw | (*o >> nb));
2313 }
2314 return i;
2315 }
2316 #endif
2317
2318 static int
2319 dhcp6_findia(struct interface *ifp, struct dhcp6_message *m, size_t l,
2320 const char *sfrom, const struct timespec *acquired)
2321 {
2322 struct dhcp6_state *state;
2323 const struct if_options *ifo;
2324 struct dhcp6_option o;
2325 uint8_t *d, *p;
2326 struct dhcp6_ia_na ia;
2327 int i, e, error;
2328 size_t j;
2329 uint16_t nl;
2330 uint8_t iaid[4];
2331 char buf[sizeof(iaid) * 3];
2332 struct ipv6_addr *ap;
2333 struct if_ia *ifia;
2334
2335 if (l < sizeof(*m)) {
2336 /* Should be impossible with guards at packet in
2337 * and reading leases */
2338 errno = EINVAL;
2339 return -1;
2340 }
2341
2342 ifo = ifp->options;
2343 i = e = 0;
2344 state = D6_STATE(ifp);
2345 TAILQ_FOREACH(ap, &state->addrs, next) {
2346 if (!(ap->flags & IPV6_AF_DELEGATED))
2347 ap->flags |= IPV6_AF_STALE;
2348 }
2349
2350 d = (uint8_t *)m + sizeof(*m);
2351 l -= sizeof(*m);
2352 while (l > sizeof(o)) {
2353 memcpy(&o, d, sizeof(o));
2354 o.len = ntohs(o.len);
2355 if (o.len > l || sizeof(o) + o.len > l) {
2356 errno = EINVAL;
2357 logerrx("%s: option overflow", ifp->name);
2358 break;
2359 }
2360 p = d + sizeof(o);
2361 d = p + o.len;
2362 l -= sizeof(o) + o.len;
2363
2364 o.code = ntohs(o.code);
2365 switch(o.code) {
2366 case D6_OPTION_IA_TA:
2367 nl = 4;
2368 break;
2369 case D6_OPTION_IA_NA:
2370 case D6_OPTION_IA_PD:
2371 nl = 12;
2372 break;
2373 default:
2374 continue;
2375 }
2376 if (o.len < nl) {
2377 errno = EINVAL;
2378 logerrx("%s: IA option truncated", ifp->name);
2379 continue;
2380 }
2381
2382 memcpy(&ia, p, nl);
2383 p += nl;
2384 o.len = (uint16_t)(o.len - nl);
2385
2386 for (j = 0; j < ifo->ia_len; j++) {
2387 ifia = &ifo->ia[j];
2388 if (ifia->ia_type == o.code &&
2389 memcmp(ifia->iaid, ia.iaid, sizeof(ia.iaid)) == 0)
2390 break;
2391 }
2392 if (j == ifo->ia_len &&
2393 !(ifo->ia_len == 0 && ifp->ctx->options & DHCPCD_DUMPLEASE))
2394 {
2395 logdebugx("%s: ignoring unrequested IAID %s",
2396 ifp->name,
2397 hwaddr_ntoa(ia.iaid, sizeof(ia.iaid),
2398 buf, sizeof(buf)));
2399 continue;
2400 }
2401
2402 if (o.code != D6_OPTION_IA_TA) {
2403 ia.t1 = ntohl(ia.t1);
2404 ia.t2 = ntohl(ia.t2);
2405 /* RFC 3315 22.4 */
2406 if (ia.t2 > 0 && ia.t1 > ia.t2) {
2407 logwarnx("%s: IAID %s T1(%d) > T2(%d) from %s",
2408 ifp->name,
2409 hwaddr_ntoa(iaid, sizeof(iaid), buf,
2410 sizeof(buf)),
2411 ia.t1, ia.t2, sfrom);
2412 continue;
2413 }
2414 } else
2415 ia.t1 = ia.t2 = 0; /* appease gcc */
2416 if ((error = dhcp6_checkstatusok(ifp, NULL, p, o.len)) != 0) {
2417 if (error == D6_STATUS_NOBINDING)
2418 state->has_no_binding = true;
2419 e = 1;
2420 continue;
2421 }
2422 if (o.code == D6_OPTION_IA_PD) {
2423 #ifndef SMALL
2424 if (dhcp6_findpd(ifp, ia.iaid, p, o.len,
2425 acquired) == 0)
2426 {
2427 logwarnx("%s: %s: DHCPv6 REPLY missing Prefix",
2428 ifp->name, sfrom);
2429 continue;
2430 }
2431 #endif
2432 } else {
2433 if (dhcp6_findna(ifp, o.code, ia.iaid, p, o.len,
2434 acquired) == 0)
2435 {
2436 logwarnx("%s: %s: DHCPv6 REPLY missing "
2437 "IA Address",
2438 ifp->name, sfrom);
2439 continue;
2440 }
2441 }
2442 if (o.code != D6_OPTION_IA_TA) {
2443 if (ia.t1 != 0 &&
2444 (ia.t1 < state->renew || state->renew == 0))
2445 state->renew = ia.t1;
2446 if (ia.t2 != 0 &&
2447 (ia.t2 < state->rebind || state->rebind == 0))
2448 state->rebind = ia.t2;
2449 }
2450 i++;
2451 }
2452
2453 if (i == 0 && e)
2454 return -1;
2455 return i;
2456 }
2457
2458 #ifndef SMALL
2459 static void
2460 dhcp6_deprecatedele(struct ipv6_addr *ia)
2461 {
2462 struct ipv6_addr *da, *dan, *dda;
2463 struct timespec now;
2464 struct dhcp6_state *state;
2465
2466 timespecclear(&now);
2467 TAILQ_FOREACH_SAFE(da, &ia->pd_pfxs, pd_next, dan) {
2468 if (ia->prefix_vltime == 0) {
2469 if (da->prefix_vltime != 0)
2470 da->prefix_vltime = 0;
2471 else
2472 continue;
2473 } else if (da->prefix_pltime != 0)
2474 da->prefix_pltime = 0;
2475 else
2476 continue;
2477
2478 if (ipv6_doaddr(da, &now) != -1)
2479 continue;
2480
2481 /* Delegation deleted, forget it. */
2482 TAILQ_REMOVE(&ia->pd_pfxs, da, pd_next);
2483
2484 /* Delete it from the interface. */
2485 state = D6_STATE(da->iface);
2486 TAILQ_FOREACH(dda, &state->addrs, next) {
2487 if (IN6_ARE_ADDR_EQUAL(&dda->addr, &da->addr))
2488 break;
2489 }
2490 if (dda != NULL) {
2491 TAILQ_REMOVE(&state->addrs, dda, next);
2492 ipv6_freeaddr(dda);
2493 }
2494 }
2495 }
2496 #endif
2497
2498 static void
2499 dhcp6_deprecateaddrs(struct ipv6_addrhead *addrs)
2500 {
2501 struct ipv6_addr *ia, *ian;
2502
2503 TAILQ_FOREACH_SAFE(ia, addrs, next, ian) {
2504 if (ia->flags & IPV6_AF_EXTENDED)
2505 ;
2506 else if (ia->flags & IPV6_AF_STALE) {
2507 if (ia->prefix_vltime != 0)
2508 logdebugx("%s: %s: became stale",
2509 ia->iface->name, ia->saddr);
2510 /* Technically this violates RFC 8415 18.2.10.1,
2511 * but we need a mechanism to tell the kernel to
2512 * try and prefer other addresses. */
2513 ia->prefix_pltime = 0;
2514 } else if (ia->prefix_vltime == 0)
2515 loginfox("%s: %s: no valid lifetime",
2516 ia->iface->name, ia->saddr);
2517 else
2518 continue;
2519
2520 #ifndef SMALL
2521 /* If we delegated from this prefix, deprecate or remove
2522 * the delegations. */
2523 if (ia->flags & IPV6_AF_DELEGATEDPFX)
2524 dhcp6_deprecatedele(ia);
2525 #endif
2526
2527 if (ia->flags & IPV6_AF_REQUEST) {
2528 ia->prefix_vltime = ia->prefix_pltime = 0;
2529 eloop_q_timeout_delete(ia->iface->ctx->eloop,
2530 ELOOP_QUEUE_ALL, NULL, ia);
2531 continue;
2532 }
2533 TAILQ_REMOVE(addrs, ia, next);
2534 if (ia->flags & IPV6_AF_EXTENDED)
2535 ipv6_deleteaddr(ia);
2536 ipv6_freeaddr(ia);
2537 }
2538 }
2539
2540 static int
2541 dhcp6_validatelease(struct interface *ifp,
2542 struct dhcp6_message *m, size_t len,
2543 const char *sfrom, const struct timespec *acquired)
2544 {
2545 struct dhcp6_state *state;
2546 int nia, ok_errno;
2547 struct timespec aq;
2548
2549 if (len <= sizeof(*m)) {
2550 logerrx("%s: DHCPv6 lease truncated", ifp->name);
2551 return -1;
2552 }
2553
2554 state = D6_STATE(ifp);
2555 errno = 0;
2556 if (dhcp6_checkstatusok(ifp, m, NULL, len) != 0)
2557 return -1;
2558 ok_errno = errno;
2559
2560 state->renew = state->rebind = state->expire = 0;
2561 state->lowpl = ND6_INFINITE_LIFETIME;
2562 if (!acquired) {
2563 clock_gettime(CLOCK_MONOTONIC, &aq);
2564 acquired = &aq;
2565 }
2566 state->has_no_binding = false;
2567 nia = dhcp6_findia(ifp, m, len, sfrom, acquired);
2568 if (nia == 0) {
2569 if (state->state != DH6S_CONFIRM && ok_errno != 0) {
2570 logerrx("%s: no useable IA found in lease", ifp->name);
2571 return -1;
2572 }
2573
2574 /* We are confirming and have an OK,
2575 * so look for ia's in our old lease.
2576 * IA's must have existed here otherwise we would
2577 * have rejected it earlier. */
2578 assert(state->new != NULL && state->new_len != 0);
2579 state->has_no_binding = false;
2580 nia = dhcp6_findia(ifp, state->new, state->new_len,
2581 sfrom, acquired);
2582 }
2583 return nia;
2584 }
2585
2586 static ssize_t
2587 dhcp6_readlease(struct interface *ifp, int validate)
2588 {
2589 union {
2590 struct dhcp6_message dhcp6;
2591 uint8_t buf[UDPLEN_MAX];
2592 } buf;
2593 struct dhcp6_state *state;
2594 ssize_t bytes;
2595 int fd;
2596 time_t mtime, now;
2597 #ifdef AUTH
2598 uint8_t *o;
2599 uint16_t ol;
2600 #endif
2601
2602 state = D6_STATE(ifp);
2603 if (state->leasefile[0] == '\0') {
2604 logdebugx("reading standard input");
2605 bytes = read(fileno(stdin), buf.buf, sizeof(buf.buf));
2606 } else {
2607 logdebugx("%s: reading lease: %s",
2608 ifp->name, state->leasefile);
2609 bytes = dhcp_readfile(ifp->ctx, state->leasefile,
2610 buf.buf, sizeof(buf.buf));
2611 }
2612 if (bytes == -1)
2613 goto ex;
2614
2615 if (ifp->ctx->options & DHCPCD_DUMPLEASE || state->leasefile[0] == '\0')
2616 goto out;
2617
2618 if (bytes == 0)
2619 goto ex;
2620
2621 /* If not validating IA's and if they have expired,
2622 * skip to the auth check. */
2623 if (!validate)
2624 goto auth;
2625
2626 if (dhcp_filemtime(ifp->ctx, state->leasefile, &mtime) == -1)
2627 goto ex;
2628 clock_gettime(CLOCK_MONOTONIC, &state->acquired);
2629 if ((now = time(NULL)) == -1)
2630 goto ex;
2631 state->acquired.tv_sec -= now - mtime;
2632
2633 /* Check to see if the lease is still valid */
2634 fd = dhcp6_validatelease(ifp, &buf.dhcp6, (size_t)bytes, NULL,
2635 &state->acquired);
2636 if (fd == -1)
2637 goto ex;
2638
2639 if (state->expire != ND6_INFINITE_LIFETIME &&
2640 (time_t)state->expire < now - mtime &&
2641 !(ifp->options->options & DHCPCD_LASTLEASE_EXTEND))
2642 {
2643 logdebugx("%s: discarding expired lease", ifp->name);
2644 bytes = 0;
2645 goto ex;
2646 }
2647
2648 auth:
2649 #ifdef AUTH
2650 /* Authenticate the message */
2651 o = dhcp6_findmoption(&buf.dhcp6, (size_t)bytes, D6_OPTION_AUTH, &ol);
2652 if (o) {
2653 if (dhcp_auth_validate(&state->auth, &ifp->options->auth,
2654 buf.buf, (size_t)bytes, 6, buf.dhcp6.type, o, ol) == NULL)
2655 {
2656 logerr("%s: authentication failed", ifp->name);
2657 bytes = 0;
2658 goto ex;
2659 }
2660 if (state->auth.token)
2661 logdebugx("%s: validated using 0x%08" PRIu32,
2662 ifp->name, state->auth.token->secretid);
2663 else
2664 loginfox("%s: accepted reconfigure key", ifp->name);
2665 } else if ((ifp->options->auth.options & DHCPCD_AUTH_SENDREQUIRE) ==
2666 DHCPCD_AUTH_SENDREQUIRE)
2667 {
2668 logerrx("%s: authentication now required", ifp->name);
2669 goto ex;
2670 }
2671 #endif
2672
2673 out:
2674 free(state->new);
2675 state->new = malloc((size_t)bytes);
2676 if (state->new == NULL) {
2677 logerr(__func__);
2678 goto ex;
2679 }
2680
2681 memcpy(state->new, buf.buf, (size_t)bytes);
2682 state->new_len = (size_t)bytes;
2683 return bytes;
2684
2685 ex:
2686 dhcp6_freedrop_addrs(ifp, 0, NULL);
2687 dhcp_unlink(ifp->ctx, state->leasefile);
2688 free(state->new);
2689 state->new = NULL;
2690 state->new_len = 0;
2691 dhcp6_addrequestedaddrs(ifp);
2692 return bytes == 0 ? 0 : -1;
2693 }
2694
2695 static void
2696 dhcp6_startinit(struct interface *ifp)
2697 {
2698 struct dhcp6_state *state;
2699 ssize_t r;
2700 uint8_t has_ta, has_non_ta;
2701 size_t i;
2702
2703 state = D6_STATE(ifp);
2704 state->state = DH6S_INIT;
2705 state->expire = ND6_INFINITE_LIFETIME;
2706 state->lowpl = ND6_INFINITE_LIFETIME;
2707
2708 dhcp6_addrequestedaddrs(ifp);
2709 has_ta = has_non_ta = 0;
2710 for (i = 0; i < ifp->options->ia_len; i++) {
2711 switch (ifp->options->ia[i].ia_type) {
2712 case D6_OPTION_IA_TA:
2713 has_ta = 1;
2714 break;
2715 default:
2716 has_non_ta = 1;
2717 }
2718 }
2719
2720 if (!(ifp->ctx->options & DHCPCD_TEST) &&
2721 !(has_ta && !has_non_ta) &&
2722 ifp->options->reboot != 0)
2723 {
2724 r = dhcp6_readlease(ifp, 1);
2725 if (r == -1) {
2726 if (errno != ENOENT && errno != ESRCH)
2727 logerr("%s: %s", __func__, state->leasefile);
2728 } else if (r != 0 &&
2729 !(ifp->options->options & DHCPCD_ANONYMOUS))
2730 {
2731 /* RFC 3633 section 12.1 */
2732 #ifndef SMALL
2733 if (dhcp6_hasprefixdelegation(ifp))
2734 dhcp6_startrebind(ifp);
2735 else
2736 #endif
2737 dhcp6_startconfirm(ifp);
2738 return;
2739 }
2740 }
2741 dhcp6_startdiscoinform(ifp);
2742 }
2743
2744 #ifndef SMALL
2745 static struct ipv6_addr *
2746 dhcp6_ifdelegateaddr(struct interface *ifp, struct ipv6_addr *prefix,
2747 const struct if_sla *sla, struct if_ia *if_ia)
2748 {
2749 struct dhcp6_state *state;
2750 struct in6_addr addr, daddr;
2751 struct ipv6_addr *ia;
2752 int pfxlen, dadcounter;
2753 uint64_t vl;
2754
2755 /* RFC6603 Section 4.2 */
2756 if (strcmp(ifp->name, prefix->iface->name) == 0) {
2757 if (prefix->prefix_exclude_len == 0) {
2758 /* Don't spam the log automatically */
2759 if (sla != NULL)
2760 logwarnx("%s: DHCPv6 server does not support "
2761 "OPTION_PD_EXCLUDE",
2762 ifp->name);
2763 return NULL;
2764 }
2765 pfxlen = prefix->prefix_exclude_len;
2766 memcpy(&addr, &prefix->prefix_exclude, sizeof(addr));
2767 } else if ((pfxlen = dhcp6_delegateaddr(&addr, ifp, prefix,
2768 sla, if_ia)) == -1)
2769 return NULL;
2770
2771 if (sla != NULL && fls64(sla->suffix) > 128 - pfxlen) {
2772 logerrx("%s: suffix %" PRIu64 " + prefix_len %d > 128",
2773 ifp->name, sla->suffix, pfxlen);
2774 return NULL;
2775 }
2776
2777 /* Add our suffix */
2778 if (sla != NULL && sla->suffix != 0) {
2779 daddr = addr;
2780 vl = be64dec(addr.s6_addr + 8);
2781 vl |= sla->suffix;
2782 be64enc(daddr.s6_addr + 8, vl);
2783 } else {
2784 dadcounter = ipv6_makeaddr(&daddr, ifp, &addr, pfxlen, 0);
2785 if (dadcounter == -1) {
2786 logerrx("%s: error adding slaac to prefix_len %d",
2787 ifp->name, pfxlen);
2788 return NULL;
2789 }
2790 }
2791
2792 /* Find an existing address */
2793 state = D6_STATE(ifp);
2794 TAILQ_FOREACH(ia, &state->addrs, next) {
2795 if (IN6_ARE_ADDR_EQUAL(&ia->addr, &daddr))
2796 break;
2797 }
2798 if (ia == NULL) {
2799 ia = ipv6_newaddr(ifp, &daddr, (uint8_t)pfxlen, IPV6_AF_ONLINK);
2800 if (ia == NULL)
2801 return NULL;
2802 ia->dadcallback = dhcp6_dadcallback;
2803 memcpy(&ia->iaid, &prefix->iaid, sizeof(ia->iaid));
2804 ia->created = prefix->acquired;
2805
2806 TAILQ_INSERT_TAIL(&state->addrs, ia, next);
2807 TAILQ_INSERT_TAIL(&prefix->pd_pfxs, ia, pd_next);
2808 }
2809 ia->delegating_prefix = prefix;
2810 ia->prefix = addr;
2811 ia->prefix_len = (uint8_t)pfxlen;
2812 ia->acquired = prefix->acquired;
2813 ia->prefix_pltime = prefix->prefix_pltime;
2814 ia->prefix_vltime = prefix->prefix_vltime;
2815
2816 /* If the prefix length hasn't changed,
2817 * don't install a reject route. */
2818 if (prefix->prefix_len == pfxlen)
2819 prefix->flags |= IPV6_AF_NOREJECT;
2820 else
2821 prefix->flags &= ~IPV6_AF_NOREJECT;
2822
2823 return ia;
2824 }
2825 #endif
2826
2827 static void
2828 dhcp6_script_try_run(struct interface *ifp, int delegated)
2829 {
2830 struct dhcp6_state *state;
2831 struct ipv6_addr *ap;
2832 int completed;
2833
2834 state = D6_STATE(ifp);
2835 completed = 1;
2836 /* If all addresses have completed DAD run the script */
2837 TAILQ_FOREACH(ap, &state->addrs, next) {
2838 if (!(ap->flags & IPV6_AF_ADDED))
2839 continue;
2840 if (ap->flags & IPV6_AF_ONLINK) {
2841 if (!(ap->flags & IPV6_AF_DADCOMPLETED) &&
2842 ipv6_iffindaddr(ap->iface, &ap->addr,
2843 IN6_IFF_TENTATIVE))
2844 ap->flags |= IPV6_AF_DADCOMPLETED;
2845 if ((ap->flags & IPV6_AF_DADCOMPLETED) == 0
2846 #ifndef SMALL
2847 && ((delegated && ap->delegating_prefix) ||
2848 (!delegated && !ap->delegating_prefix))
2849 #endif
2850 )
2851 {
2852 completed = 0;
2853 break;
2854 }
2855 }
2856 }
2857 if (completed) {
2858 script_runreason(ifp, delegated ? "DELEGATED6" : state->reason);
2859 if (!delegated)
2860 dhcpcd_daemonise(ifp->ctx);
2861 } else
2862 logdebugx("%s: waiting for DHCPv6 DAD to complete", ifp->name);
2863 }
2864
2865 #ifdef SMALL
2866 size_t
2867 dhcp6_find_delegates(__unused struct interface *ifp)
2868 {
2869
2870 return 0;
2871 }
2872 #else
2873 static void
2874 dhcp6_delegate_prefix(struct interface *ifp)
2875 {
2876 struct if_options *ifo;
2877 struct dhcp6_state *state;
2878 struct ipv6_addr *ap;
2879 size_t i, j, k;
2880 struct if_ia *ia;
2881 struct if_sla *sla;
2882 struct interface *ifd;
2883 bool carrier_warned;
2884
2885 ifo = ifp->options;
2886 state = D6_STATE(ifp);
2887
2888 /* Clear the logged flag. */
2889 TAILQ_FOREACH(ap, &state->addrs, next) {
2890 ap->flags &= ~IPV6_AF_DELEGATEDLOG;
2891 }
2892
2893 TAILQ_FOREACH(ifd, ifp->ctx->ifaces, next) {
2894 if (!ifd->active)
2895 continue;
2896 if (!(ifd->options->options & DHCPCD_CONFIGURE))
2897 continue;
2898 k = 0;
2899 carrier_warned = false;
2900 TAILQ_FOREACH(ap, &state->addrs, next) {
2901 if (!(ap->flags & IPV6_AF_DELEGATEDPFX))
2902 continue;
2903 if (!(ap->flags & IPV6_AF_DELEGATEDLOG)) {
2904 int loglevel;
2905
2906 if (ap->flags & IPV6_AF_NEW)
2907 loglevel = LOG_INFO;
2908 else
2909 loglevel = LOG_DEBUG;
2910 /* We only want to log this the once as we loop
2911 * through many interfaces first. */
2912 ap->flags |= IPV6_AF_DELEGATEDLOG;
2913 logmessage(loglevel, "%s: delegated prefix %s",
2914 ifp->name, ap->saddr);
2915 ap->flags &= ~IPV6_AF_NEW;
2916 }
2917 for (i = 0; i < ifo->ia_len; i++) {
2918 ia = &ifo->ia[i];
2919 if (ia->ia_type != D6_OPTION_IA_PD)
2920 continue;
2921 if (memcmp(ia->iaid, ap->iaid,
2922 sizeof(ia->iaid)))
2923 continue;
2924 if (ia->sla_len == 0) {
2925 /* no SLA configured, so lets
2926 * automate it */
2927 if (!if_is_link_up(ifd)) {
2928 logdebugx(
2929 "%s: has no carrier, cannot"
2930 " delegate addresses",
2931 ifd->name);
2932 carrier_warned = true;
2933 break;
2934 }
2935 if (dhcp6_ifdelegateaddr(ifd, ap,
2936 NULL, ia))
2937 k++;
2938 }
2939 for (j = 0; j < ia->sla_len; j++) {
2940 sla = &ia->sla[j];
2941 if (strcmp(ifd->name, sla->ifname))
2942 continue;
2943 if (!if_is_link_up(ifd)) {
2944 logdebugx(
2945 "%s: has no carrier, cannot"
2946 " delegate addresses",
2947 ifd->name);
2948 carrier_warned = true;
2949 break;
2950 }
2951 if (dhcp6_ifdelegateaddr(ifd, ap,
2952 sla, ia))
2953 k++;
2954 }
2955 if (carrier_warned)
2956 break;
2957 }
2958 if (carrier_warned)
2959 break;
2960 }
2961 if (k && !carrier_warned) {
2962 struct dhcp6_state *s = D6_STATE(ifd);
2963
2964 ipv6_addaddrs(&s->addrs);
2965 dhcp6_script_try_run(ifd, 1);
2966 }
2967 }
2968
2969 /* Now all addresses have been added, rebuild the routing table. */
2970 rt_build(ifp->ctx, AF_INET6);
2971 }
2972
2973 static void
2974 dhcp6_find_delegates1(void *arg)
2975 {
2976
2977 dhcp6_find_delegates(arg);
2978 }
2979
2980 size_t
2981 dhcp6_find_delegates(struct interface *ifp)
2982 {
2983 struct if_options *ifo;
2984 struct dhcp6_state *state;
2985 struct ipv6_addr *ap;
2986 size_t i, j, k;
2987 struct if_ia *ia;
2988 struct if_sla *sla;
2989 struct interface *ifd;
2990
2991 if (ifp->options != NULL &&
2992 !(ifp->options->options & DHCPCD_CONFIGURE))
2993 return 0;
2994
2995 k = 0;
2996 TAILQ_FOREACH(ifd, ifp->ctx->ifaces, next) {
2997 ifo = ifd->options;
2998 state = D6_STATE(ifd);
2999 if (state == NULL || state->state != DH6S_BOUND)
3000 continue;
3001 TAILQ_FOREACH(ap, &state->addrs, next) {
3002 if (!(ap->flags & IPV6_AF_DELEGATEDPFX))
3003 continue;
3004 for (i = 0; i < ifo->ia_len; i++) {
3005 ia = &ifo->ia[i];
3006 if (ia->ia_type != D6_OPTION_IA_PD)
3007 continue;
3008 if (memcmp(ia->iaid, ap->iaid,
3009 sizeof(ia->iaid)))
3010 continue;
3011 for (j = 0; j < ia->sla_len; j++) {
3012 sla = &ia->sla[j];
3013 if (strcmp(ifp->name, sla->ifname))
3014 continue;
3015 if (ipv6_linklocal(ifp) == NULL) {
3016 logdebugx(
3017 "%s: delaying adding"
3018 " delegated addresses for"
3019 " LL address",
3020 ifp->name);
3021 ipv6_addlinklocalcallback(ifp,
3022 dhcp6_find_delegates1, ifp);
3023 return 1;
3024 }
3025 if (dhcp6_ifdelegateaddr(ifp, ap,
3026 sla, ia))
3027 k++;
3028 }
3029 }
3030 }
3031 }
3032
3033 if (k) {
3034 loginfox("%s: adding delegated prefixes", ifp->name);
3035 state = D6_STATE(ifp);
3036 state->state = DH6S_DELEGATED;
3037 ipv6_addaddrs(&state->addrs);
3038 rt_build(ifp->ctx, AF_INET6);
3039 dhcp6_script_try_run(ifp, 1);
3040 }
3041 return k;
3042 }
3043 #endif
3044
3045 static void
3046 dhcp6_bind(struct interface *ifp, const char *op, const char *sfrom)
3047 {
3048 struct dhcp6_state *state = D6_STATE(ifp);
3049 bool timedout = (op == NULL), confirmed;
3050 struct ipv6_addr *ia;
3051 int loglevel;
3052 struct timespec now;
3053
3054 if (state->state == DH6S_RENEW && !state->new_start) {
3055 loglevel = LOG_DEBUG;
3056 TAILQ_FOREACH(ia, &state->addrs, next) {
3057 if (ia->flags & IPV6_AF_NEW) {
3058 loglevel = LOG_INFO;
3059 break;
3060 }
3061 }
3062 } else if (state->state == DH6S_INFORM)
3063 loglevel = state->new_start ? LOG_INFO : LOG_DEBUG;
3064 else
3065 loglevel = LOG_INFO;
3066 state->new_start = false;
3067
3068 if (!timedout) {
3069 logmessage(loglevel, "%s: %s received from %s",
3070 ifp->name, op, sfrom);
3071 #ifndef SMALL
3072 /* If we delegated from an unconfirmed lease we MUST drop
3073 * them now. Hopefully we have new delegations. */
3074 if (state->reason != NULL &&
3075 strcmp(state->reason, "TIMEOUT6") == 0)
3076 dhcp6_delete_delegates(ifp);
3077 #endif
3078 state->reason = NULL;
3079 } else
3080 state->reason = "TIMEOUT6";
3081
3082 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
3083 clock_gettime(CLOCK_MONOTONIC, &now);
3084
3085 switch(state->state) {
3086 case DH6S_INFORM:
3087 {
3088 struct dhcp6_option *o;
3089 uint16_t ol;
3090
3091 if (state->reason == NULL)
3092 state->reason = "INFORM6";
3093 o = dhcp6_findmoption(state->new, state->new_len,
3094 D6_OPTION_INFO_REFRESH_TIME, &ol);
3095 if (o == NULL || ol != sizeof(uint32_t))
3096 state->renew = IRT_DEFAULT;
3097 else {
3098 memcpy(&state->renew, o, ol);
3099 state->renew = ntohl(state->renew);
3100 if (state->renew < IRT_MINIMUM)
3101 state->renew = IRT_MINIMUM;
3102 }
3103 state->rebind = 0;
3104 state->expire = ND6_INFINITE_LIFETIME;
3105 state->lowpl = ND6_INFINITE_LIFETIME;
3106 }
3107 break;
3108
3109 case DH6S_REQUEST:
3110 if (state->reason == NULL)
3111 state->reason = "BOUND6";
3112 /* FALLTHROUGH */
3113 case DH6S_RENEW:
3114 if (state->reason == NULL)
3115 state->reason = "RENEW6";
3116 /* FALLTHROUGH */
3117 case DH6S_REBIND:
3118 if (state->reason == NULL)
3119 state->reason = "REBIND6";
3120 /* FALLTHROUGH */
3121 case DH6S_CONFIRM:
3122 if (state->reason == NULL)
3123 state->reason = "REBOOT6";
3124 if (state->renew != 0) {
3125 bool all_expired = true;
3126
3127 TAILQ_FOREACH(ia, &state->addrs, next) {
3128 if (ia->flags & IPV6_AF_STALE)
3129 continue;
3130 if (!(state->renew == ND6_INFINITE_LIFETIME
3131 && ia->prefix_vltime == ND6_INFINITE_LIFETIME)
3132 && ia->prefix_vltime != 0
3133 && ia->prefix_vltime <= state->renew)
3134 logwarnx(
3135 "%s: %s will expire before renewal",
3136 ifp->name, ia->saddr);
3137 else
3138 all_expired = false;
3139 }
3140 if (all_expired) {
3141 /* All address's vltime happens at or before
3142 * the configured T1 in the IA.
3143 * This is a badly configured server and we
3144 * have to use our own notion of what
3145 * T1 and T2 should be as a result.
3146 *
3147 * Doing this violates RFC 3315 22.4:
3148 * In a message sent by a server to a client,
3149 * the client MUST use the values in the T1
3150 * and T2 fields for the T1 and T2 parameters,
3151 * unless those values in those fields are 0.
3152 */
3153 logwarnx("%s: ignoring T1 %"PRIu32
3154 " due to address expiry",
3155 ifp->name, state->renew);
3156 state->renew = state->rebind = 0;
3157 }
3158 }
3159 if (state->renew == 0 && state->lowpl != ND6_INFINITE_LIFETIME)
3160 state->renew = (uint32_t)(state->lowpl * 0.5);
3161 if (state->rebind == 0 && state->lowpl != ND6_INFINITE_LIFETIME)
3162 state->rebind = (uint32_t)(state->lowpl * 0.8);
3163 break;
3164 default:
3165 state->reason = "UNKNOWN6";
3166 break;
3167 }
3168
3169 if (state->state != DH6S_CONFIRM && !timedout) {
3170 state->acquired = now;
3171 free(state->old);
3172 state->old = state->new;
3173 state->old_len = state->new_len;
3174 state->new = state->recv;
3175 state->new_len = state->recv_len;
3176 state->recv = NULL;
3177 state->recv_len = 0;
3178 confirmed = false;
3179 } else {
3180 /* Reduce timers based on when we got the lease. */
3181 uint32_t elapsed;
3182
3183 elapsed = (uint32_t)eloop_timespec_diff(&now,
3184 &state->acquired, NULL);
3185 if (state->renew && state->renew != ND6_INFINITE_LIFETIME) {
3186 if (state->renew > elapsed)
3187 state->renew -= elapsed;
3188 else
3189 state->renew = 0;
3190 }
3191 if (state->rebind && state->rebind != ND6_INFINITE_LIFETIME) {
3192 if (state->rebind > elapsed)
3193 state->rebind -= elapsed;
3194 else
3195 state->rebind = 0;
3196 }
3197 if (state->expire && state->expire != ND6_INFINITE_LIFETIME) {
3198 if (state->expire > elapsed)
3199 state->expire -= elapsed;
3200 else
3201 state->expire = 0;
3202 }
3203 confirmed = true;
3204 }
3205
3206 if (ifp->ctx->options & DHCPCD_TEST)
3207 script_runreason(ifp, "TEST");
3208 else {
3209 if (state->state == DH6S_INFORM)
3210 state->state = DH6S_INFORMED;
3211 else
3212 state->state = DH6S_BOUND;
3213 state->failed = false;
3214
3215 if (state->renew && state->renew != ND6_INFINITE_LIFETIME)
3216 eloop_timeout_add_sec(ifp->ctx->eloop,
3217 state->renew,
3218 state->state == DH6S_INFORMED ?
3219 dhcp6_startinform : dhcp6_startrenew, ifp);
3220 if (state->rebind && state->rebind != ND6_INFINITE_LIFETIME)
3221 eloop_timeout_add_sec(ifp->ctx->eloop,
3222 state->rebind, dhcp6_startrebind, ifp);
3223 if (state->expire != ND6_INFINITE_LIFETIME)
3224 eloop_timeout_add_sec(ifp->ctx->eloop,
3225 state->expire, dhcp6_startexpire, ifp);
3226
3227 if (ifp->options->options & DHCPCD_CONFIGURE) {
3228 ipv6_addaddrs(&state->addrs);
3229 if (!timedout)
3230 dhcp6_deprecateaddrs(&state->addrs);
3231 }
3232
3233 if (state->state == DH6S_INFORMED)
3234 logmessage(loglevel, "%s: refresh in %"PRIu32" seconds",
3235 ifp->name, state->renew);
3236 else if (state->renew == ND6_INFINITE_LIFETIME)
3237 logmessage(loglevel, "%s: leased for infinity",
3238 ifp->name);
3239 else if (state->renew || state->rebind)
3240 logmessage(loglevel, "%s: renew in %"PRIu32", "
3241 "rebind in %"PRIu32", "
3242 "expire in %"PRIu32" seconds",
3243 ifp->name,
3244 state->renew, state->rebind, state->expire);
3245 else if (state->expire == 0)
3246 logmessage(loglevel, "%s: will expire", ifp->name);
3247 else
3248 logmessage(loglevel, "%s: expire in %"PRIu32" seconds",
3249 ifp->name, state->expire);
3250 rt_build(ifp->ctx, AF_INET6);
3251 if (!confirmed && !timedout) {
3252 logdebugx("%s: writing lease: %s",
3253 ifp->name, state->leasefile);
3254 if (dhcp_writefile(ifp->ctx, state->leasefile, 0640,
3255 state->new, state->new_len) == -1)
3256 logerr("dhcp_writefile: %s",state->leasefile);
3257 }
3258 #ifndef SMALL
3259 dhcp6_delegate_prefix(ifp);
3260 #endif
3261 dhcp6_script_try_run(ifp, 0);
3262 }
3263
3264 if (ifp->ctx->options & DHCPCD_TEST ||
3265 (ifp->options->options & DHCPCD_INFORM &&
3266 !(ifp->ctx->options & DHCPCD_MANAGER)))
3267 {
3268 eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
3269 }
3270 }
3271
3272 static void
3273 dhcp6_recvif(struct interface *ifp, const char *sfrom,
3274 struct dhcp6_message *r, size_t len)
3275 {
3276 struct dhcpcd_ctx *ctx;
3277 size_t i;
3278 const char *op;
3279 struct dhcp6_state *state;
3280 uint8_t *o;
3281 uint16_t ol;
3282 const struct dhcp_opt *opt;
3283 const struct if_options *ifo;
3284 bool valid_op;
3285 #ifdef AUTH
3286 uint8_t *auth;
3287 uint16_t auth_len;
3288 #endif
3289
3290 ctx = ifp->ctx;
3291 state = D6_STATE(ifp);
3292 if (state == NULL || state->send == NULL) {
3293 logdebugx("%s: DHCPv6 reply received but not running",
3294 ifp->name);
3295 return;
3296 }
3297
3298 /* We're already bound and this message is for another machine */
3299 /* XXX DELEGATED? */
3300 if (r->type != DHCP6_RECONFIGURE &&
3301 (state->state == DH6S_BOUND || state->state == DH6S_INFORMED))
3302 {
3303 logdebugx("%s: DHCPv6 reply received but already bound",
3304 ifp->name);
3305 return;
3306 }
3307
3308 if (dhcp6_findmoption(r, len, D6_OPTION_SERVERID, NULL) == NULL) {
3309 logdebugx("%s: no DHCPv6 server ID from %s", ifp->name, sfrom);
3310 return;
3311 }
3312
3313 ifo = ifp->options;
3314 for (i = 0, opt = ctx->dhcp6_opts;
3315 i < ctx->dhcp6_opts_len;
3316 i++, opt++)
3317 {
3318 if (has_option_mask(ifo->requiremask6, opt->option) &&
3319 !dhcp6_findmoption(r, len, (uint16_t)opt->option, NULL))
3320 {
3321 logwarnx("%s: reject DHCPv6 (no option %s) from %s",
3322 ifp->name, opt->var, sfrom);
3323 return;
3324 }
3325 if (has_option_mask(ifo->rejectmask6, opt->option) &&
3326 dhcp6_findmoption(r, len, (uint16_t)opt->option, NULL))
3327 {
3328 logwarnx("%s: reject DHCPv6 (option %s) from %s",
3329 ifp->name, opt->var, sfrom);
3330 return;
3331 }
3332 }
3333
3334 #ifdef AUTH
3335 /* Authenticate the message */
3336 auth = dhcp6_findmoption(r, len, D6_OPTION_AUTH, &auth_len);
3337 if (auth != NULL) {
3338 if (dhcp_auth_validate(&state->auth, &ifo->auth,
3339 (uint8_t *)r, len, 6, r->type, auth, auth_len) == NULL)
3340 {
3341 logerr("%s: authentication failed from %s",
3342 ifp->name, sfrom);
3343 return;
3344 }
3345 if (state->auth.token)
3346 logdebugx("%s: validated using 0x%08" PRIu32,
3347 ifp->name, state->auth.token->secretid);
3348 else
3349 loginfox("%s: accepted reconfigure key", ifp->name);
3350 } else if (ifo->auth.options & DHCPCD_AUTH_SEND) {
3351 if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
3352 logerrx("%s: no authentication from %s",
3353 ifp->name, sfrom);
3354 return;
3355 }
3356 logwarnx("%s: no authentication from %s", ifp->name, sfrom);
3357 }
3358 #endif
3359
3360 op = dhcp6_get_op(r->type);
3361 valid_op = op != NULL;
3362 switch(r->type) {
3363 case DHCP6_REPLY:
3364 switch(state->state) {
3365 case DH6S_INFORM:
3366 if (dhcp6_checkstatusok(ifp, r, NULL, len) != 0)
3367 return;
3368 break;
3369 case DH6S_CONFIRM:
3370 if (dhcp6_validatelease(ifp, r, len, sfrom, NULL) == -1)
3371 {
3372 dhcp6_startdiscoinform(ifp);
3373 return;
3374 }
3375 break;
3376 case DH6S_DISCOVER:
3377 /* Only accept REPLY in DISCOVER for RAPID_COMMIT.
3378 * Normally we get an ADVERTISE for a DISCOVER. */
3379 if (!has_option_mask(ifo->requestmask6,
3380 D6_OPTION_RAPID_COMMIT) ||
3381 !dhcp6_findmoption(r, len, D6_OPTION_RAPID_COMMIT,
3382 NULL))
3383 {
3384 valid_op = false;
3385 break;
3386 }
3387 /* Validate lease before setting state to REQUEST. */
3388 /* FALLTHROUGH */
3389 case DH6S_REQUEST: /* FALLTHROUGH */
3390 case DH6S_RENEW: /* FALLTHROUGH */
3391 case DH6S_REBIND:
3392 if (dhcp6_validatelease(ifp, r, len, sfrom, NULL) == -1)
3393 {
3394 /*
3395 * If we can't use the lease, fallback to
3396 * DISCOVER and try and get a new one.
3397 *
3398 * This is needed become some servers
3399 * renumber the prefix or address
3400 * and deny the current one before it expires
3401 * rather than sending it back with a zero
3402 * lifetime along with the new prefix or
3403 * address to use.
3404 * This behavior is wrong, but moving to the
3405 * DISCOVER phase works around it.
3406 *
3407 * The currently held lease is still valid
3408 * until a new one is found.
3409 */
3410 if (state->state != DH6S_DISCOVER)
3411 dhcp6_startdiscoinform(ifp);
3412 return;
3413 }
3414 /* RFC8415 18.2.10.1 */
3415 if ((state->state == DH6S_RENEW ||
3416 state->state == DH6S_REBIND) &&
3417 state->has_no_binding)
3418 {
3419 dhcp6_startrequest(ifp);
3420 return;
3421 }
3422 if (state->state == DH6S_DISCOVER)
3423 state->state = DH6S_REQUEST;
3424 break;
3425 case DH6S_DECLINE:
3426 /* This isnt really a failure, but an
3427 * acknowledgement of one. */
3428 loginfox("%s: %s acknowledged DECLINE6",
3429 ifp->name, sfrom);
3430 dhcp6_fail(ifp);
3431 return;
3432 default:
3433 valid_op = false;
3434 break;
3435 }
3436 break;
3437 case DHCP6_ADVERTISE:
3438 if (state->state != DH6S_DISCOVER) {
3439 valid_op = false;
3440 break;
3441 }
3442 /* RFC7083 */
3443 o = dhcp6_findmoption(r, len, D6_OPTION_SOL_MAX_RT, &ol);
3444 if (o && ol == sizeof(uint32_t)) {
3445 uint32_t max_rt;
3446
3447 memcpy(&max_rt, o, sizeof(max_rt));
3448 max_rt = ntohl(max_rt);
3449 if (max_rt >= 60 && max_rt <= 86400) {
3450 logdebugx("%s: SOL_MAX_RT %llu -> %u",
3451 ifp->name,
3452 (unsigned long long)state->sol_max_rt,
3453 max_rt);
3454 state->sol_max_rt = max_rt;
3455 } else
3456 logerr("%s: invalid SOL_MAX_RT %u",
3457 ifp->name, max_rt);
3458 }
3459 o = dhcp6_findmoption(r, len, D6_OPTION_INF_MAX_RT, &ol);
3460 if (o && ol == sizeof(uint32_t)) {
3461 uint32_t max_rt;
3462
3463 memcpy(&max_rt, o, sizeof(max_rt));
3464 max_rt = ntohl(max_rt);
3465 if (max_rt >= 60 && max_rt <= 86400) {
3466 logdebugx("%s: INF_MAX_RT %llu -> %u",
3467 ifp->name,
3468 (unsigned long long)state->inf_max_rt,
3469 max_rt);
3470 state->inf_max_rt = max_rt;
3471 } else
3472 logerrx("%s: invalid INF_MAX_RT %u",
3473 ifp->name, max_rt);
3474 }
3475 if (dhcp6_validatelease(ifp, r, len, sfrom, NULL) == -1)
3476 return;
3477 break;
3478 case DHCP6_RECONFIGURE:
3479 #ifdef AUTH
3480 if (auth == NULL) {
3481 #endif
3482 logerrx("%s: unauthenticated %s from %s",
3483 ifp->name, op, sfrom);
3484 if (ifo->auth.options & DHCPCD_AUTH_REQUIRE)
3485 return;
3486 #ifdef AUTH
3487 }
3488 loginfox("%s: %s from %s", ifp->name, op, sfrom);
3489 o = dhcp6_findmoption(r, len, D6_OPTION_RECONF_MSG, &ol);
3490 if (o == NULL) {
3491 logerrx("%s: missing Reconfigure Message option",
3492 ifp->name);
3493 return;
3494 }
3495 if (ol != 1) {
3496 logerrx("%s: missing Reconfigure Message type",
3497 ifp->name);
3498 return;
3499 }
3500 switch(*o) {
3501 case DHCP6_RENEW:
3502 if (state->state != DH6S_BOUND) {
3503 logerrx("%s: not bound, ignoring %s",
3504 ifp->name, op);
3505 return;
3506 }
3507 dhcp6_startrenew(ifp);
3508 break;
3509 case DHCP6_INFORMATION_REQ:
3510 if (state->state != DH6S_INFORMED) {
3511 logerrx("%s: not informed, ignoring %s",
3512 ifp->name, op);
3513 return;
3514 }
3515 eloop_timeout_delete(ifp->ctx->eloop,
3516 dhcp6_sendinform, ifp);
3517 dhcp6_startinform(ifp);
3518 break;
3519 default:
3520 logerr("%s: unsupported %s type %d",
3521 ifp->name, op, *o);
3522 break;
3523 }
3524 return;
3525 #else
3526 break;
3527 #endif
3528 default:
3529 logerrx("%s: invalid DHCP6 type %s (%d)",
3530 ifp->name, op, r->type);
3531 return;
3532 }
3533 if (!valid_op) {
3534 logwarnx("%s: invalid state for DHCP6 type %s (%d)",
3535 ifp->name, op, r->type);
3536 return;
3537 }
3538
3539 if (state->recv_len < (size_t)len) {
3540 free(state->recv);
3541 state->recv = malloc(len);
3542 if (state->recv == NULL) {
3543 logerr(__func__);
3544 return;
3545 }
3546 }
3547 memcpy(state->recv, r, len);
3548 state->recv_len = len;
3549
3550 if (r->type == DHCP6_ADVERTISE) {
3551 struct ipv6_addr *ia;
3552
3553 if (state->state == DH6S_REQUEST) /* rapid commit */
3554 goto bind;
3555 TAILQ_FOREACH(ia, &state->addrs, next) {
3556 if (!(ia->flags & (IPV6_AF_STALE | IPV6_AF_REQUEST)))
3557 break;
3558 }
3559 if (ia == NULL)
3560 ia = TAILQ_FIRST(&state->addrs);
3561 if (ia == NULL)
3562 loginfox("%s: ADV (no address) from %s",
3563 ifp->name, sfrom);
3564 else
3565 loginfox("%s: ADV %s from %s",
3566 ifp->name, ia->saddr, sfrom);
3567 dhcp6_startrequest(ifp);
3568 return;
3569 }
3570
3571 bind:
3572 dhcp6_bind(ifp, op, sfrom);
3573 }
3574
3575 void
3576 dhcp6_recvmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg, struct ipv6_addr *ia)
3577 {
3578 struct sockaddr_in6 *from = msg->msg_name;
3579 size_t len = msg->msg_iov[0].iov_len;
3580 char sfrom[INET6_ADDRSTRLEN];
3581 struct interface *ifp;
3582 struct dhcp6_message *r;
3583 const struct dhcp6_state *state;
3584 uint8_t *o;
3585 uint16_t ol;
3586
3587 inet_ntop(AF_INET6, &from->sin6_addr, sfrom, sizeof(sfrom));
3588 if (len < sizeof(struct dhcp6_message)) {
3589 logerrx("DHCPv6 packet too short from %s", sfrom);
3590 return;
3591 }
3592
3593 if (ia != NULL)
3594 ifp = ia->iface;
3595 else {
3596 ifp = if_findifpfromcmsg(ctx, msg, NULL);
3597 if (ifp == NULL) {
3598 logerr(__func__);
3599 return;
3600 }
3601 }
3602
3603 r = (struct dhcp6_message *)msg->msg_iov[0].iov_base;
3604
3605 uint8_t duid[DUID_LEN], *dp;
3606 size_t duid_len;
3607 o = dhcp6_findmoption(r, len, D6_OPTION_CLIENTID, &ol);
3608 if (ifp->options->options & DHCPCD_ANONYMOUS) {
3609 duid_len = duid_make(duid, ifp, DUID_LL);
3610 dp = duid;
3611 } else {
3612 duid_len = ctx->duid_len;
3613 dp = ctx->duid;
3614 }
3615 if (o == NULL || ol != duid_len || memcmp(o, dp, ol) != 0) {
3616 logdebugx("%s: incorrect client ID from %s",
3617 ifp->name, sfrom);
3618 return;
3619 }
3620
3621 if (dhcp6_findmoption(r, len, D6_OPTION_SERVERID, NULL) == NULL) {
3622 logdebugx("%s: no DHCPv6 server ID from %s",
3623 ifp->name, sfrom);
3624 return;
3625 }
3626
3627 if (r->type == DHCP6_RECONFIGURE) {
3628 if (!IN6_IS_ADDR_LINKLOCAL(&from->sin6_addr)) {
3629 logerrx("%s: RECONFIGURE6 recv from %s, not LL",
3630 ifp->name, sfrom);
3631 return;
3632 }
3633 goto recvif;
3634 }
3635
3636 state = D6_CSTATE(ifp);
3637 if (state == NULL ||
3638 r->xid[0] != state->send->xid[0] ||
3639 r->xid[1] != state->send->xid[1] ||
3640 r->xid[2] != state->send->xid[2])
3641 {
3642 struct interface *ifp1;
3643 const struct dhcp6_state *state1;
3644
3645 /* Find an interface with a matching xid. */
3646 TAILQ_FOREACH(ifp1, ctx->ifaces, next) {
3647 state1 = D6_CSTATE(ifp1);
3648 if (state1 == NULL || state1->send == NULL)
3649 continue;
3650 if (r->xid[0] == state1->send->xid[0] &&
3651 r->xid[1] == state1->send->xid[1] &&
3652 r->xid[2] == state1->send->xid[2])
3653 break;
3654 }
3655
3656 if (ifp1 == NULL) {
3657 if (state != NULL)
3658 logdebugx("%s: wrong xid 0x%02x%02x%02x"
3659 " (expecting 0x%02x%02x%02x) from %s",
3660 ifp->name,
3661 r->xid[0], r->xid[1], r->xid[2],
3662 state->send->xid[0],
3663 state->send->xid[1],
3664 state->send->xid[2],
3665 sfrom);
3666 return;
3667 }
3668 logdebugx("%s: redirecting DHCP6 message to %s",
3669 ifp->name, ifp1->name);
3670 ifp = ifp1;
3671 }
3672
3673 #if 0
3674 /*
3675 * Handy code to inject raw DHCPv6 packets over responses
3676 * from our server.
3677 * This allows me to take a 3rd party wireshark trace and
3678 * replay it in my code.
3679 */
3680 static int replyn = 0;
3681 char fname[PATH_MAX], tbuf[UDPLEN_MAX];
3682 int fd;
3683 ssize_t tlen;
3684 uint8_t *si1, *si2;
3685 uint16_t si_len1, si_len2;
3686
3687 snprintf(fname, sizeof(fname),
3688 "/tmp/dhcp6.reply%d.raw", replyn++);
3689 fd = open(fname, O_RDONLY, 0);
3690 if (fd == -1) {
3691 logerr("%s: open: %s", __func__, fname);
3692 return;
3693 }
3694 tlen = read(fd, tbuf, sizeof(tbuf));
3695 if (tlen == -1)
3696 logerr("%s: read: %s", __func__, fname);
3697 close(fd);
3698
3699 /* Copy across ServerID so we can work with our own server. */
3700 si1 = dhcp6_findmoption(r, len, D6_OPTION_SERVERID, &si_len1);
3701 si2 = dhcp6_findmoption(tbuf, (size_t)tlen,
3702 D6_OPTION_SERVERID, &si_len2);
3703 if (si1 != NULL && si2 != NULL && si_len1 == si_len2)
3704 memcpy(si2, si1, si_len2);
3705 r = (struct dhcp6_message *)tbuf;
3706 len = (size_t)tlen;
3707 #endif
3708
3709 recvif:
3710 dhcp6_recvif(ifp, sfrom, r, len);
3711 }
3712
3713 static void
3714 dhcp6_recv(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia)
3715 {
3716 struct sockaddr_in6 from;
3717 union {
3718 struct dhcp6_message dhcp6;
3719 uint8_t buf[UDPLEN_MAX]; /* Maximum UDP message size */
3720 } iovbuf;
3721 struct iovec iov = {
3722 .iov_base = iovbuf.buf, .iov_len = sizeof(iovbuf.buf),
3723 };
3724 union {
3725 struct cmsghdr hdr;
3726 uint8_t buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
3727 } cmsgbuf = { .buf = { 0 } };
3728 struct msghdr msg = {
3729 .msg_name = &from, .msg_namelen = sizeof(from),
3730 .msg_iov = &iov, .msg_iovlen = 1,
3731 .msg_control = cmsgbuf.buf, .msg_controllen = sizeof(cmsgbuf.buf),
3732 };
3733 int s;
3734 ssize_t bytes;
3735
3736 s = ia != NULL ? ia->dhcp6_fd : ctx->dhcp6_rfd;
3737 bytes = recvmsg(s, &msg, 0);
3738 if (bytes == -1) {
3739 logerr(__func__);
3740 return;
3741 }
3742
3743 iov.iov_len = (size_t)bytes;
3744 dhcp6_recvmsg(ctx, &msg, ia);
3745 }
3746
3747 static void
3748 dhcp6_recvaddr(void *arg)
3749 {
3750 struct ipv6_addr *ia = arg;
3751
3752 dhcp6_recv(ia->iface->ctx, ia);
3753 }
3754
3755 static void
3756 dhcp6_recvctx(void *arg)
3757 {
3758 struct dhcpcd_ctx *ctx = arg;
3759
3760 dhcp6_recv(ctx, NULL);
3761 }
3762
3763 int
3764 dhcp6_openraw(void)
3765 {
3766 int fd, v;
3767
3768 fd = socket(PF_INET6, SOCK_RAW | SOCK_CXNB, IPPROTO_UDP);
3769 if (fd == -1)
3770 return -1;
3771
3772 v = 1;
3773 if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &v, sizeof(v)) == -1)
3774 goto errexit;
3775
3776 v = offsetof(struct udphdr, uh_sum);
3777 if (setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &v, sizeof(v)) == -1)
3778 goto errexit;
3779
3780 return fd;
3781
3782 errexit:
3783 close(fd);
3784 return -1;
3785 }
3786
3787 int
3788 dhcp6_openudp(unsigned int ifindex, struct in6_addr *ia)
3789 {
3790 struct sockaddr_in6 sa;
3791 int n, s;
3792
3793 s = xsocket(PF_INET6, SOCK_DGRAM | SOCK_CXNB, IPPROTO_UDP);
3794 if (s == -1)
3795 goto errexit;
3796
3797 memset(&sa, 0, sizeof(sa));
3798 sa.sin6_family = AF_INET6;
3799 sa.sin6_port = htons(DHCP6_CLIENT_PORT);
3800 #ifdef BSD
3801 sa.sin6_len = sizeof(sa);
3802 #endif
3803
3804 if (ia != NULL) {
3805 memcpy(&sa.sin6_addr, ia, sizeof(sa.sin6_addr));
3806 ipv6_setscope(&sa, ifindex);
3807 }
3808
3809 if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) == -1)
3810 goto errexit;
3811
3812 n = 1;
3813 if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &n, sizeof(n)) == -1)
3814 goto errexit;
3815
3816 #ifdef SO_RERROR
3817 n = 1;
3818 if (setsockopt(s, SOL_SOCKET, SO_RERROR, &n, sizeof(n)) == -1)
3819 goto errexit;
3820 #endif
3821
3822 return s;
3823
3824 errexit:
3825 logerr(__func__);
3826 if (s != -1)
3827 close(s);
3828 return -1;
3829 }
3830
3831 #ifndef SMALL
3832 static void
3833 dhcp6_activateinterfaces(struct interface *ifp)
3834 {
3835 struct interface *ifd;
3836 size_t i, j;
3837 struct if_ia *ia;
3838 struct if_sla *sla;
3839
3840 for (i = 0; i < ifp->options->ia_len; i++) {
3841 ia = &ifp->options->ia[i];
3842 if (ia->ia_type != D6_OPTION_IA_PD)
3843 continue;
3844 for (j = 0; j < ia->sla_len; j++) {
3845 sla = &ia->sla[j];
3846 ifd = if_find(ifp->ctx->ifaces, sla->ifname);
3847 if (ifd == NULL) {
3848 logwarn("%s: cannot delegate to %s",
3849 ifp->name, sla->ifname);
3850 continue;
3851 }
3852 if (!ifd->active) {
3853 loginfox("%s: activating for delegation",
3854 sla->ifname);
3855 dhcpcd_activateinterface(ifd,
3856 DHCPCD_IPV6 | DHCPCD_DHCP6);
3857 }
3858 }
3859 }
3860 }
3861 #endif
3862
3863 static void
3864 dhcp6_start1(void *arg)
3865 {
3866 struct interface *ifp = arg;
3867 struct dhcpcd_ctx *ctx = ifp->ctx;
3868 struct if_options *ifo = ifp->options;
3869 struct dhcp6_state *state;
3870 size_t i;
3871 const struct dhcp_compat *dhc;
3872
3873 if ((ctx->options & (DHCPCD_MANAGER|DHCPCD_PRIVSEP)) == DHCPCD_MANAGER &&
3874 ctx->dhcp6_rfd == -1)
3875 {
3876 ctx->dhcp6_rfd = dhcp6_openudp(0, NULL);
3877 if (ctx->dhcp6_rfd == -1) {
3878 logerr(__func__);
3879 return;
3880 }
3881 eloop_event_add(ctx->eloop, ctx->dhcp6_rfd, dhcp6_recvctx, ctx);
3882 }
3883
3884 if (!IN_PRIVSEP(ctx) && ctx->dhcp6_wfd == -1) {
3885 ctx->dhcp6_wfd = dhcp6_openraw();
3886 if (ctx->dhcp6_wfd == -1) {
3887 logerr(__func__);
3888 return;
3889 }
3890 }
3891
3892 state = D6_STATE(ifp);
3893 /* If no DHCPv6 options are configured,
3894 match configured DHCPv4 options to DHCPv6 equivalents. */
3895 for (i = 0; i < sizeof(ifo->requestmask6); i++) {
3896 if (ifo->requestmask6[i] != '\0')
3897 break;
3898 }
3899 if (i == sizeof(ifo->requestmask6)) {
3900 for (dhc = dhcp_compats; dhc->dhcp_opt; dhc++) {
3901 if (DHC_REQ(ifo->requestmask, ifo->nomask, dhc->dhcp_opt))
3902 add_option_mask(ifo->requestmask6,
3903 dhc->dhcp6_opt);
3904 }
3905 if (ifo->fqdn != FQDN_DISABLE || ifo->options & DHCPCD_HOSTNAME)
3906 add_option_mask(ifo->requestmask6, D6_OPTION_FQDN);
3907 }
3908
3909 #ifndef SMALL
3910 /* Rapid commit won't work with Prefix Delegation Exclusion */
3911 if (dhcp6_findselfsla(ifp))
3912 del_option_mask(ifo->requestmask6, D6_OPTION_RAPID_COMMIT);
3913 #endif
3914
3915 if (state->state == DH6S_INFORM) {
3916 add_option_mask(ifo->requestmask6, D6_OPTION_INFO_REFRESH_TIME);
3917 dhcp6_startinform(ifp);
3918 } else {
3919 del_option_mask(ifo->requestmask6, D6_OPTION_INFO_REFRESH_TIME);
3920 dhcp6_startinit(ifp);
3921 }
3922
3923 #ifndef SMALL
3924 dhcp6_activateinterfaces(ifp);
3925 #endif
3926 }
3927
3928 int
3929 dhcp6_start(struct interface *ifp, enum DH6S init_state)
3930 {
3931 struct dhcp6_state *state;
3932
3933 state = D6_STATE(ifp);
3934 if (state != NULL) {
3935 switch (init_state) {
3936 case DH6S_INIT:
3937 goto gogogo;
3938 case DH6S_INFORM:
3939 if (state->state == DH6S_INIT ||
3940 state->state == DH6S_INFORMED ||
3941 (state->state == DH6S_DISCOVER &&
3942 !(ifp->options->options & DHCPCD_IA_FORCED) &&
3943 !ipv6nd_hasradhcp(ifp, true)))
3944 {
3945 /* We don't want log spam when the RA
3946 * has just adjusted it's prefix times. */
3947 if (state->state != DH6S_INFORMED)
3948 state->new_start = true;
3949 dhcp6_startinform(ifp);
3950 }
3951 break;
3952 case DH6S_REQUEST:
3953 if (ifp->options->options & DHCPCD_DHCP6 &&
3954 (state->state == DH6S_INIT ||
3955 state->state == DH6S_INFORM ||
3956 state->state == DH6S_INFORMED ||
3957 state->state == DH6S_DELEGATED))
3958 {
3959 /* Change from stateless to stateful */
3960 init_state = DH6S_INIT;
3961 goto gogogo;
3962 }
3963 break;
3964 case DH6S_CONFIRM:
3965 init_state = DH6S_INIT;
3966 goto gogogo;
3967 default:
3968 /* Not possible, but sushes some compiler warnings. */
3969 break;
3970 }
3971 return 0;
3972 } else {
3973 switch (init_state) {
3974 case DH6S_CONFIRM:
3975 /* No DHCPv6 config, no existing state
3976 * so nothing to do. */
3977 return 0;
3978 case DH6S_INFORM:
3979 break;
3980 default:
3981 init_state = DH6S_INIT;
3982 break;
3983 }
3984 }
3985
3986 if (!(ifp->options->options & DHCPCD_DHCP6))
3987 return 0;
3988
3989 ifp->if_data[IF_DATA_DHCP6] = calloc(1, sizeof(*state));
3990 state = D6_STATE(ifp);
3991 if (state == NULL)
3992 return -1;
3993
3994 state->sol_max_rt = SOL_MAX_RT;
3995 state->inf_max_rt = INF_MAX_RT;
3996 TAILQ_INIT(&state->addrs);
3997
3998 gogogo:
3999 state->new_start = true;
4000 state->state = init_state;
4001 state->lerror = 0;
4002 state->failed = false;
4003 dhcp_set_leasefile(state->leasefile, sizeof(state->leasefile),
4004 AF_INET6, ifp);
4005 if (ipv6_linklocal(ifp) == NULL) {
4006 logdebugx("%s: delaying DHCPv6 for LL address", ifp->name);
4007 ipv6_addlinklocalcallback(ifp, dhcp6_start1, ifp);
4008 return 0;
4009 }
4010
4011 dhcp6_start1(ifp);
4012 return 0;
4013 }
4014
4015 void
4016 dhcp6_reboot(struct interface *ifp)
4017 {
4018 struct dhcp6_state *state;
4019
4020 state = D6_STATE(ifp);
4021 if (state == NULL)
4022 return;
4023
4024 state->lerror = 0;
4025 switch (state->state) {
4026 case DH6S_BOUND:
4027 dhcp6_startrebind(ifp);
4028 break;
4029 default:
4030 dhcp6_startdiscoinform(ifp);
4031 break;
4032 }
4033 }
4034
4035 static void
4036 dhcp6_freedrop(struct interface *ifp, int drop, const char *reason)
4037 {
4038 struct dhcp6_state *state;
4039 struct dhcpcd_ctx *ctx;
4040 unsigned long long options;
4041
4042 if (ifp->options)
4043 options = ifp->options->options;
4044 else
4045 options = ifp->ctx->options;
4046
4047 if (ifp->ctx->eloop)
4048 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
4049
4050 #ifndef SMALL
4051 /* If we're dropping the lease, drop delegated addresses.
4052 * If, for whatever reason, we don't drop them in the future
4053 * then they should at least be marked as deprecated (pltime 0). */
4054 if (drop && (options & DHCPCD_NODROP) != DHCPCD_NODROP)
4055 dhcp6_delete_delegates(ifp);
4056 #endif
4057
4058 state = D6_STATE(ifp);
4059 if (state) {
4060 /* Failure to send the release may cause this function to
4061 * re-enter */
4062 if (state->state == DH6S_RELEASE) {
4063 dhcp6_finishrelease(ifp);
4064 return;
4065 }
4066
4067 if (drop && options & DHCPCD_RELEASE &&
4068 state->state != DH6S_DELEGATED)
4069 {
4070 if (if_is_link_up(ifp) &&
4071 state->state != DH6S_RELEASED &&
4072 state->state != DH6S_INFORMED)
4073 {
4074 dhcp6_startrelease(ifp);
4075 return;
4076 }
4077 dhcp_unlink(ifp->ctx, state->leasefile);
4078 }
4079 #ifdef AUTH
4080 else if (state->auth.reconf != NULL) {
4081 /*
4082 * Drop the lease as the token may only be present
4083 * in the initial reply message and not subsequent
4084 * renewals.
4085 * If dhcpcd is restarted, the token is lost.
4086 * XXX persist this in another file?
4087 */
4088 dhcp_unlink(ifp->ctx, state->leasefile);
4089 }
4090 #endif
4091
4092 dhcp6_freedrop_addrs(ifp, drop, NULL);
4093 free(state->old);
4094 state->old = state->new;
4095 state->old_len = state->new_len;
4096 state->new = NULL;
4097 state->new_len = 0;
4098 if (drop && state->old &&
4099 (options & DHCPCD_NODROP) != DHCPCD_NODROP)
4100 {
4101 if (reason == NULL)
4102 reason = "STOP6";
4103 script_runreason(ifp, reason);
4104 }
4105 free(state->old);
4106 free(state->send);
4107 free(state->recv);
4108 free(state);
4109 ifp->if_data[IF_DATA_DHCP6] = NULL;
4110 }
4111
4112 /* If we don't have any more DHCP6 enabled interfaces,
4113 * close the global socket and release resources */
4114 ctx = ifp->ctx;
4115 if (ctx->ifaces) {
4116 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
4117 if (D6_STATE(ifp))
4118 break;
4119 }
4120 }
4121 if (ifp == NULL && ctx->dhcp6_rfd != -1) {
4122 eloop_event_delete(ctx->eloop, ctx->dhcp6_rfd);
4123 close(ctx->dhcp6_rfd);
4124 ctx->dhcp6_rfd = -1;
4125 }
4126 }
4127
4128 void
4129 dhcp6_drop(struct interface *ifp, const char *reason)
4130 {
4131
4132 dhcp6_freedrop(ifp, 1, reason);
4133 }
4134
4135 void
4136 dhcp6_free(struct interface *ifp)
4137 {
4138
4139 dhcp6_freedrop(ifp, 0, NULL);
4140 }
4141
4142 void
4143 dhcp6_abort(struct interface *ifp)
4144 {
4145 struct dhcp6_state *state;
4146 #ifdef ND6_ADVERTISE
4147 struct ipv6_addr *ia;
4148 #endif
4149
4150 eloop_timeout_delete(ifp->ctx->eloop, dhcp6_start1, ifp);
4151 state = D6_STATE(ifp);
4152 if (state == NULL)
4153 return;
4154
4155 #ifdef ND6_ADVERTISE
4156 TAILQ_FOREACH(ia, &state->addrs, next) {
4157 ipv6nd_advertise(ia);
4158 }
4159 #endif
4160
4161 eloop_timeout_delete(ifp->ctx->eloop, dhcp6_startdiscover, ifp);
4162 eloop_timeout_delete(ifp->ctx->eloop, dhcp6_senddiscover, ifp);
4163 eloop_timeout_delete(ifp->ctx->eloop, dhcp6_startinform, ifp);
4164 eloop_timeout_delete(ifp->ctx->eloop, dhcp6_sendinform, ifp);
4165
4166 switch (state->state) {
4167 case DH6S_DISCOVER: /* FALLTHROUGH */
4168 case DH6S_REQUEST: /* FALLTHROUGH */
4169 case DH6S_INFORM:
4170 state->state = DH6S_INIT;
4171 break;
4172 default:
4173 break;
4174 }
4175 }
4176
4177 void
4178 dhcp6_handleifa(int cmd, struct ipv6_addr *ia, pid_t pid)
4179 {
4180 struct dhcp6_state *state;
4181 struct interface *ifp = ia->iface;
4182
4183 /* If not running in manager mode, listen to this address */
4184 if (cmd == RTM_NEWADDR &&
4185 !(ia->addr_flags & IN6_IFF_NOTUSEABLE) &&
4186 ifp->active == IF_ACTIVE_USER &&
4187 !(ifp->ctx->options & DHCPCD_MANAGER) &&
4188 ifp->options->options & DHCPCD_DHCP6)
4189 {
4190 #ifdef PRIVSEP
4191 if (IN_PRIVSEP_SE(ifp->ctx)) {
4192 if (ps_inet_opendhcp6(ia) == -1)
4193 logerr(__func__);
4194 } else
4195 #endif
4196 {
4197 if (ia->dhcp6_fd == -1)
4198 ia->dhcp6_fd = dhcp6_openudp(ia->iface->index,
4199 &ia->addr);
4200 if (ia->dhcp6_fd != -1)
4201 eloop_event_add(ia->iface->ctx->eloop,
4202 ia->dhcp6_fd, dhcp6_recvaddr, ia);
4203 }
4204 }
4205
4206
4207 if ((state = D6_STATE(ifp)) != NULL)
4208 ipv6_handleifa_addrs(cmd, &state->addrs, ia, pid);
4209 }
4210
4211 ssize_t
4212 dhcp6_env(FILE *fp, const char *prefix, const struct interface *ifp,
4213 const struct dhcp6_message *m, size_t len)
4214 {
4215 const struct if_options *ifo;
4216 struct dhcp_opt *opt, *vo;
4217 const uint8_t *p;
4218 struct dhcp6_option o;
4219 size_t i;
4220 char *pfx;
4221 uint32_t en;
4222 const struct dhcpcd_ctx *ctx;
4223 #ifndef SMALL
4224 const struct dhcp6_state *state;
4225 const struct ipv6_addr *ap;
4226 #endif
4227
4228 if (m == NULL)
4229 goto delegated;
4230
4231 if (len < sizeof(*m)) {
4232 /* Should be impossible with guards at packet in
4233 * and reading leases */
4234 errno = EINVAL;
4235 return -1;
4236 }
4237
4238 ifo = ifp->options;
4239 ctx = ifp->ctx;
4240
4241 /* Zero our indexes */
4242 for (i = 0, opt = ctx->dhcp6_opts;
4243 i < ctx->dhcp6_opts_len;
4244 i++, opt++)
4245 dhcp_zero_index(opt);
4246 for (i = 0, opt = ifp->options->dhcp6_override;
4247 i < ifp->options->dhcp6_override_len;
4248 i++, opt++)
4249 dhcp_zero_index(opt);
4250 for (i = 0, opt = ctx->vivso;
4251 i < ctx->vivso_len;
4252 i++, opt++)
4253 dhcp_zero_index(opt);
4254 if (asprintf(&pfx, "%s_dhcp6", prefix) == -1)
4255 return -1;
4256
4257 /* Unlike DHCP, DHCPv6 options *may* occur more than once.
4258 * There is also no provision for option concatenation unlike DHCP. */
4259 p = (const uint8_t *)m + sizeof(*m);
4260 len -= sizeof(*m);
4261 for (; len != 0; p += o.len, len -= o.len) {
4262 if (len < sizeof(o)) {
4263 errno = EINVAL;
4264 break;
4265 }
4266 memcpy(&o, p, sizeof(o));
4267 p += sizeof(o);
4268 len -= sizeof(o);
4269 o.len = ntohs(o.len);
4270 if (len < o.len) {
4271 errno = EINVAL;
4272 break;
4273 }
4274 o.code = ntohs(o.code);
4275 if (has_option_mask(ifo->nomask6, o.code))
4276 continue;
4277 for (i = 0, opt = ifo->dhcp6_override;
4278 i < ifo->dhcp6_override_len;
4279 i++, opt++)
4280 if (opt->option == o.code)
4281 break;
4282 if (i == ifo->dhcp6_override_len &&
4283 o.code == D6_OPTION_VENDOR_OPTS &&
4284 o.len > sizeof(en))
4285 {
4286 memcpy(&en, p, sizeof(en));
4287 en = ntohl(en);
4288 vo = vivso_find(en, ifp);
4289 } else
4290 vo = NULL;
4291 if (i == ifo->dhcp6_override_len) {
4292 for (i = 0, opt = ctx->dhcp6_opts;
4293 i < ctx->dhcp6_opts_len;
4294 i++, opt++)
4295 if (opt->option == o.code)
4296 break;
4297 if (i == ctx->dhcp6_opts_len)
4298 opt = NULL;
4299 }
4300 if (opt) {
4301 dhcp_envoption(ifp->ctx,
4302 fp, pfx, ifp->name,
4303 opt, dhcp6_getoption, p, o.len);
4304 }
4305 if (vo) {
4306 dhcp_envoption(ifp->ctx,
4307 fp, pfx, ifp->name,
4308 vo, dhcp6_getoption,
4309 p + sizeof(en),
4310 o.len - sizeof(en));
4311 }
4312 }
4313 free(pfx);
4314
4315 delegated:
4316 #ifndef SMALL
4317 /* Needed for Delegated Prefixes */
4318 state = D6_CSTATE(ifp);
4319 TAILQ_FOREACH(ap, &state->addrs, next) {
4320 if (ap->delegating_prefix)
4321 break;
4322 }
4323 if (ap == NULL)
4324 return 1;
4325 if (fprintf(fp, "%s_delegated_dhcp6_prefix=", prefix) == -1)
4326 return -1;
4327 TAILQ_FOREACH(ap, &state->addrs, next) {
4328 if (ap->delegating_prefix == NULL)
4329 continue;
4330 if (ap != TAILQ_FIRST(&state->addrs)) {
4331 if (fputc(' ', fp) == EOF)
4332 return -1;
4333 }
4334 if (fprintf(fp, "%s", ap->saddr) == -1)
4335 return -1;
4336 }
4337 if (fputc('\0', fp) == EOF)
4338 return -1;
4339 #endif
4340
4341 return 1;
4342 }
4343 #endif
4344
4345 #ifndef SMALL
4346 int
4347 dhcp6_dump(struct interface *ifp)
4348 {
4349 struct dhcp6_state *state;
4350
4351 ifp->if_data[IF_DATA_DHCP6] = state = calloc(1, sizeof(*state));
4352 if (state == NULL) {
4353 logerr(__func__);
4354 return -1;
4355 }
4356 TAILQ_INIT(&state->addrs);
4357 if (dhcp6_readlease(ifp, 0) == -1) {
4358 logerr("dhcp6_readlease");
4359 return -1;
4360 }
4361 state->reason = "DUMP6";
4362 return script_runreason(ifp, state->reason);
4363 }
4364 #endif