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