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