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