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 (req_msg_type != DHCPV6_MSG_SOLICIT && req_msg_type != DHCPV6_MSG_REQUEST && ia_na_len == 0) 961 iov[IOV_HDR_IA_NA].iov_len = 0; 962 963 if (na_mode == IA_MODE_NONE) 964 iov[IOV_HDR_IA_NA].iov_len = 0; 965 966 if ((req_msg_type != DHCPV6_MSG_SOLICIT && req_msg_type != DHCPV6_MSG_REQUEST) || 967 !(client_options & DHCPV6_ACCEPT_RECONFIGURE)) 968 iov[IOV_RECONF_ACCEPT].iov_len = 0; 969 970 if (!(client_options & DHCPV6_CLIENT_FQDN)) { 971 iov[IOV_FQDN].iov_len = 0; 972 } else { 973 switch (req_msg_type) { 974 /* RFC4704 ยง5 975 A client MUST only include the Client FQDN option in SOLICIT, 976 REQUEST, RENEW, or REBIND messages. 977 */ 978 case DHCPV6_MSG_SOLICIT: 979 case DHCPV6_MSG_REQUEST: 980 case DHCPV6_MSG_RENEW: 981 case DHCPV6_MSG_REBIND: 982 /* RFC4704 ยง6 983 Servers MUST only include a Client FQDN option in ADVERTISE and REPLY 984 messages... 985 case DHCPV6_MSG_ADVERT: 986 case DHCPV6_MSG_REPLY: 987 */ 988 /* leave FQDN as-is */ 989 break; 990 default: 991 /* remaining MSG types cannot contain client FQDN */ 992 iov[IOV_FQDN].iov_len = 0; 993 break; 994 } 995 } 996 997 struct sockaddr_in6 srv = {AF_INET6, htons(DHCPV6_SERVER_PORT), 998 0, ALL_DHCPV6_RELAYS, ifindex}; 999 struct msghdr msg = {.msg_name = &srv, .msg_namelen = sizeof(srv), 1000 .msg_iov = iov, .msg_iovlen = cnt}; 1001 1002 switch (req_msg_type) { 1003 case DHCPV6_MSG_REQUEST: 1004 case DHCPV6_MSG_RENEW: 1005 case DHCPV6_MSG_RELEASE: 1006 case DHCPV6_MSG_DECLINE: 1007 if (!IN6_IS_ADDR_UNSPECIFIED(&server_addr) && 1008 odhcp6c_addr_in_scope(&server_addr)) { 1009 srv.sin6_addr = server_addr; 1010 if (!IN6_IS_ADDR_LINKLOCAL(&server_addr)) 1011 srv.sin6_scope_id = 0; 1012 } 1013 break; 1014 default: 1015 break; 1016 } 1017 1018 if (sendmsg(sock, &msg, 0) < 0) { 1019 char in6_str[INET6_ADDRSTRLEN]; 1020 1021 error("Failed to send %s message to %s (%s)", 1022 dhcpv6_msg_to_str(req_msg_type), 1023 inet_ntop(AF_INET6, (const void *)&srv.sin6_addr, 1024 in6_str, sizeof(in6_str)), strerror(errno)); 1025 dhcpv6_stats.transmit_failures++; 1026 } else { 1027 dhcpv6_inc_counter(req_msg_type); 1028 } 1029 } 1030 1031 static int64_t dhcpv6_rand_delay(int64_t time) 1032 { 1033 int random; 1034 odhcp6c_random(&random, sizeof(random)); 1035 1036 return (time * ((int64_t)random % (config_dhcp->rand_factor*10LL))) / 10000LL; 1037 } 1038 1039 // Message validation checks according to RFC3315 chapter 15 1040 static bool dhcpv6_response_is_valid(const void *buf, ssize_t len, 1041 const uint8_t transaction[3], enum dhcpv6_msg req_msg_type, 1042 const struct in6_addr *daddr) 1043 { 1044 const struct dhcpv6_header *response_buf = buf; 1045 if (len < (ssize_t)sizeof(*response_buf) || memcmp(response_buf->tr_id, 1046 transaction, sizeof(response_buf->tr_id))) 1047 return false; // Invalid reply 1048 1049 if (req_msg_type == DHCPV6_MSG_SOLICIT) { 1050 if (response_buf->msg_type != DHCPV6_MSG_ADVERT && 1051 response_buf->msg_type != DHCPV6_MSG_REPLY) 1052 return false; 1053 } else if (req_msg_type == DHCPV6_MSG_UNKNOWN) { 1054 if (!accept_reconfig || response_buf->msg_type != DHCPV6_MSG_RECONF) 1055 return false; 1056 } else if (response_buf->msg_type != DHCPV6_MSG_REPLY) { 1057 return false; 1058 } 1059 1060 uint8_t *end = ((uint8_t*)buf) + len, *odata = NULL, 1061 rcmsg = DHCPV6_MSG_UNKNOWN; 1062 uint16_t otype, olen = UINT16_MAX; 1063 bool clientid_ok = false, serverid_ok = false, rcauth_ok = false, 1064 auth_present = false, ia_present = false, options_valid = true; 1065 1066 size_t client_id_len, server_id_len; 1067 void *client_id = odhcp6c_get_state(STATE_CLIENT_ID, &client_id_len); 1068 void *server_id = odhcp6c_get_state(STATE_SERVER_ID, &server_id_len); 1069 1070 dhcpv6_for_each_option(&response_buf[1], end, otype, olen, odata) { 1071 switch (otype) { 1072 case DHCPV6_OPT_CLIENTID: 1073 clientid_ok = (olen + DHCPV6_OPT_HDR_SIZE_U == client_id_len) && !memcmp( 1074 &odata[-DHCPV6_OPT_HDR_SIZE], client_id, client_id_len); 1075 break; 1076 1077 case DHCPV6_OPT_SERVERID: 1078 if (server_id_len) 1079 serverid_ok = (olen + DHCPV6_OPT_HDR_SIZE_U == server_id_len) && !memcmp( 1080 &odata[-DHCPV6_OPT_HDR_SIZE], server_id, server_id_len); 1081 else 1082 serverid_ok = true; 1083 break; 1084 1085 case DHCPV6_OPT_AUTH: 1086 struct dhcpv6_auth *r = (void*)&odata[-DHCPV6_OPT_HDR_SIZE]; 1087 if (auth_present) { 1088 options_valid = false; 1089 continue; 1090 } 1091 1092 auth_present = true; 1093 if (auth_protocol == AUTH_PROT_RKAP) { 1094 struct dhcpv6_auth_reconfigure *rkap = (void*)r->data; 1095 if (r->protocol != AUTH_PROT_RKAP || r->algorithm != AUTH_ALG_HMACMD5 || r->len != 28 || rkap->reconf_type != RKAP_TYPE_HMACMD5) 1096 continue; 1097 1098 md5_ctx_t md5; 1099 uint8_t serverhash[16], secretbytes[64]; 1100 uint32_t hash[4]; 1101 memcpy(serverhash, rkap->key, sizeof(serverhash)); 1102 memset(rkap->key, 0, sizeof(rkap->key)); 1103 1104 memset(secretbytes, 0, sizeof(secretbytes)); 1105 memcpy(secretbytes, reconf_key, sizeof(reconf_key)); 1106 1107 for (size_t i = 0; i < sizeof(secretbytes); ++i) 1108 secretbytes[i] ^= 0x36; 1109 1110 md5_begin(&md5); 1111 md5_hash(secretbytes, sizeof(secretbytes), &md5); 1112 md5_hash(buf, len, &md5); 1113 md5_end(hash, &md5); 1114 1115 for (size_t i = 0; i < sizeof(secretbytes); ++i) { 1116 secretbytes[i] ^= 0x36; 1117 secretbytes[i] ^= 0x5c; 1118 } 1119 1120 md5_begin(&md5); 1121 md5_hash(secretbytes, sizeof(secretbytes), &md5); 1122 md5_hash(hash, 16, &md5); 1123 md5_end(hash, &md5); 1124 1125 rcauth_ok = !memcmp(hash, serverhash, sizeof(hash)); 1126 } else if (auth_protocol == AUTH_PROT_TOKEN) { 1127 if (r->protocol != AUTH_PROT_TOKEN || r->algorithm != AUTH_ALG_TOKEN || r->len < 12) 1128 continue; 1129 1130 uint16_t token_len = r->len - 11; 1131 if (config_dhcp->auth_token == NULL || strlen(config_dhcp->auth_token) != token_len) 1132 continue; 1133 1134 rcauth_ok = !memcmp(r->data, config_dhcp->auth_token, token_len); 1135 } 1136 break; 1137 case DHCPV6_OPT_RECONF_MESSAGE: 1138 if (olen != 1) 1139 return false; 1140 rcmsg = odata[0]; 1141 break; 1142 1143 case DHCPV6_OPT_IA_PD: 1144 case DHCPV6_OPT_IA_NA: 1145 ia_present = true; 1146 if (olen < sizeof(struct dhcpv6_ia_hdr) - DHCPV6_OPT_HDR_SIZE) 1147 options_valid = false; 1148 break; 1149 1150 case DHCPV6_OPT_IA_ADDR: 1151 case DHCPV6_OPT_IA_PREFIX: 1152 case DHCPV6_OPT_PD_EXCLUDE: 1153 // Options are not allowed on global level 1154 options_valid = false; 1155 break; 1156 1157 default: 1158 break; 1159 } 1160 } 1161 1162 if (!options_valid || ((odata + olen) > end)) 1163 return false; 1164 1165 if (req_msg_type == DHCPV6_MSG_INFO_REQ && ia_present) 1166 return false; 1167 1168 if (response_buf->msg_type == DHCPV6_MSG_RECONF) { 1169 if ((rcmsg != DHCPV6_MSG_RENEW && rcmsg != DHCPV6_MSG_REBIND && rcmsg != DHCPV6_MSG_INFO_REQ) || 1170 (rcmsg == DHCPV6_MSG_INFO_REQ && ia_present) || 1171 !rcauth_ok || IN6_IS_ADDR_MULTICAST(daddr)) 1172 return false; 1173 } 1174 1175 return clientid_ok && serverid_ok; 1176 } 1177 1178 static int dhcpv6_handle_reconfigure(enum dhcpv6_msg orig, const int rc, 1179 const void *opt, const void *end, _o_unused const struct sockaddr_in6 *from) 1180 { 1181 uint16_t otype, olen; 1182 uint8_t *odata; 1183 enum dhcpv6_msg msg = DHCPV6_MSG_UNKNOWN; 1184 1185 dhcpv6_for_each_option(opt, end, otype, olen, odata) { 1186 if (otype == DHCPV6_OPT_RECONF_MESSAGE && olen == 1) { 1187 switch (odata[0]) { 1188 case DHCPV6_MSG_REBIND: 1189 if (t2 != UINT32_MAX) 1190 t2 = 0; 1191 _o_fallthrough; 1192 case DHCPV6_MSG_RENEW: 1193 if (t1 != UINT32_MAX) 1194 t1 = 0; 1195 _o_fallthrough; 1196 case DHCPV6_MSG_INFO_REQ: 1197 msg = odata[0]; 1198 notice("Need to respond with %s in reply to %s", 1199 dhcpv6_msg_to_str(msg), dhcpv6_msg_to_str(DHCPV6_MSG_RECONF)); 1200 break; 1201 1202 default: 1203 break; 1204 } 1205 } 1206 } 1207 1208 if (msg != DHCPV6_MSG_UNKNOWN) 1209 dhcpv6_handle_reply(orig, rc, NULL, NULL, NULL); 1210 1211 return (msg == DHCPV6_MSG_UNKNOWN? -1: (int)msg); 1212 } 1213 1214 // Collect all advertised servers 1215 static int dhcpv6_handle_advert(enum dhcpv6_msg orig, const int rc, 1216 const void *opt, const void *end, _o_unused const struct sockaddr_in6 *from) 1217 { 1218 uint16_t olen, otype; 1219 uint8_t *odata, pref = 0; 1220 struct dhcpv6_server_cand cand = {false, false, 0, 0, {0}, 1221 IN6ADDR_ANY_INIT, DHCPV6_SOL_MAX_RT, 1222 DHCPV6_INF_MAX_RT, NULL, NULL, 0, 0}; 1223 bool have_na = false; 1224 int have_pd = 0; 1225 1226 dhcpv6_for_each_option(opt, end, otype, olen, odata) { 1227 if (orig == DHCPV6_MSG_SOLICIT && 1228 ((otype == DHCPV6_OPT_IA_PD && pd_mode != IA_MODE_NONE) || 1229 (otype == DHCPV6_OPT_IA_NA && na_mode != IA_MODE_NONE)) && 1230 olen > sizeof(struct dhcpv6_ia_hdr) - DHCPV6_OPT_HDR_SIZE) { 1231 struct dhcpv6_ia_hdr *ia_hdr = (void*)(&odata[-DHCPV6_OPT_HDR_SIZE]); 1232 dhcpv6_parse_ia(ia_hdr, odata + olen + sizeof(*ia_hdr), NULL); 1233 } 1234 1235 switch (otype) { 1236 case DHCPV6_OPT_SERVERID: 1237 if (olen <= DHCPV6_DUID_MAX_LEN) { 1238 memcpy(cand.duid, odata, olen); 1239 cand.duid_len = olen; 1240 } 1241 break; 1242 1243 case DHCPV6_OPT_PREF: 1244 if (olen >= 1 && cand.preference >= 0) 1245 cand.preference = pref = odata[0]; 1246 break; 1247 1248 case DHCPV6_OPT_UNICAST: 1249 if (olen == sizeof(cand.server_addr) && 1250 !(client_options & DHCPV6_IGNORE_OPT_UNICAST)) 1251 cand.server_addr = *(struct in6_addr *)odata; 1252 break; 1253 1254 case DHCPV6_OPT_RECONF_ACCEPT: 1255 cand.wants_reconfigure = true; 1256 break; 1257 1258 case DHCPV6_OPT_SOL_MAX_RT: 1259 if (olen == 4) { 1260 uint32_t sol_max_rt = ntohl_unaligned(odata); 1261 if (sol_max_rt >= DHCPV6_SOL_MAX_RT_MIN && 1262 sol_max_rt <= DHCPV6_SOL_MAX_RT_MAX) 1263 cand.sol_max_rt = sol_max_rt; 1264 } 1265 break; 1266 1267 case DHCPV6_OPT_INF_MAX_RT: 1268 if (olen == 4) { 1269 uint32_t inf_max_rt = ntohl_unaligned(odata); 1270 if (inf_max_rt >= DHCPV6_INF_MAX_RT_MIN && 1271 inf_max_rt <= DHCPV6_INF_MAX_RT_MAX) 1272 cand.inf_max_rt = inf_max_rt; 1273 } 1274 break; 1275 1276 case DHCPV6_OPT_IA_PD: 1277 if (olen >= sizeof(struct dhcpv6_ia_hdr) - DHCPV6_OPT_HDR_SIZE) { 1278 struct dhcpv6_ia_hdr *h = (struct dhcpv6_ia_hdr *)&odata[-DHCPV6_OPT_HDR_SIZE]; 1279 uint8_t *oend = odata + olen, *d; 1280 1281 dhcpv6_for_each_option(&h[1], oend, otype, olen, d) { 1282 if (otype == DHCPV6_OPT_IA_PREFIX && 1283 olen >= sizeof(struct dhcpv6_ia_prefix) - DHCPV6_OPT_HDR_SIZE) { 1284 struct dhcpv6_ia_prefix *p = 1285 (struct dhcpv6_ia_prefix *)&d[-DHCPV6_OPT_HDR_SIZE]; 1286 have_pd = p->prefix; 1287 } 1288 } 1289 } 1290 break; 1291 1292 case DHCPV6_OPT_IA_NA: 1293 if (olen >= sizeof(struct dhcpv6_ia_hdr) - DHCPV6_OPT_HDR_SIZE) { 1294 struct dhcpv6_ia_hdr *h = (struct dhcpv6_ia_hdr *)&odata[-DHCPV6_OPT_HDR_SIZE]; 1295 uint8_t *oend = odata + olen, *d; 1296 1297 dhcpv6_for_each_option(&h[1], oend, otype, olen, d) { 1298 if (otype == DHCPV6_OPT_IA_ADDR && 1299 olen >= sizeof(struct dhcpv6_ia_addr) - DHCPV6_OPT_HDR_SIZE) 1300 have_na = true; 1301 } 1302 } 1303 break; 1304 1305 default: 1306 break; 1307 } 1308 } 1309 1310 if ((stateful_only_mode && !have_na && !have_pd) || 1311 (!have_na && na_mode == IA_MODE_FORCE) || 1312 (!have_pd && pd_mode == IA_MODE_FORCE)) { 1313 /* 1314 * RFC7083 states to process the SOL_MAX_RT and 1315 * INF_MAX_RT options even if the DHCPv6 server 1316 * did not propose any IA_NA and/or IA_PD 1317 */ 1318 dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = cand.sol_max_rt; 1319 dhcpv6_retx[DHCPV6_MSG_INFO_REQ].max_timeo = cand.inf_max_rt; 1320 return -1; 1321 } 1322 1323 if (na_mode != IA_MODE_NONE && !have_na) { 1324 cand.has_noaddravail = true; 1325 cand.preference -= 1000; 1326 } 1327 1328 if (pd_mode != IA_MODE_NONE) { 1329 if (have_pd) 1330 cand.preference += 2000 + (128 - have_pd); 1331 else 1332 cand.preference -= 2000; 1333 } 1334 1335 if (cand.duid_len > 0) { 1336 cand.ia_na = odhcp6c_move_state(STATE_IA_NA, &cand.ia_na_len); 1337 cand.ia_pd = odhcp6c_move_state(STATE_IA_PD, &cand.ia_pd_len); 1338 dhcpv6_add_server_cand(&cand); 1339 } 1340 1341 return (rc > 1 || (pref == 255 && cand.preference > 0)) ? 1 : -1; 1342 } 1343 1344 static int dhcpv6_commit_advert(void) 1345 { 1346 return dhcpv6_promote_server_cand(); 1347 } 1348 1349 static int dhcpv6_handle_rebind_reply(enum dhcpv6_msg orig, const int rc, 1350 const void *opt, const void *end, const struct sockaddr_in6 *from) 1351 { 1352 dhcpv6_handle_advert(orig, rc, opt, end, from); 1353 if (dhcpv6_commit_advert() < 0) 1354 return -1; 1355 1356 return dhcpv6_handle_reply(orig, rc, opt, end, from); 1357 } 1358 1359 static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _o_unused const int rc, 1360 const void *opt, const void *end, const struct sockaddr_in6 *from) 1361 { 1362 uint8_t *odata; 1363 uint16_t otype, olen; 1364 uint32_t refresh = config_dhcp->irt_default; 1365 int ret = 1; 1366 unsigned int state_IAs; 1367 unsigned int updated_IAs = 0; 1368 bool handled_status_codes[_DHCPV6_Status_Max] = { false, }; 1369 1370 odhcp6c_expire(true); 1371 1372 if (orig == DHCPV6_MSG_UNKNOWN) { 1373 static time_t last_update = 0; 1374 time_t now = odhcp6c_get_milli_time() / 1000; 1375 1376 uint32_t elapsed = (last_update > 0) ? now - last_update : 0; 1377 last_update = now; 1378 1379 if (t1 != UINT32_MAX) 1380 t1 -= elapsed; 1381 1382 if (t2 != UINT32_MAX) 1383 t2 -= elapsed; 1384 1385 if (t3 != UINT32_MAX) 1386 t3 -= elapsed; 1387 1388 if (t1 < 0) 1389 t1 = 0; 1390 1391 if (t2 < 0) 1392 t2 = 0; 1393 1394 if (t3 < 0) 1395 t3 = 0; 1396 } 1397 1398 if (orig == DHCPV6_MSG_REQUEST && !odhcp6c_is_bound()) { 1399 // Delete NA and PD we have in the state from the Advert 1400 odhcp6c_clear_state(STATE_IA_NA); 1401 odhcp6c_clear_state(STATE_IA_PD); 1402 } 1403 1404 if (opt) { 1405 odhcp6c_clear_state(STATE_DNS); 1406 odhcp6c_clear_state(STATE_SEARCH); 1407 odhcp6c_clear_state(STATE_SNTP_IP); 1408 odhcp6c_clear_state(STATE_NTP_IP); 1409 odhcp6c_clear_state(STATE_NTP_FQDN); 1410 odhcp6c_clear_state(STATE_SIP_IP); 1411 odhcp6c_clear_state(STATE_SIP_FQDN); 1412 odhcp6c_clear_state(STATE_AFTR_NAME); 1413 odhcp6c_clear_state(STATE_S46_MAPT); 1414 odhcp6c_clear_state(STATE_S46_MAPE); 1415 odhcp6c_clear_state(STATE_S46_LW); 1416 odhcp6c_clear_state(STATE_CAPT_PORT_DHCPV6); 1417 odhcp6c_clear_state(STATE_PASSTHRU); 1418 odhcp6c_clear_state(STATE_CUSTOM_OPTS); 1419 1420 // Parse and find all matching IAs 1421 dhcpv6_for_each_option(opt, end, otype, olen, odata) { 1422 struct odhcp6c_opt *dopt = odhcp6c_find_opt(otype); 1423 1424 switch (otype) { 1425 1426 case DHCPV6_OPT_IA_NA: 1427 case DHCPV6_OPT_IA_PD: 1428 if (olen > sizeof(struct dhcpv6_ia_hdr) - DHCPV6_OPT_HDR_SIZE) { 1429 struct dhcpv6_ia_hdr *ia_hdr = (void*)(&odata[-DHCPV6_OPT_HDR_SIZE]); 1430 1431 if ((na_mode == IA_MODE_NONE && otype == DHCPV6_OPT_IA_NA) || 1432 (pd_mode == IA_MODE_NONE && otype == DHCPV6_OPT_IA_PD)) 1433 continue; 1434 1435 // Test ID 1436 if (ia_hdr->iaid != htonl(ifname_hash_iaid) && otype == DHCPV6_OPT_IA_NA) 1437 continue; 1438 1439 uint16_t code = DHCPV6_Success; 1440 uint16_t stype, slen; 1441 uint8_t *sdata; 1442 bool dhcpv6_successful_once = false; 1443 // Get and handle status code 1444 dhcpv6_for_each_option(&ia_hdr[1], odata + olen, stype, slen, sdata) { 1445 if (stype == DHCPV6_OPT_STATUS && slen >= 2) { 1446 uint8_t *mdata = (slen > 2) ? &sdata[2] : NULL; 1447 uint16_t mlen = (slen > 2) ? slen - 2 : 0; 1448 1449 code = ((int)sdata[0] << 8) | ((int)sdata[1]); 1450 1451 if (code == DHCPV6_Success) { 1452 dhcpv6_successful_once = true; 1453 continue; 1454 } 1455 1456 dhcpv6_handle_ia_status_code(orig, ia_hdr, 1457 code, mdata, mlen, handled_status_codes, &ret); 1458 1459 break; 1460 } 1461 } 1462 1463 if (!dhcpv6_successful_once && code != DHCPV6_Success) 1464 continue; 1465 1466 updated_IAs += dhcpv6_parse_ia(ia_hdr, odata + olen, &ret); 1467 } 1468 break; 1469 1470 case DHCPV6_OPT_UNICAST: 1471 if (olen == sizeof(server_addr) && 1472 !(client_options & DHCPV6_IGNORE_OPT_UNICAST)) 1473 server_addr = *(struct in6_addr *)odata; 1474 break; 1475 1476 case DHCPV6_OPT_STATUS: 1477 if (olen >= 2) { 1478 uint8_t *mdata = (olen > 2) ? &odata[2] : NULL; 1479 uint16_t mlen = (olen > 2) ? olen - 2 : 0; 1480 uint16_t code = ((int)odata[0] << 8) | ((int)odata[1]); 1481 1482 dhcpv6_handle_status_code(orig, code, mdata, mlen, &ret); 1483 } 1484 break; 1485 1486 case DHCPV6_OPT_DNS_SERVERS: 1487 if (olen % sizeof(struct in6_addr) == 0) 1488 odhcp6c_add_state(STATE_DNS, odata, olen); 1489 break; 1490 1491 case DHCPV6_OPT_DNS_DOMAIN: 1492 odhcp6c_add_state(STATE_SEARCH, odata, olen); 1493 break; 1494 1495 case DHCPV6_OPT_SNTP_SERVERS: 1496 if (olen % sizeof(struct in6_addr) == 0) 1497 odhcp6c_add_state(STATE_SNTP_IP, odata, olen); 1498 break; 1499 1500 case DHCPV6_OPT_NTP_SERVER: 1501 uint16_t stype, slen; 1502 uint8_t *sdata; 1503 // Test status and bail if error 1504 dhcpv6_for_each_option(odata, odata + olen, 1505 stype, slen, sdata) { 1506 if (slen == sizeof(struct in6_addr) && (stype == NTP_MC_ADDR || stype == NTP_SRV_ADDR)) 1507 odhcp6c_add_state(STATE_NTP_IP, sdata, slen); 1508 else if (slen > 0 && stype == NTP_SRV_FQDN) 1509 odhcp6c_add_state(STATE_NTP_FQDN, sdata, slen); 1510 } 1511 break; 1512 1513 case DHCPV6_OPT_SIP_SERVER_A: 1514 if (olen == sizeof(struct in6_addr)) 1515 odhcp6c_add_state(STATE_SIP_IP, odata, olen); 1516 break; 1517 1518 case DHCPV6_OPT_SIP_SERVER_D: 1519 odhcp6c_add_state(STATE_SIP_FQDN, odata, olen); 1520 break; 1521 1522 case DHCPV6_OPT_INFO_REFRESH: 1523 if (olen == 4) 1524 refresh = ntohl_unaligned(odata); 1525 break; 1526 1527 case DHCPV6_OPT_AUTH: 1528 struct dhcpv6_auth *r = (void*)&odata[-DHCPV6_OPT_HDR_SIZE]; 1529 if (auth_protocol == AUTH_PROT_RKAP) { 1530 struct dhcpv6_auth_reconfigure *rkap = (void*)r->data; 1531 if (r->protocol == AUTH_PROT_RKAP || r->algorithm == AUTH_ALG_HMACMD5 || 1532 r->len == 28 || rkap->reconf_type == RKAP_TYPE_KEY) 1533 memcpy(reconf_key, rkap->key, sizeof(rkap->key)); 1534 } 1535 break; 1536 1537 case DHCPV6_OPT_AFTR_NAME: 1538 if (olen > 3) { 1539 size_t cur_len; 1540 odhcp6c_get_state(STATE_AFTR_NAME, &cur_len); 1541 if (cur_len == 0) 1542 odhcp6c_add_state(STATE_AFTR_NAME, odata, olen); 1543 } 1544 break; 1545 1546 case DHCPV6_OPT_SOL_MAX_RT: 1547 if (olen == 4) { 1548 uint32_t sol_max_rt = ntohl_unaligned(odata); 1549 if (sol_max_rt >= DHCPV6_SOL_MAX_RT_MIN && sol_max_rt <= DHCPV6_SOL_MAX_RT_MAX) 1550 dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = sol_max_rt; 1551 } 1552 break; 1553 1554 case DHCPV6_OPT_INF_MAX_RT: 1555 if (olen == 4) { 1556 uint32_t inf_max_rt = ntohl_unaligned(odata); 1557 if (inf_max_rt >= DHCPV6_INF_MAX_RT_MIN && inf_max_rt <= DHCPV6_INF_MAX_RT_MAX) 1558 dhcpv6_retx[DHCPV6_MSG_INFO_REQ].max_timeo = inf_max_rt; 1559 } 1560 break; 1561 1562 case DHCPV6_OPT_S46_CONT_MAPT: 1563 odhcp6c_add_state(STATE_S46_MAPT, odata, olen); 1564 break; 1565 1566 case DHCPV6_OPT_S46_CONT_MAPE: 1567 size_t mape_len; 1568 odhcp6c_get_state(STATE_S46_MAPE, &mape_len); 1569 if (mape_len == 0) 1570 odhcp6c_add_state(STATE_S46_MAPE, odata, olen); 1571 break; 1572 1573 case DHCPV6_OPT_S46_CONT_LW: 1574 odhcp6c_add_state(STATE_S46_LW, odata, olen); 1575 break; 1576 1577 case DHCPV6_OPT_CAPTIVE_PORTAL: /* RFC8910 ยง2.2 */ 1578 size_t ref_len = sizeof(URN_IETF_CAPT_PORT_UNRESTR) - 1; 1579 /* RFC8910 ยง2: 1580 * Networks with no captive portals may explicitly indicate this 1581 * condition by using this option with the IANA-assigned URI for 1582 * this purpose. Clients observing the URI value ... may forego 1583 * time-consuming forms of captive portal detection. */ 1584 if (memcmp(odata, URN_IETF_CAPT_PORT_UNRESTR, ref_len)) { 1585 /* RFC8910 ยง2.2: 1586 * Note that the URI parameter is not null terminated. 1587 * Allocate new buffer including room for '\0' */ 1588 size_t uri_len = olen + 1; 1589 uint8_t *copy = malloc(uri_len); 1590 if (!copy) 1591 continue; 1592 memcpy(copy, odata, olen); 1593 copy[uri_len] = '\0'; 1594 odhcp6c_add_state(STATE_CAPT_PORT_DHCPV6, odata, olen); 1595 free(copy); 1596 } 1597 break; 1598 1599 default: 1600 odhcp6c_add_state(STATE_CUSTOM_OPTS, &odata[-DHCPV6_OPT_HDR_SIZE], olen + DHCPV6_OPT_HDR_SIZE); 1601 break; 1602 } 1603 1604 // Pass-through unless explicitly disabled, for every option 1605 if (!dopt || !(dopt->flags & OPT_NO_PASSTHRU)) 1606 odhcp6c_add_state(STATE_PASSTHRU, &odata[-DHCPV6_OPT_HDR_SIZE], olen + DHCPV6_OPT_HDR_SIZE); 1607 } 1608 } 1609 1610 // Bail out if fatal status code was received 1611 if (ret <= 0) 1612 return ret; 1613 1614 switch (orig) { 1615 case DHCPV6_MSG_REQUEST: 1616 case DHCPV6_MSG_REBIND: 1617 case DHCPV6_MSG_RENEW: 1618 state_IAs = dhcpv6_calc_refresh_timers(); 1619 // In case there're no state IA entries 1620 // keep sending request/renew/rebind messages 1621 if (state_IAs == 0) { 1622 ret = 0; 1623 break; 1624 } 1625 1626 switch (orig) { 1627 case DHCPV6_MSG_REQUEST: 1628 // All server candidates can be cleared if not yet bound 1629 if (!odhcp6c_is_bound()) 1630 dhcpv6_clear_all_server_cand(); 1631 1632 odhcp6c_clear_state(STATE_SERVER_ADDR); 1633 odhcp6c_add_state(STATE_SERVER_ADDR, &from->sin6_addr, sizeof(struct in6_addr)); 1634 break; 1635 case DHCPV6_MSG_RENEW: 1636 // Send further renews if T1 is not set and if 1637 // there're IAs which were not in the Reply message 1638 if (!t1 && state_IAs != updated_IAs) { 1639 if (updated_IAs) 1640 // Publish updates 1641 notify_state_change("updated", 0, false); 1642 1643 /* 1644 * RFC8415 states following in ยง18.2.10.1 : 1645 * Sends a Renew/Rebind if any of the IAs are not in the Reply 1646 * message, but as this likely indicates that the server that 1647 * responded does not support that IA type, sending immediately is 1648 * unlikely to produce a different result. Therefore, the client 1649 * MUST rate-limit its transmissions (see Section 14.1) and MAY just 1650 * wait for the normal retransmission time (as if the Reply message 1651 * had not been received). The client continues to use other 1652 * bindings for which the server did return information 1653 */ 1654 ret = -1; 1655 } 1656 break; 1657 case DHCPV6_MSG_REBIND: 1658 odhcp6c_clear_state(STATE_SERVER_ADDR); 1659 odhcp6c_add_state(STATE_SERVER_ADDR, &from->sin6_addr, sizeof(struct in6_addr)); 1660 1661 // Send further rebinds if T1 and T2 is not set and if 1662 // there're IAs which were not in the Reply message 1663 if (!t1 && !t2 && state_IAs != updated_IAs) { 1664 if (updated_IAs) 1665 // Publish updates 1666 notify_state_change("updated", 0, false); 1667 1668 /* 1669 * RFC8415 states following in ยง18.2.10.1 : 1670 * Sends a Renew/Rebind if any of the IAs are not in the Reply 1671 * message, but as this likely indicates that the server that 1672 * responded does not support that IA type, sending immediately is 1673 * unlikely to produce a different result. Therefore, the client 1674 * MUST rate-limit its transmissions (see Section 14.1) and MAY just 1675 * wait for the normal retransmission time (as if the Reply message 1676 * had not been received). The client continues to use other 1677 * bindings for which the server did return information 1678 */ 1679 ret = -1; 1680 } 1681 break; 1682 1683 default: 1684 break; 1685 } 1686 break; 1687 1688 case DHCPV6_MSG_INFO_REQ: 1689 // All server candidates can be cleared if not yet bound 1690 if (!odhcp6c_is_bound()) 1691 dhcpv6_clear_all_server_cand(); 1692 1693 odhcp6c_clear_state(STATE_SERVER_ADDR); 1694 odhcp6c_add_state(STATE_SERVER_ADDR, &from->sin6_addr, sizeof(struct in6_addr)); 1695 1696 t1 = (refresh < config_dhcp->irt_min) ? config_dhcp->irt_min : refresh; 1697 break; 1698 1699 default: 1700 break; 1701 } 1702 1703 return ret; 1704 } 1705 1706 static unsigned int dhcpv6_parse_ia(void *opt, void *end, int *ret) 1707 { 1708 struct dhcpv6_ia_hdr *ia_hdr = (struct dhcpv6_ia_hdr *)opt; 1709 unsigned int updated_IAs = 0; 1710 uint32_t t1, t2; 1711 uint16_t otype, olen; 1712 uint8_t *odata; 1713 char buf[INET6_ADDRSTRLEN]; 1714 1715 t1 = ntohl(ia_hdr->t1); 1716 t2 = ntohl(ia_hdr->t2); 1717 1718 /* RFC 8415 ยง21.4 1719 If a client receives an IA_NA with T1 greater than T2 and both T1 and 1720 T2 are greater than 0, the client discards the IA_NA option and 1721 processes the remainder of the message as though the server had not 1722 included the invalid IA_NA option. */ 1723 if (t1 > t2 && t1 > 0 && t2 > 0) 1724 return 0; 1725 1726 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); 1727 1728 // Update address IA 1729 dhcpv6_for_each_option(&ia_hdr[1], end, otype, olen, odata) { 1730 struct odhcp6c_entry entry = { 1731 .router = IN6ADDR_ANY_INIT, 1732 .auxlen = 0, 1733 .length = 0, 1734 .ra_flags = 0, 1735 .exclusion_length = 0, 1736 .target = IN6ADDR_ANY_INIT, 1737 .priority = 0, 1738 .valid = 0, 1739 .preferred = 0, 1740 .t1 = 0, 1741 .t2 = 0, 1742 .iaid = ia_hdr->iaid, 1743 }; 1744 1745 switch (otype) { 1746 case DHCPV6_OPT_IA_PREFIX: { 1747 struct dhcpv6_ia_prefix *prefix = (void*)&odata[-DHCPV6_OPT_HDR_SIZE]; 1748 if (olen + DHCPV6_OPT_HDR_SIZE_U < sizeof(*prefix)) 1749 continue; 1750 1751 entry.valid = ntohl(prefix->valid); 1752 entry.preferred = ntohl(prefix->preferred); 1753 1754 if (entry.preferred > entry.valid) 1755 continue; 1756 1757 /* RFC 8415 ยง21.21 1758 Recommended values for T1 and T2 are 0.5 and 0.8 times the 1759 shortest preferred lifetime of the prefixes in the IA_PD that the 1760 server is willing to extend. */ 1761 entry.t1 = (t1 ? t1 : (entry.preferred != UINT32_MAX ? 0.5 * entry.preferred : UINT32_MAX)); 1762 entry.t2 = (t2 ? t2 : (entry.preferred != UINT32_MAX ? 0.8 * entry.preferred : UINT32_MAX)); 1763 if (entry.t1 > entry.t2) 1764 entry.t1 = entry.t2; 1765 1766 entry.length = prefix->prefix; 1767 entry.target = prefix->addr; 1768 uint16_t stype, slen; 1769 uint8_t *sdata; 1770 1771 // Parse sub-options for PD-exclude or error status code 1772 bool update_state = true; 1773 dhcpv6_for_each_option(odata + sizeof(*prefix) - DHCPV6_OPT_HDR_SIZE, 1774 odata + olen, stype, slen, sdata) { 1775 if (stype == DHCPV6_OPT_STATUS && slen >= 2) { 1776 /* RFC 8415 ยง21.22 1777 The status of any operations involving this IA Prefix option is 1778 indicated in a Status Code option (see Section 21.13) in the 1779 IAprefix-options field. */ 1780 uint8_t *status_msg = (slen > 2) ? &sdata[2] : NULL; 1781 uint16_t msg_len = (slen > 2) ? slen - 2 : 0; 1782 uint16_t code = ((int)sdata[0]) << 8 | ((int)sdata[1]); 1783 1784 if (code == DHCPV6_Success) 1785 continue; 1786 1787 dhcpv6_log_status_code(code, "IA_PREFIX", status_msg, msg_len); 1788 if (ret) *ret = 0; // renewal failed 1789 } else if (stype == DHCPV6_OPT_PD_EXCLUDE && slen > 2) { 1790 /* RFC 6603 ยง4.2 Prefix Exclude option */ 1791 uint8_t exclude_length = sdata[0]; 1792 if (exclude_length > 64) 1793 exclude_length = 64; 1794 1795 if (entry.length < 32 || exclude_length <= entry.length) { 1796 update_state = false; 1797 continue; 1798 } 1799 1800 uint8_t bytes_needed = ((exclude_length - entry.length - 1) / 8) + 1; 1801 if (slen <= bytes_needed) { 1802 update_state = false; 1803 continue; 1804 } 1805 1806 // this decrements through the ipaddr bytes masking against 1807 // the address in the option until byte 0, the option length field. 1808 uint32_t excluded_bits = 0; 1809 do { 1810 excluded_bits = excluded_bits << 8 | sdata[bytes_needed]; 1811 } while (--bytes_needed); 1812 1813 excluded_bits >>= 8 - ((exclude_length - entry.length) % 8); 1814 excluded_bits <<= 64 - exclude_length; 1815 1816 // Re-using router field to hold the prefix 1817 entry.router = entry.target; // base prefix 1818 entry.router.s6_addr32[1] |= htonl(excluded_bits); 1819 entry.exclusion_length = exclude_length; 1820 } 1821 } 1822 1823 if (update_state) { 1824 if (odhcp6c_update_entry(STATE_IA_PD, &entry, 0)) 1825 updated_IAs++; 1826 1827 info("%s/%d preferred %d valid %d", 1828 inet_ntop(AF_INET6, &entry.target, buf, sizeof(buf)), 1829 entry.length, entry.preferred , entry.valid); 1830 } 1831 1832 entry.priority = 0; 1833 memset(&entry.router, 0, sizeof(entry.router)); 1834 break; 1835 } 1836 case DHCPV6_OPT_IA_ADDR: { 1837 struct dhcpv6_ia_addr *addr = (void*)&odata[-DHCPV6_OPT_HDR_SIZE]; 1838 if (olen + DHCPV6_OPT_HDR_SIZE_U < sizeof(*addr)) 1839 continue; 1840 1841 entry.preferred = ntohl(addr->preferred); 1842 entry.valid = ntohl(addr->valid); 1843 1844 if (entry.preferred > entry.valid) 1845 continue; 1846 1847 entry.t1 = (t1 ? t1 : (entry.preferred != UINT32_MAX ? 0.5 * entry.preferred : UINT32_MAX)); 1848 entry.t2 = (t2 ? t2 : (entry.preferred != UINT32_MAX ? 0.8 * entry.preferred : UINT32_MAX)); 1849 if (entry.t1 > entry.t2) 1850 entry.t1 = entry.t2; 1851 1852 entry.length = 128; 1853 entry.target = addr->addr; 1854 uint16_t stype, slen; 1855 uint8_t *sdata; 1856 1857 bool update_state = true; 1858 dhcpv6_for_each_option(odata + sizeof(*addr) - DHCPV6_OPT_HDR_SIZE_U, 1859 odata + olen, stype, slen, sdata) { 1860 if (stype == DHCPV6_OPT_STATUS && slen >= 2) { 1861 /* RFC 8415 ยง21.6 1862 The status of any operations involving this IA Address is indicated 1863 in a Status Code option in the IAaddr-options field, as specified in 1864 Section 21.13. */ 1865 uint8_t *status_msg = (slen > 2) ? &sdata[2] : NULL; 1866 uint16_t msg_len = (slen > 2) ? slen - 2 : 0; 1867 uint16_t code = ((int)sdata[0]) << 8 | ((int)sdata[1]); 1868 1869 if (code == DHCPV6_Success) 1870 continue; 1871 1872 dhcpv6_log_status_code(code, "IA_ADDR", status_msg, msg_len); 1873 if (ret) *ret = 0; // renewal failed 1874 update_state = false; 1875 } 1876 } 1877 1878 if (update_state) { 1879 if (odhcp6c_update_entry(STATE_IA_NA, &entry, 0)) 1880 updated_IAs++; 1881 1882 info("%s preferred %d valid %d", 1883 inet_ntop(AF_INET6, &entry.target, buf, sizeof(buf)), 1884 entry.preferred , entry.valid); 1885 } 1886 break; 1887 } 1888 default: 1889 break; 1890 } 1891 } 1892 1893 return updated_IAs; 1894 } 1895 1896 static unsigned int dhcpv6_calc_refresh_timers(void) 1897 { 1898 struct odhcp6c_entry *pd_entries; 1899 struct odhcp6c_entry *ia_entries; 1900 size_t ia_na_entry_cnt, ia_pd_entry_cnt, i; 1901 size_t invalid_entries = 0; 1902 int64_t l_t1 = UINT32_MAX, l_t2 = UINT32_MAX, l_t3 = 0; 1903 1904 ia_entries = odhcp6c_get_state(STATE_IA_NA, &ia_na_entry_cnt); 1905 ia_na_entry_cnt /= sizeof(*ia_entries); 1906 1907 for (i = 0; i < ia_na_entry_cnt; i++) { 1908 /* Exclude invalid IA_NA entries */ 1909 if (!ia_entries[i].valid) { 1910 invalid_entries++; 1911 continue; 1912 } 1913 1914 if (ia_entries[i].t1 < l_t1) 1915 l_t1 = ia_entries[i].t1; 1916 1917 if (ia_entries[i].t2 < l_t2) 1918 l_t2 = ia_entries[i].t2; 1919 1920 if (ia_entries[i].valid > l_t3) 1921 l_t3 = ia_entries[i].valid; 1922 } 1923 1924 pd_entries = odhcp6c_get_state(STATE_IA_PD, &ia_pd_entry_cnt); 1925 ia_pd_entry_cnt /= sizeof(*pd_entries); 1926 1927 for (i = 0; i < ia_pd_entry_cnt; i++) { 1928 /* Exclude invalid IA_PD entries */ 1929 if (!pd_entries[i].valid) { 1930 invalid_entries++; 1931 continue; 1932 } 1933 1934 if (pd_entries[i].t1 < l_t1) 1935 l_t1 = pd_entries[i].t1; 1936 1937 if (pd_entries[i].t2 < l_t2) 1938 l_t2 = pd_entries[i].t2; 1939 1940 if (pd_entries[i].valid > l_t3) 1941 l_t3 = pd_entries[i].valid; 1942 } 1943 1944 if (ia_pd_entry_cnt + ia_na_entry_cnt - invalid_entries) { 1945 t1 = l_t1; 1946 t2 = l_t2; 1947 t3 = l_t3; 1948 1949 info("T1 %"PRId64"s, T2 %"PRId64"s, T3 %"PRId64"s", t1, t2, t3); 1950 } 1951 1952 return (unsigned int)(ia_pd_entry_cnt + ia_na_entry_cnt); 1953 } 1954 1955 static void dhcpv6_log_status_code(const uint16_t code, const char *scope, 1956 const void *status_msg, int len) 1957 { 1958 const char *src = status_msg; 1959 char buf[len + 3]; 1960 char *dst = buf; 1961 1962 if (len) { 1963 *dst++ = '('; 1964 while (len--) { 1965 *dst = isprint((unsigned char)*src) ? *src : '?'; 1966 src++; 1967 dst++; 1968 } 1969 *dst++ = ')'; 1970 } 1971 1972 *dst = 0; 1973 1974 warn("Server returned %s status '%s %s'", 1975 scope, dhcpv6_status_code_to_str(code), buf); 1976 } 1977 1978 static void dhcpv6_handle_status_code(const enum dhcpv6_msg orig, 1979 const uint16_t code, const void *status_msg, const int len, 1980 int *ret) 1981 { 1982 dhcpv6_log_status_code(code, "message", status_msg, len); 1983 1984 switch (code) { 1985 case DHCPV6_UnspecFail: 1986 // Generic failure 1987 *ret = 0; 1988 break; 1989 1990 case DHCPV6_UseMulticast: 1991 switch(orig) { 1992 case DHCPV6_MSG_REQUEST: 1993 case DHCPV6_MSG_RENEW: 1994 case DHCPV6_MSG_RELEASE: 1995 case DHCPV6_MSG_DECLINE: 1996 // Message needs to be retransmitted according to RFC3315 chapter 18.1.8 1997 server_addr = in6addr_any; 1998 *ret = 0; 1999 break; 2000 default: 2001 break; 2002 } 2003 break; 2004 2005 case DHCPV6_NoAddrsAvail: 2006 case DHCPV6_NoPrefixAvail: 2007 if (orig == DHCPV6_MSG_REQUEST) 2008 *ret = 0; // Failure 2009 break; 2010 2011 default: 2012 break; 2013 } 2014 } 2015 2016 static void dhcpv6_handle_ia_status_code(const enum dhcpv6_msg orig, 2017 const struct dhcpv6_ia_hdr *ia_hdr, const uint16_t code, 2018 const void *status_msg, const int len, 2019 bool handled_status_codes[_DHCPV6_Status_Max], int *ret) 2020 { 2021 dhcpv6_log_status_code(code, ntohs(ia_hdr->type) == DHCPV6_OPT_IA_NA ? 2022 "IA_NA" : "IA_PD", status_msg, len); 2023 2024 switch (code) { 2025 case DHCPV6_NoBinding: 2026 switch (orig) { 2027 case DHCPV6_MSG_RENEW: 2028 case DHCPV6_MSG_REBIND: 2029 if ((*ret > 0) && !handled_status_codes[code]) { 2030 dhcpv6_set_state(DHCPV6_REQUEST); 2031 *ret = -1; 2032 } 2033 break; 2034 2035 default: 2036 *ret = 0; 2037 break; 2038 } 2039 break; 2040 2041 case DHCPV6_NoAddrsAvail: 2042 case DHCPV6_NoPrefixAvail: 2043 break; 2044 2045 default: 2046 *ret = 0; 2047 break; 2048 } 2049 } 2050 2051 // Note this always takes ownership of cand->ia_na and cand->ia_pd 2052 static void dhcpv6_add_server_cand(const struct dhcpv6_server_cand *cand) 2053 { 2054 size_t cand_len, i; 2055 struct dhcpv6_server_cand *srv_candidates = odhcp6c_get_state(STATE_SERVER_CAND, &cand_len); 2056 2057 // Remove identical DUID server candidate 2058 for (i = 0; i < cand_len / sizeof(*srv_candidates); ++i) { 2059 if (cand->duid_len == srv_candidates[i].duid_len && 2060 !memcmp(cand->duid, srv_candidates[i].duid, cand->duid_len)) { 2061 free(srv_candidates[i].ia_na); 2062 free(srv_candidates[i].ia_pd); 2063 odhcp6c_remove_state(STATE_SERVER_CAND, i * sizeof(*srv_candidates), sizeof(*srv_candidates)); 2064 break; 2065 } 2066 } 2067 2068 for (i = 0, srv_candidates = odhcp6c_get_state(STATE_SERVER_CAND, &cand_len); 2069 i < cand_len / sizeof(*srv_candidates); ++i) { 2070 if (srv_candidates[i].preference < cand->preference) 2071 break; 2072 } 2073 2074 if (odhcp6c_insert_state(STATE_SERVER_CAND, i * sizeof(*srv_candidates), cand, sizeof(*cand))) { 2075 free(cand->ia_na); 2076 free(cand->ia_pd); 2077 } 2078 } 2079 2080 static void dhcpv6_clear_all_server_cand(void) 2081 { 2082 size_t cand_len, i; 2083 struct dhcpv6_server_cand *srv_candidates = odhcp6c_get_state(STATE_SERVER_CAND, &cand_len); 2084 2085 // Server candidates need deep delete for IA_NA/IA_PD 2086 for (i = 0; i < cand_len / sizeof(*srv_candidates); ++i) { 2087 free(srv_candidates[i].ia_na); 2088 free(srv_candidates[i].ia_pd); 2089 } 2090 odhcp6c_clear_state(STATE_SERVER_CAND); 2091 } 2092 2093 int dhcpv6_promote_server_cand(void) 2094 { 2095 size_t cand_len; 2096 struct dhcpv6_server_cand *cand = odhcp6c_get_state(STATE_SERVER_CAND, &cand_len); 2097 uint16_t hdr[2]; 2098 int ret = DHCPV6_STATELESS; 2099 2100 // Clear lingering candidate state info 2101 odhcp6c_clear_state(STATE_SERVER_ID); 2102 odhcp6c_clear_state(STATE_IA_NA); 2103 odhcp6c_clear_state(STATE_IA_PD); 2104 2105 if (!cand_len) 2106 return -1; 2107 2108 if (!cand->ia_pd_len && cand->has_noaddravail) { 2109 bool override = false; 2110 2111 if (na_mode == IA_MODE_TRY) { 2112 na_mode = IA_MODE_NONE; 2113 override = true; 2114 } 2115 2116 if (pd_mode == IA_MODE_TRY) { 2117 pd_mode = IA_MODE_NONE; 2118 override = true; 2119 } 2120 2121 if (override) { 2122 dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = cand->sol_max_rt; 2123 dhcpv6_retx[DHCPV6_MSG_INFO_REQ].max_timeo = cand->inf_max_rt; 2124 2125 return -1; 2126 } 2127 } 2128 2129 hdr[0] = htons(DHCPV6_OPT_SERVERID); 2130 hdr[1] = htons(cand->duid_len); 2131 odhcp6c_add_state(STATE_SERVER_ID, hdr, sizeof(hdr)); 2132 odhcp6c_add_state(STATE_SERVER_ID, cand->duid, cand->duid_len); 2133 accept_reconfig = cand->wants_reconfigure; 2134 memset(reconf_key, 0, sizeof(reconf_key)); 2135 2136 if (cand->ia_na_len) { 2137 odhcp6c_add_state(STATE_IA_NA, cand->ia_na, cand->ia_na_len); 2138 free(cand->ia_na); 2139 if (na_mode != IA_MODE_NONE) 2140 ret = DHCPV6_STATEFUL; 2141 } 2142 2143 if (cand->ia_pd_len) { 2144 odhcp6c_add_state(STATE_IA_PD, cand->ia_pd, cand->ia_pd_len); 2145 free(cand->ia_pd); 2146 if (pd_mode != IA_MODE_NONE) 2147 ret = DHCPV6_STATEFUL; 2148 } 2149 2150 dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = cand->sol_max_rt; 2151 dhcpv6_retx[DHCPV6_MSG_INFO_REQ].max_timeo = cand->inf_max_rt; 2152 2153 odhcp6c_remove_state(STATE_SERVER_CAND, 0, sizeof(*cand)); 2154 2155 return ret; 2156 } 2157 2158 int dhcpv6_send_request(enum dhcpv6_msg req_msg_type) 2159 { 2160 struct dhcpv6_retx *retx = &dhcpv6_retx[req_msg_type]; 2161 uint64_t current_milli_time = 0; 2162 2163 if (!retx->is_retransmit) { 2164 // Initial delay handling 2165 if (retx->max_delay) { 2166 if (retx->delay_msec == 0) { 2167 // Initial delay before starting the transaction 2168 retx->delay_msec = (dhcpv6_rand_delay((10000 * retx->max_delay) / 2) + (1000 * retx->max_delay) / 2); 2169 dhcpv6_set_state_timeout(retx->delay_msec); 2170 // Add current time to calculate absolute time 2171 retx->delay_msec += odhcp6c_get_milli_time(); 2172 return 1; 2173 } else { 2174 // Wait until delay expires 2175 current_milli_time = odhcp6c_get_milli_time(); 2176 if (current_milli_time < retx->delay_msec) { 2177 // Still waiting 2178 dhcpv6_set_state_timeout(retx->delay_msec - current_milli_time); 2179 return 1; 2180 } 2181 retx->delay_msec = 0; 2182 } 2183 } 2184 2185 retx->is_retransmit = true; 2186 retx->rc = 0; 2187 retx->timeout = UINT32_MAX; 2188 retx->reply_ret = -1; 2189 2190 if (req_msg_type == DHCPV6_MSG_UNKNOWN) 2191 retx->timeout = t1; 2192 else if (req_msg_type == DHCPV6_MSG_RENEW) 2193 retx->timeout = (t2 > t1) ? t2 - t1 : ((t1 == UINT32_MAX) ? UINT32_MAX : 0); 2194 else if (req_msg_type == DHCPV6_MSG_REBIND) 2195 retx->timeout = (t3 > t2) ? t3 - t2 : ((t2 == UINT32_MAX) ? UINT32_MAX : 0); 2196 2197 if (retx->timeout == 0) 2198 return -1; 2199 2200 notice("Starting %s transaction (timeout %"PRIu64"s, max rc %d)", 2201 retx->name, retx->timeout, retx->max_rc); 2202 2203 // Generate transaction ID 2204 if (req_msg_type != DHCPV6_MSG_UNKNOWN) { 2205 odhcp6c_random(retx->tr_id, sizeof(retx->tr_id)); 2206 } 2207 2208 // Record start time 2209 retx->start = odhcp6c_get_milli_time(); 2210 retx->round_start = retx->start; 2211 // Reset retransmission timeout initial value 2212 retx->rto = 0; 2213 } 2214 2215 if (retx->rto == 0) { 2216 int64_t delay = dhcpv6_rand_delay(retx->init_timeo * 1000); 2217 2218 // First RT MUST be strictly greater than IRT for solicit messages (RFC3313 17.1.2) 2219 while (req_msg_type == DHCPV6_MSG_SOLICIT && delay <= 0) 2220 delay = dhcpv6_rand_delay(retx->init_timeo * 1000); 2221 2222 // First timeout 2223 retx->rto = (retx->init_timeo * 1000 + delay); 2224 } else { 2225 // Exponential back-off with randomization to avoid synchronization 2226 retx->rto = (2 * retx->rto + dhcpv6_rand_delay(retx->rto)); 2227 } 2228 2229 if (retx->max_timeo && (retx->rto >= retx->max_timeo * 1000)) { 2230 // Cap to max timeout if set and exceeded 2231 retx->rto = retx->max_timeo * 1000 + 2232 dhcpv6_rand_delay(retx->max_timeo * 1000); 2233 } 2234 2235 // Calculate end for this round and elapsed time 2236 retx->round_end = retx->round_start + retx->rto; 2237 uint64_t elapsed = retx->round_start - retx->start; 2238 2239 // Don't wait too long if timeout differs from infinite 2240 if ((retx->timeout != UINT32_MAX) && (retx->round_end - retx->start > retx->timeout * 1000)) 2241 retx->round_end = retx->timeout * 1000 + retx->start; 2242 2243 dhcpv6_set_state_timeout(retx->round_end - odhcp6c_get_milli_time()); 2244 2245 // Built and send package 2246 switch (req_msg_type) { 2247 case DHCPV6_MSG_UNKNOWN: 2248 break; 2249 default: 2250 notice("Send %s message (elapsed %"PRIu64"ms, rc %d)", 2251 retx->name, elapsed, retx->rc); 2252 _o_fallthrough; 2253 case DHCPV6_MSG_SOLICIT: 2254 case DHCPV6_MSG_INFO_REQ: 2255 dhcpv6_send(req_msg_type, retx->tr_id, elapsed / 10); 2256 retx->rc++; 2257 } 2258 2259 if (dhcpv6_get_state() != DHCPV6_EXIT) 2260 dhcpv6_next_state(); 2261 2262 return 0; 2263 } 2264 2265 int dhcpv6_receive_response(enum dhcpv6_msg req_msg_type) 2266 { 2267 ssize_t len = -1; 2268 struct dhcpv6_retx *retx = &dhcpv6_retx[req_msg_type]; 2269 2270 uint8_t buf[1536]; 2271 union { 2272 struct cmsghdr hdr; 2273 uint8_t buf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; 2274 } cmsg_buf; 2275 2276 struct iovec iov = {buf, sizeof(buf)}; 2277 struct sockaddr_in6 addr; 2278 struct msghdr msg = {.msg_name = &addr, .msg_namelen = sizeof(addr), 2279 .msg_iov = &iov, .msg_iovlen = 1, .msg_control = cmsg_buf.buf, 2280 .msg_controllen = sizeof(cmsg_buf)}; 2281 struct in6_pktinfo *pktinfo = NULL; 2282 const struct dhcpv6_header *hdr = (const struct dhcpv6_header *)buf; 2283 2284 // Receive cycle 2285 len = recvmsg(sock, &msg, 0); 2286 if (len < 0) { 2287 error("Error occurred when reading the response of (%s) error(%s)", 2288 retx->name, strerror(errno)); 2289 return -1; 2290 } 2291 2292 for (struct cmsghdr *ch = CMSG_FIRSTHDR(&msg); ch != NULL; 2293 ch = CMSG_NXTHDR(&msg, ch)) { 2294 if (ch->cmsg_level == SOL_IPV6 && 2295 ch->cmsg_type == IPV6_PKTINFO) { 2296 pktinfo = (struct in6_pktinfo *)CMSG_DATA(ch); 2297 break; 2298 } 2299 } 2300 2301 if (pktinfo == NULL) { 2302 dhcpv6_stats.discarded_packets++; 2303 return -1; 2304 } 2305 2306 if (!dhcpv6_response_is_valid(buf, len, retx->tr_id, req_msg_type, 2307 &pktinfo->ipi6_addr)) { 2308 dhcpv6_stats.discarded_packets++; 2309 return -1; 2310 } 2311 2312 dhcpv6_inc_counter(hdr->msg_type); 2313 2314 uint8_t *opt = &buf[4]; 2315 uint8_t *opt_end = opt + len - DHCPV6_OPT_HDR_SIZE; 2316 retx->round_start = odhcp6c_get_milli_time(); 2317 uint64_t elapsed = retx->round_start - retx->start; 2318 2319 notice("Got a valid %s after %"PRIu64"ms", 2320 dhcpv6_msg_to_str(hdr->msg_type), elapsed); 2321 2322 if (retx->handler_reply) { 2323 retx->reply_ret = retx->handler_reply(req_msg_type, retx->rc, opt, opt_end, &addr); 2324 len = retx->reply_ret; 2325 } 2326 2327 // Clamp round end (Round Trip Time) to 1s max wait after receiving a valid response (in milliseconds) 2328 if (len > 0 && retx->round_end - retx->round_start > 1000) 2329 retx->round_end = 1000 + retx->round_start; 2330 2331 return retx->reply_ret; 2332 } 2333 2334 int dhcpv6_state_processing(enum dhcpv6_msg req_msg_type) 2335 { 2336 struct dhcpv6_retx *retx = &dhcpv6_retx[req_msg_type]; 2337 int ret = retx->reply_ret; 2338 retx->round_start = odhcp6c_get_milli_time(); 2339 uint64_t elapsed = retx->round_start - retx->start; 2340 2341 if (retx->round_start >= retx->round_end || ret >=0 ) { 2342 if (retx->handler_finish) 2343 ret = retx->handler_finish(); 2344 2345 if (ret < 0 && ((retx->timeout == UINT32_MAX) || (elapsed / 1000 < retx->timeout)) && 2346 (!retx->max_rc || retx->rc < retx->max_rc)) { 2347 retx->reply_ret = -1; 2348 dhcpv6_prev_state(); 2349 } else { 2350 retx->is_retransmit = false; 2351 dhcpv6_next_state(); 2352 } 2353 } else { 2354 // This sets the response polling timeout (round_end - round_start) in milliseconds 2355 dhcpv6_set_state_timeout(retx->round_end - retx->round_start); 2356 } 2357 2358 return ret; 2359 } 2360
This page was automatically generated by LXR 0.3.1. • OpenWrt