1 /** 2 * Copyright (C) 2012-2014 Steven Barth <steven@midlink.org> 3 * Copyright (C) 2017-2018 Hans Dedecker <dedeckeh@gmail.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License v2 as published by 7 * the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 */ 15 16 #include <arpa/inet.h> 17 #include <ctype.h> 18 #include <errno.h> 19 #include <fcntl.h> 20 #include <inttypes.h> 21 #include <libubox/md5.h> 22 #include <limits.h> 23 #include <netinet/in.h> 24 #include <net/if.h> 25 #include <net/ethernet.h> 26 #include <resolv.h> 27 #include <signal.h> 28 #include <stdbool.h> 29 #include <stdlib.h> 30 #include <string.h> 31 #include <sys/ioctl.h> 32 #include <sys/socket.h> 33 #include <sys/time.h> 34 #include <time.h> 35 #include <unistd.h> 36 37 #include "config.h" 38 #include "odhcp6c.h" 39 40 #define ALL_DHCPV6_RELAYS {{{0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ 41 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02}}} 42 #define DHCPV6_CLIENT_PORT 546 43 #define DHCPV6_SERVER_PORT 547 44 #define DHCPV6_DUID_LLADDR 3 45 46 #define DHCPV6_SOL_MAX_RT_MIN 60 47 #define DHCPV6_SOL_MAX_RT_MAX 86400 48 #define DHCPV6_INF_MAX_RT_MIN 60 49 #define DHCPV6_INF_MAX_RT_MAX 86400 50 51 static bool dhcpv6_response_is_valid(const void *buf, ssize_t len, 52 const uint8_t transaction[3], enum dhcpv6_msg req_msg_type, 53 const struct in6_addr *daddr); 54 55 static unsigned int dhcpv6_parse_ia(void *opt, void *end, int *ret); 56 57 static unsigned int dhcpv6_calc_refresh_timers(void); 58 static void dhcpv6_handle_status_code(_o_unused const enum dhcpv6_msg orig, 59 const uint16_t code, const void *status_msg, const int len, 60 int *ret); 61 static void dhcpv6_handle_ia_status_code(const enum dhcpv6_msg orig, 62 const struct dhcpv6_ia_hdr *ia_hdr, const uint16_t code, 63 const void *status_msg, const int len, 64 bool handled_status_codes[_DHCPV6_Status_Max], 65 int *ret); 66 static void dhcpv6_add_server_cand(const struct dhcpv6_server_cand *cand); 67 static void dhcpv6_clear_all_server_cand(void); 68 69 static void dhcpv6_log_status_code(const uint16_t code, const char *scope, 70 const void *status_msg, int len); 71 72 static reply_handler dhcpv6_handle_reply; 73 static reply_handler dhcpv6_handle_advert; 74 static reply_handler dhcpv6_handle_rebind_reply; 75 static reply_handler dhcpv6_handle_reconfigure; 76 static int dhcpv6_commit_advert(void); 77 78 // RFC 3315 - 5.5 Timeout and Delay values 79 static const struct dhcpv6_retx dhcpv6_retx_default[_DHCPV6_MSG_MAX] = { 80 [DHCPV6_MSG_UNKNOWN] = { 81 0, 82 1, 83 120, 84 0, 85 "<POLL>", 86 dhcpv6_handle_reconfigure, 87 NULL, 88 false, 89 0, 90 0, 91 0, 92 {0, 0, 0}, 93 0, 94 0, 95 0, 96 -1, 97 0 98 }, 99 [DHCPV6_MSG_SOLICIT] = { 100 DHCPV6_MAX_DELAY, 101 DHCPV6_SOL_INIT_RT, 102 DHCPV6_SOL_MAX_RT, 103 0, 104 "SOLICIT", 105 dhcpv6_handle_advert, 106 dhcpv6_commit_advert, 107 false, 108 0, 109 0, 110 0, 111 {0, 0, 0}, 112 0, 113 0, 114 0, 115 -1, 116 0 117 }, 118 [DHCPV6_MSG_REQUEST] = { 119 0, 120 DHCPV6_REQ_INIT_RT, 121 DHCPV6_REQ_MAX_RT, 122 DHCPV6_REQ_MAX_RC, 123 "REQUEST", 124 dhcpv6_handle_reply, 125 NULL, 126 false, 127 0, 128 0, 129 0, 130 {0, 0, 0}, 131 0, 132 0, 133 0, 134 -1, 135 0 136 }, 137 [DHCPV6_MSG_RENEW] = { 138 0, 139 DHCPV6_REN_INIT_RT, 140 DHCPV6_REN_MAX_RT, 141 0, 142 "RENEW", 143 dhcpv6_handle_reply, 144 NULL, 145 false, 146 0, 147 0, 148 0, 149 {0, 0, 0}, 150 0, 151 0, 152 0, 153 -1, 154 0 155 }, 156 [DHCPV6_MSG_REBIND] = { 157 0, 158 DHCPV6_REB_INIT_RT, 159 DHCPV6_REB_MAX_RT, 160 0, 161 "REBIND", 162 dhcpv6_handle_rebind_reply, 163 NULL, 164 false, 165 0, 166 0, 167 0, 168 {0, 0, 0}, 169 0, 170 0, 171 0, 172 -1, 173 0 174 }, 175 [DHCPV6_MSG_RELEASE] = { 176 0, 177 DHCPV6_REL_INIT_RT, 178 0, 179 DHCPV6_REL_MAX_RC, 180 "RELEASE", 181 NULL, 182 NULL, 183 false, 184 0, 185 0, 186 0, 187 {0, 0, 0}, 188 0, 189 0, 190 0, 191 -1, 192 0 193 }, 194 [DHCPV6_MSG_DECLINE] = { 195 0, 196 DHCPV6_DEC_INIT_RT, 197 0, 198 DHCPV6_DEC_MAX_RC, 199 "DECLINE", 200 NULL, 201 NULL, 202 false, 203 0, 204 0, 205 0, 206 {0, 0, 0}, 207 0, 208 0, 209 0, 210 -1, 211 0 212 }, 213 [DHCPV6_MSG_INFO_REQ] = { 214 DHCPV6_MAX_DELAY, 215 DHCPV6_INF_INIT_RT, 216 DHCPV6_INF_MAX_RT, 217 0, 218 "INFOREQ", 219 dhcpv6_handle_reply, 220 NULL, 221 false, 222 0, 223 0, 224 0, 225 {0, 0, 0}, 226 0, 227 0, 228 0, 229 -1, 230 0 231 }, 232 }; 233 static struct dhcpv6_retx dhcpv6_retx[_DHCPV6_MSG_MAX] = {0}; 234 235 // Sockets 236 static int sock = -1; 237 static int ifindex = -1; 238 static int64_t t1 = 0, t2 = 0, t3 = 0; 239 240 // IA states 241 static enum odhcp6c_ia_mode na_mode = IA_MODE_NONE, pd_mode = IA_MODE_NONE; 242 static bool stateful_only_mode = false; 243 static bool accept_reconfig = false; 244 // Server unicast address 245 static struct in6_addr server_addr = IN6ADDR_ANY_INIT; 246 247 // Initial state of the DHCPv6 service 248 static enum dhcpv6_state dhcpv6_state = DHCPV6_INIT; 249 static int dhcpv6_state_timeout = 0; 250 251 // Authentication options 252 static enum odhcp6c_auth_protocol auth_protocol = AUTH_PROT_RKAP; 253 static uint8_t reconf_key[16]; 254 255 // client options 256 static unsigned int client_options = 0; 257 258 // counters for statistics 259 static struct dhcpv6_stats dhcpv6_stats = {0}; 260 261 // config 262 static struct config_dhcp* config_dhcp = NULL; 263 264 // store unique ifname hash to use as IA->IAID 265 static uint32_t ifname_hash_iaid = 0; 266 267 static uint32_t ntohl_unaligned(const uint8_t *data) 268 { 269 uint32_t buf; 270 271 memcpy(&buf, data, sizeof(buf)); 272 return ntohl(buf); 273 } 274 275 static void dhcpv6_next_state(void) 276 { 277 dhcpv6_state++; 278 dhcpv6_reset_state_timeout(); 279 } 280 281 static void dhcpv6_prev_state(void) 282 { 283 dhcpv6_state--; 284 dhcpv6_reset_state_timeout(); 285 } 286 287 static void dhcpv6_inc_counter(enum dhcpv6_msg type) 288 { 289 switch (type) { 290 case DHCPV6_MSG_SOLICIT: 291 dhcpv6_stats.solicit++; 292 break; 293 294 case DHCPV6_MSG_ADVERT: 295 dhcpv6_stats.advertise++; 296 break; 297 298 case DHCPV6_MSG_REQUEST: 299 dhcpv6_stats.request++; 300 break; 301 302 case DHCPV6_MSG_RENEW: 303 dhcpv6_stats.renew++; 304 break; 305 306 case DHCPV6_MSG_REBIND: 307 dhcpv6_stats.rebind++; 308 break; 309 310 case DHCPV6_MSG_REPLY: 311 dhcpv6_stats.reply++; 312 break; 313 314 case DHCPV6_MSG_RELEASE: 315 dhcpv6_stats.release++; 316 break; 317 318 case DHCPV6_MSG_DECLINE: 319 dhcpv6_stats.decline++; 320 break; 321 322 case DHCPV6_MSG_RECONF: 323 dhcpv6_stats.reconfigure++; 324 break; 325 326 case DHCPV6_MSG_INFO_REQ: 327 dhcpv6_stats.information_request++; 328 break; 329 330 default: 331 break; 332 } 333 } 334 335 static char *dhcpv6_msg_to_str(enum dhcpv6_msg msg) 336 { 337 switch (msg) { 338 case DHCPV6_MSG_SOLICIT: 339 return "SOLICIT"; 340 341 case DHCPV6_MSG_ADVERT: 342 return "ADVERTISE"; 343 344 case DHCPV6_MSG_REQUEST: 345 return "REQUEST"; 346 347 case DHCPV6_MSG_RENEW: 348 return "RENEW"; 349 350 case DHCPV6_MSG_REBIND: 351 return "REBIND"; 352 353 case DHCPV6_MSG_REPLY: 354 return "REPLY"; 355 356 case DHCPV6_MSG_RELEASE: 357 return "RELEASE"; 358 359 case DHCPV6_MSG_DECLINE: 360 return "DECLINE"; 361 362 case DHCPV6_MSG_RECONF: 363 return "RECONFIGURE"; 364 365 case DHCPV6_MSG_INFO_REQ: 366 return "INFORMATION REQUEST"; 367 368 default: 369 break; 370 } 371 372 return "UNKNOWN"; 373 } 374 375 static char *dhcpv6_status_code_to_str(uint16_t code) 376 { 377 switch (code) { 378 case DHCPV6_Success: 379 return "Success"; 380 381 case DHCPV6_UnspecFail: 382 return "Unspecified Failure"; 383 384 case DHCPV6_NoAddrsAvail: 385 return "No Address Available"; 386 387 case DHCPV6_NoBinding: 388 return "No Binding"; 389 390 case DHCPV6_NotOnLink: 391 return "Not On Link"; 392 393 case DHCPV6_UseMulticast: 394 return "Use Multicast"; 395 396 case DHCPV6_NoPrefixAvail: 397 return "No Prefix Available"; 398 399 default: 400 break; 401 } 402 403 return "Unknown"; 404 } 405 406 const char *dhcpv6_state_to_str(enum dhcpv6_state state) 407 { 408 switch (state) { 409 case DHCPV6_INIT: 410 return "INIT"; 411 412 case DHCPV6_SOLICIT: 413 return "SOLICIT"; 414 415 case DHCPV6_SOLICIT_PROCESSING: 416 return "SOLICIT_PROCESSING"; 417 418 case DHCPV6_ADVERT: 419 return "ADVERT"; 420 421 case DHCPV6_REQUEST: 422 return "REQUEST"; 423 424 case DHCPV6_REQUEST_PROCESSING: 425 return "REQUEST_PROCESSING"; 426 427 case DHCPV6_REPLY: 428 return "REPLY"; 429 430 case DHCPV6_BOUND: 431 return "BOUND"; 432 433 case DHCPV6_BOUND_PROCESSING: 434 return "BOUND_PROCESSING"; 435 436 case DHCPV6_BOUND_REPLY: 437 return "BOUND_REPLY"; 438 439 case DHCPV6_RECONF: 440 return "RECONF"; 441 442 case DHCPV6_RECONF_PROCESSING: 443 return "RECONF_PROCESSING"; 444 445 case DHCPV6_RECONF_REPLY: 446 return "RECONF_REPLY"; 447 448 case DHCPV6_RENEW: 449 return "RENEW"; 450 451 case DHCPV6_RENEW_PROCESSING: 452 return "RENEW_PROCESSING"; 453 454 case DHCPV6_RENEW_REPLY: 455 return "RENEW_REPLY"; 456 457 case DHCPV6_REBIND: 458 return "REBIND"; 459 460 case DHCPV6_REBIND_PROCESSING: 461 return "REBIND_PROCESSING"; 462 463 case DHCPV6_REBIND_REPLY: 464 return "REBIND_REPLY"; 465 466 case DHCPV6_INFO: 467 return "INFO"; 468 469 case DHCPV6_INFO_PROCESSING: 470 return "INFO_PROCESSING"; 471 472 case DHCPV6_INFO_REPLY: 473 return "INFO_REPLY"; 474 475 case DHCPV6_EXIT: 476 return "EXIT"; 477 478 default: 479 return "INVALID_STATE"; 480 } 481 } 482 483 static int fd_set_nonblocking(int sockfd) 484 { 485 int flags = fcntl(sockfd, F_GETFL, 0); 486 if (flags == -1) { 487 error( 488 "Failed to get the dhcpv6 socket flags: fcntl F_GETFL failed (%s)", 489 strerror(errno)); 490 return -1; 491 } 492 493 // Set the socket to non-blocking 494 if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) { 495 error( 496 "Failed to set the dhcpv6 socket to non-blocking: fcntl F_SETFL failed (%s)", 497 strerror(errno)); 498 return -1; 499 } 500 501 return 0; 502 } 503 504 int dhcpv6_get_socket(void) 505 { 506 return sock; 507 } 508 509 enum dhcpv6_state dhcpv6_get_state(void) 510 { 511 return dhcpv6_state; 512 } 513 514 void dhcpv6_set_state(enum dhcpv6_state state) 515 { 516 dhcpv6_state = state; 517 dhcpv6_reset_state_timeout(); 518 } 519 520 int dhcpv6_get_state_timeout(void) 521 { 522 return dhcpv6_state_timeout; 523 } 524 525 void dhcpv6_set_state_timeout(int timeout) 526 { 527 if (timeout > 0 && (dhcpv6_state_timeout == 0 || timeout < dhcpv6_state_timeout)) { 528 dhcpv6_state_timeout = timeout; 529 } 530 } 531 532 void dhcpv6_reset_state_timeout(void) 533 { 534 dhcpv6_state_timeout = 0; 535 } 536 537 struct dhcpv6_stats dhcpv6_get_stats(void) 538 { 539 return dhcpv6_stats; 540 } 541 542 void dhcpv6_reset_stats(void) 543 { 544 memset(&dhcpv6_stats, 0, sizeof(dhcpv6_stats)); 545 } 546 547 static uint32_t dhcpv6_generate_iface_iaid(const char *ifname) { 548 uint8_t hash[16] = {0}; 549 uint32_t iaid; 550 md5_ctx_t md5; 551 552 md5_begin(&md5); 553 md5_hash(ifname, strlen(ifname), &md5); 554 md5_end(hash, &md5); 555 556 iaid = hash[0] << 24; 557 iaid |= hash[1] << 16; 558 iaid |= hash[2] << 8; 559 iaid |= hash[3]; 560 561 return iaid; 562 } 563 564 int init_dhcpv6(const char *ifname) 565 { 566 config_dhcp = config_dhcp_get(); 567 568 memcpy(dhcpv6_retx, dhcpv6_retx_default, sizeof(dhcpv6_retx)); 569 config_apply_dhcp_rtx(dhcpv6_retx); 570 571 client_options = config_dhcp->client_options; 572 na_mode = config_dhcp->ia_na_mode; 573 pd_mode = config_dhcp->ia_pd_mode; 574 stateful_only_mode = config_dhcp->stateful_only_mode; 575 auth_protocol = config_dhcp->auth_protocol; 576 577 sock = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP); 578 if (sock < 0) 579 goto failure; 580 581 // Detect interface 582 struct ifreq ifr; 583 memset(&ifr, 0, sizeof(ifr)); 584 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); 585 if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) 586 goto failure; 587 588 ifname_hash_iaid = dhcpv6_generate_iface_iaid(ifname); 589 590 ifindex = ifr.ifr_ifindex; 591 592 // Set the socket to non-blocking mode 593 if (fd_set_nonblocking(sock) < 0) 594 goto failure; 595 596 // Build our FQDN 597 size_t fqdn_len; 598 odhcp6c_get_state(STATE_OUR_FQDN, &fqdn_len); 599 if(fqdn_len == 0) { 600 char fqdn_buf[256]; 601 gethostname(fqdn_buf, sizeof(fqdn_buf)); 602 struct { 603 uint16_t type; 604 uint16_t len; 605 uint8_t flags; 606 uint8_t data[256]; 607 } fqdn = {0}; 608 int dn_result = dn_comp(fqdn_buf, fqdn.data, 609 sizeof(fqdn.data), NULL, NULL); 610 fqdn_len = 0; 611 if (dn_result > 0) { 612 fqdn.type = htons(DHCPV6_OPT_FQDN); 613 fqdn.len = htons(1 + dn_result); 614 fqdn.flags = 0; 615 fqdn_len = DHCPV6_OPT_HDR_SIZE + 1 + dn_result; 616 } 617 odhcp6c_add_state(STATE_OUR_FQDN, &fqdn, fqdn_len); 618 } 619 620 // Create client DUID 621 size_t client_id_len; 622 odhcp6c_get_state(STATE_CLIENT_ID, &client_id_len); 623 if (client_id_len == 0) { 624 uint8_t duid[14] = {0, DHCPV6_OPT_CLIENTID, 0, 10, 0, 625 DHCPV6_DUID_LLADDR, 0, 1}; 626 627 if (ioctl(sock, SIOCGIFHWADDR, &ifr) >= 0) 628 memcpy(&duid[8], ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); 629 630 uint8_t zero[ETHER_ADDR_LEN] = {0, 0, 0, 0, 0, 0}; 631 struct ifreq ifs[100], *ifp, *ifend; 632 struct ifconf ifc; 633 ifc.ifc_req = ifs; 634 ifc.ifc_len = sizeof(ifs); 635 636 if (!memcmp(&duid[8], zero, ETHER_ADDR_LEN) && 637 ioctl(sock, SIOCGIFCONF, &ifc) >= 0) { 638 // If our interface doesn't have an address... 639 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq)); 640 for (ifp = ifc.ifc_req; ifp < ifend && 641 !memcmp(&duid[8], zero, ETHER_ADDR_LEN); ifp++) { 642 memcpy(ifr.ifr_name, ifp->ifr_name, 643 sizeof(ifr.ifr_name)); 644 if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) 645 continue; 646 647 memcpy(&duid[8], ifr.ifr_hwaddr.sa_data, 648 ETHER_ADDR_LEN); 649 } 650 } 651 652 odhcp6c_add_state(STATE_CLIENT_ID, duid, sizeof(duid)); 653 } 654 655 // Create ORO 656 if (!(client_options & DHCPV6_STRICT_OPTIONS)) { 657 uint16_t oro[] = { 658 htons(DHCPV6_OPT_SIP_SERVER_D), 659 htons(DHCPV6_OPT_SIP_SERVER_A), 660 htons(DHCPV6_OPT_DNS_SERVERS), 661 htons(DHCPV6_OPT_DNS_DOMAIN), 662 htons(DHCPV6_OPT_SNTP_SERVERS), 663 htons(DHCPV6_OPT_NTP_SERVER), 664 htons(DHCPV6_OPT_PD_EXCLUDE), 665 /* RFC8910: Clients that support this option SHOULD include it */ 666 htons(DHCPV6_OPT_CAPTIVE_PORTAL), 667 }; 668 odhcp6c_add_state(STATE_ORO, oro, sizeof(oro)); 669 } 670 // Required ORO 671 uint16_t req_oro[] = { 672 htons(DHCPV6_OPT_INF_MAX_RT), 673 htons(DHCPV6_OPT_SOL_MAX_RT), 674 htons(DHCPV6_OPT_INFO_REFRESH), 675 }; 676 odhcp6c_add_state(STATE_ORO, req_oro, sizeof(req_oro)); 677 678 // Configure IPv6-options 679 int val = 1; 680 if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) < 0) 681 goto failure; 682 683 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) 684 goto failure; 685 686 if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val, sizeof(val)) < 0) 687 goto failure; 688 689 if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname)) < 0) 690 goto failure; 691 692 if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &(config_dhcp->sk_prio), sizeof(config_dhcp->sk_prio)) < 0) 693 goto failure; 694 695 val = config_dhcp->dscp << 2; 696 if (setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, &val, sizeof(val)) < 0) { 697 goto failure; 698 } 699 700 struct sockaddr_in6 client_addr = { .sin6_family = AF_INET6, 701 .sin6_port = htons(DHCPV6_CLIENT_PORT), .sin6_flowinfo = 0 }; 702 703 if (bind(sock, (struct sockaddr*)&client_addr, sizeof(client_addr)) < 0) 704 goto failure; 705 706 return 0; 707 708 failure: 709 if (sock >= 0) 710 close(sock); 711 712 return -1; 713 } 714 715 enum { 716 IOV_HDR=0, 717 IOV_ORO, 718 IOV_CL_ID, 719 IOV_SRV_ID, 720 IOV_OPTS, 721 IOV_RECONF_ACCEPT, 722 IOV_FQDN, 723 IOV_HDR_IA_NA, 724 IOV_IA_NA, 725 IOV_IA_PD, 726 IOV_TOTAL 727 }; 728 729 int dhcpv6_get_ia_mode(void) 730 { 731 int mode = DHCPV6_UNKNOWN; 732 733 if (na_mode == IA_MODE_NONE && pd_mode == IA_MODE_NONE) 734 mode = DHCPV6_STATELESS; 735 else if (na_mode == IA_MODE_FORCE || pd_mode == IA_MODE_FORCE) 736 mode = DHCPV6_STATEFUL; 737 738 return mode; 739 } 740 741 static void dhcpv6_send(enum dhcpv6_msg req_msg_type, uint8_t trid[3], uint32_t ecs) 742 { 743 // Build FQDN 744 size_t fqdn_len; 745 void *fqdn = odhcp6c_get_state(STATE_OUR_FQDN, &fqdn_len); 746 747 // Build Client ID 748 size_t cl_id_len; 749 void *cl_id = odhcp6c_get_state(STATE_CLIENT_ID, &cl_id_len); 750 751 // Get Server ID 752 size_t srv_id_len; 753 void *srv_id = odhcp6c_get_state(STATE_SERVER_ID, &srv_id_len); 754 755 // Build IA_PDs 756 size_t ia_pd_entry_cnt = 0, ia_pd_len = 0; 757 uint8_t *ia_pd; 758 struct odhcp6c_entry *pd_entries = odhcp6c_get_state(STATE_IA_PD, &ia_pd_entry_cnt); 759 ia_pd_entry_cnt /= sizeof(*pd_entries); 760 761 if (req_msg_type == DHCPV6_MSG_SOLICIT || (req_msg_type == DHCPV6_MSG_REQUEST && ia_pd_entry_cnt == 0 && pd_mode != IA_MODE_NONE)) { 762 odhcp6c_clear_state(STATE_IA_PD); 763 size_t n_prefixes; 764 struct odhcp6c_request_prefix *request_prefixes = odhcp6c_get_state(STATE_IA_PD_INIT, &n_prefixes); 765 n_prefixes /= sizeof(struct odhcp6c_request_prefix); 766 767 ia_pd = alloca(n_prefixes * (sizeof(struct dhcpv6_ia_hdr) + sizeof(struct dhcpv6_ia_prefix))); 768 769 for (size_t i = 0; i < n_prefixes; i++) { 770 struct dhcpv6_ia_hdr hdr_ia_pd = { 771 htons(DHCPV6_OPT_IA_PD), 772 htons(sizeof(hdr_ia_pd) - DHCPV6_OPT_HDR_SIZE + 773 sizeof(struct dhcpv6_ia_prefix) * !!request_prefixes[i].length), 774 request_prefixes[i].iaid, 0, 0 775 }; 776 struct dhcpv6_ia_prefix pref = { 777 .type = htons(DHCPV6_OPT_IA_PREFIX), 778 .len = htons(sizeof(pref) - DHCPV6_OPT_HDR_SIZE), 779 .prefix = request_prefixes[i].length, 780 .addr = request_prefixes[i].addr 781 }; 782 memcpy(ia_pd + ia_pd_len, &hdr_ia_pd, sizeof(hdr_ia_pd)); 783 ia_pd_len += sizeof(hdr_ia_pd); 784 if (request_prefixes[i].length) { 785 memcpy(ia_pd + ia_pd_len, &pref, sizeof(pref)); 786 ia_pd_len += sizeof(pref); 787 } 788 } 789 } else { 790 // we're too lazy to count our distinct IAIDs, 791 // so just allocate maximally needed space 792 ia_pd = alloca(ia_pd_entry_cnt * (sizeof(struct dhcpv6_ia_prefix) + 10 + 793 sizeof(struct dhcpv6_ia_hdr))); 794 795 for (size_t i = 0; i < ia_pd_entry_cnt; ++i) { 796 uint32_t iaid = pd_entries[i].iaid; 797 798 // check if this is an unprocessed IAID and skip if not. 799 bool new_iaid = true; 800 for (int j = i-1; j >= 0; j--) { 801 if (pd_entries[j].iaid == iaid) { 802 new_iaid = false; 803 break; 804 } 805 } 806 807 if (!new_iaid) 808 continue; 809 810 // construct header 811 struct dhcpv6_ia_hdr hdr_ia_pd = { 812 htons(DHCPV6_OPT_IA_PD), 813 htons(sizeof(hdr_ia_pd) - DHCPV6_OPT_HDR_SIZE), 814 iaid, 0, 0 815 }; 816 817 memcpy(ia_pd + ia_pd_len, &hdr_ia_pd, sizeof(hdr_ia_pd)); 818 struct dhcpv6_ia_hdr *hdr = (struct dhcpv6_ia_hdr *) (ia_pd + ia_pd_len); 819 ia_pd_len += sizeof(hdr_ia_pd); 820 821 for (size_t j = i; j < ia_pd_entry_cnt; j++) { 822 if (pd_entries[j].iaid != iaid) 823 continue; 824 825 uint8_t ex_len = 0; 826 if (pd_entries[j].exclusion_length > 0) 827 ex_len = ((pd_entries[j].exclusion_length - pd_entries[j].length - 1) / 8) + 6; 828 829 struct dhcpv6_ia_prefix p = { 830 .type = htons(DHCPV6_OPT_IA_PREFIX), 831 .len = htons(sizeof(p) - DHCPV6_OPT_HDR_SIZE_U + ex_len), 832 .prefix = pd_entries[j].length, 833 .addr = pd_entries[j].target 834 }; 835 836 if (req_msg_type == DHCPV6_MSG_REQUEST) { 837 p.preferred = htonl(pd_entries[j].preferred); 838 p.valid = htonl(pd_entries[j].valid); 839 } 840 841 memcpy(ia_pd + ia_pd_len, &p, sizeof(p)); 842 ia_pd_len += sizeof(p); 843 844 if (ex_len) { 845 ia_pd[ia_pd_len++] = 0; 846 ia_pd[ia_pd_len++] = DHCPV6_OPT_PD_EXCLUDE; 847 ia_pd[ia_pd_len++] = 0; 848 ia_pd[ia_pd_len++] = ex_len - DHCPV6_OPT_HDR_SIZE; 849 ia_pd[ia_pd_len++] = pd_entries[j].exclusion_length; 850 851 uint32_t excl = ntohl(pd_entries[j].router.s6_addr32[1]); 852 excl >>= (64 - pd_entries[j].exclusion_length); 853 excl <<= 8 - ((pd_entries[j].exclusion_length - pd_entries[j].length) % 8); 854 855 for (size_t k = ex_len - 5; k > 0; --k, excl >>= 8) 856 ia_pd[ia_pd_len + k] = excl & 0xff; 857 858 ia_pd_len += ex_len - 5; 859 } 860 861 hdr->len = htons(ntohs(hdr->len) + ntohs(p.len) + 4U); 862 } 863 } 864 } 865 866 // Build IA_NAs 867 size_t ia_na_entry_cnt, ia_na_len = 0; 868 void *ia_na = NULL; 869 struct odhcp6c_entry *ia_entries = odhcp6c_get_state(STATE_IA_NA, &ia_na_entry_cnt); 870 ia_na_entry_cnt /= sizeof(*ia_entries); 871 872 struct dhcpv6_ia_hdr hdr_ia_na = { 873 .type = htons(DHCPV6_OPT_IA_NA), 874 .len = htons(sizeof(hdr_ia_na) - DHCPV6_OPT_HDR_SIZE), 875 .iaid = htonl(ifname_hash_iaid), 876 .t1 = 0, 877 .t2 = 0, 878 }; 879 880 struct dhcpv6_ia_addr ia_na_array[ia_na_entry_cnt]; 881 for (size_t i = 0; i < ia_na_entry_cnt; ++i) { 882 ia_na_array[i].type = htons(DHCPV6_OPT_IA_ADDR); 883 ia_na_array[i].len = htons(sizeof(ia_na_array[i]) - DHCPV6_OPT_HDR_SIZE_U); 884 ia_na_array[i].addr = ia_entries[i].target; 885 886 if (req_msg_type == DHCPV6_MSG_REQUEST) { 887 ia_na_array[i].preferred = htonl(ia_entries[i].preferred); 888 ia_na_array[i].valid = htonl(ia_entries[i].valid); 889 } else { 890 ia_na_array[i].preferred = 0; 891 ia_na_array[i].valid = 0; 892 } 893 } 894 895 ia_na = ia_na_array; 896 ia_na_len = sizeof(ia_na_array); 897 hdr_ia_na.len = htons(ntohs(hdr_ia_na.len) + ia_na_len); 898 899 // Reconfigure Accept 900 struct { 901 uint16_t type; 902 uint16_t length; 903 } reconf_accept = {htons(DHCPV6_OPT_RECONF_ACCEPT), 0}; 904 905 // Option list 906 size_t opts_len; 907 void *opts = odhcp6c_get_state(STATE_OPTS, &opts_len); 908 909 // Option Request List 910 size_t oro_entries, oro_len = 0; 911 uint16_t *oro, *s_oro = odhcp6c_get_state(STATE_ORO, &oro_entries); 912 913 oro_entries /= sizeof(*s_oro); 914 oro = alloca(oro_entries * sizeof(*oro)); 915 916 for (size_t i = 0; i < oro_entries; i++) { 917 struct odhcp6c_opt *opt = odhcp6c_find_opt(htons(s_oro[i])); 918 919 if (opt) { 920 if (!(opt->flags & OPT_ORO)) 921 continue; 922 923 if ((opt->flags & OPT_ORO_SOLICIT) && req_msg_type != DHCPV6_MSG_SOLICIT) 924 continue; 925 926 if ((opt->flags & OPT_ORO_STATELESS) && req_msg_type != DHCPV6_MSG_INFO_REQ) 927 continue; 928 929 if ((opt->flags & OPT_ORO_STATEFUL) && req_msg_type == DHCPV6_MSG_INFO_REQ) 930 continue; 931 } 932 933 oro[oro_len++] = s_oro[i]; 934 } 935 oro_len *= sizeof(*oro); 936 937 // Prepare Header 938 struct { 939 uint8_t type; 940 uint8_t trid[3]; 941 uint16_t elapsed_type; 942 uint16_t elapsed_len; 943 uint16_t elapsed_value; 944 uint16_t oro_type; 945 uint16_t oro_len; 946 } hdr = { 947 req_msg_type, {trid[0], trid[1], trid[2]}, 948 htons(DHCPV6_OPT_ELAPSED), htons(2), 949 htons((ecs > 0xffff) ? 0xffff : ecs), 950 htons(DHCPV6_OPT_ORO), htons(oro_len), 951 }; 952 953 struct iovec iov[IOV_TOTAL] = { 954 [IOV_HDR] = {&hdr, sizeof(hdr)}, 955 [IOV_ORO] = {oro, oro_len}, 956 [IOV_CL_ID] = {cl_id, cl_id_len}, 957 [IOV_SRV_ID] = {srv_id, srv_id_len}, 958 [IOV_OPTS] = { opts, opts_len }, 959 [IOV_RECONF_ACCEPT] = {&reconf_accept, sizeof(reconf_accept)}, 960 [IOV_FQDN] = {fqdn, fqdn_len}, 961 [IOV_HDR_IA_NA] = {&hdr_ia_na, sizeof(hdr_ia_na)}, 962 [IOV_IA_NA] = {ia_na, ia_na_len}, 963 [IOV_IA_PD] = {ia_pd, ia_pd_len}, 964 }; 965 966 size_t cnt = IOV_TOTAL; 967 if (req_msg_type == DHCPV6_MSG_INFO_REQ) 968 cnt = IOV_HDR_IA_NA; 969 970 // Disable IAs if not used 971 if (na_mode == IA_MODE_NONE) { 972 iov[IOV_HDR_IA_NA].iov_len = 0; 973 } else if (ia_na_len == 0) { 974 /* RFC7550 §4.2 975 * Solution: a client SHOULD accept Advertise messages, even 976 * when not all IA option types are being offered. And, in 977 * this case, the client SHOULD include the not offered IA 978 * option types in its Request. A client SHOULD only ignore 979 * an Advertise message when none of the requested IA 980 * options include offered addresses or delegated prefixes. 981 * Note that ignored messages MUST still be processed for 982 * SOL_MAX_RT and INF_MAX_RT options as specified in 983 * [RFC7083]. 984 */ 985 986 switch (req_msg_type) { 987 case DHCPV6_MSG_REQUEST: 988 if (!config_dhcp->strict_rfc7550) { 989 /* Some broken ISPs won't behave properly if IA_NA is 990 * sent on Requests when they have provided an empty 991 * IA_NA on Advertise. 992 * Therefore we don't comply with RFC7550 and omit 993 * IA_NA as a workaround. 994 */ 995 iov[IOV_HDR_IA_NA].iov_len = 0; 996 } 997 break; 998 case DHCPV6_MSG_SOLICIT: 999 break; 1000 default: 1001 iov[IOV_HDR_IA_NA].iov_len = 0; 1002 break; 1003 } 1004 } 1005 1006 if ((req_msg_type != DHCPV6_MSG_SOLICIT && req_msg_type != DHCPV6_MSG_REQUEST) || 1007 !(client_options & DHCPV6_ACCEPT_RECONFIGURE)) 1008 iov[IOV_RECONF_ACCEPT].iov_len = 0; 1009 1010 if (!(client_options & DHCPV6_CLIENT_FQDN)) { 1011 iov[IOV_FQDN].iov_len = 0; 1012 } else { 1013 switch (req_msg_type) { 1014 /* RFC4704 §5 1015 A client MUST only include the Client FQDN option in SOLICIT, 1016 REQUEST, RENEW, or REBIND messages. 1017 */ 1018 case DHCPV6_MSG_SOLICIT: 1019 case DHCPV6_MSG_REQUEST: 1020 case DHCPV6_MSG_RENEW: 1021 case DHCPV6_MSG_REBIND: 1022 /* RFC4704 §6 1023 Servers MUST only include a Client FQDN option in ADVERTISE and REPLY 1024 messages... 1025 case DHCPV6_MSG_ADVERT: 1026 case DHCPV6_MSG_REPLY: 1027 */ 1028 /* leave FQDN as-is */ 1029 break; 1030 default: 1031 /* remaining MSG types cannot contain client FQDN */ 1032 iov[IOV_FQDN].iov_len = 0; 1033 break; 1034 } 1035 } 1036 1037 struct sockaddr_in6 srv = {AF_INET6, htons(DHCPV6_SERVER_PORT), 1038 0, ALL_DHCPV6_RELAYS, ifindex}; 1039 struct msghdr msg = {.msg_name = &srv, .msg_namelen = sizeof(srv), 1040 .msg_iov = iov, .msg_iovlen = cnt}; 1041 1042 switch (req_msg_type) { 1043 case DHCPV6_MSG_REQUEST: 1044 case DHCPV6_MSG_RENEW: 1045 case DHCPV6_MSG_RELEASE: 1046 case DHCPV6_MSG_DECLINE: 1047 if (!IN6_IS_ADDR_UNSPECIFIED(&server_addr) && 1048 odhcp6c_addr_in_scope(&server_addr)) { 1049 srv.sin6_addr = server_addr; 1050 if (!IN6_IS_ADDR_LINKLOCAL(&server_addr)) 1051 srv.sin6_scope_id = 0; 1052 } 1053 break; 1054 default: 1055 break; 1056 } 1057 1058 if (sendmsg(sock, &msg, 0) < 0) { 1059 char in6_str[INET6_ADDRSTRLEN]; 1060 1061 error("Failed to send %s message to %s (%s)", 1062 dhcpv6_msg_to_str(req_msg_type), 1063 inet_ntop(AF_INET6, (const void *)&srv.sin6_addr, 1064 in6_str, sizeof(in6_str)), strerror(errno)); 1065 dhcpv6_stats.transmit_failures++; 1066 } else { 1067 dhcpv6_inc_counter(req_msg_type); 1068 } 1069 } 1070 1071 static int64_t dhcpv6_rand_delay(int64_t time) 1072 { 1073 int random; 1074 odhcp6c_random(&random, sizeof(random)); 1075 1076 return (time * ((int64_t)random % (config_dhcp->rand_factor*10LL))) / 10000LL; 1077 } 1078 1079 // Message validation checks according to RFC3315 chapter 15 1080 static bool dhcpv6_response_is_valid(const void *buf, ssize_t len, 1081 const uint8_t transaction[3], enum dhcpv6_msg req_msg_type, 1082 const struct in6_addr *daddr) 1083 { 1084 const struct dhcpv6_header *response_buf = buf; 1085 if (len < (ssize_t)sizeof(*response_buf) || memcmp(response_buf->tr_id, 1086 transaction, sizeof(response_buf->tr_id))) 1087 return false; // Invalid reply 1088 1089 if (req_msg_type == DHCPV6_MSG_SOLICIT) { 1090 if (response_buf->msg_type != DHCPV6_MSG_ADVERT && 1091 response_buf->msg_type != DHCPV6_MSG_REPLY) 1092 return false; 1093 } else if (req_msg_type == DHCPV6_MSG_UNKNOWN) { 1094 if (!accept_reconfig || response_buf->msg_type != DHCPV6_MSG_RECONF) 1095 return false; 1096 } else if (response_buf->msg_type != DHCPV6_MSG_REPLY) { 1097 return false; 1098 } 1099 1100 uint8_t *end = ((uint8_t*)buf) + len, *odata = NULL, 1101 rcmsg = DHCPV6_MSG_UNKNOWN; 1102 uint16_t otype, olen = UINT16_MAX; 1103 bool clientid_ok = false, serverid_ok = false, rcauth_ok = false, 1104 auth_present = false, ia_present = false, options_valid = true; 1105 1106 size_t client_id_len, server_id_len; 1107 void *client_id = odhcp6c_get_state(STATE_CLIENT_ID, &client_id_len); 1108 void *server_id = odhcp6c_get_state(STATE_SERVER_ID, &server_id_len); 1109 1110 dhcpv6_for_each_option(&response_buf[1], end, otype, olen, odata) { 1111 switch (otype) { 1112 case DHCPV6_OPT_CLIENTID: 1113 clientid_ok = (olen + DHCPV6_OPT_HDR_SIZE_U == client_id_len) && !memcmp( 1114 &odata[-DHCPV6_OPT_HDR_SIZE], client_id, client_id_len); 1115 break; 1116 1117 case DHCPV6_OPT_SERVERID: 1118 if (server_id_len) 1119 serverid_ok = (olen + DHCPV6_OPT_HDR_SIZE_U == server_id_len) && !memcmp( 1120 &odata[-DHCPV6_OPT_HDR_SIZE], server_id, server_id_len); 1121 else 1122 serverid_ok = true; 1123 break; 1124 1125 case DHCPV6_OPT_AUTH: 1126 struct dhcpv6_auth *r = (void*)&odata[-DHCPV6_OPT_HDR_SIZE]; 1127 if (auth_present) { 1128 options_valid = false; 1129 continue; 1130 } 1131 1132 auth_present = true; 1133 if (auth_protocol == AUTH_PROT_RKAP) { 1134 struct dhcpv6_auth_reconfigure *rkap = (void*)r->data; 1135 if (r->protocol != AUTH_PROT_RKAP || r->algorithm != AUTH_ALG_HMACMD5 || r->len != 28 || rkap->reconf_type != RKAP_TYPE_HMACMD5) 1136 continue; 1137 1138 md5_ctx_t md5; 1139 uint8_t serverhash[16], secretbytes[64]; 1140 uint32_t hash[4]; 1141 memcpy(serverhash, rkap->key, sizeof(serverhash)); 1142 memset(rkap->key, 0, sizeof(rkap->key)); 1143 1144 memset(secretbytes, 0, sizeof(secretbytes)); 1145 memcpy(secretbytes, reconf_key, sizeof(reconf_key)); 1146 1147 for (size_t i = 0; i < sizeof(secretbytes); ++i) 1148 secretbytes[i] ^= 0x36; 1149 1150 md5_begin(&md5); 1151 md5_hash(secretbytes, sizeof(secretbytes), &md5); 1152 md5_hash(buf, len, &md5); 1153 md5_end(hash, &md5); 1154 1155 for (size_t i = 0; i < sizeof(secretbytes); ++i) { 1156 secretbytes[i] ^= 0x36; 1157 secretbytes[i] ^= 0x5c; 1158 } 1159 1160 md5_begin(&md5); 1161 md5_hash(secretbytes, sizeof(secretbytes), &md5); 1162 md5_hash(hash, 16, &md5); 1163 md5_end(hash, &md5); 1164 1165 rcauth_ok = !memcmp(hash, serverhash, sizeof(hash)); 1166 } else if (auth_protocol == AUTH_PROT_TOKEN) { 1167 if (r->protocol != AUTH_PROT_TOKEN || r->algorithm != AUTH_ALG_TOKEN || r->len < 12) 1168 continue; 1169 1170 uint16_t token_len = r->len - 11; 1171 if (config_dhcp->auth_token == NULL || strlen(config_dhcp->auth_token) != token_len) 1172 continue; 1173 1174 rcauth_ok = !memcmp(r->data, config_dhcp->auth_token, token_len); 1175 } 1176 break; 1177 case DHCPV6_OPT_RECONF_MESSAGE: 1178 if (olen != 1) 1179 return false; 1180 rcmsg = odata[0]; 1181 break; 1182 1183 case DHCPV6_OPT_IA_PD: 1184 case DHCPV6_OPT_IA_NA: 1185 ia_present = true; 1186 if (olen < sizeof(struct dhcpv6_ia_hdr) - DHCPV6_OPT_HDR_SIZE) 1187 options_valid = false; 1188 break; 1189 1190 case DHCPV6_OPT_IA_ADDR: 1191 case DHCPV6_OPT_IA_PREFIX: 1192 case DHCPV6_OPT_PD_EXCLUDE: 1193 // Options are not allowed on global level 1194 options_valid = false; 1195 break; 1196 1197 default: 1198 break; 1199 } 1200 } 1201 1202 if (!options_valid || ((odata + olen) > end)) 1203 return false; 1204 1205 if (req_msg_type == DHCPV6_MSG_INFO_REQ && ia_present) 1206 return false; 1207 1208 if (response_buf->msg_type == DHCPV6_MSG_RECONF) { 1209 if ((rcmsg != DHCPV6_MSG_RENEW && rcmsg != DHCPV6_MSG_REBIND && rcmsg != DHCPV6_MSG_INFO_REQ) || 1210 (rcmsg == DHCPV6_MSG_INFO_REQ && ia_present) || 1211 !rcauth_ok || IN6_IS_ADDR_MULTICAST(daddr)) 1212 return false; 1213 } 1214 1215 return clientid_ok && serverid_ok; 1216 } 1217 1218 static int dhcpv6_handle_reconfigure(enum dhcpv6_msg orig, const int rc, 1219 const void *opt, const void *end, _o_unused const struct sockaddr_in6 *from) 1220 { 1221 uint16_t otype, olen; 1222 uint8_t *odata; 1223 enum dhcpv6_msg msg = DHCPV6_MSG_UNKNOWN; 1224 1225 dhcpv6_for_each_option(opt, end, otype, olen, odata) { 1226 if (otype == DHCPV6_OPT_RECONF_MESSAGE && olen == 1) { 1227 switch (odata[0]) { 1228 case DHCPV6_MSG_REBIND: 1229 if (t2 != UINT32_MAX) 1230 t2 = 0; 1231 _o_fallthrough; 1232 case DHCPV6_MSG_RENEW: 1233 if (t1 != UINT32_MAX) 1234 t1 = 0; 1235 _o_fallthrough; 1236 case DHCPV6_MSG_INFO_REQ: 1237 msg = odata[0]; 1238 notice("Need to respond with %s in reply to %s", 1239 dhcpv6_msg_to_str(msg), dhcpv6_msg_to_str(DHCPV6_MSG_RECONF)); 1240 break; 1241 1242 default: 1243 break; 1244 } 1245 } 1246 } 1247 1248 if (msg != DHCPV6_MSG_UNKNOWN) 1249 dhcpv6_handle_reply(orig, rc, NULL, NULL, NULL); 1250 1251 return (msg == DHCPV6_MSG_UNKNOWN? -1: (int)msg); 1252 } 1253 1254 // Collect all advertised servers 1255 static int dhcpv6_handle_advert(enum dhcpv6_msg orig, const int rc, 1256 const void *opt, const void *end, _o_unused const struct sockaddr_in6 *from) 1257 { 1258 uint16_t olen, otype; 1259 uint8_t *odata, pref = 0; 1260 struct dhcpv6_server_cand cand = {false, false, 0, 0, {0}, 1261 IN6ADDR_ANY_INIT, DHCPV6_SOL_MAX_RT, 1262 DHCPV6_INF_MAX_RT, NULL, NULL, 0, 0}; 1263 bool have_na = false; 1264 int have_pd = 0; 1265 1266 dhcpv6_for_each_option(opt, end, otype, olen, odata) { 1267 if (orig == DHCPV6_MSG_SOLICIT && 1268 ((otype == DHCPV6_OPT_IA_PD && pd_mode != IA_MODE_NONE) || 1269 (otype == DHCPV6_OPT_IA_NA && na_mode != IA_MODE_NONE)) && 1270 olen > sizeof(struct dhcpv6_ia_hdr) - DHCPV6_OPT_HDR_SIZE) { 1271 struct dhcpv6_ia_hdr *ia_hdr = (void*)(&odata[-DHCPV6_OPT_HDR_SIZE]); 1272 dhcpv6_parse_ia(ia_hdr, odata + olen + sizeof(*ia_hdr), NULL); 1273 } 1274 1275 switch (otype) { 1276 case DHCPV6_OPT_SERVERID: 1277 if (olen <= DHCPV6_DUID_MAX_LEN) { 1278 memcpy(cand.duid, odata, olen); 1279 cand.duid_len = olen; 1280 } 1281 break; 1282 1283 case DHCPV6_OPT_PREF: 1284 if (olen >= 1 && cand.preference >= 0) 1285 cand.preference = pref = odata[0]; 1286 break; 1287 1288 case DHCPV6_OPT_UNICAST: 1289 if (olen == sizeof(cand.server_addr) && 1290 !(client_options & DHCPV6_IGNORE_OPT_UNICAST)) 1291 cand.server_addr = *(struct in6_addr *)odata; 1292 break; 1293 1294 case DHCPV6_OPT_RECONF_ACCEPT: 1295 cand.wants_reconfigure = true; 1296 break; 1297 1298 case DHCPV6_OPT_SOL_MAX_RT: 1299 if (olen == 4) { 1300 uint32_t sol_max_rt = ntohl_unaligned(odata); 1301 if (sol_max_rt >= DHCPV6_SOL_MAX_RT_MIN && 1302 sol_max_rt <= DHCPV6_SOL_MAX_RT_MAX) 1303 cand.sol_max_rt = sol_max_rt; 1304 } 1305 break; 1306 1307 case DHCPV6_OPT_INF_MAX_RT: 1308 if (olen == 4) { 1309 uint32_t inf_max_rt = ntohl_unaligned(odata); 1310 if (inf_max_rt >= DHCPV6_INF_MAX_RT_MIN && 1311 inf_max_rt <= DHCPV6_INF_MAX_RT_MAX) 1312 cand.inf_max_rt = inf_max_rt; 1313 } 1314 break; 1315 1316 case DHCPV6_OPT_IA_PD: 1317 if (olen >= sizeof(struct dhcpv6_ia_hdr) - DHCPV6_OPT_HDR_SIZE) { 1318 struct dhcpv6_ia_hdr *h = (struct dhcpv6_ia_hdr *)&odata[-DHCPV6_OPT_HDR_SIZE]; 1319 uint8_t *oend = odata + olen, *d; 1320 1321 dhcpv6_for_each_option(&h[1], oend, otype, olen, d) { 1322 if (otype == DHCPV6_OPT_IA_PREFIX && 1323 olen >= sizeof(struct dhcpv6_ia_prefix) - DHCPV6_OPT_HDR_SIZE) { 1324 struct dhcpv6_ia_prefix *p = 1325 (struct dhcpv6_ia_prefix *)&d[-DHCPV6_OPT_HDR_SIZE]; 1326 have_pd = p->prefix; 1327 } 1328 } 1329 } 1330 break; 1331 1332 case DHCPV6_OPT_IA_NA: 1333 if (olen >= sizeof(struct dhcpv6_ia_hdr) - DHCPV6_OPT_HDR_SIZE) { 1334 struct dhcpv6_ia_hdr *h = (struct dhcpv6_ia_hdr *)&odata[-DHCPV6_OPT_HDR_SIZE]; 1335 uint8_t *oend = odata + olen, *d; 1336 1337 dhcpv6_for_each_option(&h[1], oend, otype, olen, d) { 1338 if (otype == DHCPV6_OPT_IA_ADDR && 1339 olen >= sizeof(struct dhcpv6_ia_addr) - DHCPV6_OPT_HDR_SIZE) 1340 have_na = true; 1341 } 1342 } 1343 break; 1344 1345 default: 1346 break; 1347 } 1348 } 1349 1350 if ((stateful_only_mode && !have_na && !have_pd) || 1351 (!have_na && na_mode == IA_MODE_FORCE) || 1352 (!have_pd && pd_mode == IA_MODE_FORCE)) { 1353 /* 1354 * RFC7083 states to process the SOL_MAX_RT and 1355 * INF_MAX_RT options even if the DHCPv6 server 1356 * did not propose any IA_NA and/or IA_PD 1357 */ 1358 dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = cand.sol_max_rt; 1359 dhcpv6_retx[DHCPV6_MSG_INFO_REQ].max_timeo = cand.inf_max_rt; 1360 return -1; 1361 } 1362 1363 if (na_mode != IA_MODE_NONE && !have_na) { 1364 cand.has_noaddravail = true; 1365 cand.preference -= 1000; 1366 } 1367 1368 if (pd_mode != IA_MODE_NONE) { 1369 if (have_pd) 1370 cand.preference += 2000 + (128 - have_pd); 1371 else 1372 cand.preference -= 2000; 1373 } 1374 1375 if (cand.duid_len > 0) { 1376 cand.ia_na = odhcp6c_move_state(STATE_IA_NA, &cand.ia_na_len); 1377 cand.ia_pd = odhcp6c_move_state(STATE_IA_PD, &cand.ia_pd_len); 1378 dhcpv6_add_server_cand(&cand); 1379 } 1380 1381 return (rc > 1 || (pref == 255 && cand.preference > 0)) ? 1 : -1; 1382 } 1383 1384 static int dhcpv6_commit_advert(void) 1385 { 1386 return dhcpv6_promote_server_cand(); 1387 } 1388 1389 static int dhcpv6_handle_rebind_reply(enum dhcpv6_msg orig, const int rc, 1390 const void *opt, const void *end, const struct sockaddr_in6 *from) 1391 { 1392 dhcpv6_handle_advert(orig, rc, opt, end, from); 1393 if (dhcpv6_commit_advert() < 0) 1394 return -1; 1395 1396 return dhcpv6_handle_reply(orig, rc, opt, end, from); 1397 } 1398 1399 static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _o_unused const int rc, 1400 const void *opt, const void *end, const struct sockaddr_in6 *from) 1401 { 1402 uint8_t *odata; 1403 uint16_t otype, olen; 1404 uint32_t refresh = config_dhcp->irt_default; 1405 int ret = 1; 1406 unsigned int state_IAs; 1407 unsigned int updated_IAs = 0; 1408 bool handled_status_codes[_DHCPV6_Status_Max] = { false, }; 1409 1410 odhcp6c_expire(true); 1411 1412 if (orig == DHCPV6_MSG_UNKNOWN) { 1413 static time_t last_update = 0; 1414 time_t now = odhcp6c_get_milli_time() / 1000; 1415 1416 uint32_t elapsed = (last_update > 0) ? now - last_update : 0; 1417 last_update = now; 1418 1419 if (t1 != UINT32_MAX) 1420 t1 -= elapsed; 1421 1422 if (t2 != UINT32_MAX) 1423 t2 -= elapsed; 1424 1425 if (t3 != UINT32_MAX) 1426 t3 -= elapsed; 1427 1428 if (t1 < 0) 1429 t1 = 0; 1430 1431 if (t2 < 0) 1432 t2 = 0; 1433 1434 if (t3 < 0) 1435 t3 = 0; 1436 } 1437 1438 if (orig == DHCPV6_MSG_REQUEST && !odhcp6c_is_bound()) { 1439 // Delete NA and PD we have in the state from the Advert 1440 odhcp6c_clear_state(STATE_IA_NA); 1441 odhcp6c_clear_state(STATE_IA_PD); 1442 } 1443 1444 if (opt) { 1445 odhcp6c_clear_state(STATE_DNS); 1446 odhcp6c_clear_state(STATE_SEARCH); 1447 odhcp6c_clear_state(STATE_SNTP_IP); 1448 odhcp6c_clear_state(STATE_NTP_IP); 1449 odhcp6c_clear_state(STATE_NTP_FQDN); 1450 odhcp6c_clear_state(STATE_SIP_IP); 1451 odhcp6c_clear_state(STATE_SIP_FQDN); 1452 odhcp6c_clear_state(STATE_AFTR_NAME); 1453 odhcp6c_clear_state(STATE_S46_MAPT); 1454 odhcp6c_clear_state(STATE_S46_MAPE); 1455 odhcp6c_clear_state(STATE_S46_LW); 1456 odhcp6c_clear_state(STATE_CAPT_PORT_DHCPV6); 1457 odhcp6c_clear_state(STATE_PASSTHRU); 1458 odhcp6c_clear_state(STATE_CUSTOM_OPTS); 1459 1460 // Parse and find all matching IAs 1461 dhcpv6_for_each_option(opt, end, otype, olen, odata) { 1462 struct odhcp6c_opt *dopt = odhcp6c_find_opt(otype); 1463 1464 switch (otype) { 1465 1466 case DHCPV6_OPT_IA_NA: 1467 case DHCPV6_OPT_IA_PD: 1468 if (olen > sizeof(struct dhcpv6_ia_hdr) - DHCPV6_OPT_HDR_SIZE) { 1469 struct dhcpv6_ia_hdr *ia_hdr = (void*)(&odata[-DHCPV6_OPT_HDR_SIZE]); 1470 1471 if ((na_mode == IA_MODE_NONE && otype == DHCPV6_OPT_IA_NA) || 1472 (pd_mode == IA_MODE_NONE && otype == DHCPV6_OPT_IA_PD)) 1473 continue; 1474 1475 // Test ID 1476 if (ia_hdr->iaid != htonl(ifname_hash_iaid) && otype == DHCPV6_OPT_IA_NA) 1477 continue; 1478 1479 uint16_t code = DHCPV6_Success; 1480 uint16_t stype, slen; 1481 uint8_t *sdata; 1482 bool dhcpv6_successful_once = false; 1483 // Get and handle status code 1484 dhcpv6_for_each_option(&ia_hdr[1], odata + olen, stype, slen, sdata) { 1485 if (stype == DHCPV6_OPT_STATUS && slen >= 2) { 1486 uint8_t *mdata = (slen > 2) ? &sdata[2] : NULL; 1487 uint16_t mlen = (slen > 2) ? slen - 2 : 0; 1488 1489 code = ((int)sdata[0] << 8) | ((int)sdata[1]); 1490 1491 if (code == DHCPV6_Success) { 1492 dhcpv6_successful_once = true; 1493 continue; 1494 } 1495 1496 dhcpv6_handle_ia_status_code(orig, ia_hdr, 1497 code, mdata, mlen, handled_status_codes, &ret); 1498 1499 break; 1500 } 1501 } 1502 1503 if (!dhcpv6_successful_once && code != DHCPV6_Success) 1504 continue; 1505 1506 updated_IAs += dhcpv6_parse_ia(ia_hdr, odata + olen, &ret); 1507 } 1508 break; 1509 1510 case DHCPV6_OPT_UNICAST: 1511 if (olen == sizeof(server_addr) && 1512 !(client_options & DHCPV6_IGNORE_OPT_UNICAST)) 1513 server_addr = *(struct in6_addr *)odata; 1514 break; 1515 1516 case DHCPV6_OPT_STATUS: 1517 if (olen >= 2) { 1518 uint8_t *mdata = (olen > 2) ? &odata[2] : NULL; 1519 uint16_t mlen = (olen > 2) ? olen - 2 : 0; 1520 uint16_t code = ((int)odata[0] << 8) | ((int)odata[1]); 1521 1522 dhcpv6_handle_status_code(orig, code, mdata, mlen, &ret); 1523 } 1524 break; 1525 1526 case DHCPV6_OPT_DNS_SERVERS: 1527 if (olen % sizeof(struct in6_addr) == 0) 1528 odhcp6c_add_state(STATE_DNS, odata, olen); 1529 break; 1530 1531 case DHCPV6_OPT_DNS_DOMAIN: 1532 odhcp6c_add_state(STATE_SEARCH, odata, olen); 1533 break; 1534 1535 case DHCPV6_OPT_SNTP_SERVERS: 1536 if (olen % sizeof(struct in6_addr) == 0) 1537 odhcp6c_add_state(STATE_SNTP_IP, odata, olen); 1538 break; 1539 1540 case DHCPV6_OPT_NTP_SERVER: 1541 uint16_t stype, slen; 1542 uint8_t *sdata; 1543 // Test status and bail if error 1544 dhcpv6_for_each_option(odata, odata + olen, 1545 stype, slen, sdata) { 1546 if (slen == sizeof(struct in6_addr) && (stype == NTP_MC_ADDR || stype == NTP_SRV_ADDR)) 1547 odhcp6c_add_state(STATE_NTP_IP, sdata, slen); 1548 else if (slen > 0 && stype == NTP_SRV_FQDN) 1549 odhcp6c_add_state(STATE_NTP_FQDN, sdata, slen); 1550 } 1551 break; 1552 1553 case DHCPV6_OPT_SIP_SERVER_A: 1554 if (olen == sizeof(struct in6_addr)) 1555 odhcp6c_add_state(STATE_SIP_IP, odata, olen); 1556 break; 1557 1558 case DHCPV6_OPT_SIP_SERVER_D: 1559 odhcp6c_add_state(STATE_SIP_FQDN, odata, olen); 1560 break; 1561 1562 case DHCPV6_OPT_INFO_REFRESH: 1563 if (olen == 4) 1564 refresh = ntohl_unaligned(odata); 1565 break; 1566 1567 case DHCPV6_OPT_AUTH: 1568 struct dhcpv6_auth *r = (void*)&odata[-DHCPV6_OPT_HDR_SIZE]; 1569 if (auth_protocol == AUTH_PROT_RKAP) { 1570 struct dhcpv6_auth_reconfigure *rkap = (void*)r->data; 1571 if (r->protocol == AUTH_PROT_RKAP || r->algorithm == AUTH_ALG_HMACMD5 || 1572 r->len == 28 || rkap->reconf_type == RKAP_TYPE_KEY) 1573 memcpy(reconf_key, rkap->key, sizeof(rkap->key)); 1574 } 1575 break; 1576 1577 case DHCPV6_OPT_AFTR_NAME: 1578 if (olen > 3) { 1579 size_t cur_len; 1580 odhcp6c_get_state(STATE_AFTR_NAME, &cur_len); 1581 if (cur_len == 0) 1582 odhcp6c_add_state(STATE_AFTR_NAME, odata, olen); 1583 } 1584 break; 1585 1586 case DHCPV6_OPT_SOL_MAX_RT: 1587 if (olen == 4) { 1588 uint32_t sol_max_rt = ntohl_unaligned(odata); 1589 if (sol_max_rt >= DHCPV6_SOL_MAX_RT_MIN && sol_max_rt <= DHCPV6_SOL_MAX_RT_MAX) 1590 dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = sol_max_rt; 1591 } 1592 break; 1593 1594 case DHCPV6_OPT_INF_MAX_RT: 1595 if (olen == 4) { 1596 uint32_t inf_max_rt = ntohl_unaligned(odata); 1597 if (inf_max_rt >= DHCPV6_INF_MAX_RT_MIN && inf_max_rt <= DHCPV6_INF_MAX_RT_MAX) 1598 dhcpv6_retx[DHCPV6_MSG_INFO_REQ].max_timeo = inf_max_rt; 1599 } 1600 break; 1601 1602 case DHCPV6_OPT_S46_CONT_MAPT: 1603 odhcp6c_add_state(STATE_S46_MAPT, odata, olen); 1604 break; 1605 1606 case DHCPV6_OPT_S46_CONT_MAPE: 1607 size_t mape_len; 1608 odhcp6c_get_state(STATE_S46_MAPE, &mape_len); 1609 if (mape_len == 0) 1610 odhcp6c_add_state(STATE_S46_MAPE, odata, olen); 1611 break; 1612 1613 case DHCPV6_OPT_S46_CONT_LW: 1614 odhcp6c_add_state(STATE_S46_LW, odata, olen); 1615 break; 1616 1617 case DHCPV6_OPT_CAPTIVE_PORTAL: /* RFC8910 §2.2 */ 1618 size_t ref_len = sizeof(URN_IETF_CAPT_PORT_UNRESTR) - 1; 1619 /* RFC8910 §2: 1620 * Networks with no captive portals may explicitly indicate this 1621 * condition by using this option with the IANA-assigned URI for 1622 * this purpose. Clients observing the URI value ... may forego 1623 * time-consuming forms of captive portal detection. */ 1624 if (memcmp(odata, URN_IETF_CAPT_PORT_UNRESTR, ref_len)) { 1625 /* RFC8910 §2.2: 1626 * Note that the URI parameter is not null terminated. 1627 * Allocate new buffer including room for '\0' */ 1628 size_t uri_len = olen + 1; 1629 uint8_t *copy = malloc(uri_len); 1630 if (!copy) 1631 continue; 1632 memcpy(copy, odata, olen); 1633 copy[uri_len] = '\0'; 1634 odhcp6c_add_state(STATE_CAPT_PORT_DHCPV6, odata, olen); 1635 free(copy); 1636 } 1637 break; 1638 1639 default: 1640 odhcp6c_add_state(STATE_CUSTOM_OPTS, &odata[-DHCPV6_OPT_HDR_SIZE], olen + DHCPV6_OPT_HDR_SIZE); 1641 break; 1642 } 1643 1644 // Pass-through unless explicitly disabled, for every option 1645 if (!dopt || !(dopt->flags & OPT_NO_PASSTHRU)) 1646 odhcp6c_add_state(STATE_PASSTHRU, &odata[-DHCPV6_OPT_HDR_SIZE], olen + DHCPV6_OPT_HDR_SIZE); 1647 } 1648 } 1649 1650 // Bail out if fatal status code was received 1651 if (ret <= 0) 1652 return ret; 1653 1654 switch (orig) { 1655 case DHCPV6_MSG_REQUEST: 1656 case DHCPV6_MSG_REBIND: 1657 case DHCPV6_MSG_RENEW: 1658 state_IAs = dhcpv6_calc_refresh_timers(); 1659 // In case there're no state IA entries 1660 // keep sending request/renew/rebind messages 1661 if (state_IAs == 0) { 1662 ret = 0; 1663 break; 1664 } 1665 1666 switch (orig) { 1667 case DHCPV6_MSG_REQUEST: 1668 // All server candidates can be cleared if not yet bound 1669 if (!odhcp6c_is_bound()) 1670 dhcpv6_clear_all_server_cand(); 1671 1672 odhcp6c_clear_state(STATE_SERVER_ADDR); 1673 odhcp6c_add_state(STATE_SERVER_ADDR, &from->sin6_addr, sizeof(struct in6_addr)); 1674 break; 1675 case DHCPV6_MSG_RENEW: 1676 // Send further renews if T1 is not set and if 1677 // there're IAs which were not in the Reply message 1678 if (!t1 && state_IAs != updated_IAs) { 1679 if (updated_IAs) 1680 // Publish updates 1681 notify_state_change("updated", 0, false); 1682 1683 /* 1684 * RFC8415 states following in §18.2.10.1 : 1685 * Sends a Renew/Rebind if any of the IAs are not in the Reply 1686 * message, but as this likely indicates that the server that 1687 * responded does not support that IA type, sending immediately is 1688 * unlikely to produce a different result. Therefore, the client 1689 * MUST rate-limit its transmissions (see Section 14.1) and MAY just 1690 * wait for the normal retransmission time (as if the Reply message 1691 * had not been received). The client continues to use other 1692 * bindings for which the server did return information 1693 */ 1694 ret = -1; 1695 } 1696 break; 1697 case DHCPV6_MSG_REBIND: 1698 odhcp6c_clear_state(STATE_SERVER_ADDR); 1699 odhcp6c_add_state(STATE_SERVER_ADDR, &from->sin6_addr, sizeof(struct in6_addr)); 1700 1701 // Send further rebinds if T1 and T2 is not set and if 1702 // there're IAs which were not in the Reply message 1703 if (!t1 && !t2 && state_IAs != updated_IAs) { 1704 if (updated_IAs) 1705 // Publish updates 1706 notify_state_change("updated", 0, false); 1707 1708 /* 1709 * RFC8415 states following in §18.2.10.1 : 1710 * Sends a Renew/Rebind if any of the IAs are not in the Reply 1711 * message, but as this likely indicates that the server that 1712 * responded does not support that IA type, sending immediately is 1713 * unlikely to produce a different result. Therefore, the client 1714 * MUST rate-limit its transmissions (see Section 14.1) and MAY just 1715 * wait for the normal retransmission time (as if the Reply message 1716 * had not been received). The client continues to use other 1717 * bindings for which the server did return information 1718 */ 1719 ret = -1; 1720 } 1721 break; 1722 1723 default: 1724 break; 1725 } 1726 break; 1727 1728 case DHCPV6_MSG_INFO_REQ: 1729 // All server candidates can be cleared if not yet bound 1730 if (!odhcp6c_is_bound()) 1731 dhcpv6_clear_all_server_cand(); 1732 1733 odhcp6c_clear_state(STATE_SERVER_ADDR); 1734 odhcp6c_add_state(STATE_SERVER_ADDR, &from->sin6_addr, sizeof(struct in6_addr)); 1735 1736 t1 = (refresh < config_dhcp->irt_min) ? config_dhcp->irt_min : refresh; 1737 break; 1738 1739 default: 1740 break; 1741 } 1742 1743 return ret; 1744 } 1745 1746 static unsigned int dhcpv6_parse_ia(void *opt, void *end, int *ret) 1747 { 1748 struct dhcpv6_ia_hdr *ia_hdr = (struct dhcpv6_ia_hdr *)opt; 1749 unsigned int updated_IAs = 0; 1750 uint32_t t1, t2; 1751 uint16_t otype, olen; 1752 uint8_t *odata; 1753 char buf[INET6_ADDRSTRLEN]; 1754 1755 t1 = ntohl(ia_hdr->t1); 1756 t2 = ntohl(ia_hdr->t2); 1757 1758 /* RFC 8415 §21.4 1759 If a client receives an IA_NA with T1 greater than T2 and both T1 and 1760 T2 are greater than 0, the client discards the IA_NA option and 1761 processes the remainder of the message as though the server had not 1762 included the invalid IA_NA option. */ 1763 if (t1 > t2 && t1 > 0 && t2 > 0) 1764 return 0; 1765 1766 info("%s %04x T1 %d T2 %d", ntohs(ia_hdr->type) == DHCPV6_OPT_IA_PD ? "IA_PD" : "IA_NA", ntohl(ia_hdr->iaid), t1, t2); 1767 1768 // Update address IA 1769 dhcpv6_for_each_option(&ia_hdr[1], end, otype, olen, odata) { 1770 struct odhcp6c_entry entry = { 1771 .router = IN6ADDR_ANY_INIT, 1772 .auxlen = 0, 1773 .length = 0, 1774 .ra_flags = 0, 1775 .exclusion_length = 0, 1776 .target = IN6ADDR_ANY_INIT, 1777 .priority = 0, 1778 .valid = 0, 1779 .preferred = 0, 1780 .t1 = 0, 1781 .t2 = 0, 1782 .iaid = ia_hdr->iaid, 1783 }; 1784 1785 switch (otype) { 1786 case DHCPV6_OPT_IA_PREFIX: { 1787 struct dhcpv6_ia_prefix *prefix = (void*)&odata[-DHCPV6_OPT_HDR_SIZE]; 1788 if (olen + DHCPV6_OPT_HDR_SIZE_U < sizeof(*prefix)) 1789 continue; 1790 1791 entry.valid = ntohl(prefix->valid); 1792 entry.preferred = ntohl(prefix->preferred); 1793 1794 if (entry.preferred > entry.valid) 1795 continue; 1796 1797 /* RFC 8415 §21.21 1798 Recommended values for T1 and T2 are 0.5 and 0.8 times the 1799 shortest preferred lifetime of the prefixes in the IA_PD that the 1800 server is willing to extend. */ 1801 entry.t1 = (t1 ? t1 : (entry.preferred != UINT32_MAX ? 0.5 * entry.preferred : UINT32_MAX)); 1802 entry.t2 = (t2 ? t2 : (entry.preferred != UINT32_MAX ? 0.8 * entry.preferred : UINT32_MAX)); 1803 if (entry.t1 > entry.t2) 1804 entry.t1 = entry.t2; 1805 1806 entry.length = prefix->prefix; 1807 entry.target = prefix->addr; 1808 uint16_t stype, slen; 1809 uint8_t *sdata; 1810 1811 // Parse sub-options for PD-exclude or error status code 1812 bool update_state = true; 1813 dhcpv6_for_each_option(odata + sizeof(*prefix) - DHCPV6_OPT_HDR_SIZE, 1814 odata + olen, stype, slen, sdata) { 1815 if (stype == DHCPV6_OPT_STATUS && slen >= 2) { 1816 /* RFC 8415 §21.22 1817 The status of any operations involving this IA Prefix option is 1818 indicated in a Status Code option (see Section 21.13) in the 1819 IAprefix-options field. */ 1820 uint8_t *status_msg = (slen > 2) ? &sdata[2] : NULL; 1821 uint16_t msg_len = (slen > 2) ? slen - 2 : 0; 1822 uint16_t code = ((int)sdata[0]) << 8 | ((int)sdata[1]); 1823 1824 if (code == DHCPV6_Success) 1825 continue; 1826 1827 dhcpv6_log_status_code(code, "IA_PREFIX", status_msg, msg_len); 1828 if (ret) *ret = 0; // renewal failed 1829 } else if (stype == DHCPV6_OPT_PD_EXCLUDE && slen > 2) { 1830 /* RFC 6603 §4.2 Prefix Exclude option */ 1831 uint8_t exclude_length = sdata[0]; 1832 if (exclude_length > 64) 1833 exclude_length = 64; 1834 1835 if (entry.length < 32 || exclude_length <= entry.length) { 1836 update_state = false; 1837 continue; 1838 } 1839 1840 uint8_t bytes_needed = ((exclude_length - entry.length - 1) / 8) + 1; 1841 if (slen <= bytes_needed) { 1842 update_state = false; 1843 continue; 1844 } 1845 1846 // this decrements through the ipaddr bytes masking against 1847 // the address in the option until byte 0, the option length field. 1848 uint32_t excluded_bits = 0; 1849 do { 1850 excluded_bits = excluded_bits << 8 | sdata[bytes_needed]; 1851 } while (--bytes_needed); 1852 1853 excluded_bits >>= 8 - ((exclude_length - entry.length) % 8); 1854 excluded_bits <<= 64 - exclude_length; 1855 1856 // Re-using router field to hold the prefix 1857 entry.router = entry.target; // base prefix 1858 entry.router.s6_addr32[1] |= htonl(excluded_bits); 1859 entry.exclusion_length = exclude_length; 1860 } 1861 } 1862 1863 if (update_state) { 1864 if (odhcp6c_update_entry(STATE_IA_PD, &entry, 0)) 1865 updated_IAs++; 1866 1867 info("%s/%d preferred %d valid %d", 1868 inet_ntop(AF_INET6, &entry.target, buf, sizeof(buf)), 1869 entry.length, entry.preferred , entry.valid); 1870 } 1871 1872 entry.priority = 0; 1873 memset(&entry.router, 0, sizeof(entry.router)); 1874 break; 1875 } 1876 case DHCPV6_OPT_IA_ADDR: { 1877 struct dhcpv6_ia_addr *addr = (void*)&odata[-DHCPV6_OPT_HDR_SIZE]; 1878 if (olen + DHCPV6_OPT_HDR_SIZE_U < sizeof(*addr)) 1879 continue; 1880 1881 entry.preferred = ntohl(addr->preferred); 1882 entry.valid = ntohl(addr->valid); 1883 1884 if (entry.preferred > entry.valid) 1885 continue; 1886 1887 entry.t1 = (t1 ? t1 : (entry.preferred != UINT32_MAX ? 0.5 * entry.preferred : UINT32_MAX)); 1888 entry.t2 = (t2 ? t2 : (entry.preferred != UINT32_MAX ? 0.8 * entry.preferred : UINT32_MAX)); 1889 if (entry.t1 > entry.t2) 1890 entry.t1 = entry.t2; 1891 1892 entry.length = 128; 1893 entry.target = addr->addr; 1894 uint16_t stype, slen; 1895 uint8_t *sdata; 1896 1897 bool update_state = true; 1898 dhcpv6_for_each_option(odata + sizeof(*addr) - DHCPV6_OPT_HDR_SIZE_U, 1899 odata + olen, stype, slen, sdata) { 1900 if (stype == DHCPV6_OPT_STATUS && slen >= 2) { 1901 /* RFC 8415 §21.6 1902 The status of any operations involving this IA Address is indicated 1903 in a Status Code option in the IAaddr-options field, as specified in 1904 Section 21.13. */ 1905 uint8_t *status_msg = (slen > 2) ? &sdata[2] : NULL; 1906 uint16_t msg_len = (slen > 2) ? slen - 2 : 0; 1907 uint16_t code = ((int)sdata[0]) << 8 | ((int)sdata[1]); 1908 1909 if (code == DHCPV6_Success) 1910 continue; 1911 1912 dhcpv6_log_status_code(code, "IA_ADDR", status_msg, msg_len); 1913 if (ret) *ret = 0; // renewal failed 1914 update_state = false; 1915 } 1916 } 1917 1918 if (update_state) { 1919 if (odhcp6c_update_entry(STATE_IA_NA, &entry, 0)) 1920 updated_IAs++; 1921 1922 info("%s preferred %d valid %d", 1923 inet_ntop(AF_INET6, &entry.target, buf, sizeof(buf)), 1924 entry.preferred , entry.valid); 1925 } 1926 break; 1927 } 1928 default: 1929 break; 1930 } 1931 } 1932 1933 return updated_IAs; 1934 } 1935 1936 static unsigned int dhcpv6_calc_refresh_timers(void) 1937 { 1938 struct odhcp6c_entry *pd_entries; 1939 struct odhcp6c_entry *ia_entries; 1940 size_t ia_na_entry_cnt, ia_pd_entry_cnt, i; 1941 size_t invalid_entries = 0; 1942 int64_t l_t1 = UINT32_MAX, l_t2 = UINT32_MAX, l_t3 = 0; 1943 1944 ia_entries = odhcp6c_get_state(STATE_IA_NA, &ia_na_entry_cnt); 1945 ia_na_entry_cnt /= sizeof(*ia_entries); 1946 1947 for (i = 0; i < ia_na_entry_cnt; i++) { 1948 /* Exclude invalid IA_NA entries */ 1949 if (!ia_entries[i].valid) { 1950 invalid_entries++; 1951 continue; 1952 } 1953 1954 if (ia_entries[i].t1 < l_t1) 1955 l_t1 = ia_entries[i].t1; 1956 1957 if (ia_entries[i].t2 < l_t2) 1958 l_t2 = ia_entries[i].t2; 1959 1960 if (ia_entries[i].valid > l_t3) 1961 l_t3 = ia_entries[i].valid; 1962 } 1963 1964 pd_entries = odhcp6c_get_state(STATE_IA_PD, &ia_pd_entry_cnt); 1965 ia_pd_entry_cnt /= sizeof(*pd_entries); 1966 1967 for (i = 0; i < ia_pd_entry_cnt; i++) { 1968 /* Exclude invalid IA_PD entries */ 1969 if (!pd_entries[i].valid) { 1970 invalid_entries++; 1971 continue; 1972 } 1973 1974 if (pd_entries[i].t1 < l_t1) 1975 l_t1 = pd_entries[i].t1; 1976 1977 if (pd_entries[i].t2 < l_t2) 1978 l_t2 = pd_entries[i].t2; 1979 1980 if (pd_entries[i].valid > l_t3) 1981 l_t3 = pd_entries[i].valid; 1982 } 1983 1984 if (ia_pd_entry_cnt + ia_na_entry_cnt - invalid_entries) { 1985 t1 = l_t1; 1986 t2 = l_t2; 1987 t3 = l_t3; 1988 1989 info("T1 %"PRId64"s, T2 %"PRId64"s, T3 %"PRId64"s", t1, t2, t3); 1990 } 1991 1992 return (unsigned int)(ia_pd_entry_cnt + ia_na_entry_cnt); 1993 } 1994 1995 static void dhcpv6_log_status_code(const uint16_t code, const char *scope, 1996 const void *status_msg, int len) 1997 { 1998 const char *src = status_msg; 1999 char buf[len + 3]; 2000 char *dst = buf; 2001 2002 if (len) { 2003 *dst++ = '('; 2004 while (len--) { 2005 *dst = isprint((unsigned char)*src) ? *src : '?'; 2006 src++; 2007 dst++; 2008 } 2009 *dst++ = ')'; 2010 } 2011 2012 *dst = 0; 2013 2014 warn("Server returned %s status '%s %s'", 2015 scope, dhcpv6_status_code_to_str(code), buf); 2016 } 2017 2018 static void dhcpv6_handle_status_code(const enum dhcpv6_msg orig, 2019 const uint16_t code, const void *status_msg, const int len, 2020 int *ret) 2021 { 2022 dhcpv6_log_status_code(code, "message", status_msg, len); 2023 2024 switch (code) { 2025 case DHCPV6_UnspecFail: 2026 // Generic failure 2027 *ret = 0; 2028 break; 2029 2030 case DHCPV6_UseMulticast: 2031 switch(orig) { 2032 case DHCPV6_MSG_REQUEST: 2033 case DHCPV6_MSG_RENEW: 2034 case DHCPV6_MSG_RELEASE: 2035 case DHCPV6_MSG_DECLINE: 2036 // Message needs to be retransmitted according to RFC3315 chapter 18.1.8 2037 server_addr = in6addr_any; 2038 *ret = 0; 2039 break; 2040 default: 2041 break; 2042 } 2043 break; 2044 2045 case DHCPV6_NoAddrsAvail: 2046 case DHCPV6_NoPrefixAvail: 2047 if (orig == DHCPV6_MSG_REQUEST) 2048 *ret = 0; // Failure 2049 break; 2050 2051 default: 2052 break; 2053 } 2054 } 2055 2056 static void dhcpv6_handle_ia_status_code(const enum dhcpv6_msg orig, 2057 const struct dhcpv6_ia_hdr *ia_hdr, const uint16_t code, 2058 const void *status_msg, const int len, 2059 bool handled_status_codes[_DHCPV6_Status_Max], int *ret) 2060 { 2061 dhcpv6_log_status_code(code, ntohs(ia_hdr->type) == DHCPV6_OPT_IA_NA ? 2062 "IA_NA" : "IA_PD", status_msg, len); 2063 2064 switch (code) { 2065 case DHCPV6_NoBinding: 2066 switch (orig) { 2067 case DHCPV6_MSG_RENEW: 2068 case DHCPV6_MSG_REBIND: 2069 if ((*ret > 0) && !handled_status_codes[code]) { 2070 dhcpv6_set_state(DHCPV6_REQUEST); 2071 *ret = -1; 2072 } 2073 break; 2074 2075 default: 2076 *ret = 0; 2077 break; 2078 } 2079 break; 2080 2081 case DHCPV6_NoAddrsAvail: 2082 case DHCPV6_NoPrefixAvail: 2083 break; 2084 2085 default: 2086 *ret = 0; 2087 break; 2088 } 2089 } 2090 2091 // Note this always takes ownership of cand->ia_na and cand->ia_pd 2092 static void dhcpv6_add_server_cand(const struct dhcpv6_server_cand *cand) 2093 { 2094 size_t cand_len, i; 2095 struct dhcpv6_server_cand *srv_candidates = odhcp6c_get_state(STATE_SERVER_CAND, &cand_len); 2096 2097 // Remove identical DUID server candidate 2098 for (i = 0; i < cand_len / sizeof(*srv_candidates); ++i) { 2099 if (cand->duid_len == srv_candidates[i].duid_len && 2100 !memcmp(cand->duid, srv_candidates[i].duid, cand->duid_len)) { 2101 free(srv_candidates[i].ia_na); 2102 free(srv_candidates[i].ia_pd); 2103 odhcp6c_remove_state(STATE_SERVER_CAND, i * sizeof(*srv_candidates), sizeof(*srv_candidates)); 2104 break; 2105 } 2106 } 2107 2108 for (i = 0, srv_candidates = odhcp6c_get_state(STATE_SERVER_CAND, &cand_len); 2109 i < cand_len / sizeof(*srv_candidates); ++i) { 2110 if (srv_candidates[i].preference < cand->preference) 2111 break; 2112 } 2113 2114 if (odhcp6c_insert_state(STATE_SERVER_CAND, i * sizeof(*srv_candidates), cand, sizeof(*cand))) { 2115 free(cand->ia_na); 2116 free(cand->ia_pd); 2117 } 2118 } 2119 2120 static void dhcpv6_clear_all_server_cand(void) 2121 { 2122 size_t cand_len, i; 2123 struct dhcpv6_server_cand *srv_candidates = odhcp6c_get_state(STATE_SERVER_CAND, &cand_len); 2124 2125 // Server candidates need deep delete for IA_NA/IA_PD 2126 for (i = 0; i < cand_len / sizeof(*srv_candidates); ++i) { 2127 free(srv_candidates[i].ia_na); 2128 free(srv_candidates[i].ia_pd); 2129 } 2130 odhcp6c_clear_state(STATE_SERVER_CAND); 2131 } 2132 2133 int dhcpv6_promote_server_cand(void) 2134 { 2135 size_t cand_len; 2136 struct dhcpv6_server_cand *cand = odhcp6c_get_state(STATE_SERVER_CAND, &cand_len); 2137 uint16_t hdr[2]; 2138 int ret = DHCPV6_STATELESS; 2139 bool override_ia = false; 2140 2141 // Clear lingering candidate state info 2142 odhcp6c_clear_state(STATE_SERVER_ID); 2143 odhcp6c_clear_state(STATE_IA_NA); 2144 odhcp6c_clear_state(STATE_IA_PD); 2145 2146 if (!cand_len) 2147 return -1; 2148 2149 if (config_dhcp->strict_rfc7550) { 2150 if (!cand->ia_pd_len && cand->has_noaddravail) { 2151 /* Some ISPs provide neither IA_NA nor IA_PD, so we 2152 * should fallback to SLAAC. 2153 */ 2154 2155 if (na_mode == IA_MODE_TRY) { 2156 na_mode = IA_MODE_NONE; 2157 override_ia = true; 2158 } 2159 2160 if (pd_mode == IA_MODE_TRY) { 2161 pd_mode = IA_MODE_NONE; 2162 override_ia = true; 2163 } 2164 } 2165 } else { 2166 if (cand->has_noaddravail && na_mode == IA_MODE_TRY) { 2167 /* Some broken ISPs require a new Solicit message 2168 * without IA_NA if they haven't provided an address 2169 * on the Advertise message. 2170 */ 2171 na_mode = IA_MODE_NONE; 2172 override_ia = true; 2173 } 2174 2175 if (!cand->ia_pd_len && pd_mode == IA_MODE_TRY) { 2176 /* Some broken ISPs require a new Solicit message 2177 * without IA_PD if they haven't provided a prefix 2178 * on the Advertise message. 2179 */ 2180 pd_mode = IA_MODE_NONE; 2181 override_ia = true; 2182 } 2183 } 2184 2185 if (override_ia) { 2186 dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = cand->sol_max_rt; 2187 dhcpv6_retx[DHCPV6_MSG_INFO_REQ].max_timeo = cand->inf_max_rt; 2188 2189 return -1; 2190 } 2191 2192 hdr[0] = htons(DHCPV6_OPT_SERVERID); 2193 hdr[1] = htons(cand->duid_len); 2194 odhcp6c_add_state(STATE_SERVER_ID, hdr, sizeof(hdr)); 2195 odhcp6c_add_state(STATE_SERVER_ID, cand->duid, cand->duid_len); 2196 accept_reconfig = cand->wants_reconfigure; 2197 memset(reconf_key, 0, sizeof(reconf_key)); 2198 2199 if (cand->ia_na_len) { 2200 odhcp6c_add_state(STATE_IA_NA, cand->ia_na, cand->ia_na_len); 2201 free(cand->ia_na); 2202 if (na_mode != IA_MODE_NONE) 2203 ret = DHCPV6_STATEFUL; 2204 } 2205 2206 if (cand->ia_pd_len) { 2207 odhcp6c_add_state(STATE_IA_PD, cand->ia_pd, cand->ia_pd_len); 2208 free(cand->ia_pd); 2209 if (pd_mode != IA_MODE_NONE) 2210 ret = DHCPV6_STATEFUL; 2211 } 2212 2213 dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = cand->sol_max_rt; 2214 dhcpv6_retx[DHCPV6_MSG_INFO_REQ].max_timeo = cand->inf_max_rt; 2215 2216 odhcp6c_remove_state(STATE_SERVER_CAND, 0, sizeof(*cand)); 2217 2218 return ret; 2219 } 2220 2221 int dhcpv6_send_request(enum dhcpv6_msg req_msg_type) 2222 { 2223 struct dhcpv6_retx *retx = &dhcpv6_retx[req_msg_type]; 2224 uint64_t current_milli_time = 0; 2225 2226 if (!retx->is_retransmit) { 2227 // Initial delay handling 2228 if (retx->max_delay) { 2229 if (retx->delay_msec == 0) { 2230 // Initial delay before starting the transaction 2231 retx->delay_msec = (dhcpv6_rand_delay((10000 * retx->max_delay) / 2) + (1000 * retx->max_delay) / 2); 2232 dhcpv6_set_state_timeout(retx->delay_msec); 2233 // Add current time to calculate absolute time 2234 retx->delay_msec += odhcp6c_get_milli_time(); 2235 return 1; 2236 } else { 2237 // Wait until delay expires 2238 current_milli_time = odhcp6c_get_milli_time(); 2239 if (current_milli_time < retx->delay_msec) { 2240 // Still waiting 2241 dhcpv6_set_state_timeout(retx->delay_msec - current_milli_time); 2242 return 1; 2243 } 2244 retx->delay_msec = 0; 2245 } 2246 } 2247 2248 retx->is_retransmit = true; 2249 retx->rc = 0; 2250 retx->timeout = UINT32_MAX; 2251 retx->reply_ret = -1; 2252 2253 if (req_msg_type == DHCPV6_MSG_UNKNOWN) 2254 retx->timeout = t1; 2255 else if (req_msg_type == DHCPV6_MSG_RENEW) 2256 retx->timeout = (t2 > t1) ? t2 - t1 : ((t1 == UINT32_MAX) ? UINT32_MAX : 0); 2257 else if (req_msg_type == DHCPV6_MSG_REBIND) 2258 retx->timeout = (t3 > t2) ? t3 - t2 : ((t2 == UINT32_MAX) ? UINT32_MAX : 0); 2259 2260 if (retx->timeout == 0) 2261 return -1; 2262 2263 notice("Starting %s transaction (timeout %"PRIu64"s, max rc %d)", 2264 retx->name, retx->timeout, retx->max_rc); 2265 2266 // Generate transaction ID 2267 if (req_msg_type != DHCPV6_MSG_UNKNOWN) { 2268 odhcp6c_random(retx->tr_id, sizeof(retx->tr_id)); 2269 } 2270 2271 // Record start time 2272 retx->start = odhcp6c_get_milli_time(); 2273 retx->round_start = retx->start; 2274 // Reset retransmission timeout initial value 2275 retx->rto = 0; 2276 } 2277 2278 if (retx->rto == 0) { 2279 int64_t delay = dhcpv6_rand_delay(retx->init_timeo * 1000); 2280 2281 // First RT MUST be strictly greater than IRT for solicit messages (RFC3313 17.1.2) 2282 while (req_msg_type == DHCPV6_MSG_SOLICIT && delay <= 0) 2283 delay = dhcpv6_rand_delay(retx->init_timeo * 1000); 2284 2285 // First timeout 2286 retx->rto = (retx->init_timeo * 1000 + delay); 2287 } else { 2288 // Exponential back-off with randomization to avoid synchronization 2289 retx->rto = (2 * retx->rto + dhcpv6_rand_delay(retx->rto)); 2290 } 2291 2292 if (retx->max_timeo && (retx->rto >= retx->max_timeo * 1000)) { 2293 // Cap to max timeout if set and exceeded 2294 retx->rto = retx->max_timeo * 1000 + 2295 dhcpv6_rand_delay(retx->max_timeo * 1000); 2296 } 2297 2298 // Calculate end for this round and elapsed time 2299 retx->round_end = retx->round_start + retx->rto; 2300 uint64_t elapsed = retx->round_start - retx->start; 2301 2302 // Don't wait too long if timeout differs from infinite 2303 if ((retx->timeout != UINT32_MAX) && (retx->round_end - retx->start > retx->timeout * 1000)) 2304 retx->round_end = retx->timeout * 1000 + retx->start; 2305 2306 dhcpv6_set_state_timeout(retx->round_end - odhcp6c_get_milli_time()); 2307 2308 // Built and send package 2309 switch (req_msg_type) { 2310 case DHCPV6_MSG_UNKNOWN: 2311 break; 2312 default: 2313 notice("Send %s message (elapsed %"PRIu64"ms, rc %d)", 2314 retx->name, elapsed, retx->rc); 2315 _o_fallthrough; 2316 case DHCPV6_MSG_SOLICIT: 2317 case DHCPV6_MSG_INFO_REQ: 2318 dhcpv6_send(req_msg_type, retx->tr_id, elapsed / 10); 2319 retx->rc++; 2320 } 2321 2322 if (dhcpv6_get_state() != DHCPV6_EXIT) 2323 dhcpv6_next_state(); 2324 2325 return 0; 2326 } 2327 2328 int dhcpv6_receive_response(enum dhcpv6_msg req_msg_type) 2329 { 2330 ssize_t len = -1; 2331 struct dhcpv6_retx *retx = &dhcpv6_retx[req_msg_type]; 2332 2333 uint8_t buf[1536]; 2334 union { 2335 struct cmsghdr hdr; 2336 uint8_t buf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; 2337 } cmsg_buf; 2338 2339 struct iovec iov = {buf, sizeof(buf)}; 2340 struct sockaddr_in6 addr; 2341 struct msghdr msg = {.msg_name = &addr, .msg_namelen = sizeof(addr), 2342 .msg_iov = &iov, .msg_iovlen = 1, .msg_control = cmsg_buf.buf, 2343 .msg_controllen = sizeof(cmsg_buf)}; 2344 struct in6_pktinfo *pktinfo = NULL; 2345 const struct dhcpv6_header *hdr = (const struct dhcpv6_header *)buf; 2346 2347 // Receive cycle 2348 len = recvmsg(sock, &msg, 0); 2349 if (len < 0) { 2350 error("Error occurred when reading the response of (%s) error(%s)", 2351 retx->name, strerror(errno)); 2352 return -1; 2353 } 2354 2355 for (struct cmsghdr *ch = CMSG_FIRSTHDR(&msg); ch != NULL; 2356 ch = CMSG_NXTHDR(&msg, ch)) { 2357 if (ch->cmsg_level == SOL_IPV6 && 2358 ch->cmsg_type == IPV6_PKTINFO) { 2359 pktinfo = (struct in6_pktinfo *)CMSG_DATA(ch); 2360 break; 2361 } 2362 } 2363 2364 if (pktinfo == NULL) { 2365 dhcpv6_stats.discarded_packets++; 2366 return -1; 2367 } 2368 2369 if (!dhcpv6_response_is_valid(buf, len, retx->tr_id, req_msg_type, 2370 &pktinfo->ipi6_addr)) { 2371 dhcpv6_stats.discarded_packets++; 2372 return -1; 2373 } 2374 2375 dhcpv6_inc_counter(hdr->msg_type); 2376 2377 uint8_t *opt = &buf[4]; 2378 uint8_t *opt_end = opt + len - DHCPV6_OPT_HDR_SIZE; 2379 retx->round_start = odhcp6c_get_milli_time(); 2380 uint64_t elapsed = retx->round_start - retx->start; 2381 2382 notice("Got a valid %s after %"PRIu64"ms", 2383 dhcpv6_msg_to_str(hdr->msg_type), elapsed); 2384 2385 if (retx->handler_reply) { 2386 retx->reply_ret = retx->handler_reply(req_msg_type, retx->rc, opt, opt_end, &addr); 2387 len = retx->reply_ret; 2388 } 2389 2390 // Clamp round end (Round Trip Time) to 1s max wait after receiving a valid response (in milliseconds) 2391 if (len > 0 && retx->round_end - retx->round_start > 1000) 2392 retx->round_end = 1000 + retx->round_start; 2393 2394 return retx->reply_ret; 2395 } 2396 2397 int dhcpv6_state_processing(enum dhcpv6_msg req_msg_type) 2398 { 2399 struct dhcpv6_retx *retx = &dhcpv6_retx[req_msg_type]; 2400 int ret = retx->reply_ret; 2401 retx->round_start = odhcp6c_get_milli_time(); 2402 uint64_t elapsed = retx->round_start - retx->start; 2403 2404 if (retx->round_start >= retx->round_end || ret >=0 ) { 2405 if (retx->handler_finish) 2406 ret = retx->handler_finish(); 2407 2408 if (ret < 0 && ((retx->timeout == UINT32_MAX) || (elapsed / 1000 < retx->timeout)) && 2409 (!retx->max_rc || retx->rc < retx->max_rc)) { 2410 retx->reply_ret = -1; 2411 dhcpv6_prev_state(); 2412 } else { 2413 retx->is_retransmit = false; 2414 dhcpv6_next_state(); 2415 } 2416 } else { 2417 // This sets the response polling timeout (round_end - round_start) in milliseconds 2418 dhcpv6_set_state_timeout(retx->round_end - retx->round_start); 2419 } 2420 2421 return ret; 2422 } 2423
This page was automatically generated by LXR 0.3.1. • OpenWrt