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