1 /* $NetBSD: dhc6.c,v 1.6 2014/07/12 12:09:37 spz Exp $ */ 2 /* dhc6.c - DHCPv6 client routines. */ 3 4 /* 5 * Copyright (c) 2012-2013 by Internet Systems Consortium, Inc. ("ISC") 6 * Copyright (c) 2006-2010 by Internet Systems Consortium, Inc. ("ISC") 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 18 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 * 20 * Internet Systems Consortium, Inc. 21 * 950 Charter Street 22 * Redwood City, CA 94063 23 * <info@isc.org> 24 * https://www.isc.org/ 25 */ 26 27 #include <sys/cdefs.h> 28 __RCSID("$NetBSD: dhc6.c,v 1.6 2014/07/12 12:09:37 spz Exp $"); 29 30 #include "dhcpd.h" 31 32 #ifdef DHCPv6 33 34 struct sockaddr_in6 DHCPv6DestAddr; 35 36 /* 37 * Option definition structures that are used by the software - declared 38 * here once and assigned at startup to save lookups. 39 */ 40 struct option *clientid_option = NULL; 41 struct option *elapsed_option = NULL; 42 struct option *ia_na_option = NULL; 43 struct option *ia_ta_option = NULL; 44 struct option *ia_pd_option = NULL; 45 struct option *iaaddr_option = NULL; 46 struct option *iaprefix_option = NULL; 47 struct option *oro_option = NULL; 48 struct option *irt_option = NULL; 49 50 static struct dhc6_lease *dhc6_dup_lease(struct dhc6_lease *lease, 51 const char *file, int line); 52 static struct dhc6_ia *dhc6_dup_ia(struct dhc6_ia *ia, 53 const char *file, int line); 54 static struct dhc6_addr *dhc6_dup_addr(struct dhc6_addr *addr, 55 const char *file, int line); 56 static void dhc6_ia_destroy(struct dhc6_ia **src, const char *file, int line); 57 static isc_result_t dhc6_parse_ia_na(struct dhc6_ia **pia, 58 struct packet *packet, 59 struct option_state *options); 60 static isc_result_t dhc6_parse_ia_ta(struct dhc6_ia **pia, 61 struct packet *packet, 62 struct option_state *options); 63 static isc_result_t dhc6_parse_ia_pd(struct dhc6_ia **pia, 64 struct packet *packet, 65 struct option_state *options); 66 static isc_result_t dhc6_parse_addrs(struct dhc6_addr **paddr, 67 struct packet *packet, 68 struct option_state *options); 69 static isc_result_t dhc6_parse_prefixes(struct dhc6_addr **ppref, 70 struct packet *packet, 71 struct option_state *options); 72 static struct dhc6_ia *find_ia(struct dhc6_ia *head, 73 u_int16_t type, const char *id); 74 static struct dhc6_addr *find_addr(struct dhc6_addr *head, 75 struct iaddr *address); 76 static struct dhc6_addr *find_pref(struct dhc6_addr *head, 77 struct iaddr *prefix, u_int8_t plen); 78 void init_handler(struct packet *packet, struct client_state *client); 79 void info_request_handler(struct packet *packet, struct client_state *client); 80 void rapid_commit_handler(struct packet *packet, struct client_state *client); 81 void do_init6(void *input); 82 void do_info_request6(void *input); 83 void do_confirm6(void *input); 84 void reply_handler(struct packet *packet, struct client_state *client); 85 static isc_result_t dhc6_add_ia_na(struct client_state *client, 86 struct data_string *packet, 87 struct dhc6_lease *lease, 88 u_int8_t message); 89 static isc_result_t dhc6_add_ia_ta(struct client_state *client, 90 struct data_string *packet, 91 struct dhc6_lease *lease, 92 u_int8_t message); 93 static isc_result_t dhc6_add_ia_pd(struct client_state *client, 94 struct data_string *packet, 95 struct dhc6_lease *lease, 96 u_int8_t message); 97 static isc_boolean_t stopping_finished(void); 98 static void dhc6_merge_lease(struct dhc6_lease *src, struct dhc6_lease *dst); 99 void do_select6(void *input); 100 void do_refresh6(void *input); 101 static void do_release6(void *input); 102 static void start_bound(struct client_state *client); 103 static void start_informed(struct client_state *client); 104 void informed_handler(struct packet *packet, struct client_state *client); 105 void bound_handler(struct packet *packet, struct client_state *client); 106 void start_renew6(void *input); 107 void start_rebind6(void *input); 108 void do_depref(void *input); 109 void do_expire(void *input); 110 static void make_client6_options(struct client_state *client, 111 struct option_state **op, 112 struct dhc6_lease *lease, u_int8_t message); 113 static void script_write_params6(struct client_state *client, 114 const char *prefix, 115 struct option_state *options); 116 static void script_write_requested6(struct client_state *client); 117 static isc_boolean_t active_prefix(struct client_state *client); 118 119 static int check_timing6(struct client_state *client, u_int8_t msg_type, 120 char *msg_str, struct dhc6_lease *lease, 121 struct data_string *ds); 122 123 extern int onetry; 124 extern int stateless; 125 126 /* 127 * Assign DHCPv6 port numbers as a client. 128 */ 129 void 130 dhcpv6_client_assignments(void) 131 { 132 struct servent *ent; 133 unsigned code; 134 135 if (path_dhclient_pid == NULL) 136 path_dhclient_pid = _PATH_DHCLIENT6_PID; 137 if (path_dhclient_db == NULL) 138 path_dhclient_db = _PATH_DHCLIENT6_DB; 139 140 if (local_port == 0) { 141 ent = getservbyname("dhcpv6-client", "udp"); 142 if (ent == NULL) 143 local_port = htons(546); 144 else 145 local_port = ent->s_port; 146 } 147 148 if (remote_port == 0) { 149 ent = getservbyname("dhcpv6-server", "udp"); 150 if (ent == NULL) 151 remote_port = htons(547); 152 else 153 remote_port = ent->s_port; 154 } 155 156 memset(&DHCPv6DestAddr, 0, sizeof(DHCPv6DestAddr)); 157 DHCPv6DestAddr.sin6_family = AF_INET6; 158 DHCPv6DestAddr.sin6_port = remote_port; 159 if (inet_pton(AF_INET6, All_DHCP_Relay_Agents_and_Servers, 160 &DHCPv6DestAddr.sin6_addr) <= 0) { 161 log_fatal("Bad address %s", All_DHCP_Relay_Agents_and_Servers); 162 } 163 164 code = D6O_CLIENTID; 165 if (!option_code_hash_lookup(&clientid_option, 166 dhcpv6_universe.code_hash, &code, 0, MDL)) 167 log_fatal("Unable to find the CLIENTID option definition."); 168 169 code = D6O_ELAPSED_TIME; 170 if (!option_code_hash_lookup(&elapsed_option, 171 dhcpv6_universe.code_hash, &code, 0, MDL)) 172 log_fatal("Unable to find the ELAPSED_TIME option definition."); 173 174 code = D6O_IA_NA; 175 if (!option_code_hash_lookup(&ia_na_option, dhcpv6_universe.code_hash, 176 &code, 0, MDL)) 177 log_fatal("Unable to find the IA_NA option definition."); 178 179 code = D6O_IA_TA; 180 if (!option_code_hash_lookup(&ia_ta_option, dhcpv6_universe.code_hash, 181 &code, 0, MDL)) 182 log_fatal("Unable to find the IA_TA option definition."); 183 184 code = D6O_IA_PD; 185 if (!option_code_hash_lookup(&ia_pd_option, dhcpv6_universe.code_hash, 186 &code, 0, MDL)) 187 log_fatal("Unable to find the IA_PD option definition."); 188 189 code = D6O_IAADDR; 190 if (!option_code_hash_lookup(&iaaddr_option, dhcpv6_universe.code_hash, 191 &code, 0, MDL)) 192 log_fatal("Unable to find the IAADDR option definition."); 193 194 code = D6O_IAPREFIX; 195 if (!option_code_hash_lookup(&iaprefix_option, 196 dhcpv6_universe.code_hash, 197 &code, 0, MDL)) 198 log_fatal("Unable to find the IAPREFIX option definition."); 199 200 code = D6O_ORO; 201 if (!option_code_hash_lookup(&oro_option, dhcpv6_universe.code_hash, 202 &code, 0, MDL)) 203 log_fatal("Unable to find the ORO option definition."); 204 205 code = D6O_INFORMATION_REFRESH_TIME; 206 if (!option_code_hash_lookup(&irt_option, dhcpv6_universe.code_hash, 207 &code, 0, MDL)) 208 log_fatal("Unable to find the IRT option definition."); 209 210 #ifndef __CYGWIN32__ /* XXX */ 211 endservent(); 212 #endif 213 } 214 215 /* 216 * Instead of implementing RFC3315 RAND (section 14) as a float "between" 217 * -0.1 and 0.1 non-inclusive, we implement it as an integer. 218 * 219 * The result is expected to follow this table: 220 * 221 * split range answer 222 * - ERROR - base <= 0 223 * 0 1 0..0 1 <= base <= 10 224 * 1 3 -1..1 11 <= base <= 20 225 * 2 5 -2..2 21 <= base <= 30 226 * 3 7 -3..3 31 <= base <= 40 227 * ... 228 * 229 * XXX: For this to make sense, we really need to do timing on a 230 * XXX: usec scale...we currently can assume zero for any value less than 231 * XXX: 11, which are very common in early stages of transmission for most 232 * XXX: messages. 233 */ 234 static TIME 235 dhc6_rand(TIME base) 236 { 237 TIME rval; 238 TIME range; 239 TIME split; 240 241 /* 242 * A zero or less timeout is a bad thing...we don't want to 243 * DHCP-flood anyone. 244 */ 245 if (base <= 0) 246 log_fatal("Impossible condition at %s:%d.", MDL); 247 248 /* 249 * The first thing we do is count how many random integers we want 250 * in either direction (best thought of as the maximum negative 251 * integer, as we will subtract this potentially from a random 0). 252 */ 253 split = (base - 1) / 10; 254 255 /* Don't bother with the rest of the math if we know we'll get 0. */ 256 if (split == 0) 257 return 0; 258 259 /* 260 * Then we count the total number of integers in this set. This 261 * is twice the number of integers in positive and negative 262 * directions, plus zero (-1, 0, 1 is 3, -2..2 adds 2 to 5, so forth). 263 */ 264 range = (split * 2) + 1; 265 266 /* Take a random number from [0..(range-1)]. */ 267 rval = random(); 268 rval %= range; 269 270 /* Offset it to uncover potential negative values. */ 271 rval -= split; 272 273 return rval; 274 } 275 276 /* Initialize message exchange timers (set RT from Initial-RT). */ 277 static void 278 dhc6_retrans_init(struct client_state *client) 279 { 280 int xid; 281 282 /* Initialize timers. */ 283 client->txcount = 0; 284 client->RT = client->IRT + dhc6_rand(client->IRT); 285 286 /* Generate a new random 24-bit transaction ID for this exchange. */ 287 288 #if (RAND_MAX >= 0x00ffffff) 289 xid = random(); 290 #elif (RAND_MAX >= 0x0000ffff) 291 xid = (random() << 16) ^ random(); 292 #elif (RAND_MAX >= 0x000000ff) 293 xid = (random() << 16) ^ (random() << 8) ^ random(); 294 #else 295 # error "Random number generator of less than 8 bits not supported." 296 #endif 297 298 client->dhcpv6_transaction_id[0] = (xid >> 16) & 0xff; 299 client->dhcpv6_transaction_id[1] = (xid >> 8) & 0xff; 300 client->dhcpv6_transaction_id[2] = xid & 0xff; 301 } 302 303 /* Advance the DHCPv6 retransmission state once. */ 304 static void 305 dhc6_retrans_advance(struct client_state *client) 306 { 307 struct timeval elapsed; 308 309 /* elapsed = cur - start */ 310 elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec; 311 elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec; 312 if (elapsed.tv_usec < 0) { 313 elapsed.tv_sec -= 1; 314 elapsed.tv_usec += 1000000; 315 } 316 /* retrans_advance is called after consuming client->RT. */ 317 /* elapsed += RT */ 318 elapsed.tv_sec += client->RT / 100; 319 elapsed.tv_usec += (client->RT % 100) * 10000; 320 if (elapsed.tv_usec >= 1000000) { 321 elapsed.tv_sec += 1; 322 elapsed.tv_usec -= 1000000; 323 } 324 325 /* 326 * RT for each subsequent message transmission is based on the previous 327 * value of RT: 328 * 329 * RT = 2*RTprev + RAND*RTprev 330 */ 331 client->RT += client->RT + dhc6_rand(client->RT); 332 333 /* 334 * MRT specifies an upper bound on the value of RT (disregarding the 335 * randomization added by the use of RAND). If MRT has a value of 0, 336 * there is no upper limit on the value of RT. Otherwise: 337 * 338 * if (RT > MRT) 339 * RT = MRT + RAND*MRT 340 */ 341 if ((client->MRT != 0) && (client->RT > client->MRT)) 342 client->RT = client->MRT + dhc6_rand(client->MRT); 343 344 /* 345 * Further, if there's an MRD, we should wake up upon reaching 346 * the MRD rather than at some point after it. 347 */ 348 if (client->MRD == 0) { 349 /* Done. */ 350 client->txcount++; 351 return; 352 } 353 /* elapsed += client->RT */ 354 elapsed.tv_sec += client->RT / 100; 355 elapsed.tv_usec += (client->RT % 100) * 10000; 356 if (elapsed.tv_usec >= 1000000) { 357 elapsed.tv_sec += 1; 358 elapsed.tv_usec -= 1000000; 359 } 360 if (elapsed.tv_sec >= client->MRD) { 361 /* 362 * wake at RT + cur = start + MRD 363 */ 364 client->RT = client->MRD + 365 (client->start_time.tv_sec - cur_tv.tv_sec); 366 client->RT = client->RT * 100 + 367 (client->start_time.tv_usec - cur_tv.tv_usec) / 10000; 368 } 369 client->txcount++; 370 } 371 372 /* Quick validation of DHCPv6 ADVERTISE packet contents. */ 373 static int 374 valid_reply(struct packet *packet, struct client_state *client) 375 { 376 struct data_string sid, cid; 377 struct option_cache *oc; 378 int rval = ISC_TRUE; 379 380 memset(&sid, 0, sizeof(sid)); 381 memset(&cid, 0, sizeof(cid)); 382 383 if (!lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID)) { 384 log_error("Response without a server identifier received."); 385 rval = ISC_FALSE; 386 } 387 388 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_CLIENTID); 389 if (!oc || 390 !evaluate_option_cache(&sid, packet, NULL, client, packet->options, 391 client->sent_options, &global_scope, oc, 392 MDL)) { 393 log_error("Response without a client identifier."); 394 rval = ISC_FALSE; 395 } 396 397 oc = lookup_option(&dhcpv6_universe, client->sent_options, 398 D6O_CLIENTID); 399 if (!oc || 400 !evaluate_option_cache(&cid, packet, NULL, client, 401 client->sent_options, NULL, &global_scope, 402 oc, MDL)) { 403 log_error("Local client identifier is missing!"); 404 rval = ISC_FALSE; 405 } 406 407 if (sid.len == 0 || 408 sid.len != cid.len || 409 memcmp(sid.data, cid.data, sid.len)) { 410 log_error("Advertise with matching transaction ID, but " 411 "mismatching client id."); 412 rval = ISC_FALSE; 413 } 414 415 return rval; 416 } 417 418 /* 419 * Create a complete copy of a DHCPv6 lease structure. 420 */ 421 static struct dhc6_lease * 422 dhc6_dup_lease(struct dhc6_lease *lease, const char *file, int line) 423 { 424 struct dhc6_lease *copy; 425 struct dhc6_ia **insert_ia, *ia; 426 427 copy = dmalloc(sizeof(*copy), file, line); 428 if (copy == NULL) { 429 log_error("Out of memory for v6 lease structure."); 430 return NULL; 431 } 432 433 data_string_copy(©->server_id, &lease->server_id, file, line); 434 copy->pref = lease->pref; 435 436 memcpy(copy->dhcpv6_transaction_id, lease->dhcpv6_transaction_id, 437 sizeof(copy->dhcpv6_transaction_id)); 438 439 option_state_reference(©->options, lease->options, file, line); 440 441 insert_ia = ©->bindings; 442 for (ia = lease->bindings ; ia != NULL ; ia = ia->next) { 443 *insert_ia = dhc6_dup_ia(ia, file, line); 444 445 if (*insert_ia == NULL) { 446 dhc6_lease_destroy(©, file, line); 447 return NULL; 448 } 449 450 insert_ia = &(*insert_ia)->next; 451 } 452 453 return copy; 454 } 455 456 /* 457 * Duplicate an IA structure. 458 */ 459 static struct dhc6_ia * 460 dhc6_dup_ia(struct dhc6_ia *ia, const char *file, int line) 461 { 462 struct dhc6_ia *copy; 463 struct dhc6_addr **insert_addr, *addr; 464 465 copy = dmalloc(sizeof(*ia), file, line); 466 467 memcpy(copy->iaid, ia->iaid, sizeof(copy->iaid)); 468 469 copy->ia_type = ia->ia_type; 470 copy->starts = ia->starts; 471 copy->renew = ia->renew; 472 copy->rebind = ia->rebind; 473 474 insert_addr = ©->addrs; 475 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) { 476 *insert_addr = dhc6_dup_addr(addr, file, line); 477 478 if (*insert_addr == NULL) { 479 dhc6_ia_destroy(©, file, line); 480 return NULL; 481 } 482 483 insert_addr = &(*insert_addr)->next; 484 } 485 486 if (ia->options != NULL) 487 option_state_reference(©->options, ia->options, 488 file, line); 489 490 return copy; 491 } 492 493 /* 494 * Duplicate an IAADDR or IAPREFIX structure. 495 */ 496 static struct dhc6_addr * 497 dhc6_dup_addr(struct dhc6_addr *addr, const char *file, int line) 498 { 499 struct dhc6_addr *copy; 500 501 copy = dmalloc(sizeof(*addr), file, line); 502 503 if (copy == NULL) 504 return NULL; 505 506 memcpy(©->address, &addr->address, sizeof(copy->address)); 507 508 copy->plen = addr->plen; 509 copy->flags = addr->flags; 510 copy->starts = addr->starts; 511 copy->preferred_life = addr->preferred_life; 512 copy->max_life = addr->max_life; 513 514 if (addr->options != NULL) 515 option_state_reference(©->options, addr->options, 516 file, line); 517 518 return copy; 519 } 520 521 /* 522 * Form a DHCPv6 lease structure based upon packet contents. Creates and 523 * populates IA's and any IAADDR/IAPREFIX's they contain. 524 * Parsed options are deleted in order to not save them in the lease file. 525 */ 526 static struct dhc6_lease * 527 dhc6_leaseify(struct packet *packet) 528 { 529 struct data_string ds; 530 struct dhc6_lease *lease; 531 struct option_cache *oc; 532 533 lease = dmalloc(sizeof(*lease), MDL); 534 if (lease == NULL) { 535 log_error("Out of memory for v6 lease structure."); 536 return NULL; 537 } 538 539 memcpy(lease->dhcpv6_transaction_id, packet->dhcpv6_transaction_id, 3); 540 option_state_reference(&lease->options, packet->options, MDL); 541 542 memset(&ds, 0, sizeof(ds)); 543 544 /* Determine preference (default zero). */ 545 oc = lookup_option(&dhcpv6_universe, lease->options, D6O_PREFERENCE); 546 if (oc && 547 evaluate_option_cache(&ds, packet, NULL, NULL, lease->options, 548 NULL, &global_scope, oc, MDL)) { 549 if (ds.len != 1) { 550 log_error("Invalid length of DHCPv6 Preference option " 551 "(%d != 1)", ds.len); 552 data_string_forget(&ds, MDL); 553 dhc6_lease_destroy(&lease, MDL); 554 return NULL; 555 } else { 556 lease->pref = ds.data[0]; 557 log_debug("RCV: X-- Preference %u.", 558 (unsigned)lease->pref); 559 } 560 561 data_string_forget(&ds, MDL); 562 } 563 delete_option(&dhcpv6_universe, lease->options, D6O_PREFERENCE); 564 565 /* 566 * Dig into recursive DHCPv6 pockets for IA_NA and contained IAADDR 567 * options. 568 */ 569 if (dhc6_parse_ia_na(&lease->bindings, packet, 570 lease->options) != ISC_R_SUCCESS) { 571 /* Error conditions are logged by the caller. */ 572 dhc6_lease_destroy(&lease, MDL); 573 return NULL; 574 } 575 /* 576 * Dig into recursive DHCPv6 pockets for IA_TA and contained IAADDR 577 * options. 578 */ 579 if (dhc6_parse_ia_ta(&lease->bindings, packet, 580 lease->options) != ISC_R_SUCCESS) { 581 /* Error conditions are logged by the caller. */ 582 dhc6_lease_destroy(&lease, MDL); 583 return NULL; 584 } 585 /* 586 * Dig into recursive DHCPv6 pockets for IA_PD and contained IAPREFIX 587 * options. 588 */ 589 if (dhc6_parse_ia_pd(&lease->bindings, packet, 590 lease->options) != ISC_R_SUCCESS) { 591 /* Error conditions are logged by the caller. */ 592 dhc6_lease_destroy(&lease, MDL); 593 return NULL; 594 } 595 596 /* 597 * This is last because in the future we may want to make a different 598 * key based upon additional information from the packet (we may need 599 * to allow multiple leases in one client state per server, but we're 600 * not sure based on what additional keys now). 601 */ 602 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID); 603 if ((oc == NULL) || 604 !evaluate_option_cache(&lease->server_id, packet, NULL, NULL, 605 lease->options, NULL, &global_scope, 606 oc, MDL) || 607 lease->server_id.len == 0) { 608 /* This should be impossible due to validation checks earlier. 609 */ 610 log_error("Invalid SERVERID option cache."); 611 dhc6_lease_destroy(&lease, MDL); 612 return NULL; 613 } else { 614 log_debug("RCV: X-- Server ID: %s", 615 print_hex_1(lease->server_id.len, 616 lease->server_id.data, 52)); 617 } 618 619 return lease; 620 } 621 622 static isc_result_t 623 dhc6_parse_ia_na(struct dhc6_ia **pia, struct packet *packet, 624 struct option_state *options) 625 { 626 struct data_string ds; 627 struct dhc6_ia *ia; 628 struct option_cache *oc; 629 isc_result_t result; 630 631 memset(&ds, 0, sizeof(ds)); 632 633 oc = lookup_option(&dhcpv6_universe, options, D6O_IA_NA); 634 for ( ; oc != NULL ; oc = oc->next) { 635 ia = dmalloc(sizeof(*ia), MDL); 636 if (ia == NULL) { 637 log_error("Out of memory allocating IA_NA structure."); 638 return ISC_R_NOMEMORY; 639 } else if (evaluate_option_cache(&ds, packet, NULL, NULL, 640 options, NULL, 641 &global_scope, oc, MDL) && 642 ds.len >= 12) { 643 memcpy(ia->iaid, ds.data, 4); 644 ia->ia_type = D6O_IA_NA; 645 ia->starts = cur_time; 646 ia->renew = getULong(ds.data + 4); 647 ia->rebind = getULong(ds.data + 8); 648 649 log_debug("RCV: X-- IA_NA %s", 650 print_hex_1(4, ia->iaid, 59)); 651 /* XXX: This should be the printed time I think. */ 652 log_debug("RCV: | X-- starts %u", 653 (unsigned)ia->starts); 654 log_debug("RCV: | X-- t1 - renew +%u", ia->renew); 655 log_debug("RCV: | X-- t2 - rebind +%u", ia->rebind); 656 657 /* 658 * RFC3315 section 22.4, discard IA_NA's that 659 * have t1 greater than t2, and both not zero. 660 * Since RFC3315 defines this behaviour, it is not 661 * an error - just normal operation. 662 * 663 * Note that RFC3315 says we MUST honor these values 664 * if they are not zero. So insane values are 665 * totally OK. 666 */ 667 if ((ia->renew > 0) && (ia->rebind > 0) && 668 (ia->renew > ia->rebind)) { 669 log_debug("RCV: | !-- INVALID renew/rebind " 670 "times, IA_NA discarded."); 671 dfree(ia, MDL); 672 data_string_forget(&ds, MDL); 673 continue; 674 } 675 676 if (ds.len > 12) { 677 log_debug("RCV: | X-- [Options]"); 678 679 if (!option_state_allocate(&ia->options, 680 MDL)) { 681 log_error("Out of memory allocating " 682 "IA_NA option state."); 683 dfree(ia, MDL); 684 data_string_forget(&ds, MDL); 685 return ISC_R_NOMEMORY; 686 } 687 688 if (!parse_option_buffer(ia->options, 689 ds.data + 12, 690 ds.len - 12, 691 &dhcpv6_universe)) { 692 log_error("Corrupt IA_NA options."); 693 option_state_dereference(&ia->options, 694 MDL); 695 dfree(ia, MDL); 696 data_string_forget(&ds, MDL); 697 return DHCP_R_BADPARSE; 698 } 699 } 700 data_string_forget(&ds, MDL); 701 702 if (ia->options != NULL) { 703 result = dhc6_parse_addrs(&ia->addrs, packet, 704 ia->options); 705 if (result != ISC_R_SUCCESS) { 706 option_state_dereference(&ia->options, 707 MDL); 708 dfree(ia, MDL); 709 return result; 710 } 711 } 712 713 while (*pia != NULL) 714 pia = &(*pia)->next; 715 *pia = ia; 716 pia = &ia->next; 717 } else { 718 log_error("Invalid IA_NA option cache."); 719 dfree(ia, MDL); 720 if (ds.len != 0) 721 data_string_forget(&ds, MDL); 722 return ISC_R_UNEXPECTED; 723 } 724 } 725 delete_option(&dhcpv6_universe, options, D6O_IA_NA); 726 727 return ISC_R_SUCCESS; 728 } 729 730 static isc_result_t 731 dhc6_parse_ia_ta(struct dhc6_ia **pia, struct packet *packet, 732 struct option_state *options) 733 { 734 struct data_string ds; 735 struct dhc6_ia *ia; 736 struct option_cache *oc; 737 isc_result_t result; 738 739 memset(&ds, 0, sizeof(ds)); 740 741 oc = lookup_option(&dhcpv6_universe, options, D6O_IA_TA); 742 for ( ; oc != NULL ; oc = oc->next) { 743 ia = dmalloc(sizeof(*ia), MDL); 744 if (ia == NULL) { 745 log_error("Out of memory allocating IA_TA structure."); 746 return ISC_R_NOMEMORY; 747 } else if (evaluate_option_cache(&ds, packet, NULL, NULL, 748 options, NULL, 749 &global_scope, oc, MDL) && 750 ds.len >= 4) { 751 memcpy(ia->iaid, ds.data, 4); 752 ia->ia_type = D6O_IA_TA; 753 ia->starts = cur_time; 754 755 log_debug("RCV: X-- IA_TA %s", 756 print_hex_1(4, ia->iaid, 59)); 757 /* XXX: This should be the printed time I think. */ 758 log_debug("RCV: | X-- starts %u", 759 (unsigned)ia->starts); 760 761 if (ds.len > 4) { 762 log_debug("RCV: | X-- [Options]"); 763 764 if (!option_state_allocate(&ia->options, 765 MDL)) { 766 log_error("Out of memory allocating " 767 "IA_TA option state."); 768 dfree(ia, MDL); 769 data_string_forget(&ds, MDL); 770 return ISC_R_NOMEMORY; 771 } 772 773 if (!parse_option_buffer(ia->options, 774 ds.data + 4, 775 ds.len - 4, 776 &dhcpv6_universe)) { 777 log_error("Corrupt IA_TA options."); 778 option_state_dereference(&ia->options, 779 MDL); 780 dfree(ia, MDL); 781 data_string_forget(&ds, MDL); 782 return DHCP_R_BADPARSE; 783 } 784 } 785 data_string_forget(&ds, MDL); 786 787 if (ia->options != NULL) { 788 result = dhc6_parse_addrs(&ia->addrs, packet, 789 ia->options); 790 if (result != ISC_R_SUCCESS) { 791 option_state_dereference(&ia->options, 792 MDL); 793 dfree(ia, MDL); 794 return result; 795 } 796 } 797 798 while (*pia != NULL) 799 pia = &(*pia)->next; 800 *pia = ia; 801 pia = &ia->next; 802 } else { 803 log_error("Invalid IA_TA option cache."); 804 dfree(ia, MDL); 805 if (ds.len != 0) 806 data_string_forget(&ds, MDL); 807 return ISC_R_UNEXPECTED; 808 } 809 } 810 delete_option(&dhcpv6_universe, options, D6O_IA_TA); 811 812 return ISC_R_SUCCESS; 813 } 814 815 static isc_result_t 816 dhc6_parse_ia_pd(struct dhc6_ia **pia, struct packet *packet, 817 struct option_state *options) 818 { 819 struct data_string ds; 820 struct dhc6_ia *ia; 821 struct option_cache *oc; 822 isc_result_t result; 823 824 memset(&ds, 0, sizeof(ds)); 825 826 oc = lookup_option(&dhcpv6_universe, options, D6O_IA_PD); 827 for ( ; oc != NULL ; oc = oc->next) { 828 ia = dmalloc(sizeof(*ia), MDL); 829 if (ia == NULL) { 830 log_error("Out of memory allocating IA_PD structure."); 831 return ISC_R_NOMEMORY; 832 } else if (evaluate_option_cache(&ds, packet, NULL, NULL, 833 options, NULL, 834 &global_scope, oc, MDL) && 835 ds.len >= 12) { 836 memcpy(ia->iaid, ds.data, 4); 837 ia->ia_type = D6O_IA_PD; 838 ia->starts = cur_time; 839 ia->renew = getULong(ds.data + 4); 840 ia->rebind = getULong(ds.data + 8); 841 842 log_debug("RCV: X-- IA_PD %s", 843 print_hex_1(4, ia->iaid, 59)); 844 /* XXX: This should be the printed time I think. */ 845 log_debug("RCV: | X-- starts %u", 846 (unsigned)ia->starts); 847 log_debug("RCV: | X-- t1 - renew +%u", ia->renew); 848 log_debug("RCV: | X-- t2 - rebind +%u", ia->rebind); 849 850 /* 851 * RFC3633 section 9, discard IA_PD's that 852 * have t1 greater than t2, and both not zero. 853 * Since RFC3633 defines this behaviour, it is not 854 * an error - just normal operation. 855 */ 856 if ((ia->renew > 0) && (ia->rebind > 0) && 857 (ia->renew > ia->rebind)) { 858 log_debug("RCV: | !-- INVALID renew/rebind " 859 "times, IA_PD discarded."); 860 dfree(ia, MDL); 861 data_string_forget(&ds, MDL); 862 continue; 863 } 864 865 if (ds.len > 12) { 866 log_debug("RCV: | X-- [Options]"); 867 868 if (!option_state_allocate(&ia->options, 869 MDL)) { 870 log_error("Out of memory allocating " 871 "IA_PD option state."); 872 dfree(ia, MDL); 873 data_string_forget(&ds, MDL); 874 return ISC_R_NOMEMORY; 875 } 876 877 if (!parse_option_buffer(ia->options, 878 ds.data + 12, 879 ds.len - 12, 880 &dhcpv6_universe)) { 881 log_error("Corrupt IA_PD options."); 882 option_state_dereference(&ia->options, 883 MDL); 884 dfree(ia, MDL); 885 data_string_forget(&ds, MDL); 886 return DHCP_R_BADPARSE; 887 } 888 } 889 data_string_forget(&ds, MDL); 890 891 if (ia->options != NULL) { 892 result = dhc6_parse_prefixes(&ia->addrs, 893 packet, 894 ia->options); 895 if (result != ISC_R_SUCCESS) { 896 option_state_dereference(&ia->options, 897 MDL); 898 dfree(ia, MDL); 899 return result; 900 } 901 } 902 903 while (*pia != NULL) 904 pia = &(*pia)->next; 905 *pia = ia; 906 pia = &ia->next; 907 } else { 908 log_error("Invalid IA_PD option cache."); 909 dfree(ia, MDL); 910 if (ds.len != 0) 911 data_string_forget(&ds, MDL); 912 return ISC_R_UNEXPECTED; 913 } 914 } 915 delete_option(&dhcpv6_universe, options, D6O_IA_PD); 916 917 return ISC_R_SUCCESS; 918 } 919 920 921 static isc_result_t 922 dhc6_parse_addrs(struct dhc6_addr **paddr, struct packet *packet, 923 struct option_state *options) 924 { 925 struct data_string ds; 926 struct option_cache *oc; 927 struct dhc6_addr *addr; 928 929 memset(&ds, 0, sizeof(ds)); 930 931 oc = lookup_option(&dhcpv6_universe, options, D6O_IAADDR); 932 for ( ; oc != NULL ; oc = oc->next) { 933 addr = dmalloc(sizeof(*addr), MDL); 934 if (addr == NULL) { 935 log_error("Out of memory allocating " 936 "address structure."); 937 return ISC_R_NOMEMORY; 938 } else if (evaluate_option_cache(&ds, packet, NULL, NULL, 939 options, NULL, &global_scope, 940 oc, MDL) && 941 (ds.len >= 24)) { 942 943 addr->address.len = 16; 944 memcpy(addr->address.iabuf, ds.data, 16); 945 addr->starts = cur_time; 946 addr->preferred_life = getULong(ds.data + 16); 947 addr->max_life = getULong(ds.data + 20); 948 949 log_debug("RCV: | | X-- IAADDR %s", 950 piaddr(addr->address)); 951 log_debug("RCV: | | | X-- Preferred lifetime %u.", 952 addr->preferred_life); 953 log_debug("RCV: | | | X-- Max lifetime %u.", 954 addr->max_life); 955 956 /* 957 * RFC 3315 section 22.6 says we must discard 958 * addresses whose pref is later than valid. 959 */ 960 if ((addr->preferred_life > addr->max_life)) { 961 log_debug("RCV: | | | !-- INVALID lifetimes, " 962 "IAADDR discarded. Check your " 963 "server configuration."); 964 dfree(addr, MDL); 965 data_string_forget(&ds, MDL); 966 continue; 967 } 968 969 /* 970 * Fortunately this is the last recursion in the 971 * protocol. 972 */ 973 if (ds.len > 24) { 974 if (!option_state_allocate(&addr->options, 975 MDL)) { 976 log_error("Out of memory allocating " 977 "IAADDR option state."); 978 dfree(addr, MDL); 979 data_string_forget(&ds, MDL); 980 return ISC_R_NOMEMORY; 981 } 982 983 if (!parse_option_buffer(addr->options, 984 ds.data + 24, 985 ds.len - 24, 986 &dhcpv6_universe)) { 987 log_error("Corrupt IAADDR options."); 988 option_state_dereference(&addr->options, 989 MDL); 990 dfree(addr, MDL); 991 data_string_forget(&ds, MDL); 992 return DHCP_R_BADPARSE; 993 } 994 } 995 996 if (addr->options != NULL) 997 log_debug("RCV: | | | X-- " 998 "[Options]"); 999 1000 data_string_forget(&ds, MDL); 1001 1002 *paddr = addr; 1003 paddr = &addr->next; 1004 } else { 1005 log_error("Invalid IAADDR option cache."); 1006 dfree(addr, MDL); 1007 if (ds.len != 0) 1008 data_string_forget(&ds, MDL); 1009 return ISC_R_UNEXPECTED; 1010 } 1011 } 1012 delete_option(&dhcpv6_universe, options, D6O_IAADDR); 1013 1014 return ISC_R_SUCCESS; 1015 } 1016 1017 static isc_result_t 1018 dhc6_parse_prefixes(struct dhc6_addr **ppfx, struct packet *packet, 1019 struct option_state *options) 1020 { 1021 struct data_string ds; 1022 struct option_cache *oc; 1023 struct dhc6_addr *pfx; 1024 1025 memset(&ds, 0, sizeof(ds)); 1026 1027 oc = lookup_option(&dhcpv6_universe, options, D6O_IAPREFIX); 1028 for ( ; oc != NULL ; oc = oc->next) { 1029 pfx = dmalloc(sizeof(*pfx), MDL); 1030 if (pfx == NULL) { 1031 log_error("Out of memory allocating " 1032 "prefix structure."); 1033 return ISC_R_NOMEMORY; 1034 } else if (evaluate_option_cache(&ds, packet, NULL, NULL, 1035 options, NULL, &global_scope, 1036 oc, MDL) && 1037 (ds.len >= 25)) { 1038 1039 pfx->preferred_life = getULong(ds.data); 1040 pfx->max_life = getULong(ds.data + 4); 1041 pfx->plen = getUChar(ds.data + 8); 1042 pfx->address.len = 16; 1043 memcpy(pfx->address.iabuf, ds.data + 9, 16); 1044 pfx->starts = cur_time; 1045 1046 log_debug("RCV: | | X-- IAPREFIX %s/%d", 1047 piaddr(pfx->address), (int)pfx->plen); 1048 log_debug("RCV: | | | X-- Preferred lifetime %u.", 1049 pfx->preferred_life); 1050 log_debug("RCV: | | | X-- Max lifetime %u.", 1051 pfx->max_life); 1052 1053 /* Sanity check over the prefix length */ 1054 if ((pfx->plen < 4) || (pfx->plen > 128)) { 1055 log_debug("RCV: | | | !-- INVALID prefix " 1056 "length, IAPREFIX discarded. " 1057 "Check your server configuration."); 1058 dfree(pfx, MDL); 1059 data_string_forget(&ds, MDL); 1060 continue; 1061 } 1062 /* 1063 * RFC 3633 section 10 says we must discard 1064 * prefixes whose pref is later than valid. 1065 */ 1066 if ((pfx->preferred_life > pfx->max_life)) { 1067 log_debug("RCV: | | | !-- INVALID lifetimes, " 1068 "IAPREFIX discarded. Check your " 1069 "server configuration."); 1070 dfree(pfx, MDL); 1071 data_string_forget(&ds, MDL); 1072 continue; 1073 } 1074 1075 /* 1076 * Fortunately this is the last recursion in the 1077 * protocol. 1078 */ 1079 if (ds.len > 25) { 1080 if (!option_state_allocate(&pfx->options, 1081 MDL)) { 1082 log_error("Out of memory allocating " 1083 "IAPREFIX option state."); 1084 dfree(pfx, MDL); 1085 data_string_forget(&ds, MDL); 1086 return ISC_R_NOMEMORY; 1087 } 1088 1089 if (!parse_option_buffer(pfx->options, 1090 ds.data + 25, 1091 ds.len - 25, 1092 &dhcpv6_universe)) { 1093 log_error("Corrupt IAPREFIX options."); 1094 option_state_dereference(&pfx->options, 1095 MDL); 1096 dfree(pfx, MDL); 1097 data_string_forget(&ds, MDL); 1098 return DHCP_R_BADPARSE; 1099 } 1100 } 1101 1102 if (pfx->options != NULL) 1103 log_debug("RCV: | | | X-- " 1104 "[Options]"); 1105 1106 data_string_forget(&ds, MDL); 1107 1108 *ppfx = pfx; 1109 ppfx = &pfx->next; 1110 } else { 1111 log_error("Invalid IAPREFIX option cache."); 1112 dfree(pfx, MDL); 1113 if (ds.len != 0) 1114 data_string_forget(&ds, MDL); 1115 return ISC_R_UNEXPECTED; 1116 } 1117 } 1118 delete_option(&dhcpv6_universe, options, D6O_IAPREFIX); 1119 1120 return ISC_R_SUCCESS; 1121 } 1122 1123 /* Clean up a lease object, deallocate all its parts, and set it to NULL. */ 1124 void 1125 dhc6_lease_destroy(struct dhc6_lease **src, const char *file, int line) 1126 { 1127 struct dhc6_ia *ia, *nia; 1128 struct dhc6_lease *lease; 1129 1130 if (src == NULL || *src == NULL) { 1131 log_error("Attempt to destroy null lease."); 1132 return; 1133 } 1134 lease = *src; 1135 1136 if (lease->server_id.len != 0) 1137 data_string_forget(&lease->server_id, file, line); 1138 1139 for (ia = lease->bindings ; ia != NULL ; ia = nia) { 1140 nia = ia->next; 1141 1142 dhc6_ia_destroy(&ia, file, line); 1143 } 1144 1145 if (lease->options != NULL) 1146 option_state_dereference(&lease->options, file, line); 1147 1148 dfree(lease, file, line); 1149 *src = NULL; 1150 } 1151 1152 /* 1153 * Traverse the addresses list, and destroy their contents, and NULL the 1154 * list pointer. 1155 */ 1156 static void 1157 dhc6_ia_destroy(struct dhc6_ia **src, const char *file, int line) 1158 { 1159 struct dhc6_addr *addr, *naddr; 1160 struct dhc6_ia *ia; 1161 1162 if (src == NULL || *src == NULL) { 1163 log_error("Attempt to destroy null IA."); 1164 return; 1165 } 1166 ia = *src; 1167 1168 for (addr = ia->addrs ; addr != NULL ; addr = naddr) { 1169 naddr = addr->next; 1170 1171 if (addr->options != NULL) 1172 option_state_dereference(&addr->options, file, line); 1173 1174 dfree(addr, file, line); 1175 } 1176 1177 if (ia->options != NULL) 1178 option_state_dereference(&ia->options, file, line); 1179 1180 dfree(ia, file, line); 1181 *src = NULL; 1182 } 1183 1184 /* 1185 * For a given lease, insert it into the tail of the lease list. Upon 1186 * finding a duplicate by server id, remove it and take over its position. 1187 */ 1188 static void 1189 insert_lease(struct dhc6_lease **head, struct dhc6_lease *new) 1190 { 1191 while (*head != NULL) { 1192 if ((*head)->server_id.len == new->server_id.len && 1193 memcmp((*head)->server_id.data, new->server_id.data, 1194 new->server_id.len) == 0) { 1195 new->next = (*head)->next; 1196 dhc6_lease_destroy(head, MDL); 1197 break; 1198 } 1199 1200 head= &(*head)->next; 1201 } 1202 1203 *head = new; 1204 return; 1205 } 1206 1207 /* 1208 * Not really clear what to do here yet. 1209 */ 1210 static int 1211 dhc6_score_lease(struct client_state *client, struct dhc6_lease *lease) 1212 { 1213 struct dhc6_ia *ia; 1214 struct dhc6_addr *addr; 1215 struct option **req; 1216 int i; 1217 1218 if (lease->score) 1219 return lease->score; 1220 1221 lease->score = 1; 1222 1223 /* If this lease lacks a required option, dump it. */ 1224 /* XXX: we should be able to cache the failure... */ 1225 req = client->config->required_options; 1226 if (req != NULL) { 1227 for (i = 0 ; req[i] != NULL ; i++) { 1228 if (lookup_option(&dhcpv6_universe, lease->options, 1229 req[i]->code) == NULL) { 1230 lease->score = 0; 1231 return lease->score; 1232 } 1233 } 1234 } 1235 1236 /* If this lease contains a requested option, improve its score. */ 1237 req = client->config->requested_options; 1238 if (req != NULL) { 1239 for (i = 0 ; req[i] != NULL ; i++) { 1240 if (lookup_option(&dhcpv6_universe, lease->options, 1241 req[i]->code) != NULL) 1242 lease->score++; 1243 } 1244 } 1245 1246 for (ia = lease->bindings ; ia != NULL ; ia = ia->next) { 1247 lease->score += 50; 1248 1249 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) { 1250 lease->score += 100; 1251 } 1252 } 1253 1254 return lease->score; 1255 } 1256 1257 /* 1258 * start_init6() kicks off the process, transmitting a packet and 1259 * scheduling a retransmission event. 1260 */ 1261 void 1262 start_init6(struct client_state *client) 1263 { 1264 struct timeval tv; 1265 1266 log_debug("PRC: Soliciting for leases (INIT)."); 1267 client->state = S_INIT; 1268 1269 /* Initialize timers, RFC3315 section 17.1.2. */ 1270 client->IRT = SOL_TIMEOUT * 100; 1271 client->MRT = SOL_MAX_RT * 100; 1272 client->MRC = 0; 1273 /* Default is 0 (no max) but -1 changes this. */ 1274 if (!onetry) 1275 client->MRD = 0; 1276 else 1277 client->MRD = client->config->timeout; 1278 1279 dhc6_retrans_init(client); 1280 1281 /* 1282 * RFC3315 section 17.1.2 goes out of its way: 1283 * Also, the first RT MUST be selected to be strictly greater than IRT 1284 * by choosing RAND to be strictly greater than 0. 1285 */ 1286 /* if RAND < 0 then RAND = -RAND */ 1287 if (client->RT <= client->IRT) 1288 client->RT = client->IRT + (client->IRT - client->RT); 1289 /* if RAND == 0 then RAND = 1 */ 1290 if (client->RT <= client->IRT) 1291 client->RT = client->IRT + 1; 1292 1293 client->v6_handler = init_handler; 1294 1295 /* 1296 * RFC3315 section 17.1.2 says we MUST start the first packet 1297 * between 0 and SOL_MAX_DELAY seconds. The good news is 1298 * SOL_MAX_DELAY is 1. 1299 */ 1300 tv.tv_sec = cur_tv.tv_sec; 1301 tv.tv_usec = cur_tv.tv_usec; 1302 tv.tv_usec += (random() % (SOL_MAX_DELAY * 100)) * 10000; 1303 if (tv.tv_usec >= 1000000) { 1304 tv.tv_sec += 1; 1305 tv.tv_usec -= 1000000; 1306 } 1307 add_timeout(&tv, do_init6, client, NULL, NULL); 1308 1309 if (nowait) 1310 finish_daemon(); 1311 } 1312 1313 /* 1314 * start_info_request6() kicks off the process, transmitting an info 1315 * request packet and scheduling a retransmission event. 1316 */ 1317 void 1318 start_info_request6(struct client_state *client) 1319 { 1320 struct timeval tv; 1321 1322 log_debug("PRC: Requesting information (INIT)."); 1323 client->state = S_INIT; 1324 1325 /* Initialize timers, RFC3315 section 18.1.5. */ 1326 client->IRT = INF_TIMEOUT * 100; 1327 client->MRT = INF_MAX_RT * 100; 1328 client->MRC = 0; 1329 /* Default is 0 (no max) but -1 changes this. */ 1330 if (!onetry) 1331 client->MRD = 0; 1332 else 1333 client->MRD = client->config->timeout; 1334 1335 dhc6_retrans_init(client); 1336 1337 client->v6_handler = info_request_handler; 1338 1339 /* 1340 * RFC3315 section 18.1.5 says we MUST start the first packet 1341 * between 0 and INF_MAX_DELAY seconds. The good news is 1342 * INF_MAX_DELAY is 1. 1343 */ 1344 tv.tv_sec = cur_tv.tv_sec; 1345 tv.tv_usec = cur_tv.tv_usec; 1346 tv.tv_usec += (random() % (INF_MAX_DELAY * 100)) * 10000; 1347 if (tv.tv_usec >= 1000000) { 1348 tv.tv_sec += 1; 1349 tv.tv_usec -= 1000000; 1350 } 1351 add_timeout(&tv, do_info_request6, client, NULL, NULL); 1352 1353 if (nowait) 1354 go_daemon(); 1355 } 1356 1357 /* 1358 * start_confirm6() kicks off an "init-reboot" version of the process, at 1359 * startup to find out if old bindings are 'fair' and at runtime whenever 1360 * a link cycles state we'll eventually want to do this. 1361 */ 1362 void 1363 start_confirm6(struct client_state *client) 1364 { 1365 struct timeval tv; 1366 1367 /* If there is no active lease, there is nothing to check. */ 1368 if ((client->active_lease == NULL) || 1369 !active_prefix(client) || 1370 client->active_lease->released) { 1371 start_init6(client); 1372 return; 1373 } 1374 1375 log_debug("PRC: Confirming active lease (INIT-REBOOT)."); 1376 client->state = S_REBOOTING; 1377 1378 /* Initialize timers, RFC3315 section 17.1.3. */ 1379 client->IRT = CNF_TIMEOUT * 100; 1380 client->MRT = CNF_MAX_RT * 100; 1381 client->MRC = 0; 1382 client->MRD = CNF_MAX_RD; 1383 1384 dhc6_retrans_init(client); 1385 1386 client->v6_handler = reply_handler; 1387 1388 /* 1389 * RFC3315 section 18.1.2 says we MUST start the first packet 1390 * between 0 and CNF_MAX_DELAY seconds. The good news is 1391 * CNF_MAX_DELAY is 1. 1392 */ 1393 tv.tv_sec = cur_tv.tv_sec; 1394 tv.tv_usec = cur_tv.tv_usec; 1395 tv.tv_usec += (random() % (CNF_MAX_DELAY * 100)) * 10000; 1396 if (tv.tv_usec >= 1000000) { 1397 tv.tv_sec += 1; 1398 tv.tv_usec -= 1000000; 1399 } 1400 if (wanted_ia_pd != 0) { 1401 client->state = S_REBINDING; 1402 client->refresh_type = DHCPV6_REBIND; 1403 add_timeout(&tv, do_refresh6, client, NULL, NULL); 1404 } else 1405 add_timeout(&tv, do_confirm6, client, NULL, NULL); 1406 } 1407 1408 /* 1409 * check_timing6() check on the timing for sending a v6 message 1410 * and then do the basic initialization for a v6 message. 1411 */ 1412 #define CHK_TIM_SUCCESS 0 1413 #define CHK_TIM_MRC_EXCEEDED 1 1414 #define CHK_TIM_MRD_EXCEEDED 2 1415 #define CHK_TIM_ALLOC_FAILURE 3 1416 1417 int 1418 check_timing6 (struct client_state *client, u_int8_t msg_type, 1419 char *msg_str, struct dhc6_lease *lease, 1420 struct data_string *ds) 1421 { 1422 struct timeval elapsed; 1423 1424 /* 1425 * Start_time starts at the first transmission. 1426 */ 1427 if (client->txcount == 0) { 1428 client->start_time.tv_sec = cur_tv.tv_sec; 1429 client->start_time.tv_usec = cur_tv.tv_usec; 1430 } else if ((client->MRC != 0) && (client->txcount > client->MRC)) { 1431 log_info("Max retransmission count exceeded."); 1432 return(CHK_TIM_MRC_EXCEEDED); 1433 } 1434 1435 /* elapsed = cur - start */ 1436 elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec; 1437 elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec; 1438 if (elapsed.tv_usec < 0) { 1439 elapsed.tv_sec -= 1; 1440 elapsed.tv_usec += 1000000; 1441 } 1442 1443 /* Check if finished (-1 argument). */ 1444 if ((client->MRD != 0) && (elapsed.tv_sec > client->MRD)) { 1445 log_info("Max retransmission duration exceeded."); 1446 return(CHK_TIM_MRD_EXCEEDED); 1447 } 1448 1449 memset(ds, 0, sizeof(*ds)); 1450 if (!buffer_allocate(&(ds->buffer), 4, MDL)) { 1451 log_error("Unable to allocate memory for %s.", msg_str); 1452 return(CHK_TIM_ALLOC_FAILURE); 1453 } 1454 ds->data = ds->buffer->data; 1455 ds->len = 4; 1456 1457 ds->buffer->data[0] = msg_type; 1458 memcpy(ds->buffer->data + 1, client->dhcpv6_transaction_id, 3); 1459 1460 /* Form an elapsed option. */ 1461 /* Maximum value is 65535 1/100s coded as 0xffff. */ 1462 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) || 1463 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) { 1464 client->elapsed = 0xffff; 1465 } else { 1466 client->elapsed = elapsed.tv_sec * 100; 1467 client->elapsed += elapsed.tv_usec / 10000; 1468 } 1469 1470 if (client->elapsed == 0) 1471 log_debug("XMT: Forming %s, 0 ms elapsed.", msg_str); 1472 else 1473 log_debug("XMT: Forming %s, %u0 ms elapsed.", msg_str, 1474 (unsigned)client->elapsed); 1475 1476 client->elapsed = htons(client->elapsed); 1477 1478 make_client6_options(client, &client->sent_options, lease, msg_type); 1479 1480 return(CHK_TIM_SUCCESS); 1481 } 1482 1483 /* 1484 * do_init6() marshals and transmits a solicit. 1485 */ 1486 void 1487 do_init6(void *input) 1488 { 1489 struct client_state *client; 1490 struct dhc6_ia *old_ia; 1491 struct dhc6_addr *old_addr; 1492 struct data_string ds; 1493 struct data_string ia; 1494 struct data_string addr; 1495 struct timeval tv; 1496 u_int32_t t1, t2; 1497 int i, idx, len, send_ret; 1498 1499 client = input; 1500 1501 /* 1502 * In RFC3315 section 17.1.2, the retransmission timer is 1503 * used as the selecting timer. 1504 */ 1505 if (client->advertised_leases != NULL) { 1506 start_selecting6(client); 1507 return; 1508 } 1509 1510 switch(check_timing6(client, DHCPV6_SOLICIT, "Solicit", NULL, &ds)) { 1511 case CHK_TIM_MRC_EXCEEDED: 1512 case CHK_TIM_ALLOC_FAILURE: 1513 return; 1514 case CHK_TIM_MRD_EXCEEDED: 1515 client->state = S_STOPPED; 1516 if (client->active_lease != NULL) { 1517 dhc6_lease_destroy(&client->active_lease, MDL); 1518 client->active_lease = NULL; 1519 } 1520 /* Stop if and only if this is the last client. */ 1521 if (stopping_finished()) 1522 exit(2); 1523 return; 1524 } 1525 1526 /* 1527 * Fetch any configured 'sent' options (includes DUID) in wire format. 1528 */ 1529 dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, 1530 NULL, client->sent_options, &global_scope, 1531 &dhcpv6_universe); 1532 1533 /* Use a specific handler with rapid-commit. */ 1534 if (lookup_option(&dhcpv6_universe, client->sent_options, 1535 D6O_RAPID_COMMIT) != NULL) { 1536 client->v6_handler = rapid_commit_handler; 1537 } 1538 1539 /* Append IA_NA. */ 1540 for (i = 0; i < wanted_ia_na; i++) { 1541 /* 1542 * XXX: maybe the IA_NA('s) should be put into the sent_options 1543 * cache. They'd have to be pulled down as they also contain 1544 * different option caches in the same universe... 1545 */ 1546 memset(&ia, 0, sizeof(ia)); 1547 if (!buffer_allocate(&ia.buffer, 12, MDL)) { 1548 log_error("Unable to allocate memory for IA_NA."); 1549 data_string_forget(&ds, MDL); 1550 return; 1551 } 1552 ia.data = ia.buffer->data; 1553 ia.len = 12; 1554 1555 /* 1556 * A simple IAID is the last 4 bytes 1557 * of the hardware address. 1558 */ 1559 if (client->interface->hw_address.hlen > 4) { 1560 idx = client->interface->hw_address.hlen - 4; 1561 len = 4; 1562 } else { 1563 idx = 0; 1564 len = client->interface->hw_address.hlen; 1565 } 1566 memcpy(ia.buffer->data, 1567 client->interface->hw_address.hbuf + idx, 1568 len); 1569 if (i) 1570 ia.buffer->data[3] += i; 1571 1572 t1 = client->config->requested_lease / 2; 1573 t2 = t1 + (t1 / 2); 1574 putULong(ia.buffer->data + 4, t1); 1575 putULong(ia.buffer->data + 8, t2); 1576 1577 log_debug("XMT: X-- IA_NA %s", 1578 print_hex_1(4, ia.buffer->data, 55)); 1579 log_debug("XMT: | X-- Request renew in +%u", (unsigned)t1); 1580 log_debug("XMT: | X-- Request rebind in +%u", (unsigned)t2); 1581 1582 if ((client->active_lease != NULL) && 1583 ((old_ia = find_ia(client->active_lease->bindings, 1584 D6O_IA_NA, 1585 (char *)ia.buffer->data)) != NULL)) { 1586 /* 1587 * For each address in the old IA_NA, 1588 * request a binding. 1589 */ 1590 memset(&addr, 0, sizeof(addr)); 1591 for (old_addr = old_ia->addrs ; old_addr != NULL ; 1592 old_addr = old_addr->next) { 1593 if (old_addr->address.len != 16) { 1594 log_error("Invalid IPv6 address " 1595 "length %d. " 1596 "Ignoring. (%s:%d)", 1597 old_addr->address.len, 1598 MDL); 1599 continue; 1600 } 1601 1602 if (!buffer_allocate(&addr.buffer, 24, MDL)) { 1603 log_error("Unable to allocate memory " 1604 "for IAADDR."); 1605 data_string_forget(&ia, MDL); 1606 data_string_forget(&ds, MDL); 1607 return; 1608 } 1609 addr.data = addr.buffer->data; 1610 addr.len = 24; 1611 1612 memcpy(addr.buffer->data, 1613 old_addr->address.iabuf, 1614 16); 1615 1616 t1 = client->config->requested_lease; 1617 t2 = t1 + (t1 / 2); 1618 putULong(addr.buffer->data + 16, t1); 1619 putULong(addr.buffer->data + 20, t2); 1620 1621 log_debug("XMT: | X-- Request address %s.", 1622 piaddr(old_addr->address)); 1623 log_debug("XMT: | | X-- Request " 1624 "preferred in +%u", 1625 (unsigned)t1); 1626 log_debug("XMT: | | X-- Request valid " 1627 "in +%u", 1628 (unsigned)t2); 1629 1630 append_option(&ia, &dhcpv6_universe, 1631 iaaddr_option, 1632 &addr); 1633 1634 data_string_forget(&addr, MDL); 1635 } 1636 } 1637 1638 append_option(&ds, &dhcpv6_universe, ia_na_option, &ia); 1639 data_string_forget(&ia, MDL); 1640 } 1641 1642 /* Append IA_TA. */ 1643 for (i = 0; i < wanted_ia_ta; i++) { 1644 /* 1645 * XXX: maybe the IA_TA('s) should be put into the sent_options 1646 * cache. They'd have to be pulled down as they also contain 1647 * different option caches in the same universe... 1648 */ 1649 memset(&ia, 0, sizeof(ia)); 1650 if (!buffer_allocate(&ia.buffer, 4, MDL)) { 1651 log_error("Unable to allocate memory for IA_TA."); 1652 data_string_forget(&ds, MDL); 1653 return; 1654 } 1655 ia.data = ia.buffer->data; 1656 ia.len = 4; 1657 1658 /* 1659 * A simple IAID is the last 4 bytes 1660 * of the hardware address. 1661 */ 1662 if (client->interface->hw_address.hlen > 4) { 1663 idx = client->interface->hw_address.hlen - 4; 1664 len = 4; 1665 } else { 1666 idx = 0; 1667 len = client->interface->hw_address.hlen; 1668 } 1669 memcpy(ia.buffer->data, 1670 client->interface->hw_address.hbuf + idx, 1671 len); 1672 if (i) 1673 ia.buffer->data[3] += i; 1674 1675 log_debug("XMT: X-- IA_TA %s", 1676 print_hex_1(4, ia.buffer->data, 55)); 1677 1678 if ((client->active_lease != NULL) && 1679 ((old_ia = find_ia(client->active_lease->bindings, 1680 D6O_IA_TA, 1681 (char *)ia.buffer->data)) != NULL)) { 1682 /* 1683 * For each address in the old IA_TA, 1684 * request a binding. 1685 */ 1686 memset(&addr, 0, sizeof(addr)); 1687 for (old_addr = old_ia->addrs ; old_addr != NULL ; 1688 old_addr = old_addr->next) { 1689 if (old_addr->address.len != 16) { 1690 log_error("Invalid IPv6 address " 1691 "length %d. " 1692 "Ignoring. (%s:%d)", 1693 old_addr->address.len, 1694 MDL); 1695 continue; 1696 } 1697 1698 if (!buffer_allocate(&addr.buffer, 24, MDL)) { 1699 log_error("Unable to allocate memory " 1700 "for IAADDR."); 1701 data_string_forget(&ia, MDL); 1702 data_string_forget(&ds, MDL); 1703 return; 1704 } 1705 addr.data = addr.buffer->data; 1706 addr.len = 24; 1707 1708 memcpy(addr.buffer->data, 1709 old_addr->address.iabuf, 1710 16); 1711 1712 t1 = client->config->requested_lease; 1713 t2 = t1 + (t1 / 2); 1714 putULong(addr.buffer->data + 16, t1); 1715 putULong(addr.buffer->data + 20, t2); 1716 1717 log_debug("XMT: | X-- Request address %s.", 1718 piaddr(old_addr->address)); 1719 log_debug("XMT: | | X-- Request " 1720 "preferred in +%u", 1721 (unsigned)t1); 1722 log_debug("XMT: | | X-- Request valid " 1723 "in +%u", 1724 (unsigned)t2); 1725 1726 append_option(&ia, &dhcpv6_universe, 1727 iaaddr_option, 1728 &addr); 1729 1730 data_string_forget(&addr, MDL); 1731 } 1732 } 1733 1734 append_option(&ds, &dhcpv6_universe, ia_ta_option, &ia); 1735 data_string_forget(&ia, MDL); 1736 } 1737 1738 /* Append IA_PD. */ 1739 for (i = 0; i < wanted_ia_pd; i++) { 1740 /* 1741 * XXX: maybe the IA_PD('s) should be put into the sent_options 1742 * cache. They'd have to be pulled down as they also contain 1743 * different option caches in the same universe... 1744 */ 1745 memset(&ia, 0, sizeof(ia)); 1746 if (!buffer_allocate(&ia.buffer, 12, MDL)) { 1747 log_error("Unable to allocate memory for IA_PD."); 1748 data_string_forget(&ds, MDL); 1749 return; 1750 } 1751 ia.data = ia.buffer->data; 1752 ia.len = 12; 1753 1754 /* 1755 * A simple IAID is the last 4 bytes 1756 * of the hardware address. 1757 */ 1758 if (client->interface->hw_address.hlen > 4) { 1759 idx = client->interface->hw_address.hlen - 4; 1760 len = 4; 1761 } else { 1762 idx = 0; 1763 len = client->interface->hw_address.hlen; 1764 } 1765 memcpy(ia.buffer->data, 1766 client->interface->hw_address.hbuf + idx, 1767 len); 1768 if (i) 1769 ia.buffer->data[3] += i; 1770 1771 t1 = client->config->requested_lease / 2; 1772 t2 = t1 + (t1 / 2); 1773 putULong(ia.buffer->data + 4, t1); 1774 putULong(ia.buffer->data + 8, t2); 1775 1776 log_debug("XMT: X-- IA_PD %s", 1777 print_hex_1(4, ia.buffer->data, 55)); 1778 log_debug("XMT: | X-- Request renew in +%u", (unsigned)t1); 1779 log_debug("XMT: | X-- Request rebind in +%u", (unsigned)t2); 1780 1781 if ((client->active_lease != NULL) && 1782 ((old_ia = find_ia(client->active_lease->bindings, 1783 D6O_IA_PD, 1784 (char *)ia.buffer->data)) != NULL)) { 1785 /* 1786 * For each prefix in the old IA_PD, 1787 * request a binding. 1788 */ 1789 memset(&addr, 0, sizeof(addr)); 1790 for (old_addr = old_ia->addrs ; old_addr != NULL ; 1791 old_addr = old_addr->next) { 1792 if (old_addr->address.len != 16) { 1793 log_error("Invalid IPv6 prefix, " 1794 "Ignoring. (%s:%d)", 1795 MDL); 1796 continue; 1797 } 1798 1799 if (!buffer_allocate(&addr.buffer, 25, MDL)) { 1800 log_error("Unable to allocate memory " 1801 "for IAPREFIX."); 1802 data_string_forget(&ia, MDL); 1803 data_string_forget(&ds, MDL); 1804 return; 1805 } 1806 addr.data = addr.buffer->data; 1807 addr.len = 25; 1808 1809 t1 = client->config->requested_lease; 1810 t2 = t1 + (t1 / 2); 1811 putULong(addr.buffer->data, t1); 1812 putULong(addr.buffer->data + 4, t2); 1813 1814 putUChar(addr.buffer->data + 8, 1815 old_addr->plen); 1816 memcpy(addr.buffer->data + 9, 1817 old_addr->address.iabuf, 1818 16); 1819 1820 log_debug("XMT: | X-- Request prefix %s/%u.", 1821 piaddr(old_addr->address), 1822 (unsigned) old_addr->plen); 1823 log_debug("XMT: | | X-- Request " 1824 "preferred in +%u", 1825 (unsigned)t1); 1826 log_debug("XMT: | | X-- Request valid " 1827 "in +%u", 1828 (unsigned)t2); 1829 1830 append_option(&ia, &dhcpv6_universe, 1831 iaprefix_option, 1832 &addr); 1833 1834 data_string_forget(&addr, MDL); 1835 } 1836 } 1837 1838 append_option(&ds, &dhcpv6_universe, ia_pd_option, &ia); 1839 data_string_forget(&ia, MDL); 1840 } 1841 1842 /* Transmit and wait. */ 1843 1844 log_info("XMT: Solicit on %s, interval %ld0ms.", 1845 client->name ? client->name : client->interface->name, 1846 (long int)client->RT); 1847 1848 send_ret = send_packet6(client->interface, 1849 ds.data, ds.len, &DHCPv6DestAddr); 1850 if (send_ret != ds.len) { 1851 log_error("dhc6: send_packet6() sent %d of %d bytes", 1852 send_ret, ds.len); 1853 } 1854 1855 data_string_forget(&ds, MDL); 1856 1857 /* Wait RT */ 1858 tv.tv_sec = cur_tv.tv_sec + client->RT / 100; 1859 tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000; 1860 if (tv.tv_usec >= 1000000) { 1861 tv.tv_sec += 1; 1862 tv.tv_usec -= 1000000; 1863 } 1864 add_timeout(&tv, do_init6, client, NULL, NULL); 1865 1866 dhc6_retrans_advance(client); 1867 } 1868 1869 /* do_info_request6() marshals and transmits an information-request. */ 1870 void 1871 do_info_request6(void *input) 1872 { 1873 struct client_state *client; 1874 struct data_string ds; 1875 struct timeval tv; 1876 int send_ret; 1877 1878 client = input; 1879 1880 switch(check_timing6(client, DHCPV6_INFORMATION_REQUEST, 1881 "Info-Request", NULL, &ds)) { 1882 case CHK_TIM_MRC_EXCEEDED: 1883 case CHK_TIM_ALLOC_FAILURE: 1884 return; 1885 case CHK_TIM_MRD_EXCEEDED: 1886 exit(2); 1887 case CHK_TIM_SUCCESS: 1888 break; 1889 } 1890 1891 /* Fetch any configured 'sent' options (includes DUID) in wire format. 1892 */ 1893 dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, 1894 NULL, client->sent_options, &global_scope, 1895 &dhcpv6_universe); 1896 1897 /* Transmit and wait. */ 1898 1899 log_info("XMT: Info-Request on %s, interval %ld0ms.", 1900 client->name ? client->name : client->interface->name, 1901 (long int)client->RT); 1902 1903 send_ret = send_packet6(client->interface, 1904 ds.data, ds.len, &DHCPv6DestAddr); 1905 if (send_ret != ds.len) { 1906 log_error("dhc6: send_packet6() sent %d of %d bytes", 1907 send_ret, ds.len); 1908 } 1909 1910 data_string_forget(&ds, MDL); 1911 1912 /* Wait RT */ 1913 tv.tv_sec = cur_tv.tv_sec + client->RT / 100; 1914 tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000; 1915 if (tv.tv_usec >= 1000000) { 1916 tv.tv_sec += 1; 1917 tv.tv_usec -= 1000000; 1918 } 1919 add_timeout(&tv, do_info_request6, client, NULL, NULL); 1920 1921 dhc6_retrans_advance(client); 1922 } 1923 1924 /* do_confirm6() creates a Confirm packet and transmits it. This function 1925 * is called on every timeout to (re)transmit. 1926 */ 1927 void 1928 do_confirm6(void *input) 1929 { 1930 struct client_state *client; 1931 struct data_string ds; 1932 int send_ret; 1933 struct timeval tv; 1934 1935 client = input; 1936 1937 if (client->active_lease == NULL) 1938 log_fatal("Impossible condition at %s:%d.", MDL); 1939 1940 /* In section 17.1.3, it is said: 1941 * 1942 * If the client receives no responses before the message 1943 * transmission process terminates, as described in section 14, 1944 * the client SHOULD continue to use any IP addresses, using the 1945 * last known lifetimes for those addresses, and SHOULD continue 1946 * to use any other previously obtained configuration parameters. 1947 * 1948 * So if confirm times out, we go active. 1949 * 1950 * XXX: Should we reduce all IA's t1 to 0, so that we renew and 1951 * stick there until we get a reply? 1952 */ 1953 1954 switch(check_timing6(client, DHCPV6_CONFIRM, "Confirm", 1955 client->active_lease, &ds)) { 1956 case CHK_TIM_MRC_EXCEEDED: 1957 case CHK_TIM_MRD_EXCEEDED: 1958 start_bound(client); 1959 return; 1960 case CHK_TIM_ALLOC_FAILURE: 1961 return; 1962 case CHK_TIM_SUCCESS: 1963 break; 1964 } 1965 1966 /* Fetch any configured 'sent' options (includes DUID') in wire format. 1967 */ 1968 dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL, 1969 client->sent_options, &global_scope, 1970 &dhcpv6_universe); 1971 1972 /* Append IA's. */ 1973 if (wanted_ia_na && 1974 dhc6_add_ia_na(client, &ds, client->active_lease, 1975 DHCPV6_CONFIRM) != ISC_R_SUCCESS) { 1976 data_string_forget(&ds, MDL); 1977 return; 1978 } 1979 if (wanted_ia_ta && 1980 dhc6_add_ia_ta(client, &ds, client->active_lease, 1981 DHCPV6_CONFIRM) != ISC_R_SUCCESS) { 1982 data_string_forget(&ds, MDL); 1983 return; 1984 } 1985 1986 /* Transmit and wait. */ 1987 1988 log_info("XMT: Confirm on %s, interval %ld0ms.", 1989 client->name ? client->name : client->interface->name, 1990 (long int)client->RT); 1991 1992 send_ret = send_packet6(client->interface, ds.data, ds.len, 1993 &DHCPv6DestAddr); 1994 if (send_ret != ds.len) { 1995 log_error("dhc6: sendpacket6() sent %d of %d bytes", 1996 send_ret, ds.len); 1997 } 1998 1999 data_string_forget(&ds, MDL); 2000 2001 /* Wait RT */ 2002 tv.tv_sec = cur_tv.tv_sec + client->RT / 100; 2003 tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000; 2004 if (tv.tv_usec >= 1000000) { 2005 tv.tv_sec += 1; 2006 tv.tv_usec -= 1000000; 2007 } 2008 add_timeout(&tv, do_confirm6, client, NULL, NULL); 2009 2010 dhc6_retrans_advance(client); 2011 } 2012 2013 /* 2014 * Release addresses. 2015 */ 2016 void 2017 start_release6(struct client_state *client) 2018 { 2019 /* Cancel any pending transmissions */ 2020 cancel_timeout(do_confirm6, client); 2021 cancel_timeout(do_select6, client); 2022 cancel_timeout(do_refresh6, client); 2023 cancel_timeout(do_release6, client); 2024 client->state = S_STOPPED; 2025 2026 /* 2027 * It is written: "The client MUST NOT use any of the addresses it 2028 * is releasing as the source address in the Release message or in 2029 * any subsequently transmitted message." So unconfigure now. 2030 */ 2031 unconfigure6(client, "RELEASE6"); 2032 2033 /* Note this in the lease file. */ 2034 if (client->active_lease == NULL) 2035 return; 2036 client->active_lease->released = ISC_TRUE; 2037 write_client6_lease(client, client->active_lease, 0, 1); 2038 2039 /* Set timers per RFC3315 section 18.1.6. */ 2040 client->IRT = REL_TIMEOUT * 100; 2041 client->MRT = 0; 2042 client->MRC = REL_MAX_RC; 2043 client->MRD = 0; 2044 2045 dhc6_retrans_init(client); 2046 client->v6_handler = reply_handler; 2047 2048 do_release6(client); 2049 } 2050 /* 2051 * do_release6() creates a Release packet and transmits it. 2052 */ 2053 static void 2054 do_release6(void *input) 2055 { 2056 struct client_state *client; 2057 struct data_string ds; 2058 int send_ret; 2059 struct timeval tv; 2060 2061 client = input; 2062 2063 if ((client->active_lease == NULL) || !active_prefix(client)) 2064 return; 2065 2066 switch(check_timing6(client, DHCPV6_RELEASE, "Release", 2067 client->active_lease, &ds)) { 2068 case CHK_TIM_MRC_EXCEEDED: 2069 case CHK_TIM_ALLOC_FAILURE: 2070 case CHK_TIM_MRD_EXCEEDED: 2071 goto release_done; 2072 case CHK_TIM_SUCCESS: 2073 break; 2074 } 2075 2076 /* 2077 * Don't use unicast as we don't know if we still have an 2078 * available address with enough scope. 2079 */ 2080 2081 dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL, 2082 client->sent_options, &global_scope, 2083 &dhcpv6_universe); 2084 2085 /* Append IA's (but don't release temporary addresses). */ 2086 if (wanted_ia_na && 2087 dhc6_add_ia_na(client, &ds, client->active_lease, 2088 DHCPV6_RELEASE) != ISC_R_SUCCESS) { 2089 data_string_forget(&ds, MDL); 2090 goto release_done; 2091 } 2092 if (wanted_ia_pd && 2093 dhc6_add_ia_pd(client, &ds, client->active_lease, 2094 DHCPV6_RELEASE) != ISC_R_SUCCESS) { 2095 data_string_forget(&ds, MDL); 2096 goto release_done; 2097 } 2098 2099 /* Transmit and wait. */ 2100 log_info("XMT: Release on %s, interval %ld0ms.", 2101 client->name ? client->name : client->interface->name, 2102 (long int)client->RT); 2103 2104 send_ret = send_packet6(client->interface, ds.data, ds.len, 2105 &DHCPv6DestAddr); 2106 if (send_ret != ds.len) { 2107 log_error("dhc6: sendpacket6() sent %d of %d bytes", 2108 send_ret, ds.len); 2109 } 2110 2111 data_string_forget(&ds, MDL); 2112 2113 /* Wait RT */ 2114 tv.tv_sec = cur_tv.tv_sec + client->RT / 100; 2115 tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000; 2116 if (tv.tv_usec >= 1000000) { 2117 tv.tv_sec += 1; 2118 tv.tv_usec -= 1000000; 2119 } 2120 add_timeout(&tv, do_release6, client, NULL, NULL); 2121 dhc6_retrans_advance(client); 2122 return; 2123 2124 release_done: 2125 dhc6_lease_destroy(&client->active_lease, MDL); 2126 client->active_lease = NULL; 2127 if (stopping_finished()) 2128 exit(0); 2129 } 2130 2131 /* status_log() just puts a status code into displayable form and logs it 2132 * to info level. 2133 */ 2134 static void 2135 status_log(int code, const char *scope, const char *additional, int len) 2136 { 2137 const char *msg = NULL; 2138 2139 switch(code) { 2140 case STATUS_Success: 2141 msg = "Success"; 2142 break; 2143 2144 case STATUS_UnspecFail: 2145 msg = "UnspecFail"; 2146 break; 2147 2148 case STATUS_NoAddrsAvail: 2149 msg = "NoAddrsAvail"; 2150 break; 2151 2152 case STATUS_NoBinding: 2153 msg = "NoBinding"; 2154 break; 2155 2156 case STATUS_NotOnLink: 2157 msg = "NotOnLink"; 2158 break; 2159 2160 case STATUS_UseMulticast: 2161 msg = "UseMulticast"; 2162 break; 2163 2164 case STATUS_NoPrefixAvail: 2165 msg = "NoPrefixAvail"; 2166 break; 2167 2168 default: 2169 msg = "UNKNOWN"; 2170 break; 2171 } 2172 2173 if (len > 0) 2174 log_info("%s status code %s: %s", scope, msg, 2175 print_hex_1(len, 2176 (const unsigned char *)additional, 50)); 2177 else 2178 log_info("%s status code %s.", scope, msg); 2179 } 2180 2181 /* Acquire a status code. 2182 */ 2183 static isc_result_t 2184 dhc6_get_status_code(struct option_state *options, unsigned *code, 2185 struct data_string *msg) 2186 { 2187 struct option_cache *oc; 2188 struct data_string ds; 2189 isc_result_t rval = ISC_R_SUCCESS; 2190 2191 if ((options == NULL) || (code == NULL)) 2192 return DHCP_R_INVALIDARG; 2193 2194 if ((msg != NULL) && (msg->len != 0)) 2195 return DHCP_R_INVALIDARG; 2196 2197 memset(&ds, 0, sizeof(ds)); 2198 2199 /* Assume success if there is no option. */ 2200 *code = STATUS_Success; 2201 2202 oc = lookup_option(&dhcpv6_universe, options, D6O_STATUS_CODE); 2203 if ((oc != NULL) && 2204 evaluate_option_cache(&ds, NULL, NULL, NULL, options, 2205 NULL, &global_scope, oc, MDL)) { 2206 if (ds.len < 2) { 2207 log_error("Invalid status code length %d.", ds.len); 2208 rval = DHCP_R_FORMERR; 2209 } else 2210 *code = getUShort(ds.data); 2211 2212 if ((msg != NULL) && (ds.len > 2)) { 2213 data_string_copy(msg, &ds, MDL); 2214 msg->data += 2; 2215 msg->len -= 2; 2216 } 2217 2218 data_string_forget(&ds, MDL); 2219 return rval; 2220 } 2221 2222 return ISC_R_NOTFOUND; 2223 } 2224 2225 /* Look at status codes in an advertise, and reform the return value. 2226 */ 2227 static isc_result_t 2228 dhc6_check_status(isc_result_t rval, struct option_state *options, 2229 const char *scope, unsigned *code) 2230 { 2231 struct data_string msg; 2232 isc_result_t status; 2233 2234 if ((scope == NULL) || (code == NULL)) 2235 return DHCP_R_INVALIDARG; 2236 2237 /* If we don't find a code, we assume success. */ 2238 *code = STATUS_Success; 2239 2240 /* If there is no options cache, then there is no code. */ 2241 if (options != NULL) { 2242 memset(&msg, 0, sizeof(msg)); 2243 status = dhc6_get_status_code(options, code, &msg); 2244 2245 if (status == ISC_R_SUCCESS) { 2246 status_log(*code, scope, (char *)msg.data, msg.len); 2247 data_string_forget(&msg, MDL); 2248 2249 if (*code != STATUS_Success) 2250 rval = ISC_R_FAILURE; 2251 2252 } else if (status != ISC_R_NOTFOUND) 2253 rval = status; 2254 } 2255 2256 return rval; 2257 } 2258 2259 /* Look in the packet, any IA's, and any IAADDR's within those IA's to find 2260 * status code options that are not SUCCESS. 2261 */ 2262 static isc_result_t 2263 dhc6_check_advertise(struct dhc6_lease *lease) 2264 { 2265 struct dhc6_ia *ia; 2266 struct dhc6_addr *addr; 2267 isc_result_t rval = ISC_R_SUCCESS; 2268 int have_addrs = ISC_FALSE; 2269 unsigned code; 2270 const char *scope; 2271 2272 rval = dhc6_check_status(rval, lease->options, "message", &code); 2273 2274 for (ia = lease->bindings ; ia != NULL ; ia = ia->next) { 2275 switch (ia->ia_type) { 2276 case D6O_IA_NA: 2277 scope = "IA_NA"; 2278 break; 2279 case D6O_IA_TA: 2280 scope = "IA_TA"; 2281 break; 2282 case D6O_IA_PD: 2283 scope = "IA_PD"; 2284 break; 2285 default: 2286 log_error("dhc6_check_advertise: no type."); 2287 return ISC_R_FAILURE; 2288 } 2289 rval = dhc6_check_status(rval, ia->options, scope, &code); 2290 2291 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) { 2292 if (ia->ia_type != D6O_IA_PD) 2293 scope = "IAADDR"; 2294 else 2295 scope = "IAPREFIX"; 2296 rval = dhc6_check_status(rval, addr->options, 2297 scope, &code); 2298 have_addrs = ISC_TRUE; 2299 } 2300 } 2301 2302 if (have_addrs != ISC_TRUE) 2303 rval = ISC_R_ADDRNOTAVAIL; 2304 2305 return rval; 2306 } 2307 2308 /* status code <-> action matrix for the client in INIT state 2309 * (rapid/commit). Returns always false as no action is defined. 2310 */ 2311 static isc_boolean_t 2312 dhc6_init_action(struct client_state *client, isc_result_t *rvalp, 2313 unsigned code) 2314 { 2315 if (rvalp == NULL) 2316 log_fatal("Impossible condition at %s:%d.", MDL); 2317 2318 if (client == NULL) { 2319 *rvalp = DHCP_R_INVALIDARG; 2320 return ISC_FALSE; 2321 } 2322 2323 if (*rvalp == ISC_R_SUCCESS) 2324 return ISC_FALSE; 2325 2326 /* No possible action in any case... */ 2327 return ISC_FALSE; 2328 } 2329 2330 /* status code <-> action matrix for the client in SELECT state 2331 * (request/reply). Returns true if action was taken (and the 2332 * packet should be ignored), or false if no action was taken. 2333 */ 2334 static isc_boolean_t 2335 dhc6_select_action(struct client_state *client, isc_result_t *rvalp, 2336 unsigned code) 2337 { 2338 struct dhc6_lease *lease; 2339 isc_result_t rval; 2340 2341 if (rvalp == NULL) 2342 log_fatal("Impossible condition at %s:%d.", MDL); 2343 2344 if (client == NULL) { 2345 *rvalp = DHCP_R_INVALIDARG; 2346 return ISC_FALSE; 2347 } 2348 rval = *rvalp; 2349 2350 if (rval == ISC_R_SUCCESS) 2351 return ISC_FALSE; 2352 2353 switch (code) { 2354 /* We may have an earlier failure status code (so no 2355 * success rval), and a success code now. This 2356 * doesn't upgrade the rval to success, but it does 2357 * mean we take no action here. 2358 */ 2359 case STATUS_Success: 2360 /* Gimpy server, or possibly an attacker. */ 2361 case STATUS_NoBinding: 2362 case STATUS_UseMulticast: 2363 /* Take no action. */ 2364 return ISC_FALSE; 2365 2366 /* If the server can't deal with us, either try the 2367 * next advertised server, or continue retrying if there 2368 * weren't any. 2369 */ 2370 default: 2371 case STATUS_UnspecFail: 2372 if (client->advertised_leases != NULL) { 2373 dhc6_lease_destroy(&client->selected_lease, MDL); 2374 client->selected_lease = NULL; 2375 2376 start_selecting6(client); 2377 2378 break; 2379 } else /* Take no action - continue to retry. */ 2380 return ISC_FALSE; 2381 2382 /* If the server has no addresses, try other servers if 2383 * we got some, otherwise go to INIT to hope for more 2384 * servers. 2385 */ 2386 case STATUS_NoAddrsAvail: 2387 case STATUS_NoPrefixAvail: 2388 if (client->state == S_REBOOTING) 2389 return ISC_FALSE; 2390 2391 if (client->selected_lease == NULL) 2392 log_fatal("Impossible case at %s:%d.", MDL); 2393 2394 dhc6_lease_destroy(&client->selected_lease, MDL); 2395 client->selected_lease = NULL; 2396 2397 if (client->advertised_leases != NULL) 2398 start_selecting6(client); 2399 else 2400 start_init6(client); 2401 2402 break; 2403 2404 /* If we got a NotOnLink from a Confirm, then we're not 2405 * on link. Kill the old-active binding and start over. 2406 * 2407 * If we got a NotOnLink from our Request, something weird 2408 * happened. Start over from scratch anyway. 2409 */ 2410 case STATUS_NotOnLink: 2411 if (client->state == S_REBOOTING) { 2412 if (client->active_lease == NULL) 2413 log_fatal("Impossible case at %s:%d.", MDL); 2414 2415 dhc6_lease_destroy(&client->active_lease, MDL); 2416 } else { 2417 if (client->selected_lease == NULL) 2418 log_fatal("Impossible case at %s:%d.", MDL); 2419 2420 dhc6_lease_destroy(&client->selected_lease, MDL); 2421 client->selected_lease = NULL; 2422 2423 while (client->advertised_leases != NULL) { 2424 lease = client->advertised_leases; 2425 client->advertised_leases = lease->next; 2426 2427 dhc6_lease_destroy(&lease, MDL); 2428 } 2429 } 2430 2431 start_init6(client); 2432 break; 2433 } 2434 2435 return ISC_TRUE; 2436 } 2437 2438 static void 2439 dhc6_withdraw_lease(struct client_state *client) 2440 { 2441 struct dhc6_ia *ia; 2442 struct dhc6_addr *addr; 2443 2444 if ((client == NULL) || (client->active_lease == NULL)) 2445 return; 2446 2447 for (ia = client->active_lease->bindings ; ia != NULL ; 2448 ia = ia->next) { 2449 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) { 2450 addr->max_life = addr->preferred_life = 0; 2451 } 2452 } 2453 2454 /* Perform expiry. */ 2455 do_expire(client); 2456 } 2457 2458 /* status code <-> action matrix for the client in BOUND state 2459 * (request/reply). Returns true if action was taken (and the 2460 * packet should be ignored), or false if no action was taken. 2461 */ 2462 static isc_boolean_t 2463 dhc6_reply_action(struct client_state *client, isc_result_t *rvalp, 2464 unsigned code) 2465 { 2466 isc_result_t rval; 2467 2468 if (rvalp == NULL) 2469 log_fatal("Impossible condition at %s:%d.", MDL); 2470 2471 if (client == NULL) { 2472 *rvalp = DHCP_R_INVALIDARG; 2473 return ISC_FALSE; 2474 } 2475 rval = *rvalp; 2476 2477 if (rval == ISC_R_SUCCESS) 2478 return ISC_FALSE; 2479 2480 switch (code) { 2481 /* It's possible an earlier status code set rval to a failure 2482 * code, and we've encountered a later success. 2483 */ 2484 case STATUS_Success: 2485 /* In "refreshes" (where we get replies), we probably 2486 * still have a valid lease. So "take no action" and 2487 * the upper levels will keep retrying until the lease 2488 * expires (or we rebind). 2489 */ 2490 case STATUS_UnspecFail: 2491 /* For unknown codes...it's a soft (retryable) error. */ 2492 default: 2493 return ISC_FALSE; 2494 2495 /* The server is telling us to use a multicast address, so 2496 * we have to delete the unicast option from the active 2497 * lease, then allow retransmission to occur normally. 2498 * (XXX: It might be preferable in this case to retransmit 2499 * sooner than the current interval, but for now we don't.) 2500 */ 2501 case STATUS_UseMulticast: 2502 if (client->active_lease != NULL) 2503 delete_option(&dhcp_universe, 2504 client->active_lease->options, 2505 D6O_UNICAST); 2506 return ISC_FALSE; 2507 2508 /* "When the client receives a NotOnLink status from the 2509 * server in response to a Request, the client can either 2510 * re-issue the Request without specifying any addresses 2511 * or restart the DHCP server discovery process." 2512 * 2513 * This is strange. If competing server evaluation is 2514 * useful (and therefore in the protocol), then why would 2515 * a client's first reaction be to request from the same 2516 * server on a different link? Surely you'd want to 2517 * re-evaluate your server selection. 2518 * 2519 * Well, I guess that's the answer. 2520 */ 2521 case STATUS_NotOnLink: 2522 /* In this case, we need to rescind all current active 2523 * bindings (just 'expire' them all normally, if early). 2524 * They're no use to us on the wrong link. Then head back 2525 * to init, redo server selection and get new addresses. 2526 */ 2527 dhc6_withdraw_lease(client); 2528 break; 2529 2530 /* "If the status code is NoAddrsAvail, the client has 2531 * received no usable addresses in the IA and may choose 2532 * to try obtaining addresses for the IA from another 2533 * server." 2534 */ 2535 case STATUS_NoAddrsAvail: 2536 case STATUS_NoPrefixAvail: 2537 /* Head back to init, keeping any active bindings (!). */ 2538 start_init6(client); 2539 break; 2540 2541 /* - sends a Request message if the IA contained a Status 2542 * Code option with the NoBinding status (and does not 2543 * send any additional Renew/Rebind messages) 2544 */ 2545 case STATUS_NoBinding: 2546 if (client->advertised_leases != NULL) 2547 log_fatal("Impossible condition at %s:%d.", MDL); 2548 2549 client->advertised_leases = 2550 dhc6_dup_lease(client->active_lease, MDL); 2551 start_selecting6(client); 2552 break; 2553 } 2554 2555 return ISC_TRUE; 2556 } 2557 2558 /* status code <-> action matrix for the client in STOPPED state 2559 * (release/decline). Returns true if action was taken (and the 2560 * packet should be ignored), or false if no action was taken. 2561 * NoBinding is translated into Success. 2562 */ 2563 static isc_boolean_t 2564 dhc6_stop_action(struct client_state *client, isc_result_t *rvalp, 2565 unsigned code) 2566 { 2567 isc_result_t rval; 2568 2569 if (rvalp == NULL) 2570 log_fatal("Impossible condition at %s:%d.", MDL); 2571 2572 if (client == NULL) { 2573 *rvalp = DHCP_R_INVALIDARG; 2574 return ISC_FALSE; 2575 } 2576 rval = *rvalp; 2577 2578 if (rval == ISC_R_SUCCESS) 2579 return ISC_FALSE; 2580 2581 switch (code) { 2582 /* It's possible an earlier status code set rval to a failure 2583 * code, and we've encountered a later success. 2584 */ 2585 case STATUS_Success: 2586 /* For unknown codes...it's a soft (retryable) error. */ 2587 case STATUS_UnspecFail: 2588 default: 2589 return ISC_FALSE; 2590 2591 /* NoBinding is not an error */ 2592 case STATUS_NoBinding: 2593 if (rval == ISC_R_FAILURE) 2594 *rvalp = ISC_R_SUCCESS; 2595 return ISC_FALSE; 2596 2597 /* Should not happen */ 2598 case STATUS_NoAddrsAvail: 2599 case STATUS_NoPrefixAvail: 2600 break; 2601 2602 /* Give up on it */ 2603 case STATUS_NotOnLink: 2604 break; 2605 2606 /* The server is telling us to use a multicast address, so 2607 * we have to delete the unicast option from the active 2608 * lease, then allow retransmission to occur normally. 2609 * (XXX: It might be preferable in this case to retransmit 2610 * sooner than the current interval, but for now we don't.) 2611 */ 2612 case STATUS_UseMulticast: 2613 if (client->active_lease != NULL) 2614 delete_option(&dhcp_universe, 2615 client->active_lease->options, 2616 D6O_UNICAST); 2617 return ISC_FALSE; 2618 } 2619 2620 return ISC_TRUE; 2621 } 2622 2623 /* Look at a new and old lease, and make sure the new information is not 2624 * losing us any state. 2625 */ 2626 static isc_result_t 2627 dhc6_check_reply(struct client_state *client, struct dhc6_lease *new) 2628 { 2629 isc_boolean_t (*action)(struct client_state *, 2630 isc_result_t *, unsigned); 2631 struct dhc6_ia *ia; 2632 struct dhc6_addr *addr; 2633 isc_result_t rval = ISC_R_SUCCESS; 2634 unsigned code; 2635 const char *scope; 2636 int nscore, sscore; 2637 2638 if ((client == NULL) || (new == NULL)) 2639 return DHCP_R_INVALIDARG; 2640 2641 switch (client->state) { 2642 case S_INIT: 2643 action = dhc6_init_action; 2644 break; 2645 2646 case S_SELECTING: 2647 case S_REBOOTING: 2648 action = dhc6_select_action; 2649 break; 2650 2651 case S_RENEWING: 2652 case S_REBINDING: 2653 action = dhc6_reply_action; 2654 break; 2655 2656 case S_STOPPED: 2657 action = dhc6_stop_action; 2658 break; 2659 2660 default: 2661 log_fatal("Impossible condition at %s:%d.", MDL); 2662 return ISC_R_CANCELED; 2663 } 2664 2665 /* If there is a code to extract, and if there is some 2666 * action to take based on that code, then take the action 2667 * and do not continue. 2668 */ 2669 rval = dhc6_check_status(rval, new->options, "message", &code); 2670 if (action(client, &rval, code)) 2671 return ISC_R_CANCELED; 2672 2673 for (ia = new->bindings ; ia != NULL ; ia = ia->next) { 2674 switch (ia->ia_type) { 2675 case D6O_IA_NA: 2676 scope = "IA_NA"; 2677 break; 2678 case D6O_IA_TA: 2679 scope = "IA_TA"; 2680 break; 2681 case D6O_IA_PD: 2682 scope = "IA_PD"; 2683 break; 2684 default: 2685 log_error("dhc6_check_reply: no type."); 2686 return DHCP_R_INVALIDARG; 2687 } 2688 rval = dhc6_check_status(rval, ia->options, 2689 scope, &code); 2690 if (action(client, &rval, code)) 2691 return ISC_R_CANCELED; 2692 2693 for (addr = ia->addrs ; addr != NULL ; 2694 addr = addr->next) { 2695 if (ia->ia_type != D6O_IA_PD) 2696 scope = "IAADDR"; 2697 else 2698 scope = "IAPREFIX"; 2699 rval = dhc6_check_status(rval, addr->options, 2700 scope, &code); 2701 if (action(client, &rval, code)) 2702 return ISC_R_CANCELED; 2703 } 2704 } 2705 2706 /* A Confirm->Reply is unsuitable for comparison to the old lease. */ 2707 if (client->state == S_REBOOTING) 2708 return rval; 2709 2710 /* No old lease in rapid-commit. */ 2711 if (client->state == S_INIT) 2712 return rval; 2713 2714 switch (client->state) { 2715 case S_SELECTING: 2716 /* Compare the new lease with the selected lease to make 2717 * sure there is no risky business. 2718 */ 2719 nscore = dhc6_score_lease(client, new); 2720 sscore = dhc6_score_lease(client, client->selected_lease); 2721 if ((client->advertised_leases != NULL) && 2722 (nscore < (sscore / 2))) { 2723 /* XXX: An attacker might reply this way to make 2724 * XXX: sure we latch onto their configuration. 2725 * XXX: We might want to ignore the packet and 2726 * XXX: schedule re-selection at the next timeout? 2727 */ 2728 log_error("PRC: BAIT AND SWITCH detected. Score of " 2729 "supplied lease (%d) is substantially " 2730 "smaller than the advertised score (%d). " 2731 "Trying other servers.", 2732 nscore, sscore); 2733 2734 dhc6_lease_destroy(&client->selected_lease, MDL); 2735 client->selected_lease = NULL; 2736 2737 start_selecting6(client); 2738 2739 return ISC_R_CANCELED; 2740 } 2741 break; 2742 2743 case S_RENEWING: 2744 case S_REBINDING: 2745 /* This leaves one RFC3315 status check unimplemented: 2746 * 2747 * - sends a Renew/Rebind if the IA is not in the Reply 2748 * message 2749 * 2750 * We rely on the scheduling system to note that the IA has 2751 * not left Renewal/Rebinding/whatever since it still carries 2752 * old times from the last successful binding. So this is 2753 * implemented actually, just not explicitly. 2754 */ 2755 break; 2756 2757 case S_STOPPED: 2758 /* Nothing critical to do at this stage. */ 2759 break; 2760 2761 default: 2762 log_fatal("REALLY impossible condition at %s:%d.", MDL); 2763 return ISC_R_CANCELED; 2764 } 2765 2766 return rval; 2767 } 2768 2769 /* While in init state, we only collect advertisements. If there happens 2770 * to be an advertisement with a preference option of 255, that's an 2771 * automatic exit. Otherwise, we collect advertisements until our timeout 2772 * expires (client->RT). 2773 */ 2774 void 2775 init_handler(struct packet *packet, struct client_state *client) 2776 { 2777 struct dhc6_lease *lease; 2778 2779 /* In INIT state, we send solicits, we only expect to get 2780 * advertises (rapid commit has its own handler). 2781 */ 2782 if (packet->dhcpv6_msg_type != DHCPV6_ADVERTISE) 2783 return; 2784 2785 /* RFC3315 section 15.3 validation (same as 15.10 since we 2786 * always include a client id). 2787 */ 2788 if (!valid_reply(packet, client)) { 2789 log_error("Invalid Advertise - rejecting."); 2790 return; 2791 } 2792 2793 lease = dhc6_leaseify(packet); 2794 2795 if (dhc6_check_advertise(lease) != ISC_R_SUCCESS) { 2796 log_debug("PRC: Lease failed to satisfy."); 2797 dhc6_lease_destroy(&lease, MDL); 2798 return; 2799 } 2800 2801 insert_lease(&client->advertised_leases, lease); 2802 2803 /* According to RFC3315 section 17.1.2, the client MUST wait for 2804 * the first RT before selecting a lease. But on the 400th RT, 2805 * we dont' want to wait the full timeout if we finally get an 2806 * advertise. We could probably wait a second, but ohwell, 2807 * RFC3315 doesn't say so. 2808 * 2809 * If the lease is highest possible preference, 255, RFC3315 claims 2810 * we should continue immediately even on the first RT. We probably 2811 * should not if the advertise contains less than one IA and address. 2812 */ 2813 if ((client->txcount > 1) || 2814 ((lease->pref == 255) && 2815 (dhc6_score_lease(client, lease) > 150))) { 2816 log_debug("RCV: Advertisement immediately selected."); 2817 cancel_timeout(do_init6, client); 2818 start_selecting6(client); 2819 } else 2820 log_debug("RCV: Advertisement recorded."); 2821 } 2822 2823 /* info_request_handler() accepts a Reply to an Info-request. 2824 */ 2825 void 2826 info_request_handler(struct packet *packet, struct client_state *client) 2827 { 2828 isc_result_t check_status; 2829 unsigned code; 2830 2831 if (packet->dhcpv6_msg_type != DHCPV6_REPLY) 2832 return; 2833 2834 /* RFC3315 section 15.10 validation (same as 15.3 since we 2835 * always include a client id). 2836 */ 2837 if (!valid_reply(packet, client)) { 2838 log_error("Invalid Reply - rejecting."); 2839 return; 2840 } 2841 2842 check_status = dhc6_check_status(ISC_R_SUCCESS, packet->options, 2843 "message", &code); 2844 if (check_status != ISC_R_SUCCESS) { 2845 /* If no action was taken, but there is an error, then 2846 * we wait for a retransmission. 2847 */ 2848 if (check_status != ISC_R_CANCELED) 2849 return; 2850 } 2851 2852 /* We're done retransmitting at this point. */ 2853 cancel_timeout(do_info_request6, client); 2854 2855 /* Action was taken, so now that we've torn down our scheduled 2856 * retransmissions, return. 2857 */ 2858 if (check_status == ISC_R_CANCELED) 2859 return; 2860 2861 /* Cleanup if a previous attempt to go bound failed. */ 2862 if (client->old_lease != NULL) { 2863 dhc6_lease_destroy(&client->old_lease, MDL); 2864 client->old_lease = NULL; 2865 } 2866 2867 /* Cache options in the active_lease. */ 2868 if (client->active_lease != NULL) 2869 client->old_lease = client->active_lease; 2870 client->active_lease = dmalloc(sizeof(struct dhc6_lease), MDL); 2871 if (client->active_lease == NULL) 2872 log_fatal("Out of memory for v6 lease structure."); 2873 option_state_reference(&client->active_lease->options, 2874 packet->options, MDL); 2875 2876 start_informed(client); 2877 } 2878 2879 /* Specific version of init_handler() for rapid-commit. 2880 */ 2881 void 2882 rapid_commit_handler(struct packet *packet, struct client_state *client) 2883 { 2884 struct dhc6_lease *lease; 2885 isc_result_t check_status; 2886 2887 /* On ADVERTISE just fall back to the init_handler(). 2888 */ 2889 if (packet->dhcpv6_msg_type == DHCPV6_ADVERTISE) { 2890 init_handler(packet, client); 2891 return; 2892 } else if (packet->dhcpv6_msg_type != DHCPV6_REPLY) 2893 return; 2894 2895 /* RFC3315 section 15.10 validation (same as 15.3 since we 2896 * always include a client id). 2897 */ 2898 if (!valid_reply(packet, client)) { 2899 log_error("Invalid Reply - rejecting."); 2900 return; 2901 } 2902 2903 /* A rapid-commit option MUST be here. */ 2904 if (lookup_option(&dhcpv6_universe, packet->options, 2905 D6O_RAPID_COMMIT) == 0) { 2906 log_error("Reply without Rapid-Commit - rejecting."); 2907 return; 2908 } 2909 2910 lease = dhc6_leaseify(packet); 2911 2912 /* This is an out of memory condition...hopefully a temporary 2913 * problem. Returning now makes us try to retransmit later. 2914 */ 2915 if (lease == NULL) 2916 return; 2917 2918 check_status = dhc6_check_reply(client, lease); 2919 if (check_status != ISC_R_SUCCESS) { 2920 dhc6_lease_destroy(&lease, MDL); 2921 return; 2922 } 2923 2924 /* Jump to the selecting state. */ 2925 cancel_timeout(do_init6, client); 2926 client->state = S_SELECTING; 2927 2928 /* Merge any bindings in the active lease (if there is one) into 2929 * the new active lease. 2930 */ 2931 dhc6_merge_lease(client->active_lease, lease); 2932 2933 /* Cleanup if a previous attempt to go bound failed. */ 2934 if (client->old_lease != NULL) { 2935 dhc6_lease_destroy(&client->old_lease, MDL); 2936 client->old_lease = NULL; 2937 } 2938 2939 /* Make this lease active and BIND to it. */ 2940 if (client->active_lease != NULL) 2941 client->old_lease = client->active_lease; 2942 client->active_lease = lease; 2943 2944 /* We're done with the ADVERTISEd leases, if any. */ 2945 while(client->advertised_leases != NULL) { 2946 lease = client->advertised_leases; 2947 client->advertised_leases = lease->next; 2948 2949 dhc6_lease_destroy(&lease, MDL); 2950 } 2951 2952 start_bound(client); 2953 } 2954 2955 /* Find the 'best' lease in the cache of advertised leases (usually). From 2956 * RFC3315 Section 17.1.3: 2957 * 2958 * Upon receipt of one or more valid Advertise messages, the client 2959 * selects one or more Advertise messages based upon the following 2960 * criteria. 2961 * 2962 * - Those Advertise messages with the highest server preference value 2963 * are preferred over all other Advertise messages. 2964 * 2965 * - Within a group of Advertise messages with the same server 2966 * preference value, a client MAY select those servers whose 2967 * Advertise messages advertise information of interest to the 2968 * client. For example, the client may choose a server that returned 2969 * an advertisement with configuration options of interest to the 2970 * client. 2971 * 2972 * - The client MAY choose a less-preferred server if that server has a 2973 * better set of advertised parameters, such as the available 2974 * addresses advertised in IAs. 2975 * 2976 * Note that the first and third contradict each other. The third should 2977 * probably be taken to mean that the client should prefer answers that 2978 * offer bindings, even if that violates the preference rule. 2979 * 2980 * The above also isn't deterministic where there are ties. So the final 2981 * tiebreaker we add, if all other values are equal, is to compare the 2982 * server identifiers and to select the numerically lower one. 2983 */ 2984 static struct dhc6_lease * 2985 dhc6_best_lease(struct client_state *client, struct dhc6_lease **head) 2986 { 2987 struct dhc6_lease **rpos, *rval, **candp, *cand; 2988 int cscore, rscore; 2989 2990 if (head == NULL || *head == NULL) 2991 return NULL; 2992 2993 rpos = head; 2994 rval = *rpos; 2995 rscore = dhc6_score_lease(client, rval); 2996 candp = &rval->next; 2997 cand = *candp; 2998 2999 log_debug("PRC: Considering best lease."); 3000 log_debug("PRC: X-- Initial candidate %s (s: %d, p: %u).", 3001 print_hex_1(rval->server_id.len, 3002 rval->server_id.data, 48), 3003 rscore, (unsigned)rval->pref); 3004 3005 for (; cand != NULL ; candp = &cand->next, cand = *candp) { 3006 cscore = dhc6_score_lease(client, cand); 3007 3008 log_debug("PRC: X-- Candidate %s (s: %d, p: %u).", 3009 print_hex_1(cand->server_id.len, 3010 cand->server_id.data, 48), 3011 cscore, (unsigned)cand->pref); 3012 3013 /* Above you'll find quoted RFC3315 Section 17.1.3. 3014 * 3015 * The third clause tells us to give up on leases that 3016 * have no bindings even if their preference is better. 3017 * So where our 'selected' lease's score is less than 150 3018 * (1 ia + 1 addr), choose any candidate >= 150. 3019 * 3020 * The first clause tells us to make preference the primary 3021 * deciding factor. So if it's lower, reject, if it's 3022 * higher, select. 3023 * 3024 * The second clause tells us where the preference is 3025 * equal, we should use 'our judgement' of what we like 3026 * to see in an advertisement primarily. 3027 * 3028 * But there can still be a tie. To make this deterministic, 3029 * we compare the server identifiers and select the binary 3030 * lowest. 3031 * 3032 * Since server id's are unique in this list, there is 3033 * no further tie to break. 3034 */ 3035 if ((rscore < 150) && (cscore >= 150)) { 3036 log_debug("PRC: | X-- Selected, has bindings."); 3037 } else if (cand->pref < rval->pref) { 3038 log_debug("PRC: | X-- Rejected, lower preference."); 3039 continue; 3040 } else if (cand->pref > rval->pref) { 3041 log_debug("PRC: | X-- Selected, higher preference."); 3042 } else if (cscore > rscore) { 3043 log_debug("PRC: | X-- Selected, equal preference, " 3044 "higher score."); 3045 } else if (cscore < rscore) { 3046 log_debug("PRC: | X-- Rejected, equal preference, " 3047 "lower score."); 3048 continue; 3049 } else if ((cand->server_id.len < rval->server_id.len) || 3050 ((cand->server_id.len == rval->server_id.len) && 3051 (memcmp(cand->server_id.data, 3052 rval->server_id.data, 3053 cand->server_id.len) < 0))) { 3054 log_debug("PRC: | X-- Selected, equal preference, " 3055 "equal score, binary lesser server ID."); 3056 } else { 3057 log_debug("PRC: | X-- Rejected, equal preference, " 3058 "equal score, binary greater server ID."); 3059 continue; 3060 } 3061 3062 rpos = candp; 3063 rval = cand; 3064 rscore = cscore; 3065 } 3066 3067 /* Remove the selected lease from the chain. */ 3068 *rpos = rval->next; 3069 3070 return rval; 3071 } 3072 3073 /* Select a lease out of the advertised leases and setup state to try and 3074 * acquire that lease. 3075 */ 3076 void 3077 start_selecting6(struct client_state *client) 3078 { 3079 struct dhc6_lease *lease; 3080 3081 if (client->advertised_leases == NULL) { 3082 log_error("Can not enter DHCPv6 SELECTING state with no " 3083 "leases to select from!"); 3084 return; 3085 } 3086 3087 log_debug("PRC: Selecting best advertised lease."); 3088 client->state = S_SELECTING; 3089 3090 lease = dhc6_best_lease(client, &client->advertised_leases); 3091 3092 if (lease == NULL) 3093 log_fatal("Impossible error at %s:%d.", MDL); 3094 3095 client->selected_lease = lease; 3096 3097 /* Set timers per RFC3315 section 18.1.1. */ 3098 client->IRT = REQ_TIMEOUT * 100; 3099 client->MRT = REQ_MAX_RT * 100; 3100 client->MRC = REQ_MAX_RC; 3101 client->MRD = 0; 3102 3103 dhc6_retrans_init(client); 3104 3105 client->v6_handler = reply_handler; 3106 3107 /* ("re")transmit the first packet. */ 3108 do_select6(client); 3109 } 3110 3111 /* Transmit a Request to select a lease offered in Advertisements. In 3112 * the event of failure, either move on to the next-best advertised lease, 3113 * or head back to INIT state if there are none. 3114 */ 3115 void 3116 do_select6(void *input) 3117 { 3118 struct client_state *client; 3119 struct dhc6_lease *lease; 3120 struct data_string ds; 3121 struct timeval tv; 3122 int send_ret; 3123 3124 client = input; 3125 3126 /* 'lease' is fewer characters to type. */ 3127 lease = client->selected_lease; 3128 if (lease == NULL || lease->bindings == NULL) { 3129 log_error("Illegal to attempt selection without selecting " 3130 "a lease."); 3131 return; 3132 } 3133 3134 switch(check_timing6(client, DHCPV6_REQUEST, "Request", lease, &ds)) { 3135 case CHK_TIM_MRC_EXCEEDED: 3136 case CHK_TIM_MRD_EXCEEDED: 3137 log_debug("PRC: Lease %s failed.", 3138 print_hex_1(lease->server_id.len, 3139 lease->server_id.data, 56)); 3140 3141 /* Get rid of the lease that timed/counted out. */ 3142 dhc6_lease_destroy(&lease, MDL); 3143 client->selected_lease = NULL; 3144 3145 /* If there are more leases great. If not, get more. */ 3146 if (client->advertised_leases != NULL) 3147 start_selecting6(client); 3148 else 3149 start_init6(client); 3150 return; 3151 case CHK_TIM_ALLOC_FAILURE: 3152 return; 3153 case CHK_TIM_SUCCESS: 3154 break; 3155 } 3156 3157 /* Now make a packet that looks suspiciously like the one we 3158 * got from the server. But different. 3159 * 3160 * XXX: I guess IAID is supposed to be something the client 3161 * indicates and uses as a key to its internal state. It is 3162 * kind of odd to ask the server for IA's whose IAID the client 3163 * did not manufacture. We first need a formal dhclient.conf 3164 * construct for the iaid, then we can delve into this matter 3165 * more properly. In the time being, this will work. 3166 */ 3167 3168 /* Fetch any configured 'sent' options (includes DUID) in wire format. 3169 */ 3170 dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, 3171 NULL, client->sent_options, &global_scope, 3172 &dhcpv6_universe); 3173 3174 /* Now append any IA's, and within them any IAADDR/IAPREFIXs. */ 3175 if (wanted_ia_na && 3176 dhc6_add_ia_na(client, &ds, lease, 3177 DHCPV6_REQUEST) != ISC_R_SUCCESS) { 3178 data_string_forget(&ds, MDL); 3179 return; 3180 } 3181 if (wanted_ia_ta && 3182 dhc6_add_ia_ta(client, &ds, lease, 3183 DHCPV6_REQUEST) != ISC_R_SUCCESS) { 3184 data_string_forget(&ds, MDL); 3185 return; 3186 } 3187 if (wanted_ia_pd && 3188 dhc6_add_ia_pd(client, &ds, lease, 3189 DHCPV6_REQUEST) != ISC_R_SUCCESS) { 3190 data_string_forget(&ds, MDL); 3191 return; 3192 } 3193 3194 log_info("XMT: Request on %s, interval %ld0ms.", 3195 client->name ? client->name : client->interface->name, 3196 (long int)client->RT); 3197 3198 send_ret = send_packet6(client->interface, 3199 ds.data, ds.len, &DHCPv6DestAddr); 3200 if (send_ret != ds.len) { 3201 log_error("dhc6: send_packet6() sent %d of %d bytes", 3202 send_ret, ds.len); 3203 } 3204 3205 data_string_forget(&ds, MDL); 3206 3207 /* Wait RT */ 3208 tv.tv_sec = cur_tv.tv_sec + client->RT / 100; 3209 tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000; 3210 if (tv.tv_usec >= 1000000) { 3211 tv.tv_sec += 1; 3212 tv.tv_usec -= 1000000; 3213 } 3214 add_timeout(&tv, do_select6, client, NULL, NULL); 3215 3216 dhc6_retrans_advance(client); 3217 } 3218 3219 /* For each IA_NA in the lease, for each address in the IA_NA, 3220 * append that information onto the packet-so-far. 3221 */ 3222 static isc_result_t 3223 dhc6_add_ia_na(struct client_state *client, struct data_string *packet, 3224 struct dhc6_lease *lease, u_int8_t message) 3225 { 3226 struct data_string iads; 3227 struct data_string addrds; 3228 struct dhc6_addr *addr; 3229 struct dhc6_ia *ia; 3230 isc_result_t rval = ISC_R_SUCCESS; 3231 TIME t1, t2; 3232 3233 memset(&iads, 0, sizeof(iads)); 3234 memset(&addrds, 0, sizeof(addrds)); 3235 for (ia = lease->bindings; 3236 ia != NULL && rval == ISC_R_SUCCESS; 3237 ia = ia->next) { 3238 if (ia->ia_type != D6O_IA_NA) 3239 continue; 3240 3241 if (!buffer_allocate(&iads.buffer, 12, MDL)) { 3242 log_error("Unable to allocate memory for IA_NA."); 3243 rval = ISC_R_NOMEMORY; 3244 break; 3245 } 3246 3247 /* Copy the IAID into the packet buffer. */ 3248 memcpy(iads.buffer->data, ia->iaid, 4); 3249 iads.data = iads.buffer->data; 3250 iads.len = 12; 3251 3252 switch (message) { 3253 case DHCPV6_REQUEST: 3254 case DHCPV6_RENEW: 3255 case DHCPV6_REBIND: 3256 3257 t1 = client->config->requested_lease / 2; 3258 t2 = t1 + (t1 / 2); 3259 #if MAX_TIME > 0xffffffff 3260 if (t1 > 0xffffffff) 3261 t1 = 0xffffffff; 3262 if (t2 > 0xffffffff) 3263 t2 = 0xffffffff; 3264 #endif 3265 putULong(iads.buffer->data + 4, t1); 3266 putULong(iads.buffer->data + 8, t2); 3267 3268 log_debug("XMT: X-- IA_NA %s", 3269 print_hex_1(4, iads.data, 59)); 3270 log_debug("XMT: | X-- Requested renew +%u", 3271 (unsigned) t1); 3272 log_debug("XMT: | X-- Requested rebind +%u", 3273 (unsigned) t2); 3274 break; 3275 3276 case DHCPV6_CONFIRM: 3277 case DHCPV6_RELEASE: 3278 case DHCPV6_DECLINE: 3279 /* Set t1 and t2 to zero; server will ignore them */ 3280 memset(iads.buffer->data + 4, 0, 8); 3281 log_debug("XMT: X-- IA_NA %s", 3282 print_hex_1(4, iads.buffer->data, 55)); 3283 3284 break; 3285 3286 default: 3287 log_fatal("Impossible condition at %s:%d.", MDL); 3288 } 3289 3290 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) { 3291 /* 3292 * Do not confirm expired addresses, do not request 3293 * expired addresses (but we keep them around for 3294 * solicit). 3295 */ 3296 if (addr->flags & DHC6_ADDR_EXPIRED) 3297 continue; 3298 3299 if (addr->address.len != 16) { 3300 log_error("Illegal IPv6 address length (%d), " 3301 "ignoring. (%s:%d)", 3302 addr->address.len, MDL); 3303 continue; 3304 } 3305 3306 if (!buffer_allocate(&addrds.buffer, 24, MDL)) { 3307 log_error("Unable to allocate memory for " 3308 "IAADDR."); 3309 rval = ISC_R_NOMEMORY; 3310 break; 3311 } 3312 3313 addrds.data = addrds.buffer->data; 3314 addrds.len = 24; 3315 3316 /* Copy the address into the packet buffer. */ 3317 memcpy(addrds.buffer->data, addr->address.iabuf, 16); 3318 3319 /* Copy in additional information as appropriate */ 3320 switch (message) { 3321 case DHCPV6_REQUEST: 3322 case DHCPV6_RENEW: 3323 case DHCPV6_REBIND: 3324 t1 = client->config->requested_lease; 3325 t2 = t1 + 300; 3326 putULong(addrds.buffer->data + 16, t1); 3327 putULong(addrds.buffer->data + 20, t2); 3328 3329 log_debug("XMT: | | X-- IAADDR %s", 3330 piaddr(addr->address)); 3331 log_debug("XMT: | | | X-- Preferred " 3332 "lifetime +%u", (unsigned)t1); 3333 log_debug("XMT: | | | X-- Max lifetime +%u", 3334 (unsigned)t2); 3335 3336 break; 3337 3338 case DHCPV6_CONFIRM: 3339 /* 3340 * Set preferred and max life to zero, 3341 * per 17.1.3. 3342 */ 3343 memset(addrds.buffer->data + 16, 0, 8); 3344 log_debug("XMT: | X-- Confirm Address %s", 3345 piaddr(addr->address)); 3346 break; 3347 3348 case DHCPV6_RELEASE: 3349 /* Preferred and max life are irrelevant */ 3350 memset(addrds.buffer->data + 16, 0, 8); 3351 log_debug("XMT: | X-- Release Address %s", 3352 piaddr(addr->address)); 3353 break; 3354 3355 case DHCPV6_DECLINE: 3356 /* Preferred and max life are irrelevant */ 3357 memset(addrds.buffer->data + 16, 0, 8); 3358 log_debug("XMT: | X-- Decline Address %s", 3359 piaddr(addr->address)); 3360 break; 3361 3362 default: 3363 log_fatal("Impossible condition at %s:%d.", 3364 MDL); 3365 } 3366 3367 append_option(&iads, &dhcpv6_universe, iaaddr_option, 3368 &addrds); 3369 data_string_forget(&addrds, MDL); 3370 } 3371 3372 /* 3373 * It doesn't make sense to make a request without an 3374 * address. 3375 */ 3376 if (ia->addrs == NULL) { 3377 log_debug("!!!: V IA_NA has no IAADDRs - removed."); 3378 rval = ISC_R_FAILURE; 3379 } else if (rval == ISC_R_SUCCESS) { 3380 log_debug("XMT: V IA_NA appended."); 3381 append_option(packet, &dhcpv6_universe, ia_na_option, 3382 &iads); 3383 } 3384 3385 data_string_forget(&iads, MDL); 3386 } 3387 3388 return rval; 3389 } 3390 3391 /* For each IA_TA in the lease, for each address in the IA_TA, 3392 * append that information onto the packet-so-far. 3393 */ 3394 static isc_result_t 3395 dhc6_add_ia_ta(struct client_state *client, struct data_string *packet, 3396 struct dhc6_lease *lease, u_int8_t message) 3397 { 3398 struct data_string iads; 3399 struct data_string addrds; 3400 struct dhc6_addr *addr; 3401 struct dhc6_ia *ia; 3402 isc_result_t rval = ISC_R_SUCCESS; 3403 TIME t1, t2; 3404 3405 memset(&iads, 0, sizeof(iads)); 3406 memset(&addrds, 0, sizeof(addrds)); 3407 for (ia = lease->bindings; 3408 ia != NULL && rval == ISC_R_SUCCESS; 3409 ia = ia->next) { 3410 if (ia->ia_type != D6O_IA_TA) 3411 continue; 3412 3413 if (!buffer_allocate(&iads.buffer, 4, MDL)) { 3414 log_error("Unable to allocate memory for IA_TA."); 3415 rval = ISC_R_NOMEMORY; 3416 break; 3417 } 3418 3419 /* Copy the IAID into the packet buffer. */ 3420 memcpy(iads.buffer->data, ia->iaid, 4); 3421 iads.data = iads.buffer->data; 3422 iads.len = 4; 3423 3424 log_debug("XMT: X-- IA_TA %s", 3425 print_hex_1(4, iads.buffer->data, 55)); 3426 3427 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) { 3428 /* 3429 * Do not confirm expired addresses, do not request 3430 * expired addresses (but we keep them around for 3431 * solicit). 3432 */ 3433 if (addr->flags & DHC6_ADDR_EXPIRED) 3434 continue; 3435 3436 if (addr->address.len != 16) { 3437 log_error("Illegal IPv6 address length (%d), " 3438 "ignoring. (%s:%d)", 3439 addr->address.len, MDL); 3440 continue; 3441 } 3442 3443 if (!buffer_allocate(&addrds.buffer, 24, MDL)) { 3444 log_error("Unable to allocate memory for " 3445 "IAADDR."); 3446 rval = ISC_R_NOMEMORY; 3447 break; 3448 } 3449 3450 addrds.data = addrds.buffer->data; 3451 addrds.len = 24; 3452 3453 /* Copy the address into the packet buffer. */ 3454 memcpy(addrds.buffer->data, addr->address.iabuf, 16); 3455 3456 /* Copy in additional information as appropriate */ 3457 switch (message) { 3458 case DHCPV6_REQUEST: 3459 case DHCPV6_RENEW: 3460 case DHCPV6_REBIND: 3461 t1 = client->config->requested_lease; 3462 t2 = t1 + 300; 3463 putULong(addrds.buffer->data + 16, t1); 3464 putULong(addrds.buffer->data + 20, t2); 3465 3466 log_debug("XMT: | | X-- IAADDR %s", 3467 piaddr(addr->address)); 3468 log_debug("XMT: | | | X-- Preferred " 3469 "lifetime +%u", (unsigned)t1); 3470 log_debug("XMT: | | | X-- Max lifetime +%u", 3471 (unsigned)t2); 3472 3473 break; 3474 3475 case DHCPV6_CONFIRM: 3476 /* 3477 * Set preferred and max life to zero, 3478 * per 17.1.3. 3479 */ 3480 memset(addrds.buffer->data + 16, 0, 8); 3481 log_debug("XMT: | X-- Confirm Address %s", 3482 piaddr(addr->address)); 3483 break; 3484 3485 case DHCPV6_RELEASE: 3486 /* Preferred and max life are irrelevant */ 3487 memset(addrds.buffer->data + 16, 0, 8); 3488 log_debug("XMT: | X-- Release Address %s", 3489 piaddr(addr->address)); 3490 break; 3491 3492 default: 3493 log_fatal("Impossible condition at %s:%d.", 3494 MDL); 3495 } 3496 3497 append_option(&iads, &dhcpv6_universe, iaaddr_option, 3498 &addrds); 3499 data_string_forget(&addrds, MDL); 3500 } 3501 3502 /* 3503 * It doesn't make sense to make a request without an 3504 * address. 3505 */ 3506 if (ia->addrs == NULL) { 3507 log_debug("!!!: V IA_TA has no IAADDRs - removed."); 3508 rval = ISC_R_FAILURE; 3509 } else if (rval == ISC_R_SUCCESS) { 3510 log_debug("XMT: V IA_TA appended."); 3511 append_option(packet, &dhcpv6_universe, ia_ta_option, 3512 &iads); 3513 } 3514 3515 data_string_forget(&iads, MDL); 3516 } 3517 3518 return rval; 3519 } 3520 3521 /* For each IA_PD in the lease, for each prefix in the IA_PD, 3522 * append that information onto the packet-so-far. 3523 */ 3524 static isc_result_t 3525 dhc6_add_ia_pd(struct client_state *client, struct data_string *packet, 3526 struct dhc6_lease *lease, u_int8_t message) 3527 { 3528 struct data_string iads; 3529 struct data_string prefds; 3530 struct dhc6_addr *pref; 3531 struct dhc6_ia *ia; 3532 isc_result_t rval = ISC_R_SUCCESS; 3533 TIME t1, t2; 3534 3535 memset(&iads, 0, sizeof(iads)); 3536 memset(&prefds, 0, sizeof(prefds)); 3537 for (ia = lease->bindings; 3538 ia != NULL && rval == ISC_R_SUCCESS; 3539 ia = ia->next) { 3540 if (ia->ia_type != D6O_IA_PD) 3541 continue; 3542 3543 if (!buffer_allocate(&iads.buffer, 12, MDL)) { 3544 log_error("Unable to allocate memory for IA_PD."); 3545 rval = ISC_R_NOMEMORY; 3546 break; 3547 } 3548 3549 /* Copy the IAID into the packet buffer. */ 3550 memcpy(iads.buffer->data, ia->iaid, 4); 3551 iads.data = iads.buffer->data; 3552 iads.len = 12; 3553 3554 switch (message) { 3555 case DHCPV6_REQUEST: 3556 case DHCPV6_RENEW: 3557 case DHCPV6_REBIND: 3558 3559 t1 = client->config->requested_lease / 2; 3560 t2 = t1 + (t1 / 2); 3561 #if MAX_TIME > 0xffffffff 3562 if (t1 > 0xffffffff) 3563 t1 = 0xffffffff; 3564 if (t2 > 0xffffffff) 3565 t2 = 0xffffffff; 3566 #endif 3567 putULong(iads.buffer->data + 4, t1); 3568 putULong(iads.buffer->data + 8, t2); 3569 3570 log_debug("XMT: X-- IA_PD %s", 3571 print_hex_1(4, iads.data, 59)); 3572 log_debug("XMT: | X-- Requested renew +%u", 3573 (unsigned) t1); 3574 log_debug("XMT: | X-- Requested rebind +%u", 3575 (unsigned) t2); 3576 break; 3577 3578 case DHCPV6_RELEASE: 3579 /* Set t1 and t2 to zero; server will ignore them */ 3580 memset(iads.buffer->data + 4, 0, 8); 3581 log_debug("XMT: X-- IA_PD %s", 3582 print_hex_1(4, iads.buffer->data, 55)); 3583 3584 break; 3585 3586 default: 3587 log_fatal("Impossible condition at %s:%d.", MDL); 3588 } 3589 3590 for (pref = ia->addrs ; pref != NULL ; pref = pref->next) { 3591 /* 3592 * Do not confirm expired prefixes, do not request 3593 * expired prefixes (but we keep them around for 3594 * solicit). 3595 */ 3596 if (pref->flags & DHC6_ADDR_EXPIRED) 3597 continue; 3598 3599 if (pref->address.len != 16) { 3600 log_error("Illegal IPv6 prefix " 3601 "ignoring. (%s:%d)", 3602 MDL); 3603 continue; 3604 } 3605 3606 if (pref->plen == 0) { 3607 log_info("Null IPv6 prefix, " 3608 "ignoring. (%s:%d)", 3609 MDL); 3610 } 3611 3612 if (!buffer_allocate(&prefds.buffer, 25, MDL)) { 3613 log_error("Unable to allocate memory for " 3614 "IAPREFIX."); 3615 rval = ISC_R_NOMEMORY; 3616 break; 3617 } 3618 3619 prefds.data = prefds.buffer->data; 3620 prefds.len = 25; 3621 3622 /* Copy the prefix into the packet buffer. */ 3623 putUChar(prefds.buffer->data + 8, pref->plen); 3624 memcpy(prefds.buffer->data + 9, 3625 pref->address.iabuf, 3626 16); 3627 3628 /* Copy in additional information as appropriate */ 3629 switch (message) { 3630 case DHCPV6_REQUEST: 3631 case DHCPV6_RENEW: 3632 case DHCPV6_REBIND: 3633 t1 = client->config->requested_lease; 3634 t2 = t1 + 300; 3635 putULong(prefds.buffer->data, t1); 3636 putULong(prefds.buffer->data + 4, t2); 3637 3638 log_debug("XMT: | | X-- IAPREFIX %s/%u", 3639 piaddr(pref->address), 3640 (unsigned) pref->plen); 3641 log_debug("XMT: | | | X-- Preferred " 3642 "lifetime +%u", (unsigned)t1); 3643 log_debug("XMT: | | | X-- Max lifetime +%u", 3644 (unsigned)t2); 3645 3646 break; 3647 3648 case DHCPV6_RELEASE: 3649 /* Preferred and max life are irrelevant */ 3650 memset(prefds.buffer->data, 0, 8); 3651 log_debug("XMT: | X-- Release Prefix %s/%u", 3652 piaddr(pref->address), 3653 (unsigned) pref->plen); 3654 break; 3655 3656 default: 3657 log_fatal("Impossible condition at %s:%d.", 3658 MDL); 3659 } 3660 3661 append_option(&iads, &dhcpv6_universe, 3662 iaprefix_option, &prefds); 3663 data_string_forget(&prefds, MDL); 3664 } 3665 3666 /* 3667 * It doesn't make sense to make a request without an 3668 * address. 3669 */ 3670 if (ia->addrs == NULL) { 3671 log_debug("!!!: V IA_PD has no IAPREFIXs - removed."); 3672 rval = ISC_R_FAILURE; 3673 } else if (rval == ISC_R_SUCCESS) { 3674 log_debug("XMT: V IA_PD appended."); 3675 append_option(packet, &dhcpv6_universe, 3676 ia_pd_option, &iads); 3677 } 3678 3679 data_string_forget(&iads, MDL); 3680 } 3681 3682 return rval; 3683 } 3684 3685 /* stopping_finished() checks if there is a remaining work to do. 3686 */ 3687 static isc_boolean_t 3688 stopping_finished(void) 3689 { 3690 struct interface_info *ip; 3691 struct client_state *client; 3692 3693 for (ip = interfaces; ip; ip = ip -> next) { 3694 for (client = ip -> client; client; client = client -> next) { 3695 if (client->state != S_STOPPED) 3696 return ISC_FALSE; 3697 if (client->active_lease != NULL) 3698 return ISC_FALSE; 3699 } 3700 } 3701 return ISC_TRUE; 3702 } 3703 3704 /* reply_handler() accepts a Reply while we're attempting Select or Renew or 3705 * Rebind. Basically any Reply packet. 3706 */ 3707 void 3708 reply_handler(struct packet *packet, struct client_state *client) 3709 { 3710 struct dhc6_lease *lease; 3711 isc_result_t check_status; 3712 3713 if (packet->dhcpv6_msg_type != DHCPV6_REPLY) 3714 return; 3715 3716 /* RFC3315 section 15.10 validation (same as 15.3 since we 3717 * always include a client id). 3718 */ 3719 if (!valid_reply(packet, client)) { 3720 log_error("Invalid Reply - rejecting."); 3721 return; 3722 } 3723 3724 lease = dhc6_leaseify(packet); 3725 3726 /* This is an out of memory condition...hopefully a temporary 3727 * problem. Returning now makes us try to retransmit later. 3728 */ 3729 if (lease == NULL) 3730 return; 3731 3732 check_status = dhc6_check_reply(client, lease); 3733 if (check_status != ISC_R_SUCCESS) { 3734 dhc6_lease_destroy(&lease, MDL); 3735 3736 /* If no action was taken, but there is an error, then 3737 * we wait for a retransmission. 3738 */ 3739 if (check_status != ISC_R_CANCELED) 3740 return; 3741 } 3742 3743 /* We're done retransmitting at this point. */ 3744 cancel_timeout(do_confirm6, client); 3745 cancel_timeout(do_select6, client); 3746 cancel_timeout(do_refresh6, client); 3747 cancel_timeout(do_release6, client); 3748 3749 /* If this is in response to a Release/Decline, clean up and return. */ 3750 if (client->state == S_STOPPED) { 3751 if (client->active_lease == NULL) 3752 return; 3753 3754 dhc6_lease_destroy(&client->active_lease, MDL); 3755 client->active_lease = NULL; 3756 /* We should never wait for nothing!? */ 3757 if (stopping_finished()) 3758 exit(0); 3759 return; 3760 } 3761 3762 /* Action was taken, so now that we've torn down our scheduled 3763 * retransmissions, return. 3764 */ 3765 if (check_status == ISC_R_CANCELED) 3766 return; 3767 3768 if (client->selected_lease != NULL) { 3769 dhc6_lease_destroy(&client->selected_lease, MDL); 3770 client->selected_lease = NULL; 3771 } 3772 3773 /* If this is in response to a confirm, we use the lease we've 3774 * already got, not the reply we were sent. 3775 */ 3776 if (client->state == S_REBOOTING) { 3777 if (client->active_lease == NULL) 3778 log_fatal("Impossible condition at %s:%d.", MDL); 3779 3780 dhc6_lease_destroy(&lease, MDL); 3781 start_bound(client); 3782 return; 3783 } 3784 3785 /* Merge any bindings in the active lease (if there is one) into 3786 * the new active lease. 3787 */ 3788 dhc6_merge_lease(client->active_lease, lease); 3789 3790 /* Cleanup if a previous attempt to go bound failed. */ 3791 if (client->old_lease != NULL) { 3792 dhc6_lease_destroy(&client->old_lease, MDL); 3793 client->old_lease = NULL; 3794 } 3795 3796 /* Make this lease active and BIND to it. */ 3797 if (client->active_lease != NULL) 3798 client->old_lease = client->active_lease; 3799 client->active_lease = lease; 3800 3801 /* We're done with the ADVERTISEd leases, if any. */ 3802 while(client->advertised_leases != NULL) { 3803 lease = client->advertised_leases; 3804 client->advertised_leases = lease->next; 3805 3806 dhc6_lease_destroy(&lease, MDL); 3807 } 3808 3809 start_bound(client); 3810 } 3811 3812 /* DHCPv6 packets are a little sillier than they needed to be - the root 3813 * packet contains options, then IA's which contain options, then within 3814 * that IAADDR's which contain options. 3815 * 3816 * To sort this out at dhclient-script time (which fetches config parameters 3817 * in environment variables), start_bound() iterates over each IAADDR, and 3818 * calls this function to marshall an environment variable set that includes 3819 * the most-specific option values related to that IAADDR in particular. 3820 * 3821 * To achieve this, we load environment variables for the root options space, 3822 * then the IA, then the IAADDR. Any duplicate option names will be 3823 * over-written by the later versions. 3824 */ 3825 static void 3826 dhc6_marshall_values(const char *prefix, struct client_state *client, 3827 struct dhc6_lease *lease, struct dhc6_ia *ia, 3828 struct dhc6_addr *addr) 3829 { 3830 /* Option cache contents, in descending order of 3831 * scope. 3832 */ 3833 if ((lease != NULL) && (lease->options != NULL)) 3834 script_write_params6(client, prefix, lease->options); 3835 if ((ia != NULL) && (ia->options != NULL)) 3836 script_write_params6(client, prefix, ia->options); 3837 if ((addr != NULL) && (addr->options != NULL)) 3838 script_write_params6(client, prefix, addr->options); 3839 3840 /* addr fields. */ 3841 if (addr != NULL) { 3842 if ((ia != NULL) && (ia->ia_type == D6O_IA_PD)) { 3843 client_envadd(client, prefix, 3844 "ip6_prefix", "%s/%u", 3845 piaddr(addr->address), 3846 (unsigned) addr->plen); 3847 } else { 3848 /* Current practice is that all subnets are /64's, but 3849 * some suspect this may not be permanent. 3850 */ 3851 client_envadd(client, prefix, "ip6_prefixlen", 3852 "%d", 64); 3853 client_envadd(client, prefix, "ip6_address", 3854 "%s", piaddr(addr->address)); 3855 } 3856 if ((ia != NULL) && (ia->ia_type == D6O_IA_TA)) { 3857 client_envadd(client, prefix, 3858 "ip6_type", "temporary"); 3859 } 3860 client_envadd(client, prefix, "life_starts", "%d", 3861 (int)(addr->starts)); 3862 client_envadd(client, prefix, "preferred_life", "%d", 3863 (int)(addr->preferred_life)); 3864 client_envadd(client, prefix, "max_life", "%d", 3865 (int)(addr->max_life)); 3866 } 3867 3868 /* ia fields. */ 3869 if (ia != NULL) { 3870 client_envadd(client, prefix, "iaid", "%s", 3871 print_hex_1(4, ia->iaid, 12)); 3872 client_envadd(client, prefix, "starts", "%d", 3873 (int)(ia->starts)); 3874 client_envadd(client, prefix, "renew", "%u", ia->renew); 3875 client_envadd(client, prefix, "rebind", "%u", ia->rebind); 3876 } 3877 } 3878 3879 /* Look at where the client's active lease is sitting. If it's looking to 3880 * time out on renew, rebind, depref, or expiration, do those things. 3881 */ 3882 static void 3883 dhc6_check_times(struct client_state *client) 3884 { 3885 struct dhc6_lease *lease; 3886 struct dhc6_ia *ia; 3887 struct dhc6_addr *addr; 3888 TIME renew=MAX_TIME, rebind=MAX_TIME, depref=MAX_TIME, 3889 lo_expire=MAX_TIME, hi_expire=0, tmp; 3890 int has_addrs = ISC_FALSE; 3891 struct timeval tv; 3892 3893 lease = client->active_lease; 3894 3895 /* Bit spammy. We should probably keep record of scheduled 3896 * events instead. 3897 */ 3898 cancel_timeout(start_renew6, client); 3899 cancel_timeout(start_rebind6, client); 3900 cancel_timeout(do_depref, client); 3901 cancel_timeout(do_expire, client); 3902 3903 for(ia = lease->bindings ; ia != NULL ; ia = ia->next) { 3904 TIME this_ia_lo_expire, this_ia_hi_expire, use_expire; 3905 3906 this_ia_lo_expire = MAX_TIME; 3907 this_ia_hi_expire = 0; 3908 3909 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) { 3910 if(!(addr->flags & DHC6_ADDR_DEPREFFED)) { 3911 if (addr->preferred_life == 0xffffffff) 3912 tmp = MAX_TIME; 3913 else 3914 tmp = addr->starts + 3915 addr->preferred_life; 3916 3917 if (tmp < depref) 3918 depref = tmp; 3919 } 3920 3921 if (!(addr->flags & DHC6_ADDR_EXPIRED)) { 3922 /* Find EPOCH-relative expiration. */ 3923 if (addr->max_life == 0xffffffff) 3924 tmp = MAX_TIME; 3925 else 3926 tmp = addr->starts + addr->max_life; 3927 3928 /* Make the times ia->starts relative. */ 3929 tmp -= ia->starts; 3930 3931 if (tmp > this_ia_hi_expire) 3932 this_ia_hi_expire = tmp; 3933 if (tmp < this_ia_lo_expire) 3934 this_ia_lo_expire = tmp; 3935 3936 has_addrs = ISC_TRUE; 3937 } 3938 } 3939 3940 /* These times are ia->starts relative. */ 3941 if (this_ia_lo_expire <= (this_ia_hi_expire / 2)) 3942 use_expire = this_ia_hi_expire; 3943 else 3944 use_expire = this_ia_lo_expire; 3945 3946 /* 3947 * If the auto-selected expiration time is "infinite", or 3948 * zero, assert a reasonable default. 3949 */ 3950 if ((use_expire == MAX_TIME) || (use_expire <= 1)) 3951 use_expire = client->config->requested_lease / 2; 3952 else 3953 use_expire /= 2; 3954 3955 /* Don't renew/rebind temporary addresses. */ 3956 if (ia->ia_type != D6O_IA_TA) { 3957 3958 if (ia->renew == 0) { 3959 tmp = ia->starts + use_expire; 3960 } else if (ia->renew == 0xffffffff) 3961 tmp = MAX_TIME; 3962 else 3963 tmp = ia->starts + ia->renew; 3964 3965 if (tmp < renew) 3966 renew = tmp; 3967 3968 if (ia->rebind == 0) { 3969 /* Set rebind to 3/4 expiration interval. */ 3970 tmp = ia->starts; 3971 tmp += use_expire + (use_expire / 2); 3972 } else if (ia->rebind == 0xffffffff) 3973 tmp = MAX_TIME; 3974 else 3975 tmp = ia->starts + ia->rebind; 3976 3977 if (tmp < rebind) 3978 rebind = tmp; 3979 } 3980 3981 /* 3982 * Return expiration ranges to EPOCH relative for event 3983 * scheduling (add_timeout()). 3984 */ 3985 this_ia_hi_expire += ia->starts; 3986 this_ia_lo_expire += ia->starts; 3987 3988 if (this_ia_hi_expire > hi_expire) 3989 hi_expire = this_ia_hi_expire; 3990 if (this_ia_lo_expire < lo_expire) 3991 lo_expire = this_ia_lo_expire; 3992 } 3993 3994 /* If there are no addresses, give up, go to INIT. 3995 * Note that if an address is unexpired with a date in the past, 3996 * we're scheduling an expiration event to ocurr in the past. We 3997 * could probably optimize this to expire now (but then there's 3998 * recursion). 3999 * 4000 * In the future, we may decide that we're done here, or to 4001 * schedule a future request (using 4-pkt info-request model). 4002 */ 4003 if (has_addrs == ISC_FALSE) { 4004 dhc6_lease_destroy(&client->active_lease, MDL); 4005 client->active_lease = NULL; 4006 4007 /* Go back to the beginning. */ 4008 start_init6(client); 4009 return; 4010 } 4011 4012 switch(client->state) { 4013 case S_BOUND: 4014 /* We'd like to hit renewing, but if rebinding has already 4015 * passed (time warp), head straight there. 4016 */ 4017 if ((rebind > cur_time) && (renew < rebind)) { 4018 log_debug("PRC: Renewal event scheduled in %d seconds, " 4019 "to run for %u seconds.", 4020 (int)(renew - cur_time), 4021 (unsigned)(rebind - renew)); 4022 client->next_MRD = rebind; 4023 tv.tv_sec = renew; 4024 tv.tv_usec = 0; 4025 add_timeout(&tv, start_renew6, client, NULL, NULL); 4026 4027 break; 4028 } 4029 /* FALL THROUGH */ 4030 case S_RENEWING: 4031 /* While actively renewing, MRD is bounded by the time 4032 * we stop renewing and start rebinding. This helps us 4033 * process the state change on time. 4034 */ 4035 client->MRD = rebind - cur_time; 4036 if (rebind != MAX_TIME) { 4037 log_debug("PRC: Rebind event scheduled in %d seconds, " 4038 "to run for %d seconds.", 4039 (int)(rebind - cur_time), 4040 (int)(hi_expire - rebind)); 4041 client->next_MRD = hi_expire; 4042 tv.tv_sec = rebind; 4043 tv.tv_usec = 0; 4044 add_timeout(&tv, start_rebind6, client, NULL, NULL); 4045 } 4046 break; 4047 4048 case S_REBINDING: 4049 /* For now, we rebind up until the last lease expires. In 4050 * the future, we might want to start SOLICITing when we've 4051 * depreffed an address. 4052 */ 4053 client->MRD = hi_expire - cur_time; 4054 break; 4055 4056 default: 4057 log_fatal("Impossible condition at %s:%d.", MDL); 4058 } 4059 4060 /* Separately, set a time at which we will depref and expire 4061 * leases. This might happen with multiple addresses while we 4062 * keep trying to refresh. 4063 */ 4064 if (depref != MAX_TIME) { 4065 log_debug("PRC: Depreference scheduled in %d seconds.", 4066 (int)(depref - cur_time)); 4067 tv.tv_sec = depref; 4068 tv.tv_usec = 0; 4069 add_timeout(&tv, do_depref, client, NULL, NULL); 4070 } 4071 if (lo_expire != MAX_TIME) { 4072 log_debug("PRC: Expiration scheduled in %d seconds.", 4073 (int)(lo_expire - cur_time)); 4074 tv.tv_sec = lo_expire; 4075 tv.tv_usec = 0; 4076 add_timeout(&tv, do_expire, client, NULL, NULL); 4077 } 4078 } 4079 4080 /* In a given IA chain, find the IA with the same type and 'iaid'. */ 4081 static struct dhc6_ia * 4082 find_ia(struct dhc6_ia *head, u_int16_t type, const char *id) 4083 { 4084 struct dhc6_ia *ia; 4085 4086 for (ia = head ; ia != NULL ; ia = ia->next) { 4087 if (ia->ia_type != type) 4088 continue; 4089 if (memcmp(ia->iaid, id, 4) == 0) 4090 return ia; 4091 } 4092 4093 return NULL; 4094 } 4095 4096 /* In a given address chain, find a matching address. */ 4097 static struct dhc6_addr * 4098 find_addr(struct dhc6_addr *head, struct iaddr *address) 4099 { 4100 struct dhc6_addr *addr; 4101 4102 for (addr = head ; addr != NULL ; addr = addr->next) { 4103 if ((addr->address.len == address->len) && 4104 (memcmp(addr->address.iabuf, address->iabuf, 4105 address->len) == 0)) 4106 return addr; 4107 } 4108 4109 return NULL; 4110 } 4111 4112 /* In a given prefix chain, find a matching prefix. */ 4113 static struct dhc6_addr * 4114 find_pref(struct dhc6_addr *head, struct iaddr *prefix, u_int8_t plen) 4115 { 4116 struct dhc6_addr *pref; 4117 4118 for (pref = head ; pref != NULL ; pref = pref->next) { 4119 if ((pref->address.len == prefix->len) && 4120 (pref->plen == plen) && 4121 (memcmp(pref->address.iabuf, prefix->iabuf, 4122 prefix->len) == 0)) 4123 return pref; 4124 } 4125 4126 return NULL; 4127 } 4128 4129 /* Merge the bindings from the source lease into the destination lease 4130 * structure, where they are missing. We have to copy the stateful 4131 * objects rather than move them over, because later code needs to be 4132 * able to compare new versus old if they contain any bindings. 4133 */ 4134 static void 4135 dhc6_merge_lease(struct dhc6_lease *src, struct dhc6_lease *dst) 4136 { 4137 struct dhc6_ia *sia, *dia, *tia; 4138 struct dhc6_addr *saddr, *daddr, *taddr; 4139 int changes = 0; 4140 4141 if ((dst == NULL) || (src == NULL)) 4142 return; 4143 4144 for (sia = src->bindings ; sia != NULL ; sia = sia->next) { 4145 dia = find_ia(dst->bindings, sia->ia_type, (char *)sia->iaid); 4146 4147 if (dia == NULL) { 4148 tia = dhc6_dup_ia(sia, MDL); 4149 4150 if (tia == NULL) 4151 log_fatal("Out of memory merging lease - " 4152 "Unable to continue without losing " 4153 "state! (%s:%d)", MDL); 4154 4155 /* XXX: consider sorting? */ 4156 tia->next = dst->bindings; 4157 dst->bindings = tia; 4158 changes = 1; 4159 } else { 4160 for (saddr = sia->addrs ; saddr != NULL ; 4161 saddr = saddr->next) { 4162 if (sia->ia_type != D6O_IA_PD) 4163 daddr = find_addr(dia->addrs, 4164 &saddr->address); 4165 else 4166 daddr = find_pref(dia->addrs, 4167 &saddr->address, 4168 saddr->plen); 4169 4170 if (daddr == NULL) { 4171 taddr = dhc6_dup_addr(saddr, MDL); 4172 4173 if (taddr == NULL) 4174 log_fatal("Out of memory " 4175 "merging lease - " 4176 "Unable to continue " 4177 "without losing " 4178 "state! (%s:%d)", 4179 MDL); 4180 4181 /* XXX: consider sorting? */ 4182 taddr->next = dia->addrs; 4183 dia->addrs = taddr; 4184 changes = 1; 4185 } 4186 } 4187 } 4188 } 4189 4190 /* If we made changes, reset the score to 0 so it is recalculated. */ 4191 if (changes) 4192 dst->score = 0; 4193 } 4194 4195 /* We've either finished selecting or succeeded in Renew or Rebinding our 4196 * lease. In all cases we got a Reply. Give dhclient-script a tickle 4197 * to inform it about the new values, and then lay in wait for the next 4198 * event. 4199 */ 4200 static void 4201 start_bound(struct client_state *client) 4202 { 4203 struct dhc6_ia *ia, *oldia; 4204 struct dhc6_addr *addr, *oldaddr; 4205 struct dhc6_lease *lease, *old; 4206 const char *reason; 4207 #if defined (NSUPDATE) 4208 TIME dns_update_offset = 1; 4209 #endif 4210 4211 lease = client->active_lease; 4212 if (lease == NULL) { 4213 log_error("Cannot enter bound state unless an active lease " 4214 "is selected."); 4215 return; 4216 } 4217 lease->released = ISC_FALSE; 4218 old = client->old_lease; 4219 4220 client->v6_handler = bound_handler; 4221 4222 switch (client->state) { 4223 case S_SELECTING: 4224 case S_REBOOTING: /* Pretend we got bound. */ 4225 reason = "BOUND6"; 4226 break; 4227 4228 case S_RENEWING: 4229 reason = "RENEW6"; 4230 break; 4231 4232 case S_REBINDING: 4233 reason = "REBIND6"; 4234 break; 4235 4236 default: 4237 log_fatal("Impossible condition at %s:%d.", MDL); 4238 /* Silence compiler warnings. */ 4239 return; 4240 } 4241 4242 log_debug("PRC: Bound to lease %s.", 4243 print_hex_1(client->active_lease->server_id.len, 4244 client->active_lease->server_id.data, 55)); 4245 client->state = S_BOUND; 4246 4247 write_client6_lease(client, lease, 0, 1); 4248 4249 oldia = NULL; 4250 for (ia = lease->bindings ; ia != NULL ; ia = ia->next) { 4251 if (old != NULL) 4252 oldia = find_ia(old->bindings, 4253 ia->ia_type, 4254 (char *)ia->iaid); 4255 else 4256 oldia = NULL; 4257 4258 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) { 4259 if (oldia != NULL) { 4260 if (ia->ia_type != D6O_IA_PD) 4261 oldaddr = find_addr(oldia->addrs, 4262 &addr->address); 4263 else 4264 oldaddr = find_pref(oldia->addrs, 4265 &addr->address, 4266 addr->plen); 4267 } else 4268 oldaddr = NULL; 4269 4270 #if defined (NSUPDATE) 4271 if ((oldaddr == NULL) && (ia->ia_type == D6O_IA_NA)) 4272 dhclient_schedule_updates(client, 4273 &addr->address, 4274 dns_update_offset++); 4275 #endif 4276 4277 /* Shell out to setup the new binding. */ 4278 script_init(client, reason, NULL); 4279 4280 if (old != NULL) 4281 dhc6_marshall_values("old_", client, old, 4282 oldia, oldaddr); 4283 dhc6_marshall_values("new_", client, lease, ia, addr); 4284 script_write_requested6(client); 4285 4286 script_go(client); 4287 } 4288 4289 /* XXX: maybe we should loop on the old values instead? */ 4290 if (ia->addrs == NULL) { 4291 script_init(client, reason, NULL); 4292 4293 if (old != NULL) 4294 dhc6_marshall_values("old_", client, old, 4295 oldia, 4296 oldia != NULL ? 4297 oldia->addrs : NULL); 4298 4299 dhc6_marshall_values("new_", client, lease, ia, 4300 NULL); 4301 script_write_requested6(client); 4302 4303 script_go(client); 4304 } 4305 } 4306 4307 /* XXX: maybe we should loop on the old values instead? */ 4308 if (lease->bindings == NULL) { 4309 script_init(client, reason, NULL); 4310 4311 if (old != NULL) 4312 dhc6_marshall_values("old_", client, old, 4313 old->bindings, 4314 (old->bindings != NULL) ? 4315 old->bindings->addrs : NULL); 4316 4317 dhc6_marshall_values("new_", client, lease, NULL, NULL); 4318 script_write_requested6(client); 4319 4320 script_go(client); 4321 } 4322 4323 go_daemon(); 4324 4325 if (client->old_lease != NULL) { 4326 dhc6_lease_destroy(&client->old_lease, MDL); 4327 client->old_lease = NULL; 4328 } 4329 4330 /* Schedule events. */ 4331 dhc6_check_times(client); 4332 } 4333 4334 /* While bound, ignore packets. In the future we'll want to answer 4335 * Reconfigure-Request messages and the like. 4336 */ 4337 void 4338 bound_handler(struct packet *packet, struct client_state *client) 4339 { 4340 log_debug("RCV: Input packets are ignored once bound."); 4341 } 4342 4343 /* start_renew6() gets us all ready to go to start transmitting Renew packets. 4344 * Note that client->next_MRD must be set before entering this function - 4345 * it must be set to the time at which the client should start Rebinding. 4346 */ 4347 void 4348 start_renew6(void *input) 4349 { 4350 struct client_state *client; 4351 4352 client = (struct client_state *)input; 4353 4354 log_info("PRC: Renewing lease on %s.", 4355 client->name ? client->name : client->interface->name); 4356 client->state = S_RENEWING; 4357 4358 client->v6_handler = reply_handler; 4359 4360 /* Times per RFC3315 section 18.1.3. */ 4361 client->IRT = REN_TIMEOUT * 100; 4362 client->MRT = REN_MAX_RT * 100; 4363 client->MRC = 0; 4364 /* MRD is special in renew - we need to set it by checking timer 4365 * state. 4366 */ 4367 client->MRD = client->next_MRD - cur_time; 4368 4369 dhc6_retrans_init(client); 4370 4371 client->refresh_type = DHCPV6_RENEW; 4372 do_refresh6(client); 4373 } 4374 4375 /* do_refresh6() transmits one DHCPv6 packet, be it a Renew or Rebind, and 4376 * gives the retransmission state a bump for the next time. Note that 4377 * client->refresh_type must be set before entering this function. 4378 */ 4379 void 4380 do_refresh6(void *input) 4381 { 4382 struct option_cache *oc; 4383 struct sockaddr_in6 unicast, *dest_addr = &DHCPv6DestAddr; 4384 struct data_string ds; 4385 struct client_state *client; 4386 struct dhc6_lease *lease; 4387 struct timeval elapsed, tv; 4388 int send_ret; 4389 4390 client = (struct client_state *)input; 4391 memset(&ds, 0, sizeof(ds)); 4392 4393 lease = client->active_lease; 4394 if (lease == NULL) { 4395 log_error("Cannot renew without an active binding."); 4396 return; 4397 } 4398 4399 /* Ensure we're emitting a valid message type. */ 4400 switch (client->refresh_type) { 4401 case DHCPV6_RENEW: 4402 case DHCPV6_REBIND: 4403 break; 4404 4405 default: 4406 log_fatal("Internal inconsistency (%d) at %s:%d.", 4407 client->refresh_type, MDL); 4408 } 4409 4410 /* 4411 * Start_time starts at the first transmission. 4412 */ 4413 if (client->txcount == 0) { 4414 client->start_time.tv_sec = cur_tv.tv_sec; 4415 client->start_time.tv_usec = cur_tv.tv_usec; 4416 } 4417 4418 /* elapsed = cur - start */ 4419 elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec; 4420 elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec; 4421 if (elapsed.tv_usec < 0) { 4422 elapsed.tv_sec -= 1; 4423 elapsed.tv_usec += 1000000; 4424 } 4425 if (((client->MRC != 0) && (client->txcount > client->MRC)) || 4426 ((client->MRD != 0) && (elapsed.tv_sec >= client->MRD))) { 4427 /* We're done. Move on to the next phase, if any. */ 4428 dhc6_check_times(client); 4429 return; 4430 } 4431 4432 /* 4433 * Check whether the server has sent a unicast option; if so, we can 4434 * use the address it specified for RENEWs. 4435 */ 4436 oc = lookup_option(&dhcpv6_universe, lease->options, D6O_UNICAST); 4437 if (oc && evaluate_option_cache(&ds, NULL, NULL, NULL, 4438 lease->options, NULL, &global_scope, 4439 oc, MDL)) { 4440 if (ds.len < 16) { 4441 log_error("Invalid unicast option length %d.", ds.len); 4442 } else { 4443 memset(&unicast, 0, sizeof(DHCPv6DestAddr)); 4444 unicast.sin6_family = AF_INET6; 4445 unicast.sin6_port = remote_port; 4446 memcpy(&unicast.sin6_addr, ds.data, 16); 4447 if (client->refresh_type == DHCPV6_RENEW) { 4448 dest_addr = &unicast; 4449 } 4450 } 4451 4452 data_string_forget(&ds, MDL); 4453 } 4454 4455 /* Commence forming a renew packet. */ 4456 memset(&ds, 0, sizeof(ds)); 4457 if (!buffer_allocate(&ds.buffer, 4, MDL)) { 4458 log_error("Unable to allocate memory for packet."); 4459 return; 4460 } 4461 ds.data = ds.buffer->data; 4462 ds.len = 4; 4463 4464 ds.buffer->data[0] = client->refresh_type; 4465 memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3); 4466 4467 /* Form an elapsed option. */ 4468 /* Maximum value is 65535 1/100s coded as 0xffff. */ 4469 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) || 4470 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) { 4471 client->elapsed = 0xffff; 4472 } else { 4473 client->elapsed = elapsed.tv_sec * 100; 4474 client->elapsed += elapsed.tv_usec / 10000; 4475 } 4476 4477 if (client->elapsed == 0) 4478 log_debug("XMT: Forming %s, 0 ms elapsed.", 4479 dhcpv6_type_names[client->refresh_type]); 4480 else 4481 log_debug("XMT: Forming %s, %u0 ms elapsed.", 4482 dhcpv6_type_names[client->refresh_type], 4483 (unsigned)client->elapsed); 4484 4485 client->elapsed = htons(client->elapsed); 4486 4487 make_client6_options(client, &client->sent_options, lease, 4488 client->refresh_type); 4489 4490 /* Put in any options from the sent cache. */ 4491 dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL, 4492 client->sent_options, &global_scope, 4493 &dhcpv6_universe); 4494 4495 /* Append IA's */ 4496 if (wanted_ia_na && 4497 dhc6_add_ia_na(client, &ds, lease, 4498 client->refresh_type) != ISC_R_SUCCESS) { 4499 data_string_forget(&ds, MDL); 4500 return; 4501 } 4502 if (wanted_ia_pd && 4503 dhc6_add_ia_pd(client, &ds, lease, 4504 client->refresh_type) != ISC_R_SUCCESS) { 4505 data_string_forget(&ds, MDL); 4506 return; 4507 } 4508 4509 log_info("XMT: %s on %s, interval %ld0ms.", 4510 dhcpv6_type_names[client->refresh_type], 4511 client->name ? client->name : client->interface->name, 4512 (long int)client->RT); 4513 4514 send_ret = send_packet6(client->interface, ds.data, ds.len, dest_addr); 4515 4516 if (send_ret != ds.len) { 4517 log_error("dhc6: send_packet6() sent %d of %d bytes", 4518 send_ret, ds.len); 4519 } 4520 4521 data_string_forget(&ds, MDL); 4522 4523 /* Wait RT */ 4524 tv.tv_sec = cur_tv.tv_sec + client->RT / 100; 4525 tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000; 4526 if (tv.tv_usec >= 1000000) { 4527 tv.tv_sec += 1; 4528 tv.tv_usec -= 1000000; 4529 } 4530 add_timeout(&tv, do_refresh6, client, NULL, NULL); 4531 4532 dhc6_retrans_advance(client); 4533 } 4534 4535 /* start_rebind6() gets us all set up to go and rebind a lease. Note that 4536 * client->next_MRD must be set before entering this function. In this case, 4537 * MRD must be set to the maximum time any address in the packet will 4538 * expire. 4539 */ 4540 void 4541 start_rebind6(void *input) 4542 { 4543 struct client_state *client; 4544 4545 client = (struct client_state *)input; 4546 4547 log_info("PRC: Rebinding lease on %s.", 4548 client->name ? client->name : client->interface->name); 4549 client->state = S_REBINDING; 4550 4551 client->v6_handler = reply_handler; 4552 4553 /* Times per RFC3315 section 18.1.4. */ 4554 client->IRT = REB_TIMEOUT * 100; 4555 client->MRT = REB_MAX_RT * 100; 4556 client->MRC = 0; 4557 /* MRD is special in rebind - it's determined by the timer 4558 * state. 4559 */ 4560 client->MRD = client->next_MRD - cur_time; 4561 4562 dhc6_retrans_init(client); 4563 4564 client->refresh_type = DHCPV6_REBIND; 4565 do_refresh6(client); 4566 } 4567 4568 /* do_depref() runs through a given lease's addresses, for each that has 4569 * not yet been depreffed, shells out to the dhclient-script to inform it 4570 * of the status change. The dhclient-script should then do...something... 4571 * to encourage applications to move off the address and onto one of the 4572 * remaining 'preferred' addresses. 4573 */ 4574 void 4575 do_depref(void *input) 4576 { 4577 struct client_state *client; 4578 struct dhc6_lease *lease; 4579 struct dhc6_ia *ia; 4580 struct dhc6_addr *addr; 4581 4582 client = (struct client_state *)input; 4583 4584 lease = client->active_lease; 4585 if (lease == NULL) 4586 return; 4587 4588 for (ia = lease->bindings ; ia != NULL ; ia = ia->next) { 4589 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) { 4590 if (addr->flags & DHC6_ADDR_DEPREFFED) 4591 continue; 4592 4593 if (addr->starts + addr->preferred_life <= cur_time) { 4594 script_init(client, "DEPREF6", NULL); 4595 dhc6_marshall_values("cur_", client, lease, 4596 ia, addr); 4597 script_write_requested6(client); 4598 script_go(client); 4599 4600 addr->flags |= DHC6_ADDR_DEPREFFED; 4601 4602 if (ia->ia_type != D6O_IA_PD) 4603 log_info("PRC: Address %s depreferred.", 4604 piaddr(addr->address)); 4605 else 4606 log_info("PRC: Prefix %s/%u depreferred.", 4607 piaddr(addr->address), 4608 (unsigned) addr->plen); 4609 4610 #if defined (NSUPDATE) 4611 /* Remove DDNS bindings at depref time. */ 4612 if ((ia->ia_type == D6O_IA_NA) && 4613 client->config->do_forward_update) 4614 client_dns_remove(client, 4615 &addr->address); 4616 #endif 4617 } 4618 } 4619 } 4620 4621 dhc6_check_times(client); 4622 } 4623 4624 /* do_expire() searches through all the addresses on a given lease, and 4625 * expires/removes any addresses that are no longer valid. 4626 */ 4627 void 4628 do_expire(void *input) 4629 { 4630 struct client_state *client; 4631 struct dhc6_lease *lease; 4632 struct dhc6_ia *ia; 4633 struct dhc6_addr *addr; 4634 int has_addrs = ISC_FALSE; 4635 4636 client = (struct client_state *)input; 4637 4638 lease = client->active_lease; 4639 if (lease == NULL) 4640 return; 4641 4642 for (ia = lease->bindings ; ia != NULL ; ia = ia->next) { 4643 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) { 4644 if (addr->flags & DHC6_ADDR_EXPIRED) 4645 continue; 4646 4647 if (addr->starts + addr->max_life <= cur_time) { 4648 script_init(client, "EXPIRE6", NULL); 4649 dhc6_marshall_values("old_", client, lease, 4650 ia, addr); 4651 script_write_requested6(client); 4652 script_go(client); 4653 4654 addr->flags |= DHC6_ADDR_EXPIRED; 4655 4656 if (ia->ia_type != D6O_IA_PD) 4657 log_info("PRC: Address %s expired.", 4658 piaddr(addr->address)); 4659 else 4660 log_info("PRC: Prefix %s/%u expired.", 4661 piaddr(addr->address), 4662 (unsigned) addr->plen); 4663 4664 #if defined (NSUPDATE) 4665 /* We remove DNS records at depref time, but 4666 * it is possible that we might get here 4667 * without depreffing. 4668 */ 4669 if ((ia->ia_type == D6O_IA_NA) && 4670 client->config->do_forward_update && 4671 !(addr->flags & DHC6_ADDR_DEPREFFED)) 4672 client_dns_remove(client, 4673 &addr->address); 4674 #endif 4675 4676 continue; 4677 } 4678 4679 has_addrs = ISC_TRUE; 4680 } 4681 } 4682 4683 /* Clean up empty leases. */ 4684 if (has_addrs == ISC_FALSE) { 4685 log_info("PRC: Bound lease is devoid of active addresses." 4686 " Re-initializing."); 4687 4688 dhc6_lease_destroy(&lease, MDL); 4689 client->active_lease = NULL; 4690 4691 start_init6(client); 4692 return; 4693 } 4694 4695 /* Schedule the next run through. */ 4696 dhc6_check_times(client); 4697 } 4698 4699 /* 4700 * Run client script to unconfigure interface. 4701 * Called with reason STOP6 when dhclient -x is run, or with reason 4702 * RELEASE6 when server has replied to a Release message. 4703 * Stateless is a special case. 4704 */ 4705 void 4706 unconfigure6(struct client_state *client, const char *reason) 4707 { 4708 struct dhc6_ia *ia; 4709 struct dhc6_addr *addr; 4710 4711 if (stateless) { 4712 script_init(client, reason, NULL); 4713 if (client->active_lease != NULL) 4714 script_write_params6(client, "old_", 4715 client->active_lease->options); 4716 script_write_requested6(client); 4717 script_go(client); 4718 return; 4719 } 4720 4721 if (client->active_lease == NULL) 4722 return; 4723 4724 for (ia = client->active_lease->bindings ; ia != NULL ; ia = ia->next) { 4725 if (ia->ia_type == D6O_IA_TA) 4726 continue; 4727 4728 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) { 4729 script_init(client, reason, NULL); 4730 dhc6_marshall_values("old_", client, 4731 client->active_lease, ia, addr); 4732 script_write_requested6(client); 4733 script_go(client); 4734 4735 #if defined (NSUPDATE) 4736 if ((ia->ia_type == D6O_IA_NA) && 4737 client->config->do_forward_update) 4738 client_dns_remove(client, &addr->address); 4739 #endif 4740 } 4741 } 4742 } 4743 4744 static void 4745 refresh_info_request6(void *input) 4746 { 4747 struct client_state *client; 4748 4749 client = (struct client_state *)input; 4750 start_info_request6(client); 4751 } 4752 4753 /* Timeout for Information-Request (using the IRT option). 4754 */ 4755 static void 4756 dhc6_check_irt(struct client_state *client) 4757 { 4758 struct option **req; 4759 struct option_cache *oc; 4760 TIME expire = MAX_TIME; 4761 struct timeval tv; 4762 int i; 4763 isc_boolean_t found = ISC_FALSE; 4764 4765 cancel_timeout(refresh_info_request6, client); 4766 4767 req = client->config->requested_options; 4768 for (i = 0; req[i] != NULL; i++) { 4769 if (req[i] == irt_option) { 4770 found = ISC_TRUE; 4771 break; 4772 } 4773 } 4774 /* Simply return gives a endless loop waiting for nothing. */ 4775 if (!found) 4776 exit(0); 4777 4778 oc = lookup_option(&dhcpv6_universe, client->active_lease->options, 4779 D6O_INFORMATION_REFRESH_TIME); 4780 if (oc != NULL) { 4781 struct data_string irt; 4782 4783 memset(&irt, 0, sizeof(irt)); 4784 if (!evaluate_option_cache(&irt, NULL, NULL, client, 4785 client->active_lease->options, 4786 NULL, &global_scope, oc, MDL) || 4787 (irt.len < 4)) { 4788 log_error("Can't evaluate IRT."); 4789 } else { 4790 expire = getULong(irt.data); 4791 if (expire < IRT_MINIMUM) 4792 expire = IRT_MINIMUM; 4793 if (expire == 0xffffffff) 4794 expire = MAX_TIME; 4795 } 4796 data_string_forget(&irt, MDL); 4797 } else 4798 expire = IRT_DEFAULT; 4799 4800 if (expire != MAX_TIME) { 4801 log_debug("PRC: Refresh event scheduled in %u seconds.", 4802 (unsigned) expire); 4803 tv.tv_sec = cur_time + expire; 4804 tv.tv_usec = 0; 4805 add_timeout(&tv, refresh_info_request6, client, NULL, NULL); 4806 } 4807 } 4808 4809 /* We got a Reply. Give dhclient-script a tickle to inform it about 4810 * the new values, and then lay in wait for the next event. 4811 */ 4812 static void 4813 start_informed(struct client_state *client) 4814 { 4815 client->v6_handler = informed_handler; 4816 4817 log_debug("PRC: Done."); 4818 4819 client->state = S_BOUND; 4820 4821 script_init(client, "RENEW6", NULL); 4822 if (client->old_lease != NULL) 4823 script_write_params6(client, "old_", 4824 client->old_lease->options); 4825 script_write_params6(client, "new_", client->active_lease->options); 4826 script_write_requested6(client); 4827 script_go(client); 4828 4829 go_daemon(); 4830 4831 if (client->old_lease != NULL) { 4832 dhc6_lease_destroy(&client->old_lease, MDL); 4833 client->old_lease = NULL; 4834 } 4835 4836 /* Schedule events. */ 4837 dhc6_check_irt(client); 4838 } 4839 4840 /* While informed, ignore packets. 4841 */ 4842 void 4843 informed_handler(struct packet *packet, struct client_state *client) 4844 { 4845 log_debug("RCV: Input packets are ignored once bound."); 4846 } 4847 4848 /* make_client6_options() fetches option caches relevant to the client's 4849 * scope and places them into the sent_options cache. This cache is later 4850 * used to populate DHCPv6 output packets with options. 4851 */ 4852 static void 4853 make_client6_options(struct client_state *client, struct option_state **op, 4854 struct dhc6_lease *lease, u_int8_t message) 4855 { 4856 struct option_cache *oc; 4857 struct option **req; 4858 struct buffer *buffer; 4859 int buflen, i, oro_len; 4860 4861 if ((op == NULL) || (client == NULL)) 4862 return; 4863 4864 if (*op) 4865 option_state_dereference(op, MDL); 4866 4867 /* Create a cache to carry options to transmission. */ 4868 option_state_allocate(op, MDL); 4869 4870 /* Create and store an 'elapsed time' option in the cache. */ 4871 oc = NULL; 4872 if (option_cache_allocate(&oc, MDL)) { 4873 const unsigned char *cdata; 4874 4875 cdata = (unsigned char *)&client->elapsed; 4876 4877 if (make_const_data(&oc->expression, cdata, 2, 0, 0, MDL)) { 4878 option_reference(&oc->option, elapsed_option, MDL); 4879 save_option(&dhcpv6_universe, *op, oc); 4880 } 4881 4882 option_cache_dereference(&oc, MDL); 4883 } 4884 4885 /* Bring in any configured options to send. */ 4886 if (client->config->on_transmission) 4887 execute_statements_in_scope(NULL, NULL, NULL, client, 4888 lease ? lease->options : NULL, 4889 *op, &global_scope, 4890 client->config->on_transmission, 4891 NULL, NULL); 4892 4893 /* Rapid-commit is only for SOLICITs. */ 4894 if (message != DHCPV6_SOLICIT) 4895 delete_option(&dhcpv6_universe, *op, D6O_RAPID_COMMIT); 4896 4897 /* See if the user configured a DUID in a relevant scope. If not, 4898 * introduce our default manufactured id. 4899 */ 4900 if ((oc = lookup_option(&dhcpv6_universe, *op, 4901 D6O_CLIENTID)) == NULL) { 4902 if (!option_cache(&oc, &default_duid, NULL, clientid_option, 4903 MDL)) 4904 log_fatal("Failure assembling a DUID."); 4905 4906 save_option(&dhcpv6_universe, *op, oc); 4907 option_cache_dereference(&oc, MDL); 4908 } 4909 4910 /* In cases where we're responding to a single server, put the 4911 * server's id in the response. 4912 * 4913 * Note that lease is NULL for SOLICIT or INFO request messages, 4914 * and otherwise MUST be present. 4915 */ 4916 if (lease == NULL) { 4917 if ((message != DHCPV6_SOLICIT) && 4918 (message != DHCPV6_INFORMATION_REQUEST)) 4919 log_fatal("Impossible condition at %s:%d.", MDL); 4920 } else if ((message != DHCPV6_REBIND) && 4921 (message != DHCPV6_CONFIRM)) { 4922 oc = lookup_option(&dhcpv6_universe, lease->options, 4923 D6O_SERVERID); 4924 if (oc != NULL) 4925 save_option(&dhcpv6_universe, *op, oc); 4926 } 4927 4928 /* 'send dhcp6.oro foo;' syntax we used in 4.0.0a1/a2 has been 4929 * deprecated by adjustments to the 'request' syntax also used for 4930 * DHCPv4. 4931 */ 4932 if (lookup_option(&dhcpv6_universe, *op, D6O_ORO) != NULL) 4933 log_error("'send dhcp6.oro' syntax is deprecated, please " 4934 "use the 'request' syntax (\"man dhclient.conf\")."); 4935 4936 /* Construct and store an ORO (Option Request Option). It is a 4937 * fatal error to fail to send an ORO (of at least zero length). 4938 * 4939 * Discussion: RFC3315 appears to be inconsistent in its statements 4940 * of whether or not the ORO is mandatory. In section 18.1.1 4941 * ("Creation and Transmission of Request Messages"): 4942 * 4943 * The client MUST include an Option Request option (see section 4944 * 22.7) to indicate the options the client is interested in 4945 * receiving. The client MAY include options with data values as 4946 * hints to the server about parameter values the client would like 4947 * to have returned. 4948 * 4949 * This MUST is missing from the creation/transmission of other 4950 * messages (such as Renew and Rebind), and the section 22.7 ("Option 4951 * Request Option" format and definition): 4952 * 4953 * A client MAY include an Option Request option in a Solicit, 4954 * Request, Renew, Rebind, Confirm or Information-request message to 4955 * inform the server about options the client wants the server to 4956 * send to the client. A server MAY include an Option Request 4957 * option in a Reconfigure option to indicate which options the 4958 * client should request from the server. 4959 * 4960 * seems to relax the requirement from MUST to MAY (and still other 4961 * language in RFC3315 supports this). 4962 * 4963 * In lieu of a clarification of RFC3315, we will conform with the 4964 * MUST. Instead of an absent ORO, we will if there are no options 4965 * to request supply an empty ORO. Theoretically, an absent ORO is 4966 * difficult to interpret (does the client want all options or no 4967 * options?). A zero-length ORO is intuitively clear: requesting 4968 * nothing. 4969 */ 4970 buffer = NULL; 4971 oro_len = 0; 4972 buflen = 32; 4973 if (!buffer_allocate(&buffer, buflen, MDL)) 4974 log_fatal("Out of memory constructing DHCPv6 ORO."); 4975 req = client->config->requested_options; 4976 if (req != NULL) { 4977 for (i = 0 ; req[i] != NULL ; i++) { 4978 if (buflen == oro_len) { 4979 struct buffer *tmpbuf = NULL; 4980 4981 buflen += 32; 4982 4983 /* Shell game. */ 4984 buffer_reference(&tmpbuf, buffer, MDL); 4985 buffer_dereference(&buffer, MDL); 4986 4987 if (!buffer_allocate(&buffer, buflen, MDL)) 4988 log_fatal("Out of memory resizing " 4989 "DHCPv6 ORO buffer."); 4990 4991 memcpy(buffer->data, tmpbuf->data, oro_len); 4992 4993 buffer_dereference(&tmpbuf, MDL); 4994 } 4995 4996 if (req[i]->universe == &dhcpv6_universe) { 4997 /* Append the code to the ORO. */ 4998 putUShort(buffer->data + oro_len, 4999 req[i]->code); 5000 oro_len += 2; 5001 } 5002 } 5003 } 5004 5005 oc = NULL; 5006 if (make_const_option_cache(&oc, &buffer, NULL, oro_len, 5007 oro_option, MDL)) { 5008 save_option(&dhcpv6_universe, *op, oc); 5009 } else { 5010 log_fatal("Unable to create ORO option cache."); 5011 } 5012 5013 /* 5014 * Note: make_const_option_cache() consumes the buffer, we do not 5015 * need to dereference it (XXX). 5016 */ 5017 option_cache_dereference(&oc, MDL); 5018 } 5019 5020 /* A clone of the DHCPv4 script_write_params() minus the DHCPv4-specific 5021 * filename, server-name, etc specifics. 5022 * 5023 * Simply, store all values present in all universes of the option state 5024 * (probably derived from a DHCPv6 packet) into environment variables 5025 * named after the option names (and universe names) but with the 'prefix' 5026 * prepended. 5027 * 5028 * Later, dhclient-script may compare for example "new_time_servers" and 5029 * "old_time_servers" for differences, and only upon detecting a change 5030 * bother to rewrite ntp.conf and restart it. Or something along those 5031 * generic lines. 5032 */ 5033 static void 5034 script_write_params6(struct client_state *client, const char *prefix, 5035 struct option_state *options) 5036 { 5037 struct envadd_state es; 5038 int i; 5039 5040 if (options == NULL) 5041 return; 5042 5043 es.client = client; 5044 es.prefix = prefix; 5045 5046 for (i = 0 ; i < options->universe_count ; i++) { 5047 option_space_foreach(NULL, NULL, client, NULL, options, 5048 &global_scope, universes[i], &es, 5049 client_option_envadd); 5050 } 5051 } 5052 5053 /* 5054 * A clone of the DHCPv4 routine. 5055 * Write out the environment variables for the objects that the 5056 * client requested. If the object was requested the variable will be: 5057 * requested_<option_name>=1 5058 * If it wasn't requested there won't be a variable. 5059 */ 5060 static void script_write_requested6(client) 5061 struct client_state *client; 5062 { 5063 int i; 5064 struct option **req; 5065 char name[256]; 5066 req = client->config->requested_options; 5067 5068 if (req == NULL) 5069 return; 5070 5071 for (i = 0 ; req[i] != NULL ; i++) { 5072 if ((req[i]->universe == &dhcpv6_universe) && 5073 dhcp_option_ev_name (name, sizeof(name), req[i])) { 5074 client_envadd(client, "requested_", name, "%d", 1); 5075 } 5076 } 5077 } 5078 5079 /* 5080 * Check if there is something not fully defined in the active lease. 5081 */ 5082 static isc_boolean_t 5083 active_prefix(struct client_state *client) 5084 { 5085 struct dhc6_lease *lease; 5086 struct dhc6_ia *ia; 5087 struct dhc6_addr *pref; 5088 char zeros[16]; 5089 5090 lease = client->active_lease; 5091 if (lease == NULL) 5092 return ISC_FALSE; 5093 memset(zeros, 0, 16); 5094 for (ia = lease->bindings; ia != NULL; ia = ia->next) { 5095 if (ia->ia_type != D6O_IA_PD) 5096 continue; 5097 for (pref = ia->addrs; pref != NULL; pref = pref->next) { 5098 if (pref->plen == 0) 5099 return ISC_FALSE; 5100 if (pref->address.len != 16) 5101 return ISC_FALSE; 5102 if (memcmp(pref->address.iabuf, zeros, 16) == 0) 5103 return ISC_FALSE; 5104 } 5105 } 5106 return ISC_TRUE; 5107 } 5108 #endif /* DHCPv6 */ 5109