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 uint32_t hash_ifname(const char *s) { 548 uint32_t h = 0; 549 while (*s) h = h * 31 + *s++; 550 return h; 551 } 552 553 int init_dhcpv6(const char *ifname) 554 { 555 config_dhcp = config_dhcp_get(); 556 557 memcpy(dhcpv6_retx, dhcpv6_retx_default, sizeof(dhcpv6_retx)); 558 config_apply_dhcp_rtx(dhcpv6_retx); 559 560 client_options = config_dhcp->client_options; 561 na_mode = config_dhcp->ia_na_mode; 562 pd_mode = config_dhcp->ia_pd_mode; 563 stateful_only_mode = config_dhcp->stateful_only_mode; 564 auth_protocol = config_dhcp->auth_protocol; 565 566 sock = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP); 567 if (sock < 0) 568 goto failure; 569 570 // Detect interface 571 struct ifreq ifr; 572 memset(&ifr, 0, sizeof(ifr)); 573 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); 574 if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) 575 goto failure; 576 577 ifname_hash_iaid = hash_ifname(ifname); 578 579 ifindex = ifr.ifr_ifindex; 580 581 // Set the socket to non-blocking mode 582 if (fd_set_nonblocking(sock) < 0) 583 goto failure; 584 585 // Build our FQDN 586 size_t fqdn_len; 587 odhcp6c_get_state(STATE_OUR_FQDN, &fqdn_len); 588 if(fqdn_len == 0) { 589 char fqdn_buf[256]; 590 gethostname(fqdn_buf, sizeof(fqdn_buf)); 591 struct { 592 uint16_t type; 593 uint16_t len; 594 uint8_t flags; 595 uint8_t data[256]; 596 } fqdn = {0}; 597 int dn_result = dn_comp(fqdn_buf, fqdn.data, 598 sizeof(fqdn.data), NULL, NULL); 599 fqdn_len = 0; 600 if (dn_result > 0) { 601 fqdn.type = htons(DHCPV6_OPT_FQDN); 602 fqdn.len = htons(1 + dn_result); 603 fqdn.flags = 0; 604 fqdn_len = DHCPV6_OPT_HDR_SIZE + 1 + dn_result; 605 } 606 odhcp6c_add_state(STATE_OUR_FQDN, &fqdn, fqdn_len); 607 } 608 609 // Create client DUID 610 size_t client_id_len; 611 odhcp6c_get_state(STATE_CLIENT_ID, &client_id_len); 612 if (client_id_len == 0) { 613 uint8_t duid[14] = {0, DHCPV6_OPT_CLIENTID, 0, 10, 0, 614 DHCPV6_DUID_LLADDR, 0, 1}; 615 616 if (ioctl(sock, SIOCGIFHWADDR, &ifr) >= 0) 617 memcpy(&duid[8], ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); 618 619 uint8_t zero[ETHER_ADDR_LEN] = {0, 0, 0, 0, 0, 0}; 620 struct ifreq ifs[100], *ifp, *ifend; 621 struct ifconf ifc; 622 ifc.ifc_req = ifs; 623 ifc.ifc_len = sizeof(ifs); 624 625 if (!memcmp(&duid[8], zero, ETHER_ADDR_LEN) && 626 ioctl(sock, SIOCGIFCONF, &ifc) >= 0) { 627 // If our interface doesn't have an address... 628 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq)); 629 for (ifp = ifc.ifc_req; ifp < ifend && 630 !memcmp(&duid[8], zero, ETHER_ADDR_LEN); ifp++) { 631 memcpy(ifr.ifr_name, ifp->ifr_name, 632 sizeof(ifr.ifr_name)); 633 if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) 634 continue; 635 636 memcpy(&duid[8], ifr.ifr_hwaddr.sa_data, 637 ETHER_ADDR_LEN); 638 } 639 } 640 641 odhcp6c_add_state(STATE_CLIENT_ID, duid, sizeof(duid)); 642 } 643 644 // Create ORO 645 if (!(client_options & DHCPV6_STRICT_OPTIONS)) { 646 uint16_t oro[] = { 647 htons(DHCPV6_OPT_SIP_SERVER_D), 648 htons(DHCPV6_OPT_SIP_SERVER_A), 649 htons(DHCPV6_OPT_DNS_SERVERS), 650 htons(DHCPV6_OPT_DNS_DOMAIN), 651 htons(DHCPV6_OPT_SNTP_SERVERS), 652 htons(DHCPV6_OPT_NTP_SERVER), 653 htons(DHCPV6_OPT_PD_EXCLUDE), 654 /* RFC8910: Clients that support this option SHOULD include it */ 655 htons(DHCPV6_OPT_CAPTIVE_PORTAL), 656 }; 657 odhcp6c_add_state(STATE_ORO, oro, sizeof(oro)); 658 } 659 // Required ORO 660 uint16_t req_oro[] = { 661 htons(DHCPV6_OPT_INF_MAX_RT), 662 htons(DHCPV6_OPT_SOL_MAX_RT), 663 htons(DHCPV6_OPT_INFO_REFRESH), 664 }; 665 odhcp6c_add_state(STATE_ORO, req_oro, sizeof(req_oro)); 666 667 // Configure IPv6-options 668 int val = 1; 669 if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) < 0) 670 goto failure; 671 672 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) 673 goto failure; 674 675 if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val, sizeof(val)) < 0) 676 goto failure; 677 678 if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname)) < 0) 679 goto failure; 680 681 if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &(config_dhcp->sk_prio), sizeof(config_dhcp->sk_prio)) < 0) 682 goto failure; 683 684 val = config_dhcp->dscp << 2; 685 if (setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, &val, sizeof(val)) < 0) { 686 goto failure; 687 } 688 689 struct sockaddr_in6 client_addr = { .sin6_family = AF_INET6, 690 .sin6_port = htons(DHCPV6_CLIENT_PORT), .sin6_flowinfo = 0 }; 691 692 if (bind(sock, (struct sockaddr*)&client_addr, sizeof(client_addr)) < 0) 693 goto failure; 694 695 return 0; 696 697 failure: 698 if (sock >= 0) 699 close(sock); 700 701 return -1; 702 } 703 704 enum { 705 IOV_HDR=0, 706 IOV_ORO, 707 IOV_CL_ID, 708 IOV_SRV_ID, 709 IOV_OPTS, 710 IOV_RECONF_ACCEPT, 711 IOV_FQDN, 712 IOV_HDR_IA_NA, 713 IOV_IA_NA, 714 IOV_IA_PD, 715 IOV_TOTAL 716 }; 717 718 int dhcpv6_get_ia_mode(void) 719 { 720 int mode = DHCPV6_UNKNOWN; 721 722 if (na_mode == IA_MODE_NONE && pd_mode == IA_MODE_NONE) 723 mode = DHCPV6_STATELESS; 724 else if (na_mode == IA_MODE_FORCE || pd_mode == IA_MODE_FORCE) 725 mode = DHCPV6_STATEFUL; 726 727 return mode; 728 } 729 730 static void dhcpv6_send(enum dhcpv6_msg req_msg_type, uint8_t trid[3], uint32_t ecs) 731 { 732 // Build FQDN 733 size_t fqdn_len; 734 void *fqdn = odhcp6c_get_state(STATE_OUR_FQDN, &fqdn_len); 735 736 // Build Client ID 737 size_t cl_id_len; 738 void *cl_id = odhcp6c_get_state(STATE_CLIENT_ID, &cl_id_len); 739 740 // Get Server ID 741 size_t srv_id_len; 742 void *srv_id = odhcp6c_get_state(STATE_SERVER_ID, &srv_id_len); 743 744 // Build IA_PDs 745 size_t ia_pd_entry_cnt = 0, ia_pd_len = 0; 746 uint8_t *ia_pd; 747 struct odhcp6c_entry *pd_entries = odhcp6c_get_state(STATE_IA_PD, &ia_pd_entry_cnt); 748 ia_pd_entry_cnt /= sizeof(*pd_entries); 749 750 if (req_msg_type == DHCPV6_MSG_SOLICIT || (req_msg_type == DHCPV6_MSG_REQUEST && ia_pd_entry_cnt == 0 && pd_mode != IA_MODE_NONE)) { 751 odhcp6c_clear_state(STATE_IA_PD); 752 size_t n_prefixes; 753 struct odhcp6c_request_prefix *request_prefixes = odhcp6c_get_state(STATE_IA_PD_INIT, &n_prefixes); 754 n_prefixes /= sizeof(struct odhcp6c_request_prefix); 755 756 ia_pd = alloca(n_prefixes * (sizeof(struct dhcpv6_ia_hdr) + sizeof(struct dhcpv6_ia_prefix))); 757 758 for (size_t i = 0; i < n_prefixes; i++) { 759 struct dhcpv6_ia_hdr hdr_ia_pd = { 760 htons(DHCPV6_OPT_IA_PD), 761 htons(sizeof(hdr_ia_pd) - DHCPV6_OPT_HDR_SIZE + 762 sizeof(struct dhcpv6_ia_prefix) * !!request_prefixes[i].length), 763 request_prefixes[i].iaid, 0, 0 764 }; 765 struct dhcpv6_ia_prefix pref = { 766 .type = htons(DHCPV6_OPT_IA_PREFIX), 767 .len = htons(sizeof(pref) - DHCPV6_OPT_HDR_SIZE), 768 .prefix = request_prefixes[i].length, 769 .addr = request_prefixes[i].addr 770 }; 771 memcpy(ia_pd + ia_pd_len, &hdr_ia_pd, sizeof(hdr_ia_pd)); 772 ia_pd_len += sizeof(hdr_ia_pd); 773 if (request_prefixes[i].length) { 774 memcpy(ia_pd + ia_pd_len, &pref, sizeof(pref)); 775 ia_pd_len += sizeof(pref); 776 } 777 } 778 } else { 779 // we're too lazy to count our distinct IAIDs, 780 // so just allocate maximally needed space 781 ia_pd = alloca(ia_pd_entry_cnt * (sizeof(struct dhcpv6_ia_prefix) + 10 + 782 sizeof(struct dhcpv6_ia_hdr))); 783 784 for (size_t i = 0; i < ia_pd_entry_cnt; ++i) { 785 uint32_t iaid = pd_entries[i].iaid; 786 787 // check if this is an unprocessed IAID and skip if not. 788 bool new_iaid = true; 789 for (int j = i-1; j >= 0; j--) { 790 if (pd_entries[j].iaid == iaid) { 791 new_iaid = false; 792 break; 793 } 794 } 795 796 if (!new_iaid) 797 continue; 798 799 // construct header 800 struct dhcpv6_ia_hdr hdr_ia_pd = { 801 htons(DHCPV6_OPT_IA_PD), 802 htons(sizeof(hdr_ia_pd) - DHCPV6_OPT_HDR_SIZE), 803 iaid, 0, 0 804 }; 805 806 memcpy(ia_pd + ia_pd_len, &hdr_ia_pd, sizeof(hdr_ia_pd)); 807 struct dhcpv6_ia_hdr *hdr = (struct dhcpv6_ia_hdr *) (ia_pd + ia_pd_len); 808 ia_pd_len += sizeof(hdr_ia_pd); 809 810 for (size_t j = i; j < ia_pd_entry_cnt; j++) { 811 if (pd_entries[j].iaid != iaid) 812 continue; 813 814 uint8_t ex_len = 0; 815 if (pd_entries[j].exclusion_length > 0) 816 ex_len = ((pd_entries[j].exclusion_length - pd_entries[j].length - 1) / 8) + 6; 817 818 struct dhcpv6_ia_prefix p = { 819 .type = htons(DHCPV6_OPT_IA_PREFIX), 820 .len = htons(sizeof(p) - DHCPV6_OPT_HDR_SIZE_U + ex_len), 821 .prefix = pd_entries[j].length, 822 .addr = pd_entries[j].target 823 }; 824 825 if (req_msg_type == DHCPV6_MSG_REQUEST) { 826 p.preferred = htonl(pd_entries[j].preferred); 827 p.valid = htonl(pd_entries[j].valid); 828 } 829 830 memcpy(ia_pd + ia_pd_len, &p, sizeof(p)); 831 ia_pd_len += sizeof(p); 832 833 if (ex_len) { 834 ia_pd[ia_pd_len++] = 0; 835 ia_pd[ia_pd_len++] = DHCPV6_OPT_PD_EXCLUDE; 836 ia_pd[ia_pd_len++] = 0; 837 ia_pd[ia_pd_len++] = ex_len - DHCPV6_OPT_HDR_SIZE; 838 ia_pd[ia_pd_len++] = pd_entries[j].exclusion_length; 839 840 uint32_t excl = ntohl(pd_entries[j].router.s6_addr32[1]); 841 excl >>= (64 - pd_entries[j].exclusion_length); 842 excl <<= 8 - ((pd_entries[j].exclusion_length - pd_entries[j].length) % 8); 843 844 for (size_t k = ex_len - 5; k > 0; --k, excl >>= 8) 845 ia_pd[ia_pd_len + k] = excl & 0xff; 846 847 ia_pd_len += ex_len - 5; 848 } 849 850 hdr->len = htons(ntohs(hdr->len) + ntohs(p.len) + 4U); 851 } 852 } 853 } 854 855 // Build IA_NAs 856 size_t ia_na_entry_cnt, ia_na_len = 0; 857 void *ia_na = NULL; 858 struct odhcp6c_entry *ia_entries = odhcp6c_get_state(STATE_IA_NA, &ia_na_entry_cnt); 859 ia_na_entry_cnt /= sizeof(*ia_entries); 860 861 struct dhcpv6_ia_hdr hdr_ia_na = { 862 .type = htons(DHCPV6_OPT_IA_NA), 863 .len = htons(sizeof(hdr_ia_na) - DHCPV6_OPT_HDR_SIZE), 864 .iaid = htonl(ifname_hash_iaid), 865 .t1 = 0, 866 .t2 = 0, 867 }; 868 869 struct dhcpv6_ia_addr ia_na_array[ia_na_entry_cnt]; 870 for (size_t i = 0; i < ia_na_entry_cnt; ++i) { 871 ia_na_array[i].type = htons(DHCPV6_OPT_IA_ADDR); 872 ia_na_array[i].len = htons(sizeof(ia_na_array[i]) - DHCPV6_OPT_HDR_SIZE_U); 873 ia_na_array[i].addr = ia_entries[i].target; 874 875 if (req_msg_type == DHCPV6_MSG_REQUEST) { 876 ia_na_array[i].preferred = htonl(ia_entries[i].preferred); 877 ia_na_array[i].valid = htonl(ia_entries[i].valid); 878 } else { 879 ia_na_array[i].preferred = 0; 880 ia_na_array[i].valid = 0; 881 } 882 } 883 884 ia_na = ia_na_array; 885 ia_na_len = sizeof(ia_na_array); 886 hdr_ia_na.len = htons(ntohs(hdr_ia_na.len) + ia_na_len); 887 888 // Reconfigure Accept 889 struct { 890 uint16_t type; 891 uint16_t length; 892 } reconf_accept = {htons(DHCPV6_OPT_RECONF_ACCEPT), 0}; 893 894 // Option list 895 size_t opts_len; 896 void *opts = odhcp6c_get_state(STATE_OPTS, &opts_len); 897 898 // Option Request List 899 size_t oro_entries, oro_len = 0; 900 uint16_t *oro, *s_oro = odhcp6c_get_state(STATE_ORO, &oro_entries); 901 902 oro_entries /= sizeof(*s_oro); 903 oro = alloca(oro_entries * sizeof(*oro)); 904 905 for (size_t i = 0; i < oro_entries; i++) { 906 struct odhcp6c_opt *opt = odhcp6c_find_opt(htons(s_oro[i])); 907 908 if (opt) { 909 if (!(opt->flags & OPT_ORO)) 910 continue; 911 912 if ((opt->flags & OPT_ORO_SOLICIT) && req_msg_type != DHCPV6_MSG_SOLICIT) 913 continue; 914 915 if ((opt->flags & OPT_ORO_STATELESS) && req_msg_type != DHCPV6_MSG_INFO_REQ) 916 continue; 917 918 if ((opt->flags & OPT_ORO_STATEFUL) && req_msg_type == DHCPV6_MSG_INFO_REQ) 919 continue; 920 } 921 922 oro[oro_len++] = s_oro[i]; 923 } 924 oro_len *= sizeof(*oro); 925 926 // Prepare Header 927 struct { 928 uint8_t type; 929 uint8_t trid[3]; 930 uint16_t elapsed_type; 931 uint16_t elapsed_len; 932 uint16_t elapsed_value; 933 uint16_t oro_type; 934 uint16_t oro_len; 935 } hdr = { 936 req_msg_type, {trid[0], trid[1], trid[2]}, 937 htons(DHCPV6_OPT_ELAPSED), htons(2), 938 htons((ecs > 0xffff) ? 0xffff : ecs), 939 htons(DHCPV6_OPT_ORO), htons(oro_len), 940 }; 941 942 struct iovec iov[IOV_TOTAL] = { 943 [IOV_HDR] = {&hdr, sizeof(hdr)}, 944 [IOV_ORO] = {oro, oro_len}, 945 [IOV_CL_ID] = {cl_id, cl_id_len}, 946 [IOV_SRV_ID] = {srv_id, srv_id_len}, 947 [IOV_OPTS] = { opts, opts_len }, 948 [IOV_RECONF_ACCEPT] = {&reconf_accept, sizeof(reconf_accept)}, 949 [IOV_FQDN] = {fqdn, fqdn_len}, 950 [IOV_HDR_IA_NA] = {&hdr_ia_na, sizeof(hdr_ia_na)}, 951 [IOV_IA_NA] = {ia_na, ia_na_len}, 952 [IOV_IA_PD] = {ia_pd, ia_pd_len}, 953 }; 954 955 size_t cnt = IOV_TOTAL; 956 if (req_msg_type == DHCPV6_MSG_INFO_REQ) 957 cnt = IOV_HDR_IA_NA; 958 959 // Disable IAs if not used 960 if (na_mode == IA_MODE_NONE) { 961 iov[IOV_HDR_IA_NA].iov_len = 0; 962 } else if (ia_na_len == 0) { 963 /* RFC7550 ยง4.2 964 * Solution: a client SHOULD accept Advertise messages, even 965 * when not all IA option types are being offered. And, in 966 * this case, the client SHOULD include the not offered IA 967 * option types in its Request. A client SHOULD only ignore 968 * an Advertise message when none of the requested IA 969 * options include offered addresses or delegated prefixes. 970 * Note that ignored messages MUST still be processed for 971 * SOL_MAX_RT and INF_MAX_RT options as specified in 972 * [RFC7083]. 973 */ 974 975 switch (req_msg_type) { 976 case DHCPV6_MSG_REQUEST: 977 /* Some broken ISPs won't behave properly if IA_NA is 978 * sent on Requests when they have provided an empty 979 * IA_NA on Advertise. 980 * Therefore we don't comply with RFC7550 and omit 981 * IA_NA as a workaround. 982 */ 983 iov[IOV_HDR_IA_NA].iov_len = 0; 984 break; 985 case DHCPV6_MSG_SOLICIT: 986 break; 987 default: 988 iov[IOV_HDR_IA_NA].iov_len = 0; 989 break; 990 } 991 } 992 993 if ((req_msg_type != DHCPV6_MSG_SOLICIT && req_msg_type != DHCPV6_MSG_REQUEST) || 994 !(client_options & DHCPV6_ACCEPT_RECONFIGURE)) 995 iov[IOV_RECONF_ACCEPT].iov_len = 0; 996 997 if (!(client_options & DHCPV6_CLIENT_FQDN)) { 998 iov[IOV_FQDN].iov_len = 0; 999 } else { 1000 switch (req_msg_type) { 1001 /* RFC4704 ยง5 1002 A client MUST only include the Client FQDN option in SOLICIT, 1003 REQUEST, RENEW, or REBIND messages. 1004 */ 1005 case DHCPV6_MSG_SOLICIT: 1006 case DHCPV6_MSG_REQUEST: 1007 case DHCPV6_MSG_RENEW: 1008 case DHCPV6_MSG_REBIND: 1009 /* RFC4704 ยง6 1010 Servers MUST only include a Client FQDN option in ADVERTISE and REPLY 1011 messages... 1012 case DHCPV6_MSG_ADVERT: 1013 case DHCPV6_MSG_REPLY: 1014 */ 1015 /* leave FQDN as-is */ 1016 break; 1017 default: 1018 /* remaining MSG types cannot contain client FQDN */ 1019 iov[IOV_FQDN].iov_len = 0; 1020 break; 1021 } 1022 } 1023 1024 struct sockaddr_in6 srv = {AF_INET6, htons(DHCPV6_SERVER_PORT), 1025 0, ALL_DHCPV6_RELAYS, ifindex}; 1026 struct msghdr msg = {.msg_name = &srv, .msg_namelen = sizeof(srv), 1027 .msg_iov = iov, .msg_iovlen = cnt}; 1028 1029 switch (req_msg_type) { 1030 case DHCPV6_MSG_REQUEST: 1031 case DHCPV6_MSG_RENEW: 1032 case DHCPV6_MSG_RELEASE: 1033 case DHCPV6_MSG_DECLINE: 1034 if (!IN6_IS_ADDR_UNSPECIFIED(&server_addr) && 1035 odhcp6c_addr_in_scope(&server_addr)) { 1036 srv.sin6_addr = server_addr; 1037 if (!IN6_IS_ADDR_LINKLOCAL(&server_addr)) 1038 srv.sin6_scope_id = 0; 1039 } 1040 break; 1041 default: 1042 break; 1043 } 1044 1045 if (sendmsg(sock, &msg, 0) < 0) { 1046 char in6_str[INET6_ADDRSTRLEN]; 1047 1048 error("Failed to send %s message to %s (%s)", 1049 dhcpv6_msg_to_str(req_msg_type), 1050 inet_ntop(AF_INET6, (const void *)&srv.sin6_addr, 1051 in6_str, sizeof(in6_str)), strerror(errno)); 1052 dhcpv6_stats.transmit_failures++; 1053 } else { 1054 dhcpv6_inc_counter(req_msg_type); 1055 } 1056 } 1057 1058 static int64_t dhcpv6_rand_delay(int64_t time) 1059 { 1060 int random; 1061 odhcp6c_random(&random, sizeof(random)); 1062 1063 return (time * ((int64_t)random % (config_dhcp->rand_factor*10LL))) / 10000LL; 1064 } 1065 1066 // Message validation checks according to RFC3315 chapter 15 1067 static bool dhcpv6_response_is_valid(const void *buf, ssize_t len, 1068 const uint8_t transaction[3], enum dhcpv6_msg req_msg_type, 1069 const struct in6_addr *daddr) 1070 { 1071 const struct dhcpv6_header *response_buf = buf; 1072 if (len < (ssize_t)sizeof(*response_buf) || memcmp(response_buf->tr_id, 1073 transaction, sizeof(response_buf->tr_id))) 1074 return false; // Invalid reply 1075 1076 if (req_msg_type == DHCPV6_MSG_SOLICIT) { 1077 if (response_buf->msg_type != DHCPV6_MSG_ADVERT && 1078 response_buf->msg_type != DHCPV6_MSG_REPLY) 1079 return false; 1080 } else if (req_msg_type == DHCPV6_MSG_UNKNOWN) { 1081 if (!accept_reconfig || response_buf->msg_type != DHCPV6_MSG_RECONF) 1082 return false; 1083 } else if (response_buf->msg_type != DHCPV6_MSG_REPLY) { 1084 return false; 1085 } 1086 1087 uint8_t *end = ((uint8_t*)buf) + len, *odata = NULL, 1088 rcmsg = DHCPV6_MSG_UNKNOWN; 1089 uint16_t otype, olen = UINT16_MAX; 1090 bool clientid_ok = false, serverid_ok = false, rcauth_ok = false, 1091 auth_present = false, ia_present = false, options_valid = true; 1092 1093 size_t client_id_len, server_id_len; 1094 void *client_id = odhcp6c_get_state(STATE_CLIENT_ID, &client_id_len); 1095 void *server_id = odhcp6c_get_state(STATE_SERVER_ID, &server_id_len); 1096 1097 dhcpv6_for_each_option(&response_buf[1], end, otype, olen, odata) { 1098 switch (otype) { 1099 case DHCPV6_OPT_CLIENTID: 1100 clientid_ok = (olen + DHCPV6_OPT_HDR_SIZE_U == client_id_len) && !memcmp( 1101 &odata[-DHCPV6_OPT_HDR_SIZE], client_id, client_id_len); 1102 break; 1103 1104 case DHCPV6_OPT_SERVERID: 1105 if (server_id_len) 1106 serverid_ok = (olen + DHCPV6_OPT_HDR_SIZE_U == server_id_len) && !memcmp( 1107 &odata[-DHCPV6_OPT_HDR_SIZE], server_id, server_id_len); 1108 else 1109 serverid_ok = true; 1110 break; 1111 1112 case DHCPV6_OPT_AUTH: 1113 struct dhcpv6_auth *r = (void*)&odata[-DHCPV6_OPT_HDR_SIZE]; 1114 if (auth_present) { 1115 options_valid = false; 1116 continue; 1117 } 1118 1119 auth_present = true; 1120 if (auth_protocol == AUTH_PROT_RKAP) { 1121 struct dhcpv6_auth_reconfigure *rkap = (void*)r->data; 1122 if (r->protocol != AUTH_PROT_RKAP || r->algorithm != AUTH_ALG_HMACMD5 || r->len != 28 || rkap->reconf_type != RKAP_TYPE_HMACMD5) 1123 continue; 1124 1125 md5_ctx_t md5; 1126 uint8_t serverhash[16], secretbytes[64]; 1127 uint32_t hash[4]; 1128 memcpy(serverhash, rkap->key, sizeof(serverhash)); 1129 memset(rkap->key, 0, sizeof(rkap->key)); 1130 1131 memset(secretbytes, 0, sizeof(secretbytes)); 1132 memcpy(secretbytes, reconf_key, sizeof(reconf_key)); 1133 1134 for (size_t i = 0; i < sizeof(secretbytes); ++i) 1135 secretbytes[i] ^= 0x36; 1136 1137 md5_begin(&md5); 1138 md5_hash(secretbytes, sizeof(secretbytes), &md5); 1139 md5_hash(buf, len, &md5); 1140 md5_end(hash, &md5); 1141 1142 for (size_t i = 0; i < sizeof(secretbytes); ++i) { 1143 secretbytes[i] ^= 0x36; 1144 secretbytes[i] ^= 0x5c; 1145 } 1146 1147 md5_begin(&md5); 1148 md5_hash(secretbytes, sizeof(secretbytes), &md5); 1149 md5_hash(hash, 16, &md5); 1150 md5_end(hash, &md5); 1151 1152 rcauth_ok = !memcmp(hash, serverhash, sizeof(hash)); 1153 } else if (auth_protocol == AUTH_PROT_TOKEN) { 1154 if (r->protocol != AUTH_PROT_TOKEN || r->algorithm != AUTH_ALG_TOKEN || r->len < 12) 1155 continue; 1156 1157 uint16_t token_len = r->len - 11; 1158 if (config_dhcp->auth_token == NULL || strlen(config_dhcp->auth_token) != token_len) 1159 continue; 1160 1161 rcauth_ok = !memcmp(r->data, config_dhcp->auth_token, token_len); 1162 } 1163 break; 1164 case DHCPV6_OPT_RECONF_MESSAGE: 1165 if (olen != 1) 1166 return false; 1167 rcmsg = odata[0]; 1168 break; 1169 1170 case DHCPV6_OPT_IA_PD: 1171 case DHCPV6_OPT_IA_NA: 1172 ia_present = true; 1173 if (olen < sizeof(struct dhcpv6_ia_hdr) - DHCPV6_OPT_HDR_SIZE) 1174 options_valid = false; 1175 break; 1176 1177 case DHCPV6_OPT_IA_ADDR: 1178 case DHCPV6_OPT_IA_PREFIX: 1179 case DHCPV6_OPT_PD_EXCLUDE: 1180 // Options are not allowed on global level 1181 options_valid = false; 1182 break; 1183 1184 default: 1185 break; 1186 } 1187 } 1188 1189 if (!options_valid || ((odata + olen) > end)) 1190 return false; 1191 1192 if (req_msg_type == DHCPV6_MSG_INFO_REQ && ia_present) 1193 return false; 1194 1195 if (response_buf->msg_type == DHCPV6_MSG_RECONF) { 1196 if ((rcmsg != DHCPV6_MSG_RENEW && rcmsg != DHCPV6_MSG_REBIND && rcmsg != DHCPV6_MSG_INFO_REQ) || 1197 (rcmsg == DHCPV6_MSG_INFO_REQ && ia_present) || 1198 !rcauth_ok || IN6_IS_ADDR_MULTICAST(daddr)) 1199 return false; 1200 } 1201 1202 return clientid_ok && serverid_ok; 1203 } 1204 1205 static int dhcpv6_handle_reconfigure(enum dhcpv6_msg orig, const int rc, 1206 const void *opt, const void *end, _o_unused const struct sockaddr_in6 *from) 1207 { 1208 uint16_t otype, olen; 1209 uint8_t *odata; 1210 enum dhcpv6_msg msg = DHCPV6_MSG_UNKNOWN; 1211 1212 dhcpv6_for_each_option(opt, end, otype, olen, odata) { 1213 if (otype == DHCPV6_OPT_RECONF_MESSAGE && olen == 1) { 1214 switch (odata[0]) { 1215 case DHCPV6_MSG_REBIND: 1216 if (t2 != UINT32_MAX) 1217 t2 = 0; 1218 _o_fallthrough; 1219 case DHCPV6_MSG_RENEW: 1220 if (t1 != UINT32_MAX) 1221 t1 = 0; 1222 _o_fallthrough; 1223 case DHCPV6_MSG_INFO_REQ: 1224 msg = odata[0]; 1225 notice("Need to respond with %s in reply to %s", 1226 dhcpv6_msg_to_str(msg), dhcpv6_msg_to_str(DHCPV6_MSG_RECONF)); 1227 break; 1228 1229 default: 1230 break; 1231 } 1232 } 1233 } 1234 1235 if (msg != DHCPV6_MSG_UNKNOWN) 1236 dhcpv6_handle_reply(orig, rc, NULL, NULL, NULL); 1237 1238 return (msg == DHCPV6_MSG_UNKNOWN? -1: (int)msg); 1239 } 1240 1241 // Collect all advertised servers 1242 static int dhcpv6_handle_advert(enum dhcpv6_msg orig, const int rc, 1243 const void *opt, const void *end, _o_unused const struct sockaddr_in6 *from) 1244 { 1245 uint16_t olen, otype; 1246 uint8_t *odata, pref = 0; 1247 struct dhcpv6_server_cand cand = {false, false, 0, 0, {0}, 1248 IN6ADDR_ANY_INIT, DHCPV6_SOL_MAX_RT, 1249 DHCPV6_INF_MAX_RT, NULL, NULL, 0, 0}; 1250 bool have_na = false; 1251 int have_pd = 0; 1252 1253 dhcpv6_for_each_option(opt, end, otype, olen, odata) { 1254 if (orig == DHCPV6_MSG_SOLICIT && 1255 ((otype == DHCPV6_OPT_IA_PD && pd_mode != IA_MODE_NONE) || 1256 (otype == DHCPV6_OPT_IA_NA && na_mode != IA_MODE_NONE)) && 1257 olen > sizeof(struct dhcpv6_ia_hdr) - DHCPV6_OPT_HDR_SIZE) { 1258 struct dhcpv6_ia_hdr *ia_hdr = (void*)(&odata[-DHCPV6_OPT_HDR_SIZE]); 1259 dhcpv6_parse_ia(ia_hdr, odata + olen + sizeof(*ia_hdr), NULL); 1260 } 1261 1262 switch (otype) { 1263 case DHCPV6_OPT_SERVERID: 1264 if (olen <= DHCPV6_DUID_MAX_LEN) { 1265 memcpy(cand.duid, odata, olen); 1266 cand.duid_len = olen; 1267 } 1268 break; 1269 1270 case DHCPV6_OPT_PREF: 1271 if (olen >= 1 && cand.preference >= 0) 1272 cand.preference = pref = odata[0]; 1273 break; 1274 1275 case DHCPV6_OPT_UNICAST: 1276 if (olen == sizeof(cand.server_addr) && 1277 !(client_options & DHCPV6_IGNORE_OPT_UNICAST)) 1278 cand.server_addr = *(struct in6_addr *)odata; 1279 break; 1280 1281 case DHCPV6_OPT_RECONF_ACCEPT: 1282 cand.wants_reconfigure = true; 1283 break; 1284 1285 case DHCPV6_OPT_SOL_MAX_RT: 1286 if (olen == 4) { 1287 uint32_t sol_max_rt = ntohl_unaligned(odata); 1288 if (sol_max_rt >= DHCPV6_SOL_MAX_RT_MIN && 1289 sol_max_rt <= DHCPV6_SOL_MAX_RT_MAX) 1290 cand.sol_max_rt = sol_max_rt; 1291 } 1292 break; 1293 1294 case DHCPV6_OPT_INF_MAX_RT: 1295 if (olen == 4) { 1296 uint32_t inf_max_rt = ntohl_unaligned(odata); 1297 if (inf_max_rt >= DHCPV6_INF_MAX_RT_MIN && 1298 inf_max_rt <= DHCPV6_INF_MAX_RT_MAX) 1299 cand.inf_max_rt = inf_max_rt; 1300 } 1301 break; 1302 1303 case DHCPV6_OPT_IA_PD: 1304 if (olen >= sizeof(struct dhcpv6_ia_hdr) - DHCPV6_OPT_HDR_SIZE) { 1305 struct dhcpv6_ia_hdr *h = (struct dhcpv6_ia_hdr *)&odata[-DHCPV6_OPT_HDR_SIZE]; 1306 uint8_t *oend = odata + olen, *d; 1307 1308 dhcpv6_for_each_option(&h[1], oend, otype, olen, d) { 1309 if (otype == DHCPV6_OPT_IA_PREFIX && 1310 olen >= sizeof(struct dhcpv6_ia_prefix) - DHCPV6_OPT_HDR_SIZE) { 1311 struct dhcpv6_ia_prefix *p = 1312 (struct dhcpv6_ia_prefix *)&d[-DHCPV6_OPT_HDR_SIZE]; 1313 have_pd = p->prefix; 1314 } 1315 } 1316 } 1317 break; 1318 1319 case DHCPV6_OPT_IA_NA: 1320 if (olen >= sizeof(struct dhcpv6_ia_hdr) - DHCPV6_OPT_HDR_SIZE) { 1321 struct dhcpv6_ia_hdr *h = (struct dhcpv6_ia_hdr *)&odata[-DHCPV6_OPT_HDR_SIZE]; 1322 uint8_t *oend = odata + olen, *d; 1323 1324 dhcpv6_for_each_option(&h[1], oend, otype, olen, d) { 1325 if (otype == DHCPV6_OPT_IA_ADDR && 1326 olen >= sizeof(struct dhcpv6_ia_addr) - DHCPV6_OPT_HDR_SIZE) 1327 have_na = true; 1328 } 1329 } 1330 break; 1331 1332 default: 1333 break; 1334 } 1335 } 1336 1337 if ((stateful_only_mode && !have_na && !have_pd) || 1338 (!have_na && na_mode == IA_MODE_FORCE) || 1339 (!have_pd && pd_mode == IA_MODE_FORCE)) { 1340 /* 1341 * RFC7083 states to process the SOL_MAX_RT and 1342 * INF_MAX_RT options even if the DHCPv6 server 1343 * did not propose any IA_NA and/or IA_PD 1344 */ 1345 dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = cand.sol_max_rt; 1346 dhcpv6_retx[DHCPV6_MSG_INFO_REQ].max_timeo = cand.inf_max_rt; 1347 return -1; 1348 } 1349 1350 if (na_mode != IA_MODE_NONE && !have_na) { 1351 cand.has_noaddravail = true; 1352 cand.preference -= 1000; 1353 } 1354 1355 if (pd_mode != IA_MODE_NONE) { 1356 if (have_pd) 1357 cand.preference += 2000 + (128 - have_pd); 1358 else 1359 cand.preference -= 2000; 1360 } 1361 1362 if (cand.duid_len > 0) { 1363 cand.ia_na = odhcp6c_move_state(STATE_IA_NA, &cand.ia_na_len); 1364 cand.ia_pd = odhcp6c_move_state(STATE_IA_PD, &cand.ia_pd_len); 1365 dhcpv6_add_server_cand(&cand); 1366 } 1367 1368 return (rc > 1 || (pref == 255 && cand.preference > 0)) ? 1 : -1; 1369 } 1370 1371 static int dhcpv6_commit_advert(void) 1372 { 1373 return dhcpv6_promote_server_cand(); 1374 } 1375 1376 static int dhcpv6_handle_rebind_reply(enum dhcpv6_msg orig, const int rc, 1377 const void *opt, const void *end, const struct sockaddr_in6 *from) 1378 { 1379 dhcpv6_handle_advert(orig, rc, opt, end, from); 1380 if (dhcpv6_commit_advert() < 0) 1381 return -1; 1382 1383 return dhcpv6_handle_reply(orig, rc, opt, end, from); 1384 } 1385 1386 static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _o_unused const int rc, 1387 const void *opt, const void *end, const struct sockaddr_in6 *from) 1388 { 1389 uint8_t *odata; 1390 uint16_t otype, olen; 1391 uint32_t refresh = config_dhcp->irt_default; 1392 int ret = 1; 1393 unsigned int state_IAs; 1394 unsigned int updated_IAs = 0; 1395 bool handled_status_codes[_DHCPV6_Status_Max] = { false, }; 1396 1397 odhcp6c_expire(true); 1398 1399 if (orig == DHCPV6_MSG_UNKNOWN) { 1400 static time_t last_update = 0; 1401 time_t now = odhcp6c_get_milli_time() / 1000; 1402 1403 uint32_t elapsed = (last_update > 0) ? now - last_update : 0; 1404 last_update = now; 1405 1406 if (t1 != UINT32_MAX) 1407 t1 -= elapsed; 1408 1409 if (t2 != UINT32_MAX) 1410 t2 -= elapsed; 1411 1412 if (t3 != UINT32_MAX) 1413 t3 -= elapsed; 1414 1415 if (t1 < 0) 1416 t1 = 0; 1417 1418 if (t2 < 0) 1419 t2 = 0; 1420 1421 if (t3 < 0) 1422 t3 = 0; 1423 } 1424 1425 if (orig == DHCPV6_MSG_REQUEST && !odhcp6c_is_bound()) { 1426 // Delete NA and PD we have in the state from the Advert 1427 odhcp6c_clear_state(STATE_IA_NA); 1428 odhcp6c_clear_state(STATE_IA_PD); 1429 } 1430 1431 if (opt) { 1432 odhcp6c_clear_state(STATE_DNS); 1433 odhcp6c_clear_state(STATE_SEARCH); 1434 odhcp6c_clear_state(STATE_SNTP_IP); 1435 odhcp6c_clear_state(STATE_NTP_IP); 1436 odhcp6c_clear_state(STATE_NTP_FQDN); 1437 odhcp6c_clear_state(STATE_SIP_IP); 1438 odhcp6c_clear_state(STATE_SIP_FQDN); 1439 odhcp6c_clear_state(STATE_AFTR_NAME); 1440 odhcp6c_clear_state(STATE_S46_MAPT); 1441 odhcp6c_clear_state(STATE_S46_MAPE); 1442 odhcp6c_clear_state(STATE_S46_LW); 1443 odhcp6c_clear_state(STATE_CAPT_PORT_DHCPV6); 1444 odhcp6c_clear_state(STATE_PASSTHRU); 1445 odhcp6c_clear_state(STATE_CUSTOM_OPTS); 1446 1447 // Parse and find all matching IAs 1448 dhcpv6_for_each_option(opt, end, otype, olen, odata) { 1449 struct odhcp6c_opt *dopt = odhcp6c_find_opt(otype); 1450 1451 switch (otype) { 1452 1453 case DHCPV6_OPT_IA_NA: 1454 case DHCPV6_OPT_IA_PD: 1455 if (olen > sizeof(struct dhcpv6_ia_hdr) - DHCPV6_OPT_HDR_SIZE) { 1456 struct dhcpv6_ia_hdr *ia_hdr = (void*)(&odata[-DHCPV6_OPT_HDR_SIZE]); 1457 1458 if ((na_mode == IA_MODE_NONE && otype == DHCPV6_OPT_IA_NA) || 1459 (pd_mode == IA_MODE_NONE && otype == DHCPV6_OPT_IA_PD)) 1460 continue; 1461 1462 // Test ID 1463 if (ia_hdr->iaid != htonl(ifname_hash_iaid) && otype == DHCPV6_OPT_IA_NA) 1464 continue; 1465 1466 uint16_t code = DHCPV6_Success; 1467 uint16_t stype, slen; 1468 uint8_t *sdata; 1469 bool dhcpv6_successful_once = false; 1470 // Get and handle status code 1471 dhcpv6_for_each_option(&ia_hdr[1], odata + olen, stype, slen, sdata) { 1472 if (stype == DHCPV6_OPT_STATUS && slen >= 2) { 1473 uint8_t *mdata = (slen > 2) ? &sdata[2] : NULL; 1474 uint16_t mlen = (slen > 2) ? slen - 2 : 0; 1475 1476 code = ((int)sdata[0] << 8) | ((int)sdata[1]); 1477 1478 if (code == DHCPV6_Success) { 1479 dhcpv6_successful_once = true; 1480 continue; 1481 } 1482 1483 dhcpv6_handle_ia_status_code(orig, ia_hdr, 1484 code, mdata, mlen, handled_status_codes, &ret); 1485 1486 break; 1487 } 1488 } 1489 1490 if (!dhcpv6_successful_once && code != DHCPV6_Success) 1491 continue; 1492 1493 updated_IAs += dhcpv6_parse_ia(ia_hdr, odata + olen, &ret); 1494 } 1495 break; 1496 1497 case DHCPV6_OPT_UNICAST: 1498 if (olen == sizeof(server_addr) && 1499 !(client_options & DHCPV6_IGNORE_OPT_UNICAST)) 1500 server_addr = *(struct in6_addr *)odata; 1501 break; 1502 1503 case DHCPV6_OPT_STATUS: 1504 if (olen >= 2) { 1505 uint8_t *mdata = (olen > 2) ? &odata[2] : NULL; 1506 uint16_t mlen = (olen > 2) ? olen - 2 : 0; 1507 uint16_t code = ((int)odata[0] << 8) | ((int)odata[1]); 1508 1509 dhcpv6_handle_status_code(orig, code, mdata, mlen, &ret); 1510 } 1511 break; 1512 1513 case DHCPV6_OPT_DNS_SERVERS: 1514 if (olen % sizeof(struct in6_addr) == 0) 1515 odhcp6c_add_state(STATE_DNS, odata, olen); 1516 break; 1517 1518 case DHCPV6_OPT_DNS_DOMAIN: 1519 odhcp6c_add_state(STATE_SEARCH, odata, olen); 1520 break; 1521 1522 case DHCPV6_OPT_SNTP_SERVERS: 1523 if (olen % sizeof(struct in6_addr) == 0) 1524 odhcp6c_add_state(STATE_SNTP_IP, odata, olen); 1525 break; 1526 1527 case DHCPV6_OPT_NTP_SERVER: 1528 uint16_t stype, slen; 1529 uint8_t *sdata; 1530 // Test status and bail if error 1531 dhcpv6_for_each_option(odata, odata + olen, 1532 stype, slen, sdata) { 1533 if (slen == sizeof(struct in6_addr) && (stype == NTP_MC_ADDR || stype == NTP_SRV_ADDR)) 1534 odhcp6c_add_state(STATE_NTP_IP, sdata, slen); 1535 else if (slen > 0 && stype == NTP_SRV_FQDN) 1536 odhcp6c_add_state(STATE_NTP_FQDN, sdata, slen); 1537 } 1538 break; 1539 1540 case DHCPV6_OPT_SIP_SERVER_A: 1541 if (olen == sizeof(struct in6_addr)) 1542 odhcp6c_add_state(STATE_SIP_IP, odata, olen); 1543 break; 1544 1545 case DHCPV6_OPT_SIP_SERVER_D: 1546 odhcp6c_add_state(STATE_SIP_FQDN, odata, olen); 1547 break; 1548 1549 case DHCPV6_OPT_INFO_REFRESH: 1550 if (olen == 4) 1551 refresh = ntohl_unaligned(odata); 1552 break; 1553 1554 case DHCPV6_OPT_AUTH: 1555 struct dhcpv6_auth *r = (void*)&odata[-DHCPV6_OPT_HDR_SIZE]; 1556 if (auth_protocol == AUTH_PROT_RKAP) { 1557 struct dhcpv6_auth_reconfigure *rkap = (void*)r->data; 1558 if (r->protocol == AUTH_PROT_RKAP || r->algorithm == AUTH_ALG_HMACMD5 || 1559 r->len == 28 || rkap->reconf_type == RKAP_TYPE_KEY) 1560 memcpy(reconf_key, rkap->key, sizeof(rkap->key)); 1561 } 1562 break; 1563 1564 case DHCPV6_OPT_AFTR_NAME: 1565 if (olen > 3) { 1566 size_t cur_len; 1567 odhcp6c_get_state(STATE_AFTR_NAME, &cur_len); 1568 if (cur_len == 0) 1569 odhcp6c_add_state(STATE_AFTR_NAME, odata, olen); 1570 } 1571 break; 1572 1573 case DHCPV6_OPT_SOL_MAX_RT: 1574 if (olen == 4) { 1575 uint32_t sol_max_rt = ntohl_unaligned(odata); 1576 if (sol_max_rt >= DHCPV6_SOL_MAX_RT_MIN && sol_max_rt <= DHCPV6_SOL_MAX_RT_MAX) 1577 dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = sol_max_rt; 1578 } 1579 break; 1580 1581 case DHCPV6_OPT_INF_MAX_RT: 1582 if (olen == 4) { 1583 uint32_t inf_max_rt = ntohl_unaligned(odata); 1584 if (inf_max_rt >= DHCPV6_INF_MAX_RT_MIN && inf_max_rt <= DHCPV6_INF_MAX_RT_MAX) 1585 dhcpv6_retx[DHCPV6_MSG_INFO_REQ].max_timeo = inf_max_rt; 1586 } 1587 break; 1588 1589 case DHCPV6_OPT_S46_CONT_MAPT: 1590 odhcp6c_add_state(STATE_S46_MAPT, odata, olen); 1591 break; 1592 1593 case DHCPV6_OPT_S46_CONT_MAPE: 1594 size_t mape_len; 1595 odhcp6c_get_state(STATE_S46_MAPE, &mape_len); 1596 if (mape_len == 0) 1597 odhcp6c_add_state(STATE_S46_MAPE, odata, olen); 1598 break; 1599 1600 case DHCPV6_OPT_S46_CONT_LW: 1601 odhcp6c_add_state(STATE_S46_LW, odata, olen); 1602 break; 1603 1604 case DHCPV6_OPT_CAPTIVE_PORTAL: /* RFC8910 ยง2.2 */ 1605 size_t ref_len = sizeof(URN_IETF_CAPT_PORT_UNRESTR) - 1; 1606 /* RFC8910 ยง2: 1607 * Networks with no captive portals may explicitly indicate this 1608 * condition by using this option with the IANA-assigned URI for 1609 * this purpose. Clients observing the URI value ... may forego 1610 * time-consuming forms of captive portal detection. */ 1611 if (memcmp(odata, URN_IETF_CAPT_PORT_UNRESTR, ref_len)) { 1612 /* RFC8910 ยง2.2: 1613 * Note that the URI parameter is not null terminated. 1614 * Allocate new buffer including room for '\0' */ 1615 size_t uri_len = olen + 1; 1616 uint8_t *copy = malloc(uri_len); 1617 if (!copy) 1618 continue; 1619 memcpy(copy, odata, olen); 1620 copy[uri_len] = '\0'; 1621 odhcp6c_add_state(STATE_CAPT_PORT_DHCPV6, odata, olen); 1622 free(copy); 1623 } 1624 break; 1625 1626 default: 1627 odhcp6c_add_state(STATE_CUSTOM_OPTS, &odata[-DHCPV6_OPT_HDR_SIZE], olen + DHCPV6_OPT_HDR_SIZE); 1628 break; 1629 } 1630 1631 // Pass-through unless explicitly disabled, for every option 1632 if (!dopt || !(dopt->flags & OPT_NO_PASSTHRU)) 1633 odhcp6c_add_state(STATE_PASSTHRU, &odata[-DHCPV6_OPT_HDR_SIZE], olen + DHCPV6_OPT_HDR_SIZE); 1634 } 1635 } 1636 1637 // Bail out if fatal status code was received 1638 if (ret <= 0) 1639 return ret; 1640 1641 switch (orig) { 1642 case DHCPV6_MSG_REQUEST: 1643 case DHCPV6_MSG_REBIND: 1644 case DHCPV6_MSG_RENEW: 1645 state_IAs = dhcpv6_calc_refresh_timers(); 1646 // In case there're no state IA entries 1647 // keep sending request/renew/rebind messages 1648 if (state_IAs == 0) { 1649 ret = 0; 1650 break; 1651 } 1652 1653 switch (orig) { 1654 case DHCPV6_MSG_REQUEST: 1655 // All server candidates can be cleared if not yet bound 1656 if (!odhcp6c_is_bound()) 1657 dhcpv6_clear_all_server_cand(); 1658 1659 odhcp6c_clear_state(STATE_SERVER_ADDR); 1660 odhcp6c_add_state(STATE_SERVER_ADDR, &from->sin6_addr, sizeof(struct in6_addr)); 1661 break; 1662 case DHCPV6_MSG_RENEW: 1663 // Send further renews if T1 is not set and if 1664 // there're IAs which were not in the Reply message 1665 if (!t1 && state_IAs != updated_IAs) { 1666 if (updated_IAs) 1667 // Publish updates 1668 notify_state_change("updated", 0, false); 1669 1670 /* 1671 * RFC8415 states following in ยง18.2.10.1 : 1672 * Sends a Renew/Rebind if any of the IAs are not in the Reply 1673 * message, but as this likely indicates that the server that 1674 * responded does not support that IA type, sending immediately is 1675 * unlikely to produce a different result. Therefore, the client 1676 * MUST rate-limit its transmissions (see Section 14.1) and MAY just 1677 * wait for the normal retransmission time (as if the Reply message 1678 * had not been received). The client continues to use other 1679 * bindings for which the server did return information 1680 */ 1681 ret = -1; 1682 } 1683 break; 1684 case DHCPV6_MSG_REBIND: 1685 odhcp6c_clear_state(STATE_SERVER_ADDR); 1686 odhcp6c_add_state(STATE_SERVER_ADDR, &from->sin6_addr, sizeof(struct in6_addr)); 1687 1688 // Send further rebinds if T1 and T2 is not set and if 1689 // there're IAs which were not in the Reply message 1690 if (!t1 && !t2 && state_IAs != updated_IAs) { 1691 if (updated_IAs) 1692 // Publish updates 1693 notify_state_change("updated", 0, false); 1694 1695 /* 1696 * RFC8415 states following in ยง18.2.10.1 : 1697 * Sends a Renew/Rebind if any of the IAs are not in the Reply 1698 * message, but as this likely indicates that the server that 1699 * responded does not support that IA type, sending immediately is 1700 * unlikely to produce a different result. Therefore, the client 1701 * MUST rate-limit its transmissions (see Section 14.1) and MAY just 1702 * wait for the normal retransmission time (as if the Reply message 1703 * had not been received). The client continues to use other 1704 * bindings for which the server did return information 1705 */ 1706 ret = -1; 1707 } 1708 break; 1709 1710 default: 1711 break; 1712 } 1713 break; 1714 1715 case DHCPV6_MSG_INFO_REQ: 1716 // All server candidates can be cleared if not yet bound 1717 if (!odhcp6c_is_bound()) 1718 dhcpv6_clear_all_server_cand(); 1719 1720 odhcp6c_clear_state(STATE_SERVER_ADDR); 1721 odhcp6c_add_state(STATE_SERVER_ADDR, &from->sin6_addr, sizeof(struct in6_addr)); 1722 1723 t1 = (refresh < config_dhcp->irt_min) ? config_dhcp->irt_min : refresh; 1724 break; 1725 1726 default: 1727 break; 1728 } 1729 1730 return ret; 1731 } 1732 1733 static unsigned int dhcpv6_parse_ia(void *opt, void *end, int *ret) 1734 { 1735 struct dhcpv6_ia_hdr *ia_hdr = (struct dhcpv6_ia_hdr *)opt; 1736 unsigned int updated_IAs = 0; 1737 uint32_t t1, t2; 1738 uint16_t otype, olen; 1739 uint8_t *odata; 1740 char buf[INET6_ADDRSTRLEN]; 1741 1742 t1 = ntohl(ia_hdr->t1); 1743 t2 = ntohl(ia_hdr->t2); 1744 1745 /* RFC 8415 ยง21.4 1746 If a client receives an IA_NA with T1 greater than T2 and both T1 and 1747 T2 are greater than 0, the client discards the IA_NA option and 1748 processes the remainder of the message as though the server had not 1749 included the invalid IA_NA option. */ 1750 if (t1 > t2 && t1 > 0 && t2 > 0) 1751 return 0; 1752 1753 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); 1754 1755 // Update address IA 1756 dhcpv6_for_each_option(&ia_hdr[1], end, otype, olen, odata) { 1757 struct odhcp6c_entry entry = { 1758 .router = IN6ADDR_ANY_INIT, 1759 .auxlen = 0, 1760 .length = 0, 1761 .ra_flags = 0, 1762 .exclusion_length = 0, 1763 .target = IN6ADDR_ANY_INIT, 1764 .priority = 0, 1765 .valid = 0, 1766 .preferred = 0, 1767 .t1 = 0, 1768 .t2 = 0, 1769 .iaid = ia_hdr->iaid, 1770 }; 1771 1772 switch (otype) { 1773 case DHCPV6_OPT_IA_PREFIX: { 1774 struct dhcpv6_ia_prefix *prefix = (void*)&odata[-DHCPV6_OPT_HDR_SIZE]; 1775 if (olen + DHCPV6_OPT_HDR_SIZE_U < sizeof(*prefix)) 1776 continue; 1777 1778 entry.valid = ntohl(prefix->valid); 1779 entry.preferred = ntohl(prefix->preferred); 1780 1781 if (entry.preferred > entry.valid) 1782 continue; 1783 1784 /* RFC 8415 ยง21.21 1785 Recommended values for T1 and T2 are 0.5 and 0.8 times the 1786 shortest preferred lifetime of the prefixes in the IA_PD that the 1787 server is willing to extend. */ 1788 entry.t1 = (t1 ? t1 : (entry.preferred != UINT32_MAX ? 0.5 * entry.preferred : UINT32_MAX)); 1789 entry.t2 = (t2 ? t2 : (entry.preferred != UINT32_MAX ? 0.8 * entry.preferred : UINT32_MAX)); 1790 if (entry.t1 > entry.t2) 1791 entry.t1 = entry.t2; 1792 1793 entry.length = prefix->prefix; 1794 entry.target = prefix->addr; 1795 uint16_t stype, slen; 1796 uint8_t *sdata; 1797 1798 // Parse sub-options for PD-exclude or error status code 1799 bool update_state = true; 1800 dhcpv6_for_each_option(odata + sizeof(*prefix) - DHCPV6_OPT_HDR_SIZE, 1801 odata + olen, stype, slen, sdata) { 1802 if (stype == DHCPV6_OPT_STATUS && slen >= 2) { 1803 /* RFC 8415 ยง21.22 1804 The status of any operations involving this IA Prefix option is 1805 indicated in a Status Code option (see Section 21.13) in the 1806 IAprefix-options field. */ 1807 uint8_t *status_msg = (slen > 2) ? &sdata[2] : NULL; 1808 uint16_t msg_len = (slen > 2) ? slen - 2 : 0; 1809 uint16_t code = ((int)sdata[0]) << 8 | ((int)sdata[1]); 1810 1811 if (code == DHCPV6_Success) 1812 continue; 1813 1814 dhcpv6_log_status_code(code, "IA_PREFIX", status_msg, msg_len); 1815 if (ret) *ret = 0; // renewal failed 1816 } else if (stype == DHCPV6_OPT_PD_EXCLUDE && slen > 2) { 1817 /* RFC 6603 ยง4.2 Prefix Exclude option */ 1818 uint8_t exclude_length = sdata[0]; 1819 if (exclude_length > 64) 1820 exclude_length = 64; 1821 1822 if (entry.length < 32 || exclude_length <= entry.length) { 1823 update_state = false; 1824 continue; 1825 } 1826 1827 uint8_t bytes_needed = ((exclude_length - entry.length - 1) / 8) + 1; 1828 if (slen <= bytes_needed) { 1829 update_state = false; 1830 continue; 1831 } 1832 1833 // this decrements through the ipaddr bytes masking against 1834 // the address in the option until byte 0, the option length field. 1835 uint32_t excluded_bits = 0; 1836 do { 1837 excluded_bits = excluded_bits << 8 | sdata[bytes_needed]; 1838 } while (--bytes_needed); 1839 1840 excluded_bits >>= 8 - ((exclude_length - entry.length) % 8); 1841 excluded_bits <<= 64 - exclude_length; 1842 1843 // Re-using router field to hold the prefix 1844 entry.router = entry.target; // base prefix 1845 entry.router.s6_addr32[1] |= htonl(excluded_bits); 1846 entry.exclusion_length = exclude_length; 1847 } 1848 } 1849 1850 if (update_state) { 1851 if (odhcp6c_update_entry(STATE_IA_PD, &entry, 0)) 1852 updated_IAs++; 1853 1854 info("%s/%d preferred %d valid %d", 1855 inet_ntop(AF_INET6, &entry.target, buf, sizeof(buf)), 1856 entry.length, entry.preferred , entry.valid); 1857 } 1858 1859 entry.priority = 0; 1860 memset(&entry.router, 0, sizeof(entry.router)); 1861 break; 1862 } 1863 case DHCPV6_OPT_IA_ADDR: { 1864 struct dhcpv6_ia_addr *addr = (void*)&odata[-DHCPV6_OPT_HDR_SIZE]; 1865 if (olen + DHCPV6_OPT_HDR_SIZE_U < sizeof(*addr)) 1866 continue; 1867 1868 entry.preferred = ntohl(addr->preferred); 1869 entry.valid = ntohl(addr->valid); 1870 1871 if (entry.preferred > entry.valid) 1872 continue; 1873 1874 entry.t1 = (t1 ? t1 : (entry.preferred != UINT32_MAX ? 0.5 * entry.preferred : UINT32_MAX)); 1875 entry.t2 = (t2 ? t2 : (entry.preferred != UINT32_MAX ? 0.8 * entry.preferred : UINT32_MAX)); 1876 if (entry.t1 > entry.t2) 1877 entry.t1 = entry.t2; 1878 1879 entry.length = 128; 1880 entry.target = addr->addr; 1881 uint16_t stype, slen; 1882 uint8_t *sdata; 1883 1884 bool update_state = true; 1885 dhcpv6_for_each_option(odata + sizeof(*addr) - DHCPV6_OPT_HDR_SIZE_U, 1886 odata + olen, stype, slen, sdata) { 1887 if (stype == DHCPV6_OPT_STATUS && slen >= 2) { 1888 /* RFC 8415 ยง21.6 1889 The status of any operations involving this IA Address is indicated 1890 in a Status Code option in the IAaddr-options field, as specified in 1891 Section 21.13. */ 1892 uint8_t *status_msg = (slen > 2) ? &sdata[2] : NULL; 1893 uint16_t msg_len = (slen > 2) ? slen - 2 : 0; 1894 uint16_t code = ((int)sdata[0]) << 8 | ((int)sdata[1]); 1895 1896 if (code == DHCPV6_Success) 1897 continue; 1898 1899 dhcpv6_log_status_code(code, "IA_ADDR", status_msg, msg_len); 1900 if (ret) *ret = 0; // renewal failed 1901 update_state = false; 1902 } 1903 } 1904 1905 if (update_state) { 1906 if (odhcp6c_update_entry(STATE_IA_NA, &entry, 0)) 1907 updated_IAs++; 1908 1909 info("%s preferred %d valid %d", 1910 inet_ntop(AF_INET6, &entry.target, buf, sizeof(buf)), 1911 entry.preferred , entry.valid); 1912 } 1913 break; 1914 } 1915 default: 1916 break; 1917 } 1918 } 1919 1920 return updated_IAs; 1921 } 1922 1923 static unsigned int dhcpv6_calc_refresh_timers(void) 1924 { 1925 struct odhcp6c_entry *pd_entries; 1926 struct odhcp6c_entry *ia_entries; 1927 size_t ia_na_entry_cnt, ia_pd_entry_cnt, i; 1928 size_t invalid_entries = 0; 1929 int64_t l_t1 = UINT32_MAX, l_t2 = UINT32_MAX, l_t3 = 0; 1930 1931 ia_entries = odhcp6c_get_state(STATE_IA_NA, &ia_na_entry_cnt); 1932 ia_na_entry_cnt /= sizeof(*ia_entries); 1933 1934 for (i = 0; i < ia_na_entry_cnt; i++) { 1935 /* Exclude invalid IA_NA entries */ 1936 if (!ia_entries[i].valid) { 1937 invalid_entries++; 1938 continue; 1939 } 1940 1941 if (ia_entries[i].t1 < l_t1) 1942 l_t1 = ia_entries[i].t1; 1943 1944 if (ia_entries[i].t2 < l_t2) 1945 l_t2 = ia_entries[i].t2; 1946 1947 if (ia_entries[i].valid > l_t3) 1948 l_t3 = ia_entries[i].valid; 1949 } 1950 1951 pd_entries = odhcp6c_get_state(STATE_IA_PD, &ia_pd_entry_cnt); 1952 ia_pd_entry_cnt /= sizeof(*pd_entries); 1953 1954 for (i = 0; i < ia_pd_entry_cnt; i++) { 1955 /* Exclude invalid IA_PD entries */ 1956 if (!pd_entries[i].valid) { 1957 invalid_entries++; 1958 continue; 1959 } 1960 1961 if (pd_entries[i].t1 < l_t1) 1962 l_t1 = pd_entries[i].t1; 1963 1964 if (pd_entries[i].t2 < l_t2) 1965 l_t2 = pd_entries[i].t2; 1966 1967 if (pd_entries[i].valid > l_t3) 1968 l_t3 = pd_entries[i].valid; 1969 } 1970 1971 if (ia_pd_entry_cnt + ia_na_entry_cnt - invalid_entries) { 1972 t1 = l_t1; 1973 t2 = l_t2; 1974 t3 = l_t3; 1975 1976 info("T1 %"PRId64"s, T2 %"PRId64"s, T3 %"PRId64"s", t1, t2, t3); 1977 } 1978 1979 return (unsigned int)(ia_pd_entry_cnt + ia_na_entry_cnt); 1980 } 1981 1982 static void dhcpv6_log_status_code(const uint16_t code, const char *scope, 1983 const void *status_msg, int len) 1984 { 1985 const char *src = status_msg; 1986 char buf[len + 3]; 1987 char *dst = buf; 1988 1989 if (len) { 1990 *dst++ = '('; 1991 while (len--) { 1992 *dst = isprint((unsigned char)*src) ? *src : '?'; 1993 src++; 1994 dst++; 1995 } 1996 *dst++ = ')'; 1997 } 1998 1999 *dst = 0; 2000 2001 warn("Server returned %s status '%s %s'", 2002 scope, dhcpv6_status_code_to_str(code), buf); 2003 } 2004 2005 static void dhcpv6_handle_status_code(const enum dhcpv6_msg orig, 2006 const uint16_t code, const void *status_msg, const int len, 2007 int *ret) 2008 { 2009 dhcpv6_log_status_code(code, "message", status_msg, len); 2010 2011 switch (code) { 2012 case DHCPV6_UnspecFail: 2013 // Generic failure 2014 *ret = 0; 2015 break; 2016 2017 case DHCPV6_UseMulticast: 2018 switch(orig) { 2019 case DHCPV6_MSG_REQUEST: 2020 case DHCPV6_MSG_RENEW: 2021 case DHCPV6_MSG_RELEASE: 2022 case DHCPV6_MSG_DECLINE: 2023 // Message needs to be retransmitted according to RFC3315 chapter 18.1.8 2024 server_addr = in6addr_any; 2025 *ret = 0; 2026 break; 2027 default: 2028 break; 2029 } 2030 break; 2031 2032 case DHCPV6_NoAddrsAvail: 2033 case DHCPV6_NoPrefixAvail: 2034 if (orig == DHCPV6_MSG_REQUEST) 2035 *ret = 0; // Failure 2036 break; 2037 2038 default: 2039 break; 2040 } 2041 } 2042 2043 static void dhcpv6_handle_ia_status_code(const enum dhcpv6_msg orig, 2044 const struct dhcpv6_ia_hdr *ia_hdr, const uint16_t code, 2045 const void *status_msg, const int len, 2046 bool handled_status_codes[_DHCPV6_Status_Max], int *ret) 2047 { 2048 dhcpv6_log_status_code(code, ntohs(ia_hdr->type) == DHCPV6_OPT_IA_NA ? 2049 "IA_NA" : "IA_PD", status_msg, len); 2050 2051 switch (code) { 2052 case DHCPV6_NoBinding: 2053 switch (orig) { 2054 case DHCPV6_MSG_RENEW: 2055 case DHCPV6_MSG_REBIND: 2056 if ((*ret > 0) && !handled_status_codes[code]) { 2057 dhcpv6_set_state(DHCPV6_REQUEST); 2058 *ret = -1; 2059 } 2060 break; 2061 2062 default: 2063 *ret = 0; 2064 break; 2065 } 2066 break; 2067 2068 case DHCPV6_NoAddrsAvail: 2069 case DHCPV6_NoPrefixAvail: 2070 break; 2071 2072 default: 2073 *ret = 0; 2074 break; 2075 } 2076 } 2077 2078 // Note this always takes ownership of cand->ia_na and cand->ia_pd 2079 static void dhcpv6_add_server_cand(const struct dhcpv6_server_cand *cand) 2080 { 2081 size_t cand_len, i; 2082 struct dhcpv6_server_cand *srv_candidates = odhcp6c_get_state(STATE_SERVER_CAND, &cand_len); 2083 2084 // Remove identical DUID server candidate 2085 for (i = 0; i < cand_len / sizeof(*srv_candidates); ++i) { 2086 if (cand->duid_len == srv_candidates[i].duid_len && 2087 !memcmp(cand->duid, srv_candidates[i].duid, cand->duid_len)) { 2088 free(srv_candidates[i].ia_na); 2089 free(srv_candidates[i].ia_pd); 2090 odhcp6c_remove_state(STATE_SERVER_CAND, i * sizeof(*srv_candidates), sizeof(*srv_candidates)); 2091 break; 2092 } 2093 } 2094 2095 for (i = 0, srv_candidates = odhcp6c_get_state(STATE_SERVER_CAND, &cand_len); 2096 i < cand_len / sizeof(*srv_candidates); ++i) { 2097 if (srv_candidates[i].preference < cand->preference) 2098 break; 2099 } 2100 2101 if (odhcp6c_insert_state(STATE_SERVER_CAND, i * sizeof(*srv_candidates), cand, sizeof(*cand))) { 2102 free(cand->ia_na); 2103 free(cand->ia_pd); 2104 } 2105 } 2106 2107 static void dhcpv6_clear_all_server_cand(void) 2108 { 2109 size_t cand_len, i; 2110 struct dhcpv6_server_cand *srv_candidates = odhcp6c_get_state(STATE_SERVER_CAND, &cand_len); 2111 2112 // Server candidates need deep delete for IA_NA/IA_PD 2113 for (i = 0; i < cand_len / sizeof(*srv_candidates); ++i) { 2114 free(srv_candidates[i].ia_na); 2115 free(srv_candidates[i].ia_pd); 2116 } 2117 odhcp6c_clear_state(STATE_SERVER_CAND); 2118 } 2119 2120 int dhcpv6_promote_server_cand(void) 2121 { 2122 size_t cand_len; 2123 struct dhcpv6_server_cand *cand = odhcp6c_get_state(STATE_SERVER_CAND, &cand_len); 2124 uint16_t hdr[2]; 2125 int ret = DHCPV6_STATELESS; 2126 2127 // Clear lingering candidate state info 2128 odhcp6c_clear_state(STATE_SERVER_ID); 2129 odhcp6c_clear_state(STATE_IA_NA); 2130 odhcp6c_clear_state(STATE_IA_PD); 2131 2132 if (!cand_len) 2133 return -1; 2134 2135 if (!cand->ia_pd_len && cand->has_noaddravail) { 2136 bool override = false; 2137 2138 if (na_mode == IA_MODE_TRY) { 2139 na_mode = IA_MODE_NONE; 2140 override = true; 2141 } 2142 2143 if (pd_mode == IA_MODE_TRY) { 2144 pd_mode = IA_MODE_NONE; 2145 override = true; 2146 } 2147 2148 if (override) { 2149 dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = cand->sol_max_rt; 2150 dhcpv6_retx[DHCPV6_MSG_INFO_REQ].max_timeo = cand->inf_max_rt; 2151 2152 return -1; 2153 } 2154 } 2155 2156 hdr[0] = htons(DHCPV6_OPT_SERVERID); 2157 hdr[1] = htons(cand->duid_len); 2158 odhcp6c_add_state(STATE_SERVER_ID, hdr, sizeof(hdr)); 2159 odhcp6c_add_state(STATE_SERVER_ID, cand->duid, cand->duid_len); 2160 accept_reconfig = cand->wants_reconfigure; 2161 memset(reconf_key, 0, sizeof(reconf_key)); 2162 2163 if (cand->ia_na_len) { 2164 odhcp6c_add_state(STATE_IA_NA, cand->ia_na, cand->ia_na_len); 2165 free(cand->ia_na); 2166 if (na_mode != IA_MODE_NONE) 2167 ret = DHCPV6_STATEFUL; 2168 } 2169 2170 if (cand->ia_pd_len) { 2171 odhcp6c_add_state(STATE_IA_PD, cand->ia_pd, cand->ia_pd_len); 2172 free(cand->ia_pd); 2173 if (pd_mode != IA_MODE_NONE) 2174 ret = DHCPV6_STATEFUL; 2175 } 2176 2177 dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = cand->sol_max_rt; 2178 dhcpv6_retx[DHCPV6_MSG_INFO_REQ].max_timeo = cand->inf_max_rt; 2179 2180 odhcp6c_remove_state(STATE_SERVER_CAND, 0, sizeof(*cand)); 2181 2182 return ret; 2183 } 2184 2185 int dhcpv6_send_request(enum dhcpv6_msg req_msg_type) 2186 { 2187 struct dhcpv6_retx *retx = &dhcpv6_retx[req_msg_type]; 2188 uint64_t current_milli_time = 0; 2189 2190 if (!retx->is_retransmit) { 2191 // Initial delay handling 2192 if (retx->max_delay) { 2193 if (retx->delay_msec == 0) { 2194 // Initial delay before starting the transaction 2195 retx->delay_msec = (dhcpv6_rand_delay((10000 * retx->max_delay) / 2) + (1000 * retx->max_delay) / 2); 2196 dhcpv6_set_state_timeout(retx->delay_msec); 2197 // Add current time to calculate absolute time 2198 retx->delay_msec += odhcp6c_get_milli_time(); 2199 return 1; 2200 } else { 2201 // Wait until delay expires 2202 current_milli_time = odhcp6c_get_milli_time(); 2203 if (current_milli_time < retx->delay_msec) { 2204 // Still waiting 2205 dhcpv6_set_state_timeout(retx->delay_msec - current_milli_time); 2206 return 1; 2207 } 2208 retx->delay_msec = 0; 2209 } 2210 } 2211 2212 retx->is_retransmit = true; 2213 retx->rc = 0; 2214 retx->timeout = UINT32_MAX; 2215 retx->reply_ret = -1; 2216 2217 if (req_msg_type == DHCPV6_MSG_UNKNOWN) 2218 retx->timeout = t1; 2219 else if (req_msg_type == DHCPV6_MSG_RENEW) 2220 retx->timeout = (t2 > t1) ? t2 - t1 : ((t1 == UINT32_MAX) ? UINT32_MAX : 0); 2221 else if (req_msg_type == DHCPV6_MSG_REBIND) 2222 retx->timeout = (t3 > t2) ? t3 - t2 : ((t2 == UINT32_MAX) ? UINT32_MAX : 0); 2223 2224 if (retx->timeout == 0) 2225 return -1; 2226 2227 notice("Starting %s transaction (timeout %"PRIu64"s, max rc %d)", 2228 retx->name, retx->timeout, retx->max_rc); 2229 2230 // Generate transaction ID 2231 if (req_msg_type != DHCPV6_MSG_UNKNOWN) { 2232 odhcp6c_random(retx->tr_id, sizeof(retx->tr_id)); 2233 } 2234 2235 // Record start time 2236 retx->start = odhcp6c_get_milli_time(); 2237 retx->round_start = retx->start; 2238 // Reset retransmission timeout initial value 2239 retx->rto = 0; 2240 } 2241 2242 if (retx->rto == 0) { 2243 int64_t delay = dhcpv6_rand_delay(retx->init_timeo * 1000); 2244 2245 // First RT MUST be strictly greater than IRT for solicit messages (RFC3313 17.1.2) 2246 while (req_msg_type == DHCPV6_MSG_SOLICIT && delay <= 0) 2247 delay = dhcpv6_rand_delay(retx->init_timeo * 1000); 2248 2249 // First timeout 2250 retx->rto = (retx->init_timeo * 1000 + delay); 2251 } else { 2252 // Exponential back-off with randomization to avoid synchronization 2253 retx->rto = (2 * retx->rto + dhcpv6_rand_delay(retx->rto)); 2254 } 2255 2256 if (retx->max_timeo && (retx->rto >= retx->max_timeo * 1000)) { 2257 // Cap to max timeout if set and exceeded 2258 retx->rto = retx->max_timeo * 1000 + 2259 dhcpv6_rand_delay(retx->max_timeo * 1000); 2260 } 2261 2262 // Calculate end for this round and elapsed time 2263 retx->round_end = retx->round_start + retx->rto; 2264 uint64_t elapsed = retx->round_start - retx->start; 2265 2266 // Don't wait too long if timeout differs from infinite 2267 if ((retx->timeout != UINT32_MAX) && (retx->round_end - retx->start > retx->timeout * 1000)) 2268 retx->round_end = retx->timeout * 1000 + retx->start; 2269 2270 dhcpv6_set_state_timeout(retx->round_end - odhcp6c_get_milli_time()); 2271 2272 // Built and send package 2273 switch (req_msg_type) { 2274 case DHCPV6_MSG_UNKNOWN: 2275 break; 2276 default: 2277 notice("Send %s message (elapsed %"PRIu64"ms, rc %d)", 2278 retx->name, elapsed, retx->rc); 2279 _o_fallthrough; 2280 case DHCPV6_MSG_SOLICIT: 2281 case DHCPV6_MSG_INFO_REQ: 2282 dhcpv6_send(req_msg_type, retx->tr_id, elapsed / 10); 2283 retx->rc++; 2284 } 2285 2286 if (dhcpv6_get_state() != DHCPV6_EXIT) 2287 dhcpv6_next_state(); 2288 2289 return 0; 2290 } 2291 2292 int dhcpv6_receive_response(enum dhcpv6_msg req_msg_type) 2293 { 2294 ssize_t len = -1; 2295 struct dhcpv6_retx *retx = &dhcpv6_retx[req_msg_type]; 2296 2297 uint8_t buf[1536]; 2298 union { 2299 struct cmsghdr hdr; 2300 uint8_t buf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; 2301 } cmsg_buf; 2302 2303 struct iovec iov = {buf, sizeof(buf)}; 2304 struct sockaddr_in6 addr; 2305 struct msghdr msg = {.msg_name = &addr, .msg_namelen = sizeof(addr), 2306 .msg_iov = &iov, .msg_iovlen = 1, .msg_control = cmsg_buf.buf, 2307 .msg_controllen = sizeof(cmsg_buf)}; 2308 struct in6_pktinfo *pktinfo = NULL; 2309 const struct dhcpv6_header *hdr = (const struct dhcpv6_header *)buf; 2310 2311 // Receive cycle 2312 len = recvmsg(sock, &msg, 0); 2313 if (len < 0) { 2314 error("Error occurred when reading the response of (%s) error(%s)", 2315 retx->name, strerror(errno)); 2316 return -1; 2317 } 2318 2319 for (struct cmsghdr *ch = CMSG_FIRSTHDR(&msg); ch != NULL; 2320 ch = CMSG_NXTHDR(&msg, ch)) { 2321 if (ch->cmsg_level == SOL_IPV6 && 2322 ch->cmsg_type == IPV6_PKTINFO) { 2323 pktinfo = (struct in6_pktinfo *)CMSG_DATA(ch); 2324 break; 2325 } 2326 } 2327 2328 if (pktinfo == NULL) { 2329 dhcpv6_stats.discarded_packets++; 2330 return -1; 2331 } 2332 2333 if (!dhcpv6_response_is_valid(buf, len, retx->tr_id, req_msg_type, 2334 &pktinfo->ipi6_addr)) { 2335 dhcpv6_stats.discarded_packets++; 2336 return -1; 2337 } 2338 2339 dhcpv6_inc_counter(hdr->msg_type); 2340 2341 uint8_t *opt = &buf[4]; 2342 uint8_t *opt_end = opt + len - DHCPV6_OPT_HDR_SIZE; 2343 retx->round_start = odhcp6c_get_milli_time(); 2344 uint64_t elapsed = retx->round_start - retx->start; 2345 2346 notice("Got a valid %s after %"PRIu64"ms", 2347 dhcpv6_msg_to_str(hdr->msg_type), elapsed); 2348 2349 if (retx->handler_reply) { 2350 retx->reply_ret = retx->handler_reply(req_msg_type, retx->rc, opt, opt_end, &addr); 2351 len = retx->reply_ret; 2352 } 2353 2354 // Clamp round end (Round Trip Time) to 1s max wait after receiving a valid response (in milliseconds) 2355 if (len > 0 && retx->round_end - retx->round_start > 1000) 2356 retx->round_end = 1000 + retx->round_start; 2357 2358 return retx->reply_ret; 2359 } 2360 2361 int dhcpv6_state_processing(enum dhcpv6_msg req_msg_type) 2362 { 2363 struct dhcpv6_retx *retx = &dhcpv6_retx[req_msg_type]; 2364 int ret = retx->reply_ret; 2365 retx->round_start = odhcp6c_get_milli_time(); 2366 uint64_t elapsed = retx->round_start - retx->start; 2367 2368 if (retx->round_start >= retx->round_end || ret >=0 ) { 2369 if (retx->handler_finish) 2370 ret = retx->handler_finish(); 2371 2372 if (ret < 0 && ((retx->timeout == UINT32_MAX) || (elapsed / 1000 < retx->timeout)) && 2373 (!retx->max_rc || retx->rc < retx->max_rc)) { 2374 retx->reply_ret = -1; 2375 dhcpv6_prev_state(); 2376 } else { 2377 retx->is_retransmit = false; 2378 dhcpv6_next_state(); 2379 } 2380 } else { 2381 // This sets the response polling timeout (round_end - round_start) in milliseconds 2382 dhcpv6_set_state_timeout(retx->round_end - retx->round_start); 2383 } 2384 2385 return ret; 2386 } 2387
This page was automatically generated by LXR 0.3.1. • OpenWrt