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