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