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