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