2 * Copyright (C) 2006-2008 by Internet Systems Consortium, Inc. ("ISC")
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
22 * We use print_hex_1() to output DUID values. We could actually output
23 * the DUID with more information... MAC address if using type 1 or 3,
24 * and so on. However, RFC 3315 contains Grave Warnings against actually
25 * attempting to understand a DUID.
29 * TODO: gettext() or other method of localization for the messages
30 * for status codes (and probably for log formats eventually)
31 * TODO: refactoring (simplify, simplify, simplify)
32 * TODO: support multiple shared_networks on each interface (this
33 * will allow the server to issue multiple IPv6 addresses to
38 * DHCPv6 Reply workflow assist. A Reply packet is built by various
39 * different functions; this gives us one location where we keep state
43 /* root level persistent state */
44 struct shared_network
*shared
;
45 struct host_decl
*host
;
46 struct option_state
*opt_state
;
47 struct packet
*packet
;
48 struct data_string client_id
;
50 /* IA level persistent state */
53 unsigned client_resources
;
54 isc_boolean_t resources_included
;
55 isc_boolean_t static_lease
;
56 unsigned static_prefixes
;
59 struct option_state
*reply_ia
;
60 struct data_string fixed
;
62 /* IAADDR/PREFIX level persistent state */
63 struct iasubopt
*lease
;
66 * "t1", "t2", preferred, and valid lifetimes records for calculating
67 * t1 and t2 (min/max).
69 u_int32_t renew
, rebind
, prefer
, valid
;
71 /* Client-requested valid and preferred lifetimes. */
72 u_int32_t client_valid
, client_prefer
;
74 /* Chosen values to transmit for valid and preferred lifetimes. */
75 u_int32_t send_valid
, send_prefer
;
77 /* Preferred prefix length (-1 is any). */
80 /* Index into the data field that has been consumed. */
84 unsigned char data
[65536];
85 struct dhcpv6_packet reply
;
90 * Prototypes local to this file.
92 static int get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
93 struct data_string
*enc_opt_data
,
94 struct packet
*packet
,
95 struct option_cache
*oc
,
97 static void build_dhcpv6_reply(struct data_string
*, struct packet
*);
98 static isc_result_t
shared_network_from_packet6(struct shared_network
**shared
,
99 struct packet
*packet
);
100 static void seek_shared_host(struct host_decl
**hp
,
101 struct shared_network
*shared
);
102 static isc_boolean_t
fixed_matches_shared(struct host_decl
*host
,
103 struct shared_network
*shared
);
104 static isc_result_t
reply_process_ia_na(struct reply_state
*reply
,
105 struct option_cache
*ia
);
106 static isc_result_t
reply_process_ia_ta(struct reply_state
*reply
,
107 struct option_cache
*ia
);
108 static isc_result_t
reply_process_addr(struct reply_state
*reply
,
109 struct option_cache
*addr
);
110 static isc_boolean_t
address_is_owned(struct reply_state
*reply
,
112 static isc_result_t
find_client_temporaries(struct reply_state
*reply
);
113 static isc_result_t
reply_process_try_addr(struct reply_state
*reply
,
115 static isc_result_t
find_client_address(struct reply_state
*reply
);
116 static isc_result_t
reply_process_is_addressed(struct reply_state
*reply
,
117 struct binding_scope
**scope
,
118 struct group
*group
);
119 static isc_result_t
reply_process_send_addr(struct reply_state
*reply
,
121 static struct iasubopt
*lease_compare(struct iasubopt
*alpha
,
122 struct iasubopt
*beta
);
123 static isc_result_t
reply_process_ia_pd(struct reply_state
*reply
,
124 struct option_cache
*ia_pd
);
125 static isc_result_t
reply_process_prefix(struct reply_state
*reply
,
126 struct option_cache
*pref
);
127 static isc_boolean_t
prefix_is_owned(struct reply_state
*reply
,
128 struct iaddrcidrnet
*pref
);
129 static isc_result_t
find_client_prefix(struct reply_state
*reply
);
130 static isc_result_t
reply_process_try_prefix(struct reply_state
*reply
,
131 struct iaddrcidrnet
*pref
);
132 static isc_result_t
reply_process_is_prefixed(struct reply_state
*reply
,
133 struct binding_scope
**scope
,
134 struct group
*group
);
135 static isc_result_t
reply_process_send_prefix(struct reply_state
*reply
,
136 struct iaddrcidrnet
*pref
);
137 static struct iasubopt
*prefix_compare(struct reply_state
*reply
,
138 struct iasubopt
*alpha
,
139 struct iasubopt
*beta
);
142 * This function returns the time since DUID time start for the
143 * given time_t value.
146 duid_time(time_t when
) {
148 * This time is modulo 2^32.
150 while ((when
- DUID_TIME_EPOCH
) > 4294967295u) {
151 /* use 2^31 to avoid spurious compiler warnings */
156 return when
- DUID_TIME_EPOCH
;
163 * This must remain the same for the lifetime of this server, because
164 * clients return the server DUID that we sent them in Request packets.
166 * We pick the server DUID like this:
168 * 1. Check dhcpd.conf - any value the administrator has configured
169 * overrides any possible values.
170 * 2. Check the leases.txt - we want to use the previous value if
172 * 3. Check if dhcpd.conf specifies a type of server DUID to use,
173 * and generate that type.
174 * 4. Generate a type 1 (time + hardware address) DUID.
176 static struct data_string server_duid
;
179 * Check if the server_duid has been set.
182 server_duid_isset(void) {
183 return (server_duid
.data
!= NULL
);
187 * Return the server_duid.
190 copy_server_duid(struct data_string
*ds
, const char *file
, int line
) {
191 data_string_copy(ds
, &server_duid
, file
, line
);
195 * Set the server DUID to a specified value. This is used when
196 * the server DUID is stored in persistent memory (basically the
200 set_server_duid(struct data_string
*new_duid
) {
201 /* INSIST(new_duid != NULL); */
202 /* INSIST(new_duid->data != NULL); */
204 if (server_duid_isset()) {
205 data_string_forget(&server_duid
, MDL
);
207 data_string_copy(&server_duid
, new_duid
, MDL
);
212 * Set the server DUID based on the D6O_SERVERID option. This handles
213 * the case where the administrator explicitly put it in the dhcpd.conf
217 set_server_duid_from_option(void) {
218 struct option_state
*opt_state
;
219 struct option_cache
*oc
;
220 struct data_string option_duid
;
221 isc_result_t ret_val
;
224 if (!option_state_allocate(&opt_state
, MDL
)) {
225 log_fatal("No memory for server DUID.");
228 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
,
229 opt_state
, &global_scope
, root_group
, NULL
);
231 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
233 ret_val
= ISC_R_NOTFOUND
;
235 memset(&option_duid
, 0, sizeof(option_duid
));
236 if (!evaluate_option_cache(&option_duid
, NULL
, NULL
, NULL
,
237 opt_state
, NULL
, &global_scope
,
239 ret_val
= ISC_R_UNEXPECTED
;
241 set_server_duid(&option_duid
);
242 data_string_forget(&option_duid
, MDL
);
243 ret_val
= ISC_R_SUCCESS
;
247 option_state_dereference(&opt_state
, MDL
);
253 * DUID layout, as defined in RFC 3315, section 9.
255 * We support type 1 (hardware address plus time) and type 3 (hardware
258 * We can support type 2 for specific vendors in the future, if they
259 * publish the specification. And of course there may be additional
262 static int server_duid_type
= DUID_LLT
;
268 set_server_duid_type(int type
) {
269 server_duid_type
= type
;
273 * Generate a new server DUID. This is done if there was no DUID in
274 * the leases.txt or in the dhcpd.conf file.
277 generate_new_server_duid(void) {
278 struct interface_info
*p
;
280 struct data_string generated_duid
;
283 * Verify we have a type that we support.
285 if ((server_duid_type
!= DUID_LL
) && (server_duid_type
!= DUID_LLT
)) {
286 log_error("Invalid DUID type %d specified, "
287 "only LL and LLT types supported", server_duid_type
);
288 return ISC_R_INVALIDARG
;
292 * Find an interface with a hardware address.
295 for (p
= interfaces
; p
!= NULL
; p
= p
->next
) {
296 if (p
->hw_address
.hlen
> 0) {
301 return ISC_R_UNEXPECTED
;
307 memset(&generated_duid
, 0, sizeof(generated_duid
));
308 if (server_duid_type
== DUID_LLT
) {
309 time_val
= duid_time(time(NULL
));
310 generated_duid
.len
= 8 + p
->hw_address
.hlen
- 1;
311 if (!buffer_allocate(&generated_duid
.buffer
,
312 generated_duid
.len
, MDL
)) {
313 log_fatal("No memory for server DUID.");
315 generated_duid
.data
= generated_duid
.buffer
->data
;
316 putUShort(generated_duid
.buffer
->data
, DUID_LLT
);
317 putUShort(generated_duid
.buffer
->data
+ 2,
318 p
->hw_address
.hbuf
[0]);
319 putULong(generated_duid
.buffer
->data
+ 4, time_val
);
320 memcpy(generated_duid
.buffer
->data
+ 8,
321 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
322 } else if (server_duid_type
== DUID_LL
) {
323 generated_duid
.len
= 4 + p
->hw_address
.hlen
- 1;
324 if (!buffer_allocate(&generated_duid
.buffer
,
325 generated_duid
.len
, MDL
)) {
326 log_fatal("No memory for server DUID.");
328 generated_duid
.data
= generated_duid
.buffer
->data
;
329 putUShort(generated_duid
.buffer
->data
, DUID_LL
);
330 putUShort(generated_duid
.buffer
->data
+ 2,
331 p
->hw_address
.hbuf
[0]);
332 memcpy(generated_duid
.buffer
->data
+4,
333 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
335 log_fatal("Unsupported server DUID type %d.", server_duid_type
);
338 set_server_duid(&generated_duid
);
339 data_string_forget(&generated_duid
, MDL
);
341 return ISC_R_SUCCESS
;
345 * Get the client identifier from the packet.
348 get_client_id(struct packet
*packet
, struct data_string
*client_id
) {
349 struct option_cache
*oc
;
352 * Verify our client_id structure is empty.
354 if ((client_id
->data
!= NULL
) || (client_id
->len
!= 0)) {
355 return ISC_R_INVALIDARG
;
358 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_CLIENTID
);
360 return ISC_R_NOTFOUND
;
363 if (!evaluate_option_cache(client_id
, packet
, NULL
, NULL
,
364 packet
->options
, NULL
,
365 &global_scope
, oc
, MDL
)) {
366 return ISC_R_FAILURE
;
369 return ISC_R_SUCCESS
;
373 * Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
375 * Servers MUST discard any Solicit messages that do not include a
376 * Client Identifier option or that do include a Server Identifier
380 valid_client_msg(struct packet
*packet
, struct data_string
*client_id
) {
382 struct option_cache
*oc
;
383 struct data_string data
;
386 memset(client_id
, 0, sizeof(*client_id
));
387 memset(&data
, 0, sizeof(data
));
389 switch (get_client_id(packet
, client_id
)) {
393 log_debug("Discarding %s from %s; "
394 "client identifier missing",
395 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
396 piaddr(packet
->client_addr
));
399 log_error("Error processing %s from %s; "
400 "unable to evaluate Client Identifier",
401 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
402 piaddr(packet
->client_addr
));
407 * Required by RFC 3315, section 15.
409 if (packet
->unicast
) {
410 log_debug("Discarding %s from %s; packet sent unicast "
412 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
413 piaddr(packet
->client_addr
),
414 print_hex_1(client_id
->len
, client_id
->data
, 60));
419 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
421 if (evaluate_option_cache(&data
, packet
, NULL
, NULL
,
422 packet
->options
, NULL
,
423 &global_scope
, oc
, MDL
)) {
424 log_debug("Discarding %s from %s; "
425 "server identifier found "
426 "(CLIENTID %s, SERVERID %s)",
427 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
428 piaddr(packet
->client_addr
),
429 print_hex_1(client_id
->len
,
430 client_id
->data
, 60),
431 print_hex_2(data
.len
,
434 log_debug("Discarding %s from %s; "
435 "server identifier found "
437 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
438 print_hex_1(client_id
->len
,
439 client_id
->data
, 60),
440 piaddr(packet
->client_addr
));
450 data_string_forget(&data
, MDL
);
453 if (client_id
->len
> 0) {
454 data_string_forget(client_id
, MDL
);
461 * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
462 * 15.9 (slightly different wording, but same meaning):
464 * Servers MUST discard any received Request message that meet any of
465 * the following conditions:
467 * - the message does not include a Server Identifier option.
468 * - the contents of the Server Identifier option do not match the
470 * - the message does not include a Client Identifier option.
473 valid_client_resp(struct packet
*packet
,
474 struct data_string
*client_id
,
475 struct data_string
*server_id
)
478 struct option_cache
*oc
;
480 /* INSIST((duid.data != NULL) && (duid.len > 0)); */
483 memset(client_id
, 0, sizeof(*client_id
));
484 memset(server_id
, 0, sizeof(*server_id
));
486 switch (get_client_id(packet
, client_id
)) {
490 log_debug("Discarding %s from %s; "
491 "client identifier missing",
492 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
493 piaddr(packet
->client_addr
));
496 log_error("Error processing %s from %s; "
497 "unable to evaluate Client Identifier",
498 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
499 piaddr(packet
->client_addr
));
503 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
505 log_debug("Discarding %s from %s: "
506 "server identifier missing (CLIENTID %s)",
507 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
508 piaddr(packet
->client_addr
),
509 print_hex_1(client_id
->len
, client_id
->data
, 60));
512 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
513 packet
->options
, NULL
,
514 &global_scope
, oc
, MDL
)) {
515 log_error("Error processing %s from %s; "
516 "unable to evaluate Server Identifier (CLIENTID %s)",
517 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
518 piaddr(packet
->client_addr
),
519 print_hex_1(client_id
->len
, client_id
->data
, 60));
522 if ((server_duid
.len
!= server_id
->len
) ||
523 (memcmp(server_duid
.data
, server_id
->data
, server_duid
.len
) != 0)) {
524 log_debug("Discarding %s from %s; "
525 "not our server identifier "
526 "(CLIENTID %s, SERVERID %s, server DUID %s)",
527 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
528 piaddr(packet
->client_addr
),
529 print_hex_1(client_id
->len
, client_id
->data
, 60),
530 print_hex_2(server_id
->len
, server_id
->data
, 60),
531 print_hex_3(server_duid
.len
, server_duid
.data
, 60));
540 if (server_id
->len
> 0) {
541 data_string_forget(server_id
, MDL
);
543 if (client_id
->len
> 0) {
544 data_string_forget(client_id
, MDL
);
551 * Information request validation, defined in RFC 3315, section 15.12:
553 * Servers MUST discard any received Information-request message that
554 * meets any of the following conditions:
556 * - The message includes a Server Identifier option and the DUID in
557 * the option does not match the server's DUID.
559 * - The message includes an IA option.
562 valid_client_info_req(struct packet
*packet
, struct data_string
*server_id
) {
564 struct option_cache
*oc
;
565 struct data_string client_id
;
566 char client_id_str
[80]; /* print_hex_1() uses maximum 60 characters,
567 plus a few more for extra information */
570 memset(server_id
, 0, sizeof(*server_id
));
573 * Make a string that we can print out to give more
574 * information about the client if we need to.
576 * By RFC 3315, Section 18.1.5 clients SHOULD have a
577 * client-id on an Information-request packet, but it
578 * is not strictly necessary.
580 if (get_client_id(packet
, &client_id
) == ISC_R_SUCCESS
) {
581 snprintf(client_id_str
, sizeof(client_id_str
), " (CLIENTID %s)",
582 print_hex_1(client_id
.len
, client_id
.data
, 60));
583 data_string_forget(&client_id
, MDL
);
585 client_id_str
[0] = '\0';
589 * Required by RFC 3315, section 15.
591 if (packet
->unicast
) {
592 log_debug("Discarding %s from %s; packet sent unicast%s",
593 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
594 piaddr(packet
->client_addr
), client_id_str
);
598 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
600 log_debug("Discarding %s from %s; "
601 "IA_NA option present%s",
602 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
603 piaddr(packet
->client_addr
), client_id_str
);
606 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
608 log_debug("Discarding %s from %s; "
609 "IA_TA option present%s",
610 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
611 piaddr(packet
->client_addr
), client_id_str
);
614 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
616 log_debug("Discarding %s from %s; "
617 "IA_PD option present%s",
618 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
619 piaddr(packet
->client_addr
), client_id_str
);
623 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
625 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
626 packet
->options
, NULL
,
627 &global_scope
, oc
, MDL
)) {
628 log_error("Error processing %s from %s; "
629 "unable to evaluate Server Identifier%s",
630 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
631 piaddr(packet
->client_addr
), client_id_str
);
634 if ((server_duid
.len
!= server_id
->len
) ||
635 (memcmp(server_duid
.data
, server_id
->data
,
636 server_duid
.len
) != 0)) {
637 log_debug("Discarding %s from %s; "
638 "not our server identifier "
639 "(SERVERID %s, server DUID %s)%s",
640 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
641 piaddr(packet
->client_addr
),
642 print_hex_1(server_id
->len
,
643 server_id
->data
, 60),
644 print_hex_2(server_duid
.len
,
645 server_duid
.data
, 60),
656 if (server_id
->len
> 0) {
657 data_string_forget(server_id
, MDL
);
664 * Options that we want to send, in addition to what was requested
667 static const int required_opts
[] = {
674 static const int required_opts_NAA
[] = {
680 static const int required_opts_solicit
[] = {
692 static const int required_opts_agent
[] = {
697 static const int required_opts_IA
[] = {
702 static const int required_opts_IA_PD
[] = {
707 static const int required_opts_STATUS_CODE
[] = {
713 * Extracts from packet contents an IA_* option, storing the IA structure
714 * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
715 * in enc_opt_state for later lookup and evaluation. The 'offset' indicates
716 * where in the IA_* the DHCPv6 options commence.
719 get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
720 struct data_string
*enc_opt_data
,
721 struct packet
*packet
,
722 struct option_cache
*oc
,
726 * Get the raw data for the encapsulated options.
728 memset(enc_opt_data
, 0, sizeof(*enc_opt_data
));
729 if (!evaluate_option_cache(enc_opt_data
, packet
,
730 NULL
, NULL
, packet
->options
, NULL
,
731 &global_scope
, oc
, MDL
)) {
732 log_error("get_encapsulated_IA_state: "
733 "error evaluating raw option.");
736 if (enc_opt_data
->len
< offset
) {
737 log_error("get_encapsulated_IA_state: raw option too small.");
738 data_string_forget(enc_opt_data
, MDL
);
743 * Now create the option state structure, and pass it to the
744 * function that parses options.
746 *enc_opt_state
= NULL
;
747 if (!option_state_allocate(enc_opt_state
, MDL
)) {
748 log_error("get_encapsulated_IA_state: no memory for options.");
749 data_string_forget(enc_opt_data
, MDL
);
752 if (!parse_option_buffer(*enc_opt_state
,
753 enc_opt_data
->data
+ offset
,
754 enc_opt_data
->len
- offset
,
756 log_error("get_encapsulated_IA_state: error parsing options.");
757 option_state_dereference(enc_opt_state
, MDL
);
758 data_string_forget(enc_opt_data
, MDL
);
766 set_status_code(u_int16_t status_code
, const char *status_message
,
767 struct option_state
*opt_state
)
769 struct data_string d
;
772 memset(&d
, 0, sizeof(d
));
773 d
.len
= sizeof(status_code
) + strlen(status_message
);
774 if (!buffer_allocate(&d
.buffer
, d
.len
, MDL
)) {
775 log_fatal("set_status_code: no memory for status code.");
777 d
.data
= d
.buffer
->data
;
778 putUShort(d
.buffer
->data
, status_code
);
779 memcpy(d
.buffer
->data
+ sizeof(status_code
),
780 status_message
, d
.len
- sizeof(status_code
));
781 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
782 d
.buffer
, (unsigned char *)d
.data
, d
.len
,
783 D6O_STATUS_CODE
, 0)) {
784 log_error("set_status_code: error saving status code.");
789 data_string_forget(&d
, MDL
);
794 * We have a set of operations we do to set up the reply packet, which
795 * is the same for many message types.
798 start_reply(struct packet
*packet
,
799 const struct data_string
*client_id
,
800 const struct data_string
*server_id
,
801 struct option_state
**opt_state
,
802 struct dhcpv6_packet
*reply
)
804 struct option_cache
*oc
;
805 const unsigned char *server_id_data
;
809 * Build our option state for reply.
812 if (!option_state_allocate(opt_state
, MDL
)) {
813 log_error("start_reply: no memory for option_state.");
816 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
817 packet
->options
, *opt_state
,
818 &global_scope
, root_group
, NULL
);
821 * A small bit of special handling for Solicit messages.
823 * We could move the logic into a flag, but for now just check
826 if (packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
827 reply
->msg_type
= DHCPV6_ADVERTISE
;
831 * - this message type supports rapid commit (Solicit), and
832 * - the server is configured to supply a rapid commit, and
833 * - the client requests a rapid commit,
834 * Then we add a rapid commit option, and send Reply (instead
837 oc
= lookup_option(&dhcpv6_universe
,
838 *opt_state
, D6O_RAPID_COMMIT
);
840 oc
= lookup_option(&dhcpv6_universe
,
841 packet
->options
, D6O_RAPID_COMMIT
);
843 /* Rapid-commit in action. */
844 reply
->msg_type
= DHCPV6_REPLY
;
846 /* Don't want a rapid-commit in advertise. */
847 delete_option(&dhcpv6_universe
,
848 *opt_state
, D6O_RAPID_COMMIT
);
852 reply
->msg_type
= DHCPV6_REPLY
;
853 /* Delete the rapid-commit from the sent options. */
854 oc
= lookup_option(&dhcpv6_universe
,
855 *opt_state
, D6O_RAPID_COMMIT
);
857 delete_option(&dhcpv6_universe
,
858 *opt_state
, D6O_RAPID_COMMIT
);
863 * Use the client's transaction identifier for the reply.
865 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
866 sizeof(reply
->transaction_id
));
869 * RFC 3315, section 18.2 says we need server identifier and
872 * If the server ID is defined via the configuration file, then
873 * it will already be present in the option state at this point,
874 * so we don't need to set it.
876 * If we have a server ID passed in from the caller,
877 * use that, otherwise use the global DUID.
879 oc
= lookup_option(&dhcpv6_universe
, *opt_state
, D6O_SERVERID
);
881 if (server_id
== NULL
) {
882 server_id_data
= server_duid
.data
;
883 server_id_len
= server_duid
.len
;
885 server_id_data
= server_id
->data
;
886 server_id_len
= server_id
->len
;
888 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
889 NULL
, (unsigned char *)server_id_data
,
890 server_id_len
, D6O_SERVERID
, 0)) {
891 log_error("start_reply: "
892 "error saving server identifier.");
897 if (client_id
->buffer
!= NULL
) {
898 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
900 (unsigned char *)client_id
->data
,
903 log_error("start_reply: error saving "
904 "client identifier.");
910 * If the client accepts reconfiguration, let it know that we
913 * Note: we don't actually do this yet, but DOCSIS requires we
916 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
919 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
920 NULL
, (unsigned char *)"", 0,
921 D6O_RECONF_ACCEPT
, 0)) {
922 log_error("start_reply: "
923 "error saving RECONF_ACCEPT option.");
924 option_state_dereference(opt_state
, MDL
);
933 * Try to get the IPv6 address the client asked for from the
936 * addr is the result (should be a pointer to NULL on entry)
937 * pool is the pool to search in
938 * requested_addr is the address the client wants
941 try_client_v6_address(struct iasubopt
**addr
,
942 struct ipv6_pool
*pool
,
943 const struct data_string
*requested_addr
)
945 struct in6_addr tmp_addr
;
948 if (requested_addr
->len
< sizeof(tmp_addr
)) {
949 return ISC_R_INVALIDARG
;
951 memcpy(&tmp_addr
, requested_addr
->data
, sizeof(tmp_addr
));
952 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
)) {
953 return ISC_R_FAILURE
;
956 if (!ipv6_in_pool(&tmp_addr
, pool
)) {
957 return ISC_R_FAILURE
;
960 if (lease6_exists(pool
, &tmp_addr
)) {
961 return ISC_R_ADDRINUSE
;
964 result
= iasubopt_allocate(addr
, MDL
);
965 if (result
!= ISC_R_SUCCESS
) {
968 (*addr
)->addr
= tmp_addr
;
971 /* Default is soft binding for 2 minutes. */
972 result
= add_lease6(pool
, *addr
, cur_time
+ 120);
973 if (result
!= ISC_R_SUCCESS
) {
974 iasubopt_dereference(addr
, MDL
);
980 * Get an IPv6 address for the client.
982 * addr is the result (should be a pointer to NULL on entry)
983 * packet is the information about the packet from the client
984 * requested_iaaddr is a hint from the client
985 * client_id is the DUID for the client
988 pick_v6_address(struct iasubopt
**addr
, struct shared_network
*shared_network
,
989 const struct data_string
*client_id
)
994 unsigned int attempts
;
995 char tmp_buf
[INET6_ADDRSTRLEN
];
998 * No address pools, we're done.
1000 if (shared_network
->ipv6_pools
== NULL
) {
1001 log_debug("Unable to pick client address: "
1002 "no IPv6 pools on this shared network");
1003 return ISC_R_NORESOURCES
;
1006 p
= shared_network
->ipv6_pools
[i
];
1008 log_debug("Unable to pick client address: "
1009 "no IPv6 address pools "
1010 "on this shared network");
1011 return ISC_R_NORESOURCES
;
1013 if (p
->pool_type
== D6O_IA_NA
) {
1019 * Otherwise try to get a lease from the first subnet possible.
1021 * We start looking at the last pool we allocated from, unless
1022 * it had a collision trying to allocate an address. This will
1023 * tend to move us into less-filled pools.
1025 start_pool
= shared_network
->last_ipv6_pool
;
1029 p
= shared_network
->ipv6_pools
[i
];
1030 if ((p
->pool_type
== D6O_IA_NA
) &&
1031 (create_lease6(p
, addr
, &attempts
, client_id
,
1032 cur_time
+ 120) == ISC_R_SUCCESS
)) {
1034 * Record the pool used (or next one if there
1039 if (shared_network
->ipv6_pools
[i
] == NULL
) {
1043 shared_network
->last_ipv6_pool
= i
;
1045 log_debug("Picking pool address %s",
1046 inet_ntop(AF_INET6
, &((*addr
)->addr
),
1047 tmp_buf
, sizeof(tmp_buf
)));
1048 return ISC_R_SUCCESS
;
1052 if (shared_network
->ipv6_pools
[i
] == NULL
) {
1055 } while (i
!= start_pool
);
1058 * If we failed to pick an IPv6 address from any of the subnets.
1059 * Presumably that means we have no addresses for the client.
1061 log_debug("Unable to pick client address: no addresses available");
1062 return ISC_R_NORESOURCES
;
1066 * Try to get the IPv6 prefix the client asked for from the
1069 * pref is the result (should be a pointer to NULL on entry)
1070 * pool is the prefix pool to search in
1071 * requested_pref is the address the client wants
1074 try_client_v6_prefix(struct iasubopt
**pref
,
1075 struct ipv6_pool
*pool
,
1076 const struct data_string
*requested_pref
)
1079 struct in6_addr tmp_pref
;
1081 isc_result_t result
;
1083 if (requested_pref
->len
< sizeof(tmp_plen
) + sizeof(tmp_pref
)) {
1084 return ISC_R_INVALIDARG
;
1086 tmp_plen
= (int) requested_pref
->data
[0];
1087 if ((tmp_plen
< 3) || (tmp_plen
> 128)) {
1088 return ISC_R_FAILURE
;
1090 memcpy(&tmp_pref
, requested_pref
->data
+ 1, sizeof(tmp_pref
));
1091 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref
)) {
1092 return ISC_R_FAILURE
;
1095 memcpy(&ia
.iabuf
, &tmp_pref
, 16);
1096 if (!is_cidr_mask_valid(&ia
, (int) tmp_plen
)) {
1097 return ISC_R_FAILURE
;
1100 if (((int)tmp_plen
!= pool
->units
) ||
1101 !ipv6_in_pool(&tmp_pref
, pool
)) {
1102 return ISC_R_FAILURE
;
1105 if (prefix6_exists(pool
, &tmp_pref
, tmp_plen
)) {
1106 return ISC_R_ADDRINUSE
;
1109 result
= iasubopt_allocate(pref
, MDL
);
1110 if (result
!= ISC_R_SUCCESS
) {
1113 (*pref
)->addr
= tmp_pref
;
1114 (*pref
)->plen
= tmp_plen
;
1116 /* Default is soft binding for 2 minutes. */
1117 result
= add_lease6(pool
, *pref
, cur_time
+ 120);
1118 if (result
!= ISC_R_SUCCESS
) {
1119 iasubopt_dereference(pref
, MDL
);
1125 * Get an IPv6 prefix for the client.
1127 * pref is the result (should be a pointer to NULL on entry)
1128 * packet is the information about the packet from the client
1129 * requested_iaprefix is a hint from the client
1130 * plen is -1 or the requested prefix length
1131 * client_id is the DUID for the client
1134 pick_v6_prefix(struct iasubopt
**pref
, int plen
,
1135 struct shared_network
*shared_network
,
1136 const struct data_string
*client_id
)
1138 struct ipv6_pool
*p
;
1140 unsigned int attempts
;
1141 char tmp_buf
[INET6_ADDRSTRLEN
];
1144 * No prefix pools, we're done.
1146 if (shared_network
->ipv6_pools
== NULL
) {
1147 log_debug("Unable to pick client prefix: "
1148 "no IPv6 pools on this shared network");
1149 return ISC_R_NORESOURCES
;
1152 p
= shared_network
->ipv6_pools
[i
];
1154 log_debug("Unable to pick client prefix: "
1155 "no IPv6 prefix pools "
1156 "on this shared network");
1157 return ISC_R_NORESOURCES
;
1159 if (p
->pool_type
== D6O_IA_PD
) {
1165 * Otherwise try to get a prefix.
1168 p
= shared_network
->ipv6_pools
[i
];
1172 if (p
->pool_type
!= D6O_IA_PD
) {
1177 * Try only pools with the requested prefix length if any.
1179 if ((plen
>= 0) && (p
->units
!= plen
)) {
1183 if (create_prefix6(p
, pref
, &attempts
, client_id
,
1184 cur_time
+ 120) == ISC_R_SUCCESS
) {
1185 log_debug("Picking pool prefix %s/%u",
1186 inet_ntop(AF_INET6
, &((*pref
)->addr
),
1187 tmp_buf
, sizeof(tmp_buf
)),
1188 (unsigned) (*pref
)->plen
);
1189 return ISC_R_SUCCESS
;
1194 * If we failed to pick an IPv6 prefix
1195 * Presumably that means we have no prefixes for the client.
1197 log_debug("Unable to pick client prefix: no prefixes available");
1198 return ISC_R_NORESOURCES
;
1202 * lease_to_client() is called from several messages to construct a
1203 * reply that contains all that we know about the client's correct lease
1204 * (or projected lease).
1206 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1207 * send what we "may" give them on a request.
1209 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1210 * the client should really use).
1212 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1213 * Rebind out any "wrong" addresses the client sends. This means we send
1214 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1215 * possibly send the address with zeroed lifetimes.
1217 * Information-Request - No binding.
1219 * The basic structure is to traverse the client-supplied data first, and
1220 * validate and echo back any contents that can be. If the client-supplied
1221 * data does not error out (on renew/rebind as above), but we did not send
1222 * any addresses, attempt to allocate one.
1224 /* TODO: look at client hints for lease times */
1226 lease_to_client(struct data_string
*reply_ret
,
1227 struct packet
*packet
,
1228 const struct data_string
*client_id
,
1229 const struct data_string
*server_id
)
1231 static struct reply_state reply
;
1232 struct option_cache
*oc
;
1233 struct data_string packet_oro
;
1234 isc_boolean_t no_resources_avail
;
1236 /* Locate the client. */
1237 if (shared_network_from_packet6(&reply
.shared
,
1238 packet
) != ISC_R_SUCCESS
)
1242 * Initialize the reply.
1244 packet_reference(&reply
.packet
, packet
, MDL
);
1245 data_string_copy(&reply
.client_id
, client_id
, MDL
);
1247 if (!start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
1251 /* Set the write cursor to just past the reply header. */
1252 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1255 * Get the ORO from the packet, if any.
1257 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ORO
);
1258 memset(&packet_oro
, 0, sizeof(packet_oro
));
1260 if (!evaluate_option_cache(&packet_oro
, packet
,
1262 packet
->options
, NULL
,
1263 &global_scope
, oc
, MDL
)) {
1264 log_error("lease_to_client: error evaluating ORO.");
1270 * Find a host record that matches from the packet, if any, and is
1271 * valid for the shared network the client is on.
1273 if (find_hosts_by_option(&reply
.host
, packet
, packet
->options
, MDL
)) {
1274 seek_shared_host(&reply
.host
, reply
.shared
);
1277 if ((reply
.host
== NULL
) &&
1278 find_hosts_by_uid(&reply
.host
, client_id
->data
, client_id
->len
,
1280 seek_shared_host(&reply
.host
, reply
.shared
);
1283 /* Process the client supplied IA's onto the reply buffer. */
1285 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
1286 no_resources_avail
= ISC_FALSE
;
1287 for (; oc
!= NULL
; oc
= oc
->next
) {
1288 isc_result_t status
;
1290 /* Start counting resources (addresses) offered. */
1291 reply
.client_resources
= 0;
1292 reply
.resources_included
= ISC_FALSE
;
1294 status
= reply_process_ia_na(&reply
, oc
);
1297 * We continue to try other IA's whether we can address
1298 * this one or not. Any other result is an immediate fail.
1300 if ((status
!= ISC_R_SUCCESS
) &&
1301 (status
!= ISC_R_NORESOURCES
))
1305 * If any address cannot be given to any IA, then set the
1306 * NoAddrsAvail status code.
1308 if (reply
.client_resources
== 0)
1309 no_resources_avail
= ISC_TRUE
;
1311 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
1312 for (; oc
!= NULL
; oc
= oc
->next
) {
1313 isc_result_t status
;
1315 /* Start counting resources (addresses) offered. */
1316 reply
.client_resources
= 0;
1317 reply
.resources_included
= ISC_FALSE
;
1319 status
= reply_process_ia_ta(&reply
, oc
);
1322 * We continue to try other IA's whether we can address
1323 * this one or not. Any other result is an immediate fail.
1325 if ((status
!= ISC_R_SUCCESS
) &&
1326 (status
!= ISC_R_NORESOURCES
))
1330 * If any address cannot be given to any IA, then set the
1331 * NoAddrsAvail status code.
1333 if (reply
.client_resources
== 0)
1334 no_resources_avail
= ISC_TRUE
;
1337 /* Same for IA_PD's. */
1339 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
1340 for (; oc
!= NULL
; oc
= oc
->next
) {
1341 isc_result_t status
;
1343 /* Start counting resources (prefixes) offered. */
1344 reply
.client_resources
= 0;
1345 reply
.resources_included
= ISC_FALSE
;
1347 status
= reply_process_ia_pd(&reply
, oc
);
1350 * We continue to try other IA_PD's whether we can address
1351 * this one or not. Any other result is an immediate fail.
1353 if ((status
!= ISC_R_SUCCESS
) &&
1354 (status
!= ISC_R_NORESOURCES
))
1358 * If any prefix cannot be given to any IA_PD, then
1359 * set the NoPrefixAvail status code.
1361 if (reply
.client_resources
== 0)
1362 no_resources_avail
= ISC_TRUE
;
1366 * Make no reply if we gave no resources and is not
1367 * for Information-Request.
1369 if ((reply
.ia_count
== 0) && (reply
.pd_count
== 0)) {
1370 if (reply
.packet
->dhcpv6_msg_type
!=
1371 DHCPV6_INFORMATION_REQUEST
)
1375 * Because we only execute statements on a per-IA basis,
1376 * we need to execute statements in any non-IA reply to
1377 * source configuration.
1379 execute_statements_in_scope(NULL
, reply
.packet
, NULL
, NULL
,
1380 reply
.packet
->options
,
1381 reply
.opt_state
, &global_scope
,
1382 reply
.shared
->group
, root_group
);
1386 * RFC3315 section 17.2.2 (Solicit):
1388 * If the server will not assign any addresses to any IAs in a
1389 * subsequent Request from the client, the server MUST send an
1390 * Advertise message to the client that includes only a Status
1391 * Code option with code NoAddrsAvail and a status message for
1392 * the user, a Server Identifier option with the server's DUID,
1393 * and a Client Identifier option with the client's DUID.
1395 * Section 18.2.1 (Request):
1397 * If the server cannot assign any addresses to an IA in the
1398 * message from the client, the server MUST include the IA in
1399 * the Reply message with no addresses in the IA and a Status
1400 * Code option in the IA containing status code NoAddrsAvail.
1402 * Section 18.1.8 (Client Behavior):
1404 * Leave unchanged any information about addresses the client has
1405 * recorded in the IA but that were not included in the IA from
1407 * Sends a Renew/Rebind if the IA is not in the Reply message.
1409 if (no_resources_avail
&& (reply
.ia_count
!= 0) &&
1410 (reply
.packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
))
1412 /* Set the NoAddrsAvail status code. */
1413 if (!set_status_code(STATUS_NoAddrsAvail
,
1414 "No addresses available for this "
1415 "interface.", reply
.opt_state
)) {
1416 log_error("lease_to_client: Unable to set "
1417 "NoAddrsAvail status code.");
1421 /* Rewind the cursor to the start. */
1422 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1425 * Produce an advertise that includes only:
1431 reply
.buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
1432 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+
1436 reply
.opt_state
, reply
.packet
,
1439 } else if (no_resources_avail
&& (reply
.ia_count
== 0) &&
1440 (reply
.packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
))
1442 /* Set the NoPrefixAvail status code. */
1443 if (!set_status_code(STATUS_NoPrefixAvail
,
1444 "No prefixes available for this "
1445 "interface.", reply
.opt_state
)) {
1446 log_error("lease_to_client: Unable to set "
1447 "NoPrefixAvail status code.");
1451 /* Rewind the cursor to the start. */
1452 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1455 * Produce an advertise that includes only:
1461 reply
.buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
1462 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+
1466 reply
.opt_state
, reply
.packet
,
1471 * Having stored the client's IA's, store any options that
1472 * will fit in the remaining space.
1474 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+
1478 reply
.opt_state
, reply
.packet
,
1479 required_opts_solicit
,
1483 /* Return our reply to the caller. */
1484 reply_ret
->len
= reply
.cursor
;
1485 reply_ret
->buffer
= NULL
;
1486 if (!buffer_allocate(&reply_ret
->buffer
, reply
.cursor
, MDL
)) {
1487 log_fatal("No memory to store Reply.");
1489 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
, reply
.cursor
);
1490 reply_ret
->data
= reply_ret
->buffer
->data
;
1494 if (reply
.shared
!= NULL
)
1495 shared_network_dereference(&reply
.shared
, MDL
);
1496 if (reply
.host
!= NULL
)
1497 host_dereference(&reply
.host
, MDL
);
1498 if (reply
.opt_state
!= NULL
)
1499 option_state_dereference(&reply
.opt_state
, MDL
);
1500 if (reply
.packet
!= NULL
)
1501 packet_dereference(&reply
.packet
, MDL
);
1502 if (reply
.client_id
.data
!= NULL
)
1503 data_string_forget(&reply
.client_id
, MDL
);
1504 reply
.renew
= reply
.rebind
= reply
.prefer
= reply
.valid
= 0;
1508 /* Process a client-supplied IA_NA. This may append options to the tail of
1509 * the reply packet being built in the reply_state structure.
1512 reply_process_ia_na(struct reply_state
*reply
, struct option_cache
*ia
) {
1513 isc_result_t status
= ISC_R_SUCCESS
;
1516 struct option_state
*packet_ia
;
1517 struct option_cache
*oc
;
1518 struct data_string ia_data
, data
;
1520 /* Initialize values that will get cleaned up on return. */
1522 memset(&ia_data
, 0, sizeof(ia_data
));
1523 memset(&data
, 0, sizeof(data
));
1525 * Note that find_client_address() may set reply->lease.
1528 /* Make sure there is at least room for the header. */
1529 if ((reply
->cursor
+ IA_NA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
1530 log_error("reply_process_ia_na: Reply too long for IA.");
1531 return ISC_R_NOSPACE
;
1535 /* Fetch the IA_NA contents. */
1536 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
1537 ia
, IA_NA_OFFSET
)) {
1538 log_error("reply_process_ia_na: error evaluating ia");
1539 status
= ISC_R_FAILURE
;
1543 /* Extract IA_NA header contents. */
1544 iaid
= getULong(ia_data
.data
);
1545 reply
->renew
= getULong(ia_data
.data
+ 4);
1546 reply
->rebind
= getULong(ia_data
.data
+ 8);
1548 /* Create an IA_NA structure. */
1549 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
1550 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
1551 log_error("reply_process_ia_na: no memory for ia.");
1552 status
= ISC_R_NOMEMORY
;
1555 reply
->ia
->ia_type
= D6O_IA_NA
;
1557 /* Cache pre-existing IA, if any. */
1558 ia_hash_lookup(&reply
->old_ia
, ia_na_active
,
1559 (unsigned char *)reply
->ia
->iaid_duid
.data
,
1560 reply
->ia
->iaid_duid
.len
, MDL
);
1563 * Create an option cache to carry the IA_NA option contents, and
1564 * execute any user-supplied values into it.
1566 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
1567 status
= ISC_R_NOMEMORY
;
1571 /* Check & cache the fixed host record. */
1572 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_addr
!= NULL
)) {
1573 if (!evaluate_option_cache(&reply
->fixed
, NULL
, NULL
, NULL
,
1574 NULL
, NULL
, &global_scope
,
1575 reply
->host
->fixed_addr
, MDL
)) {
1576 log_error("reply_process_ia_na: unable to evaluate "
1578 status
= ISC_R_FAILURE
;
1582 if (reply
->fixed
.len
< 16) {
1583 log_error("reply_process_ia_na: invalid fixed address.");
1584 status
= ISC_R_INVALIDARG
;
1588 reply
->static_lease
= ISC_TRUE
;
1590 reply
->static_lease
= ISC_FALSE
;
1593 * Save the cursor position at the start of the IA, so we can
1594 * set length and adjust t1/t2 values later. We write a temporary
1595 * header out now just in case we decide to adjust the packet
1596 * within sub-process functions.
1598 ia_cursor
= reply
->cursor
;
1600 /* Initialize the IA_NA header. First the code. */
1601 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_NA
);
1604 /* Then option length. */
1605 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
1608 /* Then IA_NA header contents; IAID. */
1609 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
1612 /* We store the client's t1 for now, and may over-ride it later. */
1613 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
1616 /* We store the client's t2 for now, and may over-ride it later. */
1617 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
1621 * For each address in this IA_NA, decide what to do about it.
1625 * The client leaves unchanged any infomation about addresses
1626 * it has recorded but are not included ("cancel/break" below).
1627 * A not included IA ("cleanup" below) could give a Renew/Rebind.
1629 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
1630 reply
->valid
= reply
->prefer
= 0xffffffff;
1631 reply
->client_valid
= reply
->client_prefer
= 0;
1632 for (; oc
!= NULL
; oc
= oc
->next
) {
1633 status
= reply_process_addr(reply
, oc
);
1636 * Canceled means we did not allocate addresses to the
1637 * client, but we're "done" with this IA - we set a status
1638 * code. So transmit this reply, e.g., move on to the next
1641 if (status
== ISC_R_CANCELED
)
1644 if ((status
!= ISC_R_SUCCESS
) && (status
!= ISC_R_ADDRINUSE
))
1651 * If we fell through the above and never gave the client
1652 * an address, give it one now.
1654 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
1655 status
= find_client_address(reply
);
1657 if (status
== ISC_R_NORESOURCES
) {
1658 switch (reply
->packet
->dhcpv6_msg_type
) {
1659 case DHCPV6_SOLICIT
:
1661 * No address for any IA is handled
1666 case DHCPV6_REQUEST
:
1667 /* Section 18.2.1 (Request):
1669 * If the server cannot assign any addresses to
1670 * an IA in the message from the client, the
1671 * server MUST include the IA in the Reply
1672 * message with no addresses in the IA and a
1673 * Status Code option in the IA containing
1674 * status code NoAddrsAvail.
1676 option_state_dereference(&reply
->reply_ia
, MDL
);
1677 if (!option_state_allocate(&reply
->reply_ia
,
1680 log_error("reply_process_ia_na: No "
1681 "memory for option state "
1683 status
= ISC_R_NOMEMORY
;
1687 if (!set_status_code(STATUS_NoAddrsAvail
,
1688 "No addresses available "
1689 "for this interface.",
1691 log_error("reply_process_ia_na: Unable "
1692 "to set NoAddrsAvail status "
1694 status
= ISC_R_FAILURE
;
1698 status
= ISC_R_SUCCESS
;
1703 * RFC 3315 does not tell us to emit a status
1704 * code in this condition, or anything else.
1706 * If we included non-allocated addresses
1707 * (zeroed lifetimes) in an IA, then the client
1708 * will deconfigure them.
1710 * So we want to include the IA even if we
1711 * can't give it a new address if it includes
1712 * zeroed lifetime addresses.
1714 * We don't want to include the IA if we
1715 * provide zero addresses including zeroed
1718 if (reply
->resources_included
)
1719 status
= ISC_R_SUCCESS
;
1726 if (status
!= ISC_R_SUCCESS
)
1730 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
1731 sizeof(reply
->buf
) - reply
->cursor
,
1732 reply
->reply_ia
, reply
->packet
,
1733 required_opts_IA
, NULL
);
1735 /* Reset the length of this IA to match what was just written. */
1736 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
1737 reply
->cursor
- (ia_cursor
+ 4));
1740 * T1/T2 time selection is kind of weird. We actually use DHCP
1741 * (v4) scoped options as handy existing places where these might
1742 * be configured by an administrator. A value of zero tells the
1743 * client it may choose its own renewal time.
1746 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
1747 DHO_DHCP_RENEWAL_TIME
);
1749 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
1750 reply
->packet
->options
,
1751 reply
->opt_state
, &global_scope
,
1754 log_error("Invalid renewal time.");
1756 reply
->renew
= getULong(data
.data
);
1759 if (data
.data
!= NULL
)
1760 data_string_forget(&data
, MDL
);
1762 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
1766 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
1767 DHO_DHCP_REBINDING_TIME
);
1769 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
1770 reply
->packet
->options
,
1771 reply
->opt_state
, &global_scope
,
1774 log_error("Invalid rebinding time.");
1776 reply
->rebind
= getULong(data
.data
);
1779 if (data
.data
!= NULL
)
1780 data_string_forget(&data
, MDL
);
1782 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
1785 * If this is not a 'soft' binding, consume the new changes into
1786 * the database (if any have been attached to the ia_na).
1788 * Loop through the assigned dynamic addresses, referencing the
1789 * leases onto this IA_NA rather than any old ones, and updating
1790 * pool timers for each (if any).
1792 if ((status
!= ISC_R_CANCELED
) && !reply
->static_lease
&&
1793 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
1794 (reply
->ia
->num_iasubopt
!= 0)) {
1795 struct iasubopt
*tmp
;
1796 struct data_string
*ia_id
;
1799 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
1800 tmp
= reply
->ia
->iasubopt
[i
];
1802 if (tmp
->ia
!= NULL
)
1803 ia_dereference(&tmp
->ia
, MDL
);
1804 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
1806 /* Commit 'hard' bindings. */
1807 tmp
->hard_lifetime_end_time
=
1808 tmp
->soft_lifetime_end_time
;
1809 tmp
->soft_lifetime_end_time
= 0;
1810 renew_lease6(tmp
->ipv6_pool
, tmp
);
1811 schedule_lease_timeout(tmp
->ipv6_pool
);
1814 * Perform ddns updates.
1816 oc
= lookup_option(&server_universe
, reply
->opt_state
,
1819 evaluate_boolean_option_cache(NULL
, reply
->packet
,
1821 reply
->packet
->options
,
1825 ddns_updates(reply
->packet
, NULL
, NULL
,
1826 tmp
, NULL
, reply
->opt_state
);
1830 /* Remove any old ia from the hash. */
1831 if (reply
->old_ia
!= NULL
) {
1832 ia_id
= &reply
->old_ia
->iaid_duid
;
1833 ia_hash_delete(ia_na_active
,
1834 (unsigned char *)ia_id
->data
,
1836 ia_dereference(&reply
->old_ia
, MDL
);
1839 /* Put new ia into the hash. */
1840 reply
->ia
->cltt
= cur_time
;
1841 ia_id
= &reply
->ia
->iaid_duid
;
1842 ia_hash_add(ia_na_active
, (unsigned char *)ia_id
->data
,
1843 ia_id
->len
, reply
->ia
, MDL
);
1845 write_ia(reply
->ia
);
1849 if (packet_ia
!= NULL
)
1850 option_state_dereference(&packet_ia
, MDL
);
1851 if (reply
->reply_ia
!= NULL
)
1852 option_state_dereference(&reply
->reply_ia
, MDL
);
1853 if (ia_data
.data
!= NULL
)
1854 data_string_forget(&ia_data
, MDL
);
1855 if (data
.data
!= NULL
)
1856 data_string_forget(&data
, MDL
);
1857 if (reply
->ia
!= NULL
)
1858 ia_dereference(&reply
->ia
, MDL
);
1859 if (reply
->old_ia
!= NULL
)
1860 ia_dereference(&reply
->old_ia
, MDL
);
1861 if (reply
->lease
!= NULL
)
1862 iasubopt_dereference(&reply
->lease
, MDL
);
1863 if (reply
->fixed
.data
!= NULL
)
1864 data_string_forget(&reply
->fixed
, MDL
);
1867 * ISC_R_CANCELED is a status code used by the addr processing to
1868 * indicate we're replying with a status code. This is still a
1869 * success at higher layers.
1871 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
1875 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
1876 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
1877 * in the event we are replying with a status code and do not wish to process
1878 * more IAADDRs within this IA.
1881 reply_process_addr(struct reply_state
*reply
, struct option_cache
*addr
) {
1882 u_int32_t pref_life
, valid_life
;
1883 struct binding_scope
**scope
;
1884 struct group
*group
;
1885 struct subnet
*subnet
;
1886 struct iaddr tmp_addr
;
1887 struct option_cache
*oc
;
1888 struct data_string iaaddr
, data
;
1889 isc_result_t status
= ISC_R_SUCCESS
;
1891 /* Initializes values that will be cleaned up. */
1892 memset(&iaaddr
, 0, sizeof(iaaddr
));
1893 memset(&data
, 0, sizeof(data
));
1894 /* Note that reply->lease may be set by address_is_owned() */
1897 * There is no point trying to process an incoming address if there
1898 * is no room for an outgoing address.
1900 if ((reply
->cursor
+ 28) > sizeof(reply
->buf
)) {
1901 log_error("reply_process_addr: Out of room for address.");
1902 return ISC_R_NOSPACE
;
1905 /* Extract this IAADDR option. */
1906 if (!evaluate_option_cache(&iaaddr
, reply
->packet
, NULL
, NULL
,
1907 reply
->packet
->options
, NULL
, &global_scope
,
1909 (iaaddr
.len
< IAADDR_OFFSET
)) {
1910 log_error("reply_process_addr: error evaluating IAADDR.");
1911 status
= ISC_R_FAILURE
;
1915 /* The first 16 bytes are the IPv6 address. */
1916 pref_life
= getULong(iaaddr
.data
+ 16);
1917 valid_life
= getULong(iaaddr
.data
+ 20);
1919 if ((reply
->client_valid
== 0) ||
1920 (reply
->client_valid
> valid_life
))
1921 reply
->client_valid
= valid_life
;
1923 if ((reply
->client_prefer
== 0) ||
1924 (reply
->client_prefer
> pref_life
))
1925 reply
->client_prefer
= pref_life
;
1928 * Clients may choose to send :: as an address, with the idea to give
1929 * hints about preferred-lifetime or valid-lifetime.
1932 memset(tmp_addr
.iabuf
, 0, 16);
1933 if (!memcmp(iaaddr
.data
, tmp_addr
.iabuf
, 16)) {
1934 /* Status remains success; we just ignore this one. */
1938 /* tmp_addr len remains 16 */
1939 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
1942 * Verify that this address is on the client's network.
1944 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
1945 subnet
= subnet
->next_sibling
) {
1946 if (addr_eq(subnet_number(tmp_addr
, subnet
->netmask
),
1951 /* Address not found on shared network. */
1952 if (subnet
== NULL
) {
1953 /* Ignore this address on 'soft' bindings. */
1954 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
1955 /* disable rapid commit */
1956 reply
->buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
1957 delete_option(&dhcpv6_universe
,
1960 /* status remains success */
1965 * RFC3315 section 18.2.1:
1967 * If the server finds that the prefix on one or more IP
1968 * addresses in any IA in the message from the client is not
1969 * appropriate for the link to which the client is connected,
1970 * the server MUST return the IA to the client with a Status
1971 * Code option with the value NotOnLink.
1973 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) {
1974 /* Rewind the IA_NA to empty. */
1975 option_state_dereference(&reply
->reply_ia
, MDL
);
1976 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
1977 log_error("reply_process_addr: No memory for "
1978 "option state wipe.");
1979 status
= ISC_R_NOMEMORY
;
1983 /* Append a NotOnLink status code. */
1984 if (!set_status_code(STATUS_NotOnLink
,
1985 "Address not for use on this "
1986 "link.", reply
->reply_ia
)) {
1987 log_error("reply_process_addr: Failure "
1988 "setting status code.");
1989 status
= ISC_R_FAILURE
;
1993 /* Fin (no more IAADDRs). */
1994 status
= ISC_R_CANCELED
;
1999 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2001 * If the server finds that any of the addresses are not
2002 * appropriate for the link to which the client is attached,
2003 * the server returns the address to the client with lifetimes
2006 if ((reply
->packet
->dhcpv6_msg_type
!= DHCPV6_RENEW
) &&
2007 (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
2008 log_error("It is impossible to lease a client that is "
2009 "not sending a solicit, request, renew, or "
2011 status
= ISC_R_FAILURE
;
2015 reply
->send_prefer
= reply
->send_valid
= 0;
2019 /* Verify the address belongs to the client. */
2020 if (!address_is_owned(reply
, &tmp_addr
)) {
2022 * For solicit and request, any addresses included are
2023 * 'requested' addresses. For rebind, we actually have
2024 * no direction on what to do from 3315 section 18.2.4!
2025 * So I think the best bet is to try and give it out, and if
2026 * we can't, zero lifetimes.
2028 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
2029 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
2030 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
2031 status
= reply_process_try_addr(reply
, &tmp_addr
);
2033 /* Either error out or skip this address. */
2034 if ((status
!= ISC_R_SUCCESS
) &&
2035 (status
!= ISC_R_ADDRINUSE
))
2038 if (reply
->lease
== NULL
) {
2039 if (reply
->packet
->dhcpv6_msg_type
==
2041 reply
->send_prefer
= 0;
2042 reply
->send_valid
= 0;
2046 /* status remains success - ignore */
2050 * RFC3315 section 18.2.3:
2052 * If the server cannot find a client entry for the IA the
2053 * server returns the IA containing no addresses with a Status
2054 * Code option set to NoBinding in the Reply message.
2056 * On mismatch we (ab)use this pretending we have not the IA
2057 * as soon as we have not an address.
2059 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
2060 /* Rewind the IA_NA to empty. */
2061 option_state_dereference(&reply
->reply_ia
, MDL
);
2062 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2063 log_error("reply_process_addr: No memory for "
2064 "option state wipe.");
2065 status
= ISC_R_NOMEMORY
;
2069 /* Append a NoBinding status code. */
2070 if (!set_status_code(STATUS_NoBinding
,
2071 "Address not bound to this "
2072 "interface.", reply
->reply_ia
)) {
2073 log_error("reply_process_addr: Unable to "
2074 "attach status code.");
2075 status
= ISC_R_FAILURE
;
2079 /* Fin (no more IAADDRs). */
2080 status
= ISC_R_CANCELED
;
2083 log_error("It is impossible to lease a client that is "
2084 "not sending a solicit, request, renew, or "
2086 status
= ISC_R_FAILURE
;
2091 if (reply
->static_lease
) {
2092 if (reply
->host
== NULL
)
2093 log_fatal("Impossible condition at %s:%d.", MDL
);
2095 scope
= &global_scope
;
2096 group
= reply
->host
->group
;
2098 if (reply
->lease
== NULL
)
2099 log_fatal("Impossible condition at %s:%d.", MDL
);
2101 scope
= &reply
->lease
->scope
;
2102 group
= reply
->lease
->ipv6_pool
->subnet
->group
;
2106 * If client_resources is nonzero, then the reply_process_is_addressed
2107 * function has executed configuration state into the reply option
2108 * cache. We will use that valid cache to derive configuration for
2109 * whether or not to engage in additional addresses, and similar.
2111 if (reply
->client_resources
!= 0) {
2115 * Does this client have "enough" addresses already? Default
2116 * to one. Everybody gets one, and one should be enough for
2119 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2120 SV_LIMIT_ADDRS_PER_IA
);
2122 if (!evaluate_option_cache(&data
, reply
->packet
,
2124 reply
->packet
->options
,
2128 log_error("reply_process_addr: unable to "
2129 "evaluate addrs-per-ia value.");
2130 status
= ISC_R_FAILURE
;
2134 limit
= getULong(data
.data
);
2135 data_string_forget(&data
, MDL
);
2139 * If we wish to limit the client to a certain number of
2140 * addresses, then omit the address from the reply.
2142 if (reply
->client_resources
>= limit
)
2146 status
= reply_process_is_addressed(reply
, scope
, group
);
2147 if (status
!= ISC_R_SUCCESS
)
2151 status
= reply_process_send_addr(reply
, &tmp_addr
);
2154 if (iaaddr
.data
!= NULL
)
2155 data_string_forget(&iaaddr
, MDL
);
2156 if (data
.data
!= NULL
)
2157 data_string_forget(&data
, MDL
);
2158 if (reply
->lease
!= NULL
)
2159 iasubopt_dereference(&reply
->lease
, MDL
);
2165 * Verify the address belongs to the client. If we've got a host
2166 * record with a fixed address, it has to be the assigned address
2167 * (fault out all else). Otherwise it's a dynamic address, so lookup
2168 * that address and make sure it belongs to this DUID:IAID pair.
2170 static isc_boolean_t
2171 address_is_owned(struct reply_state
*reply
, struct iaddr
*addr
) {
2175 * This faults out addresses that don't match fixed addresses.
2177 if (reply
->static_lease
) {
2178 if (reply
->fixed
.data
== NULL
)
2179 log_fatal("Impossible condition at %s:%d.", MDL
);
2181 if (memcmp(addr
->iabuf
, reply
->fixed
.data
, 16) == 0)
2187 if ((reply
->old_ia
== NULL
) || (reply
->old_ia
->num_iasubopt
== 0))
2190 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2191 struct iasubopt
*tmp
;
2193 tmp
= reply
->old_ia
->iasubopt
[i
];
2195 if (memcmp(addr
->iabuf
, &tmp
->addr
, 16) == 0) {
2196 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
2204 /* Process a client-supplied IA_TA. This may append options to the tail of
2205 * the reply packet being built in the reply_state structure.
2208 reply_process_ia_ta(struct reply_state
*reply
, struct option_cache
*ia
) {
2209 isc_result_t status
= ISC_R_SUCCESS
;
2212 struct option_state
*packet_ia
;
2213 struct option_cache
*oc
;
2214 struct data_string ia_data
, data
;
2215 struct data_string iaaddr
;
2216 u_int32_t pref_life
, valid_life
;
2218 /* Initialize values that will get cleaned up on return. */
2220 memset(&ia_data
, 0, sizeof(ia_data
));
2221 memset(&data
, 0, sizeof(data
));
2222 memset(&iaaddr
, 0, sizeof(iaaddr
));
2224 /* Make sure there is at least room for the header. */
2225 if ((reply
->cursor
+ IA_TA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2226 log_error("reply_process_ia_ta: Reply too long for IA.");
2227 return ISC_R_NOSPACE
;
2231 /* Fetch the IA_TA contents. */
2232 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2233 ia
, IA_TA_OFFSET
)) {
2234 log_error("reply_process_ia_ta: error evaluating ia");
2235 status
= ISC_R_FAILURE
;
2239 /* Extract IA_TA header contents. */
2240 iaid
= getULong(ia_data
.data
);
2242 /* Create an IA_TA structure. */
2243 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2244 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2245 log_error("reply_process_ia_ta: no memory for ia.");
2246 status
= ISC_R_NOMEMORY
;
2249 reply
->ia
->ia_type
= D6O_IA_TA
;
2251 /* Cache pre-existing IA, if any. */
2252 ia_hash_lookup(&reply
->old_ia
, ia_ta_active
,
2253 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2254 reply
->ia
->iaid_duid
.len
, MDL
);
2257 * Create an option cache to carry the IA_TA option contents, and
2258 * execute any user-supplied values into it.
2260 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2261 status
= ISC_R_NOMEMORY
;
2266 * Temporary leases are dynamic by definition.
2268 reply
->static_lease
= ISC_FALSE
;
2271 * Save the cursor position at the start of the IA, so we can
2272 * set length later. We write a temporary
2273 * header out now just in case we decide to adjust the packet
2274 * within sub-process functions.
2276 ia_cursor
= reply
->cursor
;
2278 /* Initialize the IA_TA header. First the code. */
2279 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_TA
);
2282 /* Then option length. */
2283 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x04u
);
2286 /* Then IA_TA header contents; IAID. */
2287 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2291 * Deal with an IAADDR for lifetimes.
2293 reply
->valid
= reply
->prefer
= 0xffffffff;
2294 reply
->client_valid
= reply
->client_prefer
= 0;
2295 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2297 if (!evaluate_option_cache(&iaaddr
, reply
->packet
,
2299 reply
->packet
->options
, NULL
,
2300 &global_scope
, oc
, MDL
) ||
2301 (iaaddr
.len
< IAADDR_OFFSET
)) {
2302 log_error("reply_process_ia_ta: error "
2303 "evaluating IAADDR.");
2304 status
= ISC_R_FAILURE
;
2307 /* The first 16 bytes are the IPv6 address. */
2308 pref_life
= getULong(iaaddr
.data
+ 16);
2309 valid_life
= getULong(iaaddr
.data
+ 20);
2311 if ((reply
->client_valid
== 0) ||
2312 (reply
->client_valid
> valid_life
))
2313 reply
->client_valid
= valid_life
;
2315 if ((reply
->client_prefer
== 0) ||
2316 (reply
->client_prefer
> pref_life
))
2317 reply
->client_prefer
= pref_life
;
2322 * Cancel if not Solicit or Request.
2324 if ((reply
->packet
->dhcpv6_msg_type
!= DHCPV6_SOLICIT
) &&
2325 (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REQUEST
)) {
2326 if (!set_status_code(STATUS_UnspecFail
,
2327 "Unsupported message for temporary.",
2329 log_error("reply_process_ia_ta: Unable to set "
2330 "UnspecFail status code.");
2331 status
= ISC_R_FAILURE
;
2334 status
= ISC_R_CANCELED
;
2339 * Give the client temporary addresses.
2341 status
= find_client_temporaries(reply
);
2342 if (status
== ISC_R_NORESOURCES
) {
2343 switch (reply
->packet
->dhcpv6_msg_type
) {
2344 case DHCPV6_SOLICIT
:
2346 * No address for any IA is handled
2351 case DHCPV6_REQUEST
:
2352 /* Section 18.2.1 (Request):
2354 * If the server cannot assign any addresses to
2355 * an IA in the message from the client, the
2356 * server MUST include the IA in the Reply
2357 * message with no addresses in the IA and a
2358 * Status Code option in the IA containing
2359 * status code NoAddrsAvail.
2361 option_state_dereference(&reply
->reply_ia
, MDL
);
2362 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2363 log_error("reply_process_ia_ta: No "
2364 "memory for option state wipe.");
2365 status
= ISC_R_NOMEMORY
;
2369 if (!set_status_code(STATUS_NoAddrsAvail
,
2370 "No addresses available "
2371 "for this interface.",
2373 log_error("reply_process_ia_ta: Unable "
2374 "to set NoAddrsAvail status code.");
2375 status
= ISC_R_FAILURE
;
2379 status
= ISC_R_SUCCESS
;
2383 /* Should not happen! */
2386 } else if (status
!= ISC_R_SUCCESS
)
2390 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2391 sizeof(reply
->buf
) - reply
->cursor
,
2392 reply
->reply_ia
, reply
->packet
,
2393 required_opts_IA
, NULL
);
2395 /* Reset the length of this IA to match what was just written. */
2396 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2397 reply
->cursor
- (ia_cursor
+ 4));
2400 * Consume the new changes into the database (if any have been
2401 * attached to the ia_ta).
2403 * Loop through the assigned dynamic addresses, referencing the
2404 * leases onto this IA_TA rather than any old ones, and updating
2405 * pool timers for each (if any).
2407 if ((status
!= ISC_R_CANCELED
) &&
2408 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
2409 (reply
->ia
->num_iasubopt
!= 0)) {
2410 struct iasubopt
*tmp
;
2411 struct data_string
*ia_id
;
2414 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2415 tmp
= reply
->ia
->iasubopt
[i
];
2417 if (tmp
->ia
!= NULL
)
2418 ia_dereference(&tmp
->ia
, MDL
);
2419 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2421 /* Commit 'hard' bindings. */
2422 tmp
->hard_lifetime_end_time
=
2423 tmp
->soft_lifetime_end_time
;
2424 tmp
->soft_lifetime_end_time
= 0;
2425 renew_lease6(tmp
->ipv6_pool
, tmp
);
2426 schedule_lease_timeout(tmp
->ipv6_pool
);
2429 * Perform ddns updates.
2431 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2434 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2436 reply
->packet
->options
,
2440 ddns_updates(reply
->packet
, NULL
, NULL
,
2441 tmp
, NULL
, reply
->opt_state
);
2445 /* Remove any old ia from the hash. */
2446 if (reply
->old_ia
!= NULL
) {
2447 ia_id
= &reply
->old_ia
->iaid_duid
;
2448 ia_hash_delete(ia_ta_active
,
2449 (unsigned char *)ia_id
->data
,
2451 ia_dereference(&reply
->old_ia
, MDL
);
2454 /* Put new ia into the hash. */
2455 reply
->ia
->cltt
= cur_time
;
2456 ia_id
= &reply
->ia
->iaid_duid
;
2457 ia_hash_add(ia_ta_active
, (unsigned char *)ia_id
->data
,
2458 ia_id
->len
, reply
->ia
, MDL
);
2460 write_ia(reply
->ia
);
2464 if (packet_ia
!= NULL
)
2465 option_state_dereference(&packet_ia
, MDL
);
2466 if (iaaddr
.data
!= NULL
)
2467 data_string_forget(&iaaddr
, MDL
);
2468 if (reply
->reply_ia
!= NULL
)
2469 option_state_dereference(&reply
->reply_ia
, MDL
);
2470 if (ia_data
.data
!= NULL
)
2471 data_string_forget(&ia_data
, MDL
);
2472 if (data
.data
!= NULL
)
2473 data_string_forget(&data
, MDL
);
2474 if (reply
->ia
!= NULL
)
2475 ia_dereference(&reply
->ia
, MDL
);
2476 if (reply
->old_ia
!= NULL
)
2477 ia_dereference(&reply
->old_ia
, MDL
);
2478 if (reply
->lease
!= NULL
)
2479 iasubopt_dereference(&reply
->lease
, MDL
);
2482 * ISC_R_CANCELED is a status code used by the addr processing to
2483 * indicate we're replying with a status code. This is still a
2484 * success at higher layers.
2486 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2490 * Get a temporary address per prefix.
2493 find_client_temporaries(struct reply_state
*reply
) {
2494 struct shared_network
*shared
;
2496 struct ipv6_pool
*p
;
2497 isc_result_t status
;
2498 unsigned int attempts
;
2499 struct iaddr send_addr
;
2502 * No pools, we're done.
2504 shared
= reply
->shared
;
2505 if (shared
->ipv6_pools
== NULL
) {
2506 log_debug("Unable to get client addresses: "
2507 "no IPv6 pools on this shared network");
2508 return ISC_R_NORESOURCES
;
2511 status
= ISC_R_NORESOURCES
;
2513 p
= shared
->ipv6_pools
[i
];
2517 if (p
->pool_type
!= D6O_IA_TA
) {
2522 * Get an address in this temporary pool.
2524 status
= create_lease6(p
, &reply
->lease
, &attempts
,
2525 &reply
->client_id
, cur_time
+ 120);
2526 if (status
!= ISC_R_SUCCESS
) {
2527 log_debug("Unable to get a temporary address.");
2531 status
= reply_process_is_addressed(reply
,
2532 &reply
->lease
->scope
,
2533 reply
->lease
->ipv6_pool
->subnet
->group
);
2534 if (status
!= ISC_R_SUCCESS
) {
2538 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
2539 status
= reply_process_send_addr(reply
, &send_addr
);
2540 if (status
!= ISC_R_SUCCESS
) {
2543 if (reply
->lease
!= NULL
) {
2544 iasubopt_dereference(&reply
->lease
, MDL
);
2549 if (reply
->lease
!= NULL
) {
2550 iasubopt_dereference(&reply
->lease
, MDL
);
2556 * This function only returns failure on 'hard' failures. If it succeeds,
2557 * it will leave a lease structure behind.
2560 reply_process_try_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
2561 isc_result_t status
= ISC_R_NORESOURCES
;
2562 struct ipv6_pool
*pool
;
2564 struct data_string data_addr
;
2566 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
2567 (reply
->shared
->ipv6_pools
== NULL
) || (addr
== NULL
) ||
2568 (reply
->lease
!= NULL
))
2569 return ISC_R_INVALIDARG
;
2571 memset(&data_addr
, 0, sizeof(data_addr
));
2572 data_addr
.len
= addr
->len
;
2573 data_addr
.data
= addr
->iabuf
;
2575 for (i
= 0 ; (pool
= reply
->shared
->ipv6_pools
[i
]) != NULL
; i
++) {
2576 if (pool
->pool_type
!= D6O_IA_NA
)
2578 status
= try_client_v6_address(&reply
->lease
, pool
,
2580 if (status
== ISC_R_SUCCESS
)
2584 /* Note that this is just pedantry. There is no allocation to free. */
2585 data_string_forget(&data_addr
, MDL
);
2586 /* Return just the most recent status... */
2590 /* Look around for an address to give the client. First, look through the
2591 * old IA for addresses we can extend. Second, try to allocate a new address.
2592 * Finally, actually add that address into the current reply IA.
2595 find_client_address(struct reply_state
*reply
) {
2596 struct iaddr send_addr
;
2597 isc_result_t status
= ISC_R_NORESOURCES
;
2598 struct iasubopt
*lease
, *best_lease
= NULL
;
2599 struct binding_scope
**scope
;
2600 struct group
*group
;
2603 if (reply
->static_lease
) {
2604 if (reply
->host
== NULL
)
2605 return ISC_R_INVALIDARG
;
2608 memcpy(send_addr
.iabuf
, reply
->fixed
.data
, 16);
2610 status
= ISC_R_SUCCESS
;
2611 scope
= &global_scope
;
2612 group
= reply
->host
->group
;
2616 if (reply
->old_ia
!= NULL
) {
2617 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2618 lease
= reply
->old_ia
->iasubopt
[i
];
2620 best_lease
= lease_compare(lease
, best_lease
);
2624 /* Try to pick a new address if we didn't find one, or if we found an
2627 if ((best_lease
== NULL
) || (best_lease
->state
== FTS_ABANDONED
)) {
2628 status
= pick_v6_address(&reply
->lease
, reply
->shared
,
2630 } else if (best_lease
!= NULL
) {
2631 iasubopt_reference(&reply
->lease
, best_lease
, MDL
);
2632 status
= ISC_R_SUCCESS
;
2635 /* Pick the abandoned lease as a last resort. */
2636 if ((status
== ISC_R_NORESOURCES
) && (best_lease
!= NULL
)) {
2637 /* I don't see how this is supposed to be done right now. */
2638 log_error("Reclaiming abandoned addresses is not yet "
2639 "supported. Treating this as an out of space "
2641 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
2644 /* Give up now if we didn't find a lease. */
2645 if (status
!= ISC_R_SUCCESS
)
2648 if (reply
->lease
== NULL
)
2649 log_fatal("Impossible condition at %s:%d.", MDL
);
2651 /* Draw binding scopes from the lease's binding scope, and config
2652 * from the lease's containing subnet and higher. Note that it may
2653 * be desirable to place the group attachment directly in the pool.
2655 scope
= &reply
->lease
->scope
;
2656 group
= reply
->lease
->ipv6_pool
->subnet
->group
;
2659 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
2662 status
= reply_process_is_addressed(reply
, scope
, group
);
2663 if (status
!= ISC_R_SUCCESS
)
2666 status
= reply_process_send_addr(reply
, &send_addr
);
2670 /* Once an address is found for a client, perform several common functions;
2671 * Calculate and store valid and preferred lease times, draw client options
2672 * into the option state.
2675 reply_process_is_addressed(struct reply_state
*reply
,
2676 struct binding_scope
**scope
, struct group
*group
)
2678 isc_result_t status
= ISC_R_SUCCESS
;
2679 struct data_string data
;
2680 struct option_cache
*oc
;
2682 /* Initialize values we will cleanup. */
2683 memset(&data
, 0, sizeof(data
));
2685 /* Execute relevant options into root scope. */
2686 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
2687 reply
->packet
->options
, reply
->opt_state
,
2688 scope
, group
, root_group
);
2690 /* Determine valid lifetime. */
2691 if (reply
->client_valid
== 0)
2692 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
2694 reply
->send_valid
= reply
->client_valid
;
2696 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2697 SV_DEFAULT_LEASE_TIME
);
2699 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
2700 reply
->packet
->options
,
2704 log_error("reply_process_is_addressed: unable to "
2705 "evaluate default lease time");
2706 status
= ISC_R_FAILURE
;
2710 reply
->send_valid
= getULong(data
.data
);
2711 data_string_forget(&data
, MDL
);
2714 if (reply
->client_prefer
== 0)
2715 reply
->send_prefer
= reply
->send_valid
;
2717 reply
->send_prefer
= reply
->client_prefer
;
2719 if (reply
->send_prefer
>= reply
->send_valid
)
2720 reply
->send_prefer
= (reply
->send_valid
/ 2) +
2721 (reply
->send_valid
/ 8);
2723 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2724 SV_PREFER_LIFETIME
);
2726 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
2727 reply
->packet
->options
,
2731 log_error("reply_process_is_addressed: unable to "
2732 "evaluate preferred lease time");
2733 status
= ISC_R_FAILURE
;
2737 reply
->send_prefer
= getULong(data
.data
);
2738 data_string_forget(&data
, MDL
);
2741 /* Note lowest values for later calculation of renew/rebind times. */
2742 if (reply
->prefer
> reply
->send_prefer
)
2743 reply
->prefer
= reply
->send_prefer
;
2745 if (reply
->valid
> reply
->send_valid
)
2746 reply
->valid
= reply
->send_valid
;
2750 * XXX: Old 4.0.0 alpha code would change the host {} record
2751 * XXX: uid upon lease assignment. This was intended to cover the
2752 * XXX: case where a client first identifies itself using vendor
2753 * XXX: options in a solicit, or request, but later neglects to include
2754 * XXX: these options in a Renew or Rebind. It is not clear that this
2755 * XXX: is required, and has some startling ramifications (such as
2756 * XXX: how to recover this dynamic host {} state across restarts).
2758 if (reply
->host
!= NULL
)
2759 change_host_uid(host
, reply
->client_id
->data
,
2760 reply
->client_id
->len
);
2763 /* Perform dynamic lease related update work. */
2764 if (reply
->lease
!= NULL
) {
2765 /* Cached lifetimes */
2766 reply
->lease
->prefer
= reply
->send_prefer
;
2767 reply
->lease
->valid
= reply
->send_valid
;
2769 /* Advance (or rewind) the valid lifetime. */
2770 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
2771 reply
->lease
->soft_lifetime_end_time
=
2772 cur_time
+ reply
->send_valid
;
2773 /* Wait before renew! */
2776 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
2777 if (status
!= ISC_R_SUCCESS
) {
2778 log_fatal("reply_process_is_addressed: Unable to "
2779 "attach lease to new IA: %s",
2780 isc_result_totext(status
));
2784 * If this is a new lease, make sure it is attached somewhere.
2786 if (reply
->lease
->ia
== NULL
) {
2787 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
2791 /* Bring a copy of the relevant options into the IA scope. */
2792 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
2793 reply
->packet
->options
, reply
->reply_ia
,
2794 scope
, group
, root_group
);
2797 if (data
.data
!= NULL
)
2798 data_string_forget(&data
, MDL
);
2800 if (status
== ISC_R_SUCCESS
)
2801 reply
->client_resources
++;
2806 /* Simply send an IAADDR within the IA scope as described. */
2808 reply_process_send_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
2809 isc_result_t status
= ISC_R_SUCCESS
;
2810 struct data_string data
;
2812 memset(&data
, 0, sizeof(data
));
2814 /* Now append the lease. */
2815 data
.len
= IAADDR_OFFSET
;
2816 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
2817 log_error("reply_process_send_addr: out of memory"
2818 "allocating new IAADDR buffer.");
2819 status
= ISC_R_NOMEMORY
;
2822 data
.data
= data
.buffer
->data
;
2824 memcpy(data
.buffer
->data
, addr
->iabuf
, 16);
2825 putULong(data
.buffer
->data
+ 16, reply
->send_prefer
);
2826 putULong(data
.buffer
->data
+ 20, reply
->send_valid
);
2828 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
2829 data
.buffer
, data
.buffer
->data
,
2830 data
.len
, D6O_IAADDR
, 0)) {
2831 log_error("reply_process_send_addr: unable "
2832 "to save IAADDR option");
2833 status
= ISC_R_FAILURE
;
2837 reply
->resources_included
= ISC_TRUE
;
2840 if (data
.data
!= NULL
)
2841 data_string_forget(&data
, MDL
);
2846 /* Choose the better of two leases. */
2847 static struct iasubopt
*
2848 lease_compare(struct iasubopt
*alpha
, struct iasubopt
*beta
) {
2854 switch(alpha
->state
) {
2856 switch(beta
->state
) {
2858 /* Choose the lease with the longest lifetime (most
2859 * likely the most recently allocated).
2861 if (alpha
->hard_lifetime_end_time
<
2862 beta
->hard_lifetime_end_time
)
2872 log_fatal("Impossible condition at %s:%d.", MDL
);
2877 switch (beta
->state
) {
2882 /* Choose the most recently expired lease. */
2883 if (alpha
->hard_lifetime_end_time
<
2884 beta
->hard_lifetime_end_time
)
2886 else if ((alpha
->hard_lifetime_end_time
==
2887 beta
->hard_lifetime_end_time
) &&
2888 (alpha
->soft_lifetime_end_time
<
2889 beta
->soft_lifetime_end_time
))
2898 log_fatal("Impossible condition at %s:%d.", MDL
);
2903 switch (beta
->state
) {
2909 /* Choose the lease that was abandoned longest ago. */
2910 if (alpha
->hard_lifetime_end_time
<
2911 beta
->hard_lifetime_end_time
)
2915 log_fatal("Impossible condition at %s:%d.", MDL
);
2920 log_fatal("Impossible condition at %s:%d.", MDL
);
2923 log_fatal("Triple impossible condition at %s:%d.", MDL
);
2927 /* Process a client-supplied IA_PD. This may append options to the tail of
2928 * the reply packet being built in the reply_state structure.
2931 reply_process_ia_pd(struct reply_state
*reply
, struct option_cache
*ia
) {
2932 isc_result_t status
= ISC_R_SUCCESS
;
2935 struct option_state
*packet_ia
;
2936 struct option_cache
*oc
;
2937 struct data_string ia_data
, data
;
2939 /* Initialize values that will get cleaned up on return. */
2941 memset(&ia_data
, 0, sizeof(ia_data
));
2942 memset(&data
, 0, sizeof(data
));
2944 * Note that find_client_prefix() may set reply->lease.
2947 /* Make sure there is at least room for the header. */
2948 if ((reply
->cursor
+ IA_PD_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2949 log_error("reply_process_ia_pd: Reply too long for IA.");
2950 return ISC_R_NOSPACE
;
2954 /* Fetch the IA_PD contents. */
2955 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2956 ia
, IA_PD_OFFSET
)) {
2957 log_error("reply_process_ia_pd: error evaluating ia");
2958 status
= ISC_R_FAILURE
;
2962 /* Extract IA_PD header contents. */
2963 iaid
= getULong(ia_data
.data
);
2964 reply
->renew
= getULong(ia_data
.data
+ 4);
2965 reply
->rebind
= getULong(ia_data
.data
+ 8);
2967 /* Create an IA_PD structure. */
2968 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2969 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2970 log_error("reply_process_ia_pd: no memory for ia.");
2971 status
= ISC_R_NOMEMORY
;
2974 reply
->ia
->ia_type
= D6O_IA_PD
;
2976 /* Cache pre-existing IA_PD, if any. */
2977 ia_hash_lookup(&reply
->old_ia
, ia_pd_active
,
2978 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2979 reply
->ia
->iaid_duid
.len
, MDL
);
2982 * Create an option cache to carry the IA_PD option contents, and
2983 * execute any user-supplied values into it.
2985 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2986 status
= ISC_R_NOMEMORY
;
2990 /* Check & count the fixed prefix host records. */
2991 reply
->static_prefixes
= 0;
2992 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_prefix
!= NULL
)) {
2993 struct iaddrcidrnetlist
*fp
;
2995 for (fp
= reply
->host
->fixed_prefix
; fp
!= NULL
;
2997 reply
->static_prefixes
+= 1;
3002 * Save the cursor position at the start of the IA_PD, so we can
3003 * set length and adjust t1/t2 values later. We write a temporary
3004 * header out now just in case we decide to adjust the packet
3005 * within sub-process functions.
3007 ia_cursor
= reply
->cursor
;
3009 /* Initialize the IA_PD header. First the code. */
3010 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_PD
);
3013 /* Then option length. */
3014 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
3017 /* Then IA_PD header contents; IAID. */
3018 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
3021 /* We store the client's t1 for now, and may over-ride it later. */
3022 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
3025 /* We store the client's t2 for now, and may over-ride it later. */
3026 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
3030 * For each prefix in this IA_PD, decide what to do about it.
3032 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAPREFIX
);
3033 reply
->valid
= reply
->prefer
= 0xffffffff;
3034 reply
->client_valid
= reply
->client_prefer
= 0;
3035 reply
->preflen
= -1;
3036 for (; oc
!= NULL
; oc
= oc
->next
) {
3037 status
= reply_process_prefix(reply
, oc
);
3040 * Canceled means we did not allocate prefixes to the
3041 * client, but we're "done" with this IA - we set a status
3042 * code. So transmit this reply, e.g., move on to the next
3045 if (status
== ISC_R_CANCELED
)
3048 if ((status
!= ISC_R_SUCCESS
) && (status
!= ISC_R_ADDRINUSE
))
3055 * If we fell through the above and never gave the client
3056 * a prefix, give it one now.
3058 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
3059 status
= find_client_prefix(reply
);
3061 if (status
== ISC_R_NORESOURCES
) {
3062 switch (reply
->packet
->dhcpv6_msg_type
) {
3063 case DHCPV6_SOLICIT
:
3065 * No prefix for any IA is handled
3070 case DHCPV6_REQUEST
:
3071 /* Same than for addresses. */
3072 option_state_dereference(&reply
->reply_ia
, MDL
);
3073 if (!option_state_allocate(&reply
->reply_ia
,
3076 log_error("reply_process_ia_pd: No "
3077 "memory for option state "
3079 status
= ISC_R_NOMEMORY
;
3083 if (!set_status_code(STATUS_NoPrefixAvail
,
3084 "No prefixes available "
3085 "for this interface.",
3087 log_error("reply_process_ia_pd: "
3089 "NoPrefixAvail status "
3091 status
= ISC_R_FAILURE
;
3095 status
= ISC_R_SUCCESS
;
3099 if (reply
->resources_included
)
3100 status
= ISC_R_SUCCESS
;
3107 if (status
!= ISC_R_SUCCESS
)
3111 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
3112 sizeof(reply
->buf
) - reply
->cursor
,
3113 reply
->reply_ia
, reply
->packet
,
3114 required_opts_IA_PD
, NULL
);
3116 /* Reset the length of this IA_PD to match what was just written. */
3117 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
3118 reply
->cursor
- (ia_cursor
+ 4));
3121 * T1/T2 time selection is kind of weird. We actually use DHCP
3122 * (v4) scoped options as handy existing places where these might
3123 * be configured by an administrator. A value of zero tells the
3124 * client it may choose its own renewal time.
3127 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
3128 DHO_DHCP_RENEWAL_TIME
);
3130 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3131 reply
->packet
->options
,
3132 reply
->opt_state
, &global_scope
,
3135 log_error("Invalid renewal time.");
3137 reply
->renew
= getULong(data
.data
);
3140 if (data
.data
!= NULL
)
3141 data_string_forget(&data
, MDL
);
3143 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
3147 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
3148 DHO_DHCP_REBINDING_TIME
);
3150 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3151 reply
->packet
->options
,
3152 reply
->opt_state
, &global_scope
,
3155 log_error("Invalid rebinding time.");
3157 reply
->rebind
= getULong(data
.data
);
3160 if (data
.data
!= NULL
)
3161 data_string_forget(&data
, MDL
);
3163 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
3166 * If this is not a 'soft' binding, consume the new changes into
3167 * the database (if any have been attached to the ia_pd).
3169 * Loop through the assigned dynamic prefixes, referencing the
3170 * prefixes onto this IA_PD rather than any old ones, and updating
3171 * prefix pool timers for each (if any).
3173 if ((status
!= ISC_R_CANCELED
) && (reply
->static_prefixes
== 0) &&
3174 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
3175 (reply
->ia
->num_iasubopt
!= 0)) {
3176 struct iasubopt
*tmp
;
3177 struct data_string
*ia_id
;
3180 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3181 tmp
= reply
->ia
->iasubopt
[i
];
3183 if (tmp
->ia
!= NULL
)
3184 ia_dereference(&tmp
->ia
, MDL
);
3185 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
3187 /* Commit 'hard' bindings. */
3188 tmp
->hard_lifetime_end_time
=
3189 tmp
->soft_lifetime_end_time
;
3190 tmp
->soft_lifetime_end_time
= 0;
3191 renew_lease6(tmp
->ipv6_pool
, tmp
);
3192 schedule_lease_timeout(tmp
->ipv6_pool
);
3195 /* Remove any old ia from the hash. */
3196 if (reply
->old_ia
!= NULL
) {
3197 ia_id
= &reply
->old_ia
->iaid_duid
;
3198 ia_hash_delete(ia_pd_active
,
3199 (unsigned char *)ia_id
->data
,
3201 ia_dereference(&reply
->old_ia
, MDL
);
3204 /* Put new ia into the hash. */
3205 reply
->ia
->cltt
= cur_time
;
3206 ia_id
= &reply
->ia
->iaid_duid
;
3207 ia_hash_add(ia_pd_active
, (unsigned char *)ia_id
->data
,
3208 ia_id
->len
, reply
->ia
, MDL
);
3210 write_ia(reply
->ia
);
3214 if (packet_ia
!= NULL
)
3215 option_state_dereference(&packet_ia
, MDL
);
3216 if (reply
->reply_ia
!= NULL
)
3217 option_state_dereference(&reply
->reply_ia
, MDL
);
3218 if (ia_data
.data
!= NULL
)
3219 data_string_forget(&ia_data
, MDL
);
3220 if (data
.data
!= NULL
)
3221 data_string_forget(&data
, MDL
);
3222 if (reply
->ia
!= NULL
)
3223 ia_dereference(&reply
->ia
, MDL
);
3224 if (reply
->old_ia
!= NULL
)
3225 ia_dereference(&reply
->old_ia
, MDL
);
3226 if (reply
->lease
!= NULL
)
3227 iasubopt_dereference(&reply
->lease
, MDL
);
3230 * ISC_R_CANCELED is a status code used by the prefix processing to
3231 * indicate we're replying with a status code. This is still a
3232 * success at higher layers.
3234 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
3238 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
3239 * contents into the reply's current ia_pd-scoped option cache. Returns
3240 * ISC_R_CANCELED in the event we are replying with a status code and do
3241 * not wish to process more IAPREFIXes within this IA_PD.
3244 reply_process_prefix(struct reply_state
*reply
, struct option_cache
*pref
) {
3245 u_int32_t pref_life
, valid_life
;
3246 struct binding_scope
**scope
;
3247 struct group
*group
;
3248 struct iaddrcidrnet tmp_pref
;
3249 struct option_cache
*oc
;
3250 struct data_string iapref
, data
;
3251 isc_result_t status
= ISC_R_SUCCESS
;
3253 /* Initializes values that will be cleaned up. */
3254 memset(&iapref
, 0, sizeof(iapref
));
3255 memset(&data
, 0, sizeof(data
));
3256 /* Note that reply->lease may be set by prefix_is_owned() */
3259 * There is no point trying to process an incoming prefix if there
3260 * is no room for an outgoing prefix.
3262 if ((reply
->cursor
+ 29) > sizeof(reply
->buf
)) {
3263 log_error("reply_process_prefix: Out of room for prefix.");
3264 return ISC_R_NOSPACE
;
3267 /* Extract this IAPREFIX option. */
3268 if (!evaluate_option_cache(&iapref
, reply
->packet
, NULL
, NULL
,
3269 reply
->packet
->options
, NULL
, &global_scope
,
3271 (iapref
.len
< IAPREFIX_OFFSET
)) {
3272 log_error("reply_process_prefix: error evaluating IAPREFIX.");
3273 status
= ISC_R_FAILURE
;
3278 * Layout: preferred and valid lifetimes followed by the prefix
3279 * length and the IPv6 address.
3281 pref_life
= getULong(iapref
.data
);
3282 valid_life
= getULong(iapref
.data
+ 4);
3284 if ((reply
->client_valid
== 0) ||
3285 (reply
->client_valid
> valid_life
))
3286 reply
->client_valid
= valid_life
;
3288 if ((reply
->client_prefer
== 0) ||
3289 (reply
->client_prefer
> pref_life
))
3290 reply
->client_prefer
= pref_life
;
3293 * Clients may choose to send ::/0 as a prefix, with the idea to give
3294 * hints about preferred-lifetime or valid-lifetime.
3296 tmp_pref
.lo_addr
.len
= 16;
3297 memset(tmp_pref
.lo_addr
.iabuf
, 0, 16);
3298 if ((iapref
.data
[8] == 0) &&
3299 (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0)) {
3300 /* Status remains success; we just ignore this one. */
3305 * Clients may choose to send ::/X as a prefix to specify a
3306 * preferred/requested prefix length. Note X is never zero here.
3308 tmp_pref
.bits
= (int) iapref
.data
[8];
3309 if (reply
->preflen
< 0) {
3310 /* Cache the first preferred prefix length. */
3311 reply
->preflen
= tmp_pref
.bits
;
3313 if (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0) {
3317 memcpy(tmp_pref
.lo_addr
.iabuf
, iapref
.data
+ 9, 16);
3319 /* Verify the prefix belongs to the client. */
3320 if (!prefix_is_owned(reply
, &tmp_pref
)) {
3321 /* Same than for addresses. */
3322 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
3323 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
3324 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
3325 status
= reply_process_try_prefix(reply
, &tmp_pref
);
3327 /* Either error out or skip this prefix. */
3328 if ((status
!= ISC_R_SUCCESS
) &&
3329 (status
!= ISC_R_ADDRINUSE
))
3332 if (reply
->lease
== NULL
) {
3333 if (reply
->packet
->dhcpv6_msg_type
==
3335 reply
->send_prefer
= 0;
3336 reply
->send_valid
= 0;
3340 /* status remains success - ignore */
3344 * RFC3633 section 18.2.3:
3346 * If the delegating router cannot find a binding
3347 * for the requesting router's IA_PD the delegating
3348 * router returns the IA_PD containing no prefixes
3349 * with a Status Code option set to NoBinding in the
3352 * On mismatch we (ab)use this pretending we have not the IA
3353 * as soon as we have not a prefix.
3355 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
3356 /* Rewind the IA_PD to empty. */
3357 option_state_dereference(&reply
->reply_ia
, MDL
);
3358 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
3359 log_error("reply_process_prefix: No memory "
3360 "for option state wipe.");
3361 status
= ISC_R_NOMEMORY
;
3365 /* Append a NoBinding status code. */
3366 if (!set_status_code(STATUS_NoBinding
,
3367 "Prefix not bound to this "
3368 "interface.", reply
->reply_ia
)) {
3369 log_error("reply_process_prefix: Unable to "
3370 "attach status code.");
3371 status
= ISC_R_FAILURE
;
3375 /* Fin (no more IAPREFIXes). */
3376 status
= ISC_R_CANCELED
;
3379 log_error("It is impossible to lease a client that is "
3380 "not sending a solicit, request, renew, or "
3382 status
= ISC_R_FAILURE
;
3387 if (reply
->static_prefixes
> 0) {
3388 if (reply
->host
== NULL
)
3389 log_fatal("Impossible condition at %s:%d.", MDL
);
3391 scope
= &global_scope
;
3392 group
= reply
->host
->group
;
3394 if (reply
->lease
== NULL
)
3395 log_fatal("Impossible condition at %s:%d.", MDL
);
3397 scope
= &reply
->lease
->scope
;
3398 group
= reply
->shared
->group
;
3402 * If client_resources is nonzero, then the reply_process_is_prefixed
3403 * function has executed configuration state into the reply option
3404 * cache. We will use that valid cache to derive configuration for
3405 * whether or not to engage in additional prefixes, and similar.
3407 if (reply
->client_resources
!= 0) {
3411 * Does this client have "enough" prefixes already? Default
3412 * to one. Everybody gets one, and one should be enough for
3415 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3416 SV_LIMIT_PREFS_PER_IA
);
3418 if (!evaluate_option_cache(&data
, reply
->packet
,
3420 reply
->packet
->options
,
3424 log_error("reply_process_prefix: unable to "
3425 "evaluate prefs-per-ia value.");
3426 status
= ISC_R_FAILURE
;
3430 limit
= getULong(data
.data
);
3431 data_string_forget(&data
, MDL
);
3435 * If we wish to limit the client to a certain number of
3436 * prefixes, then omit the prefix from the reply.
3438 if (reply
->client_resources
>= limit
)
3442 status
= reply_process_is_prefixed(reply
, scope
, group
);
3443 if (status
!= ISC_R_SUCCESS
)
3447 status
= reply_process_send_prefix(reply
, &tmp_pref
);
3450 if (iapref
.data
!= NULL
)
3451 data_string_forget(&iapref
, MDL
);
3452 if (data
.data
!= NULL
)
3453 data_string_forget(&data
, MDL
);
3454 if (reply
->lease
!= NULL
)
3455 iasubopt_dereference(&reply
->lease
, MDL
);
3461 * Verify the prefix belongs to the client. If we've got a host
3462 * record with fixed prefixes, it has to be an assigned prefix
3463 * (fault out all else). Otherwise it's a dynamic prefix, so lookup
3464 * that prefix and make sure it belongs to this DUID:IAID pair.
3466 static isc_boolean_t
3467 prefix_is_owned(struct reply_state
*reply
, struct iaddrcidrnet
*pref
) {
3468 struct iaddrcidrnetlist
*l
;
3472 * This faults out prefixes that don't match fixed prefixes.
3474 if (reply
->static_prefixes
> 0) {
3475 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
3476 if ((pref
->bits
== l
->cidrnet
.bits
) &&
3477 (memcmp(pref
->lo_addr
.iabuf
,
3478 l
->cidrnet
.lo_addr
.iabuf
, 16) == 0))
3484 if ((reply
->old_ia
== NULL
) ||
3485 (reply
->old_ia
->num_iasubopt
== 0))
3488 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3489 struct iasubopt
*tmp
;
3491 tmp
= reply
->old_ia
->iasubopt
[i
];
3493 if ((pref
->bits
== (int) tmp
->plen
) &&
3494 memcmp(pref
->lo_addr
.iabuf
, &tmp
->addr
, 16) == 0) {
3495 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
3504 * This function only returns failure on 'hard' failures. If it succeeds,
3505 * it will leave a prefix structure behind.
3508 reply_process_try_prefix(struct reply_state
*reply
,
3509 struct iaddrcidrnet
*pref
) {
3510 isc_result_t status
= ISC_R_NORESOURCES
;
3511 struct ipv6_pool
*pool
;
3513 struct data_string data_pref
;
3515 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
3516 (reply
->shared
->ipv6_pools
== NULL
) || (pref
== NULL
) ||
3517 (reply
->lease
!= NULL
))
3518 return ISC_R_INVALIDARG
;
3520 memset(&data_pref
, 0, sizeof(data_pref
));
3522 if (!buffer_allocate(&data_pref
.buffer
, data_pref
.len
, MDL
)) {
3523 log_error("reply_process_try_prefix: out of memory.");
3524 return ISC_R_NOMEMORY
;
3526 data_pref
.data
= data_pref
.buffer
->data
;
3527 data_pref
.buffer
->data
[0] = (u_int8_t
) pref
->bits
;
3528 memcpy(data_pref
.buffer
->data
+ 1, pref
->lo_addr
.iabuf
, 16);
3530 for (i
= 0 ; (pool
= reply
->shared
->ipv6_pools
[i
]) != NULL
; i
++) {
3531 if (pool
->pool_type
!= D6O_IA_PD
)
3533 status
= try_client_v6_prefix(&reply
->lease
, pool
,
3535 if (status
== ISC_R_SUCCESS
)
3539 data_string_forget(&data_pref
, MDL
);
3540 /* Return just the most recent status... */
3544 /* Look around for a prefix to give the client. First, look through the old
3545 * IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
3546 * Finally, actually add that prefix into the current reply IA_PD.
3549 find_client_prefix(struct reply_state
*reply
) {
3550 struct iaddrcidrnet send_pref
;
3551 isc_result_t status
= ISC_R_NORESOURCES
;
3552 struct iasubopt
*prefix
, *best_prefix
= NULL
;
3553 struct binding_scope
**scope
;
3554 struct group
*group
;
3557 if (reply
->host
!= NULL
)
3558 group
= reply
->host
->group
;
3560 group
= reply
->shared
->group
;
3562 if (reply
->static_prefixes
> 0) {
3563 struct iaddrcidrnetlist
*l
;
3565 if (reply
->host
== NULL
)
3566 return ISC_R_INVALIDARG
;
3568 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
3569 if (l
->cidrnet
.bits
== reply
->preflen
)
3574 * If no fixed prefix has the preferred length,
3575 * get the first one.
3577 l
= reply
->host
->fixed_prefix
;
3579 memcpy(&send_pref
, &l
->cidrnet
, sizeof(send_pref
));
3581 status
= ISC_R_SUCCESS
;
3582 scope
= &global_scope
;
3586 if (reply
->old_ia
!= NULL
) {
3587 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3588 prefix
= reply
->old_ia
->iasubopt
[i
];
3590 best_prefix
= prefix_compare(reply
, prefix
,
3595 /* Try to pick a new prefix if we didn't find one, or if we found an
3598 if ((best_prefix
== NULL
) || (best_prefix
->state
== FTS_ABANDONED
)) {
3599 status
= pick_v6_prefix(&reply
->lease
, reply
->preflen
,
3600 reply
->shared
, &reply
->client_id
);
3601 } else if (best_prefix
!= NULL
) {
3602 iasubopt_reference(&reply
->lease
, best_prefix
, MDL
);
3603 status
= ISC_R_SUCCESS
;
3606 /* Pick the abandoned prefix as a last resort. */
3607 if ((status
== ISC_R_NORESOURCES
) && (best_prefix
!= NULL
)) {
3608 /* I don't see how this is supposed to be done right now. */
3609 log_error("Reclaiming abandoned prefixes is not yet "
3610 "supported. Treating this as an out of space "
3612 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
3615 /* Give up now if we didn't find a prefix. */
3616 if (status
!= ISC_R_SUCCESS
)
3619 if (reply
->lease
== NULL
)
3620 log_fatal("Impossible condition at %s:%d.", MDL
);
3622 scope
= &reply
->lease
->scope
;
3623 group
= reply
->shared
->group
;
3625 send_pref
.lo_addr
.len
= 16;
3626 memcpy(send_pref
.lo_addr
.iabuf
, &reply
->lease
->addr
, 16);
3627 send_pref
.bits
= (int) reply
->lease
->plen
;
3630 status
= reply_process_is_prefixed(reply
, scope
, group
);
3631 if (status
!= ISC_R_SUCCESS
)
3634 status
= reply_process_send_prefix(reply
, &send_pref
);
3638 /* Once a prefix is found for a client, perform several common functions;
3639 * Calculate and store valid and preferred prefix times, draw client options
3640 * into the option state.
3643 reply_process_is_prefixed(struct reply_state
*reply
,
3644 struct binding_scope
**scope
, struct group
*group
)
3646 isc_result_t status
= ISC_R_SUCCESS
;
3647 struct data_string data
;
3648 struct option_cache
*oc
;
3650 /* Initialize values we will cleanup. */
3651 memset(&data
, 0, sizeof(data
));
3653 /* Execute relevant options into root scope. */
3654 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3655 reply
->packet
->options
, reply
->opt_state
,
3656 scope
, group
, root_group
);
3658 /* Determine valid lifetime. */
3659 if (reply
->client_valid
== 0)
3660 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
3662 reply
->send_valid
= reply
->client_valid
;
3664 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3665 SV_DEFAULT_LEASE_TIME
);
3667 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3668 reply
->packet
->options
,
3672 log_error("reply_process_is_prefixed: unable to "
3673 "evaluate default prefix time");
3674 status
= ISC_R_FAILURE
;
3678 reply
->send_valid
= getULong(data
.data
);
3679 data_string_forget(&data
, MDL
);
3682 if (reply
->client_prefer
== 0)
3683 reply
->send_prefer
= reply
->send_valid
;
3685 reply
->send_prefer
= reply
->client_prefer
;
3687 if (reply
->send_prefer
>= reply
->send_valid
)
3688 reply
->send_prefer
= (reply
->send_valid
/ 2) +
3689 (reply
->send_valid
/ 8);
3691 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3692 SV_PREFER_LIFETIME
);
3694 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3695 reply
->packet
->options
,
3699 log_error("reply_process_is_prefixed: unable to "
3700 "evaluate preferred prefix time");
3701 status
= ISC_R_FAILURE
;
3705 reply
->send_prefer
= getULong(data
.data
);
3706 data_string_forget(&data
, MDL
);
3709 /* Note lowest values for later calculation of renew/rebind times. */
3710 if (reply
->prefer
> reply
->send_prefer
)
3711 reply
->prefer
= reply
->send_prefer
;
3713 if (reply
->valid
> reply
->send_valid
)
3714 reply
->valid
= reply
->send_valid
;
3716 /* Perform dynamic prefix related update work. */
3717 if (reply
->lease
!= NULL
) {
3718 /* Cached lifetimes */
3719 reply
->lease
->prefer
= reply
->send_prefer
;
3720 reply
->lease
->valid
= reply
->send_valid
;
3722 /* Advance (or rewind) the valid lifetime. */
3723 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
3724 reply
->lease
->soft_lifetime_end_time
=
3725 cur_time
+ reply
->send_valid
;
3726 /* Wait before renew! */
3729 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
3730 if (status
!= ISC_R_SUCCESS
) {
3731 log_fatal("reply_process_is_prefixed: Unable to "
3732 "attach prefix to new IA_PD: %s",
3733 isc_result_totext(status
));
3737 * If this is a new prefix, make sure it is attached somewhere.
3739 if (reply
->lease
->ia
== NULL
) {
3740 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
3744 /* Bring a copy of the relevant options into the IA_PD scope. */
3745 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3746 reply
->packet
->options
, reply
->reply_ia
,
3747 scope
, group
, root_group
);
3750 if (data
.data
!= NULL
)
3751 data_string_forget(&data
, MDL
);
3753 if (status
== ISC_R_SUCCESS
)
3754 reply
->client_resources
++;
3759 /* Simply send an IAPREFIX within the IA_PD scope as described. */
3761 reply_process_send_prefix(struct reply_state
*reply
,
3762 struct iaddrcidrnet
*pref
) {
3763 isc_result_t status
= ISC_R_SUCCESS
;
3764 struct data_string data
;
3766 memset(&data
, 0, sizeof(data
));
3768 /* Now append the prefix. */
3769 data
.len
= IAPREFIX_OFFSET
;
3770 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
3771 log_error("reply_process_send_prefix: out of memory"
3772 "allocating new IAPREFIX buffer.");
3773 status
= ISC_R_NOMEMORY
;
3776 data
.data
= data
.buffer
->data
;
3778 putULong(data
.buffer
->data
, reply
->send_prefer
);
3779 putULong(data
.buffer
->data
+ 4, reply
->send_valid
);
3780 data
.buffer
->data
[8] = pref
->bits
;
3781 memcpy(data
.buffer
->data
+ 9, pref
->lo_addr
.iabuf
, 16);
3783 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
3784 data
.buffer
, data
.buffer
->data
,
3785 data
.len
, D6O_IAPREFIX
, 0)) {
3786 log_error("reply_process_send_prefix: unable "
3787 "to save IAPREFIX option");
3788 status
= ISC_R_FAILURE
;
3792 reply
->resources_included
= ISC_TRUE
;
3795 if (data
.data
!= NULL
)
3796 data_string_forget(&data
, MDL
);
3801 /* Choose the better of two prefixes. */
3802 static struct iasubopt
*
3803 prefix_compare(struct reply_state
*reply
,
3804 struct iasubopt
*alpha
, struct iasubopt
*beta
) {
3810 if (reply
->preflen
>= 0) {
3811 if ((alpha
->plen
== reply
->preflen
) &&
3812 (beta
->plen
!= reply
->preflen
))
3814 if ((beta
->plen
== reply
->preflen
) &&
3815 (alpha
->plen
!= reply
->preflen
))
3819 switch(alpha
->state
) {
3821 switch(beta
->state
) {
3823 /* Choose the prefix with the longest lifetime (most
3824 * likely the most recently allocated).
3826 if (alpha
->hard_lifetime_end_time
<
3827 beta
->hard_lifetime_end_time
)
3837 log_fatal("Impossible condition at %s:%d.", MDL
);
3842 switch (beta
->state
) {
3847 /* Choose the most recently expired prefix. */
3848 if (alpha
->hard_lifetime_end_time
<
3849 beta
->hard_lifetime_end_time
)
3851 else if ((alpha
->hard_lifetime_end_time
==
3852 beta
->hard_lifetime_end_time
) &&
3853 (alpha
->soft_lifetime_end_time
<
3854 beta
->soft_lifetime_end_time
))
3863 log_fatal("Impossible condition at %s:%d.", MDL
);
3868 switch (beta
->state
) {
3874 /* Choose the prefix that was abandoned longest ago. */
3875 if (alpha
->hard_lifetime_end_time
<
3876 beta
->hard_lifetime_end_time
)
3880 log_fatal("Impossible condition at %s:%d.", MDL
);
3885 log_fatal("Impossible condition at %s:%d.", MDL
);
3888 log_fatal("Triple impossible condition at %s:%d.", MDL
);
3893 * Solicit is how a client starts requesting addresses.
3895 * If the client asks for rapid commit, and we support it, we will
3896 * allocate the addresses and reply.
3898 * Otherwise we will send an advertise message.
3902 dhcpv6_solicit(struct data_string
*reply_ret
, struct packet
*packet
) {
3903 struct data_string client_id
;
3906 * Validate our input.
3908 if (!valid_client_msg(packet
, &client_id
)) {
3912 lease_to_client(reply_ret
, packet
, &client_id
, NULL
);
3917 data_string_forget(&client_id
, MDL
);
3921 * Request is how a client actually requests addresses.
3923 * Very similar to Solicit handling, except the server DUID is required.
3926 /* TODO: reject unicast messages, unless we set unicast option */
3928 dhcpv6_request(struct data_string
*reply_ret
, struct packet
*packet
) {
3929 struct data_string client_id
;
3930 struct data_string server_id
;
3933 * Validate our input.
3935 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
3942 lease_to_client(reply_ret
, packet
, &client_id
, &server_id
);
3947 data_string_forget(&client_id
, MDL
);
3948 data_string_forget(&server_id
, MDL
);
3951 /* Find a DHCPv6 packet's shared network from hints in the packet.
3954 shared_network_from_packet6(struct shared_network
**shared
,
3955 struct packet
*packet
)
3957 const struct packet
*chk_packet
;
3958 const struct in6_addr
*link_addr
, *first_link_addr
;
3959 struct iaddr tmp_addr
;
3960 struct subnet
*subnet
;
3961 isc_result_t status
;
3963 if ((shared
== NULL
) || (*shared
!= NULL
) || (packet
== NULL
))
3964 return ISC_R_INVALIDARG
;
3967 * First, find the link address where the packet from the client
3968 * first appeared (if this packet was relayed).
3970 first_link_addr
= NULL
;
3971 chk_packet
= packet
->dhcpv6_container_packet
;
3972 while (chk_packet
!= NULL
) {
3973 link_addr
= &chk_packet
->dhcpv6_link_address
;
3974 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
3975 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
3976 first_link_addr
= link_addr
;
3979 chk_packet
= chk_packet
->dhcpv6_container_packet
;
3983 * If there is a relayed link address, find the subnet associated
3984 * with that, and use that to get the appropriate
3987 if (first_link_addr
!= NULL
) {
3988 tmp_addr
.len
= sizeof(*first_link_addr
);
3989 memcpy(tmp_addr
.iabuf
,
3990 first_link_addr
, sizeof(*first_link_addr
));
3992 if (!find_subnet(&subnet
, tmp_addr
, MDL
)) {
3993 log_debug("No subnet found for link-address %s.",
3995 return ISC_R_NOTFOUND
;
3997 status
= shared_network_reference(shared
,
3998 subnet
->shared_network
, MDL
);
3999 subnet_dereference(&subnet
, MDL
);
4002 * If there is no link address, we will use the interface
4003 * that this packet came in on to pick the shared_network.
4006 status
= shared_network_reference(shared
,
4007 packet
->interface
->shared_network
,
4015 * When a client thinks it might be on a new link, it sends a
4018 * From RFC3315 section 18.2.2:
4020 * When the server receives a Confirm message, the server determines
4021 * whether the addresses in the Confirm message are appropriate for the
4022 * link to which the client is attached. If all of the addresses in the
4023 * Confirm message pass this test, the server returns a status of
4024 * Success. If any of the addresses do not pass this test, the server
4025 * returns a status of NotOnLink. If the server is unable to perform
4026 * this test (for example, the server does not have information about
4027 * prefixes on the link to which the client is connected), or there were
4028 * no addresses in any of the IAs sent by the client, the server MUST
4029 * NOT send a reply to the client.
4033 dhcpv6_confirm(struct data_string
*reply_ret
, struct packet
*packet
) {
4034 struct shared_network
*shared
;
4035 struct subnet
*subnet
;
4036 struct option_cache
*ia
, *ta
, *oc
;
4037 struct data_string cli_enc_opt_data
, iaaddr
, client_id
, packet_oro
;
4038 struct option_state
*cli_enc_opt_state
, *opt_state
;
4039 struct iaddr cli_addr
;
4041 isc_boolean_t inappropriate
, has_addrs
;
4042 char reply_data
[65536];
4043 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
4044 int reply_ofs
= (int)((char *)reply
->options
- (char *)reply
);
4047 * Basic client message validation.
4049 memset(&client_id
, 0, sizeof(client_id
));
4050 if (!valid_client_msg(packet
, &client_id
)) {
4055 * Do not process Confirms that do not have IA's we do not recognize.
4057 ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
4058 ta
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
4059 if ((ia
== NULL
) && (ta
== NULL
))
4063 * IA_PD's are simply ignored.
4065 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
4068 * Bit of variable initialization.
4070 opt_state
= cli_enc_opt_state
= NULL
;
4071 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
4072 memset(&iaaddr
, 0, sizeof(iaaddr
));
4073 memset(&packet_oro
, 0, sizeof(packet_oro
));
4075 /* Determine what shared network the client is connected to. We
4076 * must not respond if we don't have any information about the
4077 * network the client is on.
4080 if ((shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
) ||
4084 /* If there are no recorded subnets, then we have no
4085 * information about this subnet - ignore Confirms.
4087 subnet
= shared
->subnets
;
4091 /* Are the addresses in all the IA's appropriate for that link? */
4092 has_addrs
= inappropriate
= ISC_FALSE
;
4094 while(!inappropriate
) {
4095 /* If we've reached the end of the IA_NA pass, move to the
4098 if ((pass
== D6O_IA_NA
) && (ia
== NULL
)) {
4103 /* If we've reached the end of all passes, we're done. */
4107 if (((pass
== D6O_IA_NA
) &&
4108 !get_encapsulated_IA_state(&cli_enc_opt_state
,
4110 packet
, ia
, IA_NA_OFFSET
)) ||
4111 ((pass
== D6O_IA_TA
) &&
4112 !get_encapsulated_IA_state(&cli_enc_opt_state
,
4114 packet
, ia
, IA_TA_OFFSET
))) {
4118 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
4121 for ( ; oc
!= NULL
; oc
= oc
->next
) {
4122 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
4123 packet
->options
, NULL
,
4124 &global_scope
, oc
, MDL
) ||
4125 (iaaddr
.len
< IAADDR_OFFSET
)) {
4126 log_error("dhcpv6_confirm: "
4127 "error evaluating IAADDR.");
4131 /* Copy out the IPv6 address for processing. */
4133 memcpy(cli_addr
.iabuf
, iaaddr
.data
, 16);
4135 data_string_forget(&iaaddr
, MDL
);
4137 /* Record that we've processed at least one address. */
4138 has_addrs
= ISC_TRUE
;
4140 /* Find out if any subnets cover this address. */
4141 for (subnet
= shared
->subnets
; subnet
!= NULL
;
4142 subnet
= subnet
->next_sibling
) {
4143 if (addr_eq(subnet_number(cli_addr
,
4149 /* If we reach the end of the subnet list, and no
4150 * subnet matches the client address, then it must
4151 * be inappropriate to the link (so far as our
4152 * configuration says). Once we've found one
4153 * inappropriate address, there is no reason to
4154 * continue searching.
4156 if (subnet
== NULL
) {
4157 inappropriate
= ISC_TRUE
;
4162 option_state_dereference(&cli_enc_opt_state
, MDL
);
4163 data_string_forget(&cli_enc_opt_data
, MDL
);
4165 /* Advance to the next IA_*. */
4169 /* If the client supplied no addresses, do not reply. */
4176 if (!start_reply(packet
, &client_id
, NULL
, &opt_state
, reply
)) {
4183 if (inappropriate
) {
4184 if (!set_status_code(STATUS_NotOnLink
,
4185 "Some of the addresses are not on link.",
4190 if (!set_status_code(STATUS_Success
,
4191 "All addresses still on link.",
4198 * Only one option: add it.
4200 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
4201 sizeof(reply_data
)-reply_ofs
,
4203 required_opts
, &packet_oro
);
4206 * Return our reply to the caller.
4208 reply_ret
->len
= reply_ofs
;
4209 reply_ret
->buffer
= NULL
;
4210 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
4211 log_fatal("No memory to store reply.");
4213 reply_ret
->data
= reply_ret
->buffer
->data
;
4214 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
4217 /* Cleanup any stale data strings. */
4218 if (cli_enc_opt_data
.buffer
!= NULL
)
4219 data_string_forget(&cli_enc_opt_data
, MDL
);
4220 if (iaaddr
.buffer
!= NULL
)
4221 data_string_forget(&iaaddr
, MDL
);
4222 if (client_id
.buffer
!= NULL
)
4223 data_string_forget(&client_id
, MDL
);
4224 if (packet_oro
.buffer
!= NULL
)
4225 data_string_forget(&packet_oro
, MDL
);
4227 /* Release any stale option states. */
4228 if (cli_enc_opt_state
!= NULL
)
4229 option_state_dereference(&cli_enc_opt_state
, MDL
);
4230 if (opt_state
!= NULL
)
4231 option_state_dereference(&opt_state
, MDL
);
4235 * Renew is when a client wants to extend its lease/prefix, at time T1.
4237 * We handle this the same as if the client wants a new lease/prefix,
4238 * except for the error code of when addresses don't match.
4241 /* TODO: reject unicast messages, unless we set unicast option */
4243 dhcpv6_renew(struct data_string
*reply
, struct packet
*packet
) {
4244 struct data_string client_id
;
4245 struct data_string server_id
;
4248 * Validate the request.
4250 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
4257 lease_to_client(reply
, packet
, &client_id
, &server_id
);
4262 data_string_forget(&server_id
, MDL
);
4263 data_string_forget(&client_id
, MDL
);
4267 * Rebind is when a client wants to extend its lease, at time T2.
4269 * We handle this the same as if the client wants a new lease, except
4270 * for the error code of when addresses don't match.
4274 dhcpv6_rebind(struct data_string
*reply
, struct packet
*packet
) {
4275 struct data_string client_id
;
4277 if (!valid_client_msg(packet
, &client_id
)) {
4281 lease_to_client(reply
, packet
, &client_id
, NULL
);
4283 data_string_forget(&client_id
, MDL
);
4287 ia_na_match_decline(const struct data_string
*client_id
,
4288 const struct data_string
*iaaddr
,
4289 struct iasubopt
*lease
)
4291 char tmp_addr
[INET6_ADDRSTRLEN
];
4293 log_error("Client %s reports address %s is "
4294 "already in use by another host!",
4295 print_hex_1(client_id
->len
, client_id
->data
, 60),
4296 inet_ntop(AF_INET6
, iaaddr
->data
,
4297 tmp_addr
, sizeof(tmp_addr
)));
4298 if (lease
!= NULL
) {
4299 decline_lease6(lease
->ipv6_pool
, lease
);
4300 lease
->ia
->cltt
= cur_time
;
4301 write_ia(lease
->ia
);
4306 ia_na_nomatch_decline(const struct data_string
*client_id
,
4307 const struct data_string
*iaaddr
,
4308 u_int32_t
*ia_na_id
,
4309 struct packet
*packet
,
4314 char tmp_addr
[INET6_ADDRSTRLEN
];
4315 struct option_state
*host_opt_state
;
4318 log_info("Client %s declines address %s, which is not offered to it.",
4319 print_hex_1(client_id
->len
, client_id
->data
, 60),
4320 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
4323 * Create state for this IA_NA.
4325 host_opt_state
= NULL
;
4326 if (!option_state_allocate(&host_opt_state
, MDL
)) {
4327 log_error("ia_na_nomatch_decline: out of memory "
4328 "allocating option_state.");
4332 if (!set_status_code(STATUS_NoBinding
, "Decline for unknown address.",
4338 * Insure we have enough space
4340 if (reply_len
< (*reply_ofs
+ 16)) {
4341 log_error("ia_na_nomatch_decline: "
4342 "out of space for reply packet.");
4347 * Put our status code into the reply packet.
4349 len
= store_options6(reply_data
+(*reply_ofs
)+16,
4350 reply_len
-(*reply_ofs
)-16,
4351 host_opt_state
, packet
,
4352 required_opts_STATUS_CODE
, NULL
);
4355 * Store the non-encapsulated option data for this
4356 * IA_NA into our reply packet. Defined in RFC 3315,
4360 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
4362 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
4363 /* IA_NA, copied from the client */
4364 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
4365 /* t1 and t2, odd that we need them, but here it is */
4366 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
4367 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
4370 * Get ready for next IA_NA.
4372 *reply_ofs
+= (len
+ 16);
4375 option_state_dereference(&host_opt_state
, MDL
);
4379 iterate_over_ia_na(struct data_string
*reply_ret
,
4380 struct packet
*packet
,
4381 const struct data_string
*client_id
,
4382 const struct data_string
*server_id
,
4383 const char *packet_type
,
4384 void (*ia_na_match
)(),
4385 void (*ia_na_nomatch
)())
4387 struct option_state
*opt_state
;
4388 struct host_decl
*packet_host
;
4389 struct option_cache
*ia
;
4390 struct option_cache
*oc
;
4391 /* cli_enc_... variables come from the IA_NA/IA_TA options */
4392 struct data_string cli_enc_opt_data
;
4393 struct option_state
*cli_enc_opt_state
;
4394 struct host_decl
*host
;
4395 struct option_state
*host_opt_state
;
4396 struct data_string iaaddr
;
4397 struct data_string fixed_addr
;
4398 int iaaddr_is_found
;
4399 char reply_data
[65536];
4400 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
4401 int reply_ofs
= (int)((char *)reply
->options
- (char *)reply
);
4402 char status_msg
[32];
4403 struct iasubopt
*lease
;
4404 struct ia_xx
*existing_ia_na
;
4406 struct data_string key
;
4410 * Initialize to empty values, in case we have to exit early.
4413 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
4414 cli_enc_opt_state
= NULL
;
4415 memset(&iaaddr
, 0, sizeof(iaaddr
));
4416 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
4417 host_opt_state
= NULL
;
4421 * Find the host record that matches from the packet, if any.
4424 if (!find_hosts_by_uid(&packet_host
,
4425 client_id
->data
, client_id
->len
, MDL
)) {
4428 * Note: In general, we don't expect a client to provide
4429 * enough information to match by option for these
4430 * types of messages, but if we don't have a UID
4431 * match we can check anyway.
4433 if (!find_hosts_by_option(&packet_host
,
4434 packet
, packet
->options
, MDL
)) {
4440 * Set our reply information.
4442 reply
->msg_type
= DHCPV6_REPLY
;
4443 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
4444 sizeof(reply
->transaction_id
));
4447 * Build our option state for reply.
4450 if (!option_state_allocate(&opt_state
, MDL
)) {
4451 log_error("iterate_over_ia_na: no memory for option_state.");
4454 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
4455 packet
->options
, opt_state
,
4456 &global_scope
, root_group
, NULL
);
4459 * RFC 3315, section 18.2.7 tells us which options to include.
4461 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
4463 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
4464 (unsigned char *)server_duid
.data
,
4465 server_duid
.len
, D6O_SERVERID
, 0)) {
4466 log_error("iterate_over_ia_na: "
4467 "error saving server identifier.");
4472 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
4474 (unsigned char *)client_id
->data
,
4477 log_error("iterate_over_ia_na: "
4478 "error saving client identifier.");
4482 snprintf(status_msg
, sizeof(status_msg
), "%s received.", packet_type
);
4483 if (!set_status_code(STATUS_Success
, status_msg
, opt_state
)) {
4488 * Add our options that are not associated with any IA_NA or IA_TA.
4490 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
4491 sizeof(reply_data
)-reply_ofs
,
4493 required_opts
, NULL
);
4496 * Loop through the IA_NA reported by the client, and deal with
4497 * addresses reported as already in use.
4499 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
4500 ia
!= NULL
; ia
= ia
->next
) {
4501 iaaddr_is_found
= 0;
4503 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
4505 packet
, ia
, IA_NA_OFFSET
)) {
4509 iaid
= getULong(cli_enc_opt_data
.data
);
4512 * XXX: It is possible that we can get multiple addresses
4513 * sent by the client. We don't send multiple
4514 * addresses, so this indicates a client error.
4515 * We should check for multiple IAADDR options, log
4516 * if found, and set as an error.
4518 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
4521 /* no address given for this IA, ignore */
4522 option_state_dereference(&cli_enc_opt_state
, MDL
);
4523 data_string_forget(&cli_enc_opt_data
, MDL
);
4527 memset(&iaaddr
, 0, sizeof(iaaddr
));
4528 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
4529 packet
->options
, NULL
,
4530 &global_scope
, oc
, MDL
)) {
4531 log_error("iterate_over_ia_na: "
4532 "error evaluating IAADDR.");
4537 * Now we need to figure out which host record matches
4538 * this IA_NA and IAADDR.
4540 * XXX: We don't currently track IA_NA separately, but
4541 * we will need to do this!
4544 if (!find_hosts_by_option(&host
, packet
,
4545 cli_enc_opt_state
, MDL
)) {
4546 if (packet_host
!= NULL
) {
4552 while (host
!= NULL
) {
4553 if (host
->fixed_addr
!= NULL
) {
4554 if (!evaluate_option_cache(&fixed_addr
, NULL
,
4556 NULL
, &global_scope
,
4559 log_error("iterate_over_ia_na: error "
4560 "evaluating host address.");
4563 if ((iaaddr
.len
>= 16) &&
4564 !memcmp(fixed_addr
.data
, iaaddr
.data
, 16)) {
4565 data_string_forget(&fixed_addr
, MDL
);
4568 data_string_forget(&fixed_addr
, MDL
);
4570 host
= host
->n_ipaddr
;
4573 if ((host
== NULL
) && (iaaddr
.len
>= IAADDR_OFFSET
)) {
4575 * Find existing IA_NA.
4577 if (ia_make_key(&key
, iaid
,
4578 (char *)client_id
->data
,
4580 MDL
) != ISC_R_SUCCESS
) {
4581 log_fatal("iterate_over_ia_na: no memory for "
4585 existing_ia_na
= NULL
;
4586 if (ia_hash_lookup(&existing_ia_na
, ia_na_active
,
4587 (unsigned char *)key
.data
,
4590 * Make sure this address is in the IA_NA.
4592 for (i
=0; i
<existing_ia_na
->num_iasubopt
; i
++) {
4593 struct iasubopt
*tmp
;
4594 struct in6_addr
*in6_addr
;
4596 tmp
= existing_ia_na
->iasubopt
[i
];
4597 in6_addr
= &tmp
->addr
;
4598 if (memcmp(in6_addr
,
4599 iaaddr
.data
, 16) == 0) {
4600 iasubopt_reference(&lease
,
4607 data_string_forget(&key
, MDL
);
4610 if ((host
!= NULL
) || (lease
!= NULL
)) {
4611 ia_na_match(client_id
, &iaaddr
, lease
);
4613 ia_na_nomatch(client_id
, &iaaddr
,
4614 (u_int32_t
*)cli_enc_opt_data
.data
,
4615 packet
, reply_data
, &reply_ofs
,
4616 sizeof(reply_data
));
4619 if (lease
!= NULL
) {
4620 iasubopt_dereference(&lease
, MDL
);
4623 data_string_forget(&iaaddr
, MDL
);
4624 option_state_dereference(&cli_enc_opt_state
, MDL
);
4625 data_string_forget(&cli_enc_opt_data
, MDL
);
4629 * Return our reply to the caller.
4631 reply_ret
->len
= reply_ofs
;
4632 reply_ret
->buffer
= NULL
;
4633 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
4634 log_fatal("No memory to store reply.");
4636 reply_ret
->data
= reply_ret
->buffer
->data
;
4637 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
4640 if (lease
!= NULL
) {
4641 iasubopt_dereference(&lease
, MDL
);
4643 if (host_opt_state
!= NULL
) {
4644 option_state_dereference(&host_opt_state
, MDL
);
4646 if (fixed_addr
.buffer
!= NULL
) {
4647 data_string_forget(&fixed_addr
, MDL
);
4649 if (iaaddr
.buffer
!= NULL
) {
4650 data_string_forget(&iaaddr
, MDL
);
4652 if (cli_enc_opt_state
!= NULL
) {
4653 option_state_dereference(&cli_enc_opt_state
, MDL
);
4655 if (cli_enc_opt_data
.buffer
!= NULL
) {
4656 data_string_forget(&cli_enc_opt_data
, MDL
);
4658 if (opt_state
!= NULL
) {
4659 option_state_dereference(&opt_state
, MDL
);
4664 * Decline means a client has detected that something else is using an
4665 * address we gave it.
4667 * Since we're only dealing with fixed leases for now, there's not
4668 * much we can do, other that log the occurrence.
4670 * When we start issuing addresses from pools, then we will have to
4671 * record our declined addresses and issue another. In general with
4672 * IPv6 there is no worry about DoS by clients exhausting space, but
4673 * we still need to be aware of this possibility.
4676 /* TODO: reject unicast messages, unless we set unicast option */
4679 dhcpv6_decline(struct data_string
*reply
, struct packet
*packet
) {
4680 struct data_string client_id
;
4681 struct data_string server_id
;
4684 * Validate our input.
4686 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
4691 * Undefined for IA_PD.
4693 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
4696 * And operate on each IA_NA in this packet.
4698 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
, "Decline",
4699 ia_na_match_decline
, ia_na_nomatch_decline
);
4701 data_string_forget(&server_id
, MDL
);
4702 data_string_forget(&client_id
, MDL
);
4706 ia_na_match_release(const struct data_string
*client_id
,
4707 const struct data_string
*iaaddr
,
4708 struct iasubopt
*lease
)
4710 char tmp_addr
[INET6_ADDRSTRLEN
];
4712 log_info("Client %s releases address %s",
4713 print_hex_1(client_id
->len
, client_id
->data
, 60),
4714 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
4715 if (lease
!= NULL
) {
4716 release_lease6(lease
->ipv6_pool
, lease
);
4717 lease
->ia
->cltt
= cur_time
;
4718 write_ia(lease
->ia
);
4723 ia_na_nomatch_release(const struct data_string
*client_id
,
4724 const struct data_string
*iaaddr
,
4725 u_int32_t
*ia_na_id
,
4726 struct packet
*packet
,
4731 char tmp_addr
[INET6_ADDRSTRLEN
];
4732 struct option_state
*host_opt_state
;
4735 log_info("Client %s releases address %s, which is not leased to it.",
4736 print_hex_1(client_id
->len
, client_id
->data
, 60),
4737 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
4740 * Create state for this IA_NA.
4742 host_opt_state
= NULL
;
4743 if (!option_state_allocate(&host_opt_state
, MDL
)) {
4744 log_error("ia_na_nomatch_release: out of memory "
4745 "allocating option_state.");
4749 if (!set_status_code(STATUS_NoBinding
,
4750 "Release for non-leased address.",
4756 * Insure we have enough space
4758 if (reply_len
< (*reply_ofs
+ 16)) {
4759 log_error("ia_na_nomatch_release: "
4760 "out of space for reply packet.");
4765 * Put our status code into the reply packet.
4767 len
= store_options6(reply_data
+(*reply_ofs
)+16,
4768 reply_len
-(*reply_ofs
)-16,
4769 host_opt_state
, packet
,
4770 required_opts_STATUS_CODE
, NULL
);
4773 * Store the non-encapsulated option data for this
4774 * IA_NA into our reply packet. Defined in RFC 3315,
4778 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
4780 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
4781 /* IA_NA, copied from the client */
4782 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
4783 /* t1 and t2, odd that we need them, but here it is */
4784 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
4785 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
4788 * Get ready for next IA_NA.
4790 *reply_ofs
+= (len
+ 16);
4793 option_state_dereference(&host_opt_state
, MDL
);
4797 ia_pd_match_release(const struct data_string
*client_id
,
4798 const struct data_string
*iapref
,
4799 struct iasubopt
*prefix
)
4801 char tmp_addr
[INET6_ADDRSTRLEN
];
4803 log_info("Client %s releases prefix %s/%u",
4804 print_hex_1(client_id
->len
, client_id
->data
, 60),
4805 inet_ntop(AF_INET6
, iapref
->data
+ 9,
4806 tmp_addr
, sizeof(tmp_addr
)),
4807 (unsigned) getUChar(iapref
->data
+ 8));
4808 if (prefix
!= NULL
) {
4809 release_lease6(prefix
->ipv6_pool
, prefix
);
4810 prefix
->ia
->cltt
= cur_time
;
4811 write_ia(prefix
->ia
);
4816 ia_pd_nomatch_release(const struct data_string
*client_id
,
4817 const struct data_string
*iapref
,
4818 u_int32_t
*ia_pd_id
,
4819 struct packet
*packet
,
4824 char tmp_addr
[INET6_ADDRSTRLEN
];
4825 struct option_state
*host_opt_state
;
4828 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
4829 print_hex_1(client_id
->len
, client_id
->data
, 60),
4830 inet_ntop(AF_INET6
, iapref
->data
+ 9,
4831 tmp_addr
, sizeof(tmp_addr
)),
4832 (unsigned) getUChar(iapref
->data
+ 8));
4835 * Create state for this IA_PD.
4837 host_opt_state
= NULL
;
4838 if (!option_state_allocate(&host_opt_state
, MDL
)) {
4839 log_error("ia_pd_nomatch_release: out of memory "
4840 "allocating option_state.");
4844 if (!set_status_code(STATUS_NoBinding
,
4845 "Release for non-leased prefix.",
4851 * Insure we have enough space
4853 if (reply_len
< (*reply_ofs
+ 16)) {
4854 log_error("ia_pd_nomatch_release: "
4855 "out of space for reply packet.");
4860 * Put our status code into the reply packet.
4862 len
= store_options6(reply_data
+(*reply_ofs
)+16,
4863 reply_len
-(*reply_ofs
)-16,
4864 host_opt_state
, packet
,
4865 required_opts_STATUS_CODE
, NULL
);
4868 * Store the non-encapsulated option data for this
4869 * IA_PD into our reply packet. Defined in RFC 3315,
4873 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_PD
);
4875 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
4876 /* IA_PD, copied from the client */
4877 memcpy(reply_data
+(*reply_ofs
)+4, ia_pd_id
, 4);
4878 /* t1 and t2, odd that we need them, but here it is */
4879 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
4880 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
4883 * Get ready for next IA_PD.
4885 *reply_ofs
+= (len
+ 16);
4888 option_state_dereference(&host_opt_state
, MDL
);
4892 iterate_over_ia_pd(struct data_string
*reply_ret
,
4893 struct packet
*packet
,
4894 const struct data_string
*client_id
,
4895 const struct data_string
*server_id
,
4896 const char *packet_type
,
4897 void (*ia_pd_match
)(),
4898 void (*ia_pd_nomatch
)())
4900 struct data_string reply_new
;
4902 struct option_state
*opt_state
;
4903 struct host_decl
*packet_host
;
4904 struct option_cache
*ia
;
4905 struct option_cache
*oc
;
4906 /* cli_enc_... variables come from the IA_PD options */
4907 struct data_string cli_enc_opt_data
;
4908 struct option_state
*cli_enc_opt_state
;
4909 struct host_decl
*host
;
4910 struct option_state
*host_opt_state
;
4911 struct data_string iaprefix
;
4912 int iaprefix_is_found
;
4913 char reply_data
[65536];
4915 struct iasubopt
*prefix
;
4916 struct ia_xx
*existing_ia_pd
;
4918 struct data_string key
;
4922 * Initialize to empty values, in case we have to exit early.
4924 memset(&reply_new
, 0, sizeof(reply_new
));
4926 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
4927 cli_enc_opt_state
= NULL
;
4928 memset(&iaprefix
, 0, sizeof(iaprefix
));
4929 host_opt_state
= NULL
;
4933 * Compute the available length for the reply.
4935 reply_len
= sizeof(reply_data
) - reply_ret
->len
;
4939 * Find the host record that matches from the packet, if any.
4942 if (!find_hosts_by_uid(&packet_host
,
4943 client_id
->data
, client_id
->len
, MDL
)) {
4946 * Note: In general, we don't expect a client to provide
4947 * enough information to match by option for these
4948 * types of messages, but if we don't have a UID
4949 * match we can check anyway.
4951 if (!find_hosts_by_option(&packet_host
,
4952 packet
, packet
->options
, MDL
)) {
4958 * Build our option state for reply.
4961 if (!option_state_allocate(&opt_state
, MDL
)) {
4962 log_error("iterate_over_ia_pd: no memory for option_state.");
4965 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
4966 packet
->options
, opt_state
,
4967 &global_scope
, root_group
, NULL
);
4970 * Loop through the IA_PD reported by the client, and deal with
4971 * prefixes reported as already in use.
4973 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
4974 ia
!= NULL
; ia
= ia
->next
) {
4975 iaprefix_is_found
= 0;
4977 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
4979 packet
, ia
, IA_PD_OFFSET
)) {
4983 iaid
= getULong(cli_enc_opt_data
.data
);
4985 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
4988 /* no prefix given for this IA_PD, ignore */
4989 option_state_dereference(&cli_enc_opt_state
, MDL
);
4990 data_string_forget(&cli_enc_opt_data
, MDL
);
4994 for (; oc
!= NULL
; oc
= oc
->next
) {
4995 memset(&iaprefix
, 0, sizeof(iaprefix
));
4996 if (!evaluate_option_cache(&iaprefix
, packet
, NULL
, NULL
,
4997 packet
->options
, NULL
,
4998 &global_scope
, oc
, MDL
)) {
4999 log_error("iterate_over_ia_pd: "
5000 "error evaluating IAPREFIX.");
5005 * Now we need to figure out which host record matches
5006 * this IA_PD and IAPREFIX.
5008 * XXX: We don't currently track IA_PD separately, but
5009 * we will need to do this!
5012 if (!find_hosts_by_option(&host
, packet
,
5013 cli_enc_opt_state
, MDL
)) {
5014 if (packet_host
!= NULL
) {
5020 while (host
!= NULL
) {
5021 if (host
->fixed_prefix
!= NULL
) {
5022 struct iaddrcidrnetlist
*l
;
5023 int plen
= (int) getUChar(iaprefix
.data
+ 8);
5025 for (l
= host
->fixed_prefix
; l
!= NULL
;
5027 if (plen
!= l
->cidrnet
.bits
)
5029 if (memcmp(iaprefix
.data
+ 9,
5030 l
->cidrnet
.lo_addr
.iabuf
,
5034 if ((l
!= NULL
) && (iaprefix
.len
>= 17))
5037 host
= host
->n_ipaddr
;
5040 if ((host
== NULL
) && (iaprefix
.len
>= IAPREFIX_OFFSET
)) {
5042 * Find existing IA_PD.
5044 if (ia_make_key(&key
, iaid
,
5045 (char *)client_id
->data
,
5047 MDL
) != ISC_R_SUCCESS
) {
5048 log_fatal("iterate_over_ia_pd: no memory for "
5052 existing_ia_pd
= NULL
;
5053 if (ia_hash_lookup(&existing_ia_pd
, ia_pd_active
,
5054 (unsigned char *)key
.data
,
5057 * Make sure this prefix is in the IA_PD.
5060 i
< existing_ia_pd
->num_iasubopt
;
5062 struct iasubopt
*tmp
;
5065 plen
= getUChar(iaprefix
.data
+ 8);
5066 tmp
= existing_ia_pd
->iasubopt
[i
];
5067 if ((tmp
->plen
== plen
) &&
5071 iasubopt_reference(&prefix
,
5078 data_string_forget(&key
, MDL
);
5081 if ((host
!= NULL
) || (prefix
!= NULL
)) {
5082 ia_pd_match(client_id
, &iaprefix
, prefix
);
5084 ia_pd_nomatch(client_id
, &iaprefix
,
5085 (u_int32_t
*)cli_enc_opt_data
.data
,
5086 packet
, reply_data
, &reply_ofs
,
5087 reply_len
- reply_ofs
);
5090 if (prefix
!= NULL
) {
5091 iasubopt_dereference(&prefix
, MDL
);
5094 data_string_forget(&iaprefix
, MDL
);
5097 option_state_dereference(&cli_enc_opt_state
, MDL
);
5098 data_string_forget(&cli_enc_opt_data
, MDL
);
5102 * Return our reply to the caller.
5103 * The IA_NA routine has already filled at least the header.
5105 reply_new
.len
= reply_ret
->len
+ reply_ofs
;
5106 if (!buffer_allocate(&reply_new
.buffer
, reply_new
.len
, MDL
)) {
5107 log_fatal("No memory to store reply.");
5109 reply_new
.data
= reply_new
.buffer
->data
;
5110 memcpy(reply_new
.buffer
->data
,
5111 reply_ret
->buffer
->data
, reply_ret
->len
);
5112 memcpy(reply_new
.buffer
->data
+ reply_ret
->len
,
5113 reply_data
, reply_ofs
);
5114 data_string_forget(reply_ret
, MDL
);
5115 data_string_copy(reply_ret
, &reply_new
, MDL
);
5116 data_string_forget(&reply_new
, MDL
);
5119 if (prefix
!= NULL
) {
5120 iasubopt_dereference(&prefix
, MDL
);
5122 if (host_opt_state
!= NULL
) {
5123 option_state_dereference(&host_opt_state
, MDL
);
5125 if (iaprefix
.buffer
!= NULL
) {
5126 data_string_forget(&iaprefix
, MDL
);
5128 if (cli_enc_opt_state
!= NULL
) {
5129 option_state_dereference(&cli_enc_opt_state
, MDL
);
5131 if (cli_enc_opt_data
.buffer
!= NULL
) {
5132 data_string_forget(&cli_enc_opt_data
, MDL
);
5134 if (opt_state
!= NULL
) {
5135 option_state_dereference(&opt_state
, MDL
);
5140 * Release means a client is done with the leases.
5143 /* TODO: reject unicast messages, unless we set unicast option */
5145 dhcpv6_release(struct data_string
*reply
, struct packet
*packet
) {
5146 struct data_string client_id
;
5147 struct data_string server_id
;
5150 * Validate our input.
5152 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5157 * And operate on each IA_NA in this packet.
5159 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
, "Release",
5160 ia_na_match_release
, ia_na_nomatch_release
);
5163 * And operate on each IA_PD in this packet.
5165 iterate_over_ia_pd(reply
, packet
, &client_id
, &server_id
, "Release",
5166 ia_pd_match_release
, ia_pd_nomatch_release
);
5168 data_string_forget(&server_id
, MDL
);
5169 data_string_forget(&client_id
, MDL
);
5173 * Information-Request is used by clients who have obtained an address
5174 * from other means, but want configuration information from the server.
5178 dhcpv6_information_request(struct data_string
*reply
, struct packet
*packet
) {
5179 struct data_string client_id
;
5180 struct data_string server_id
;
5183 * Validate our input.
5185 if (!valid_client_info_req(packet
, &server_id
)) {
5190 * Get our client ID, if there is one.
5192 memset(&client_id
, 0, sizeof(client_id
));
5193 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
) {
5194 data_string_forget(&client_id
, MDL
);
5198 * Use the lease_to_client() function. This will work fine,
5199 * because the valid_client_info_req() insures that we
5200 * don't have any IA that would cause us to allocate
5201 * resources to the client.
5203 lease_to_client(reply
, packet
, &client_id
,
5204 server_id
.data
!= NULL
? &server_id
: NULL
);
5209 if (client_id
.data
!= NULL
) {
5210 data_string_forget(&client_id
, MDL
);
5212 data_string_forget(&server_id
, MDL
);
5216 * The Relay-forw message is sent by relays. It typically contains a
5217 * single option, which encapsulates an entire packet.
5219 * We need to build an encapsulated reply.
5222 /* XXX: this is very, very similar to do_packet6(), and should probably
5223 be combined in a clever way */
5225 dhcpv6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
5226 struct option_cache
*oc
;
5227 struct data_string enc_opt_data
;
5228 struct packet
*enc_packet
;
5229 unsigned char msg_type
;
5230 const struct dhcpv6_packet
*msg
;
5231 const struct dhcpv6_relay_packet
*relay
;
5232 struct data_string enc_reply
;
5233 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
5234 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
5235 struct data_string a_opt
, packet_ero
;
5236 struct option_state
*opt_state
;
5237 static char reply_data
[65536];
5238 struct dhcpv6_relay_packet
*reply
;
5242 * Initialize variables for early exit.
5245 memset(&a_opt
, 0, sizeof(a_opt
));
5246 memset(&packet_ero
, 0, sizeof(packet_ero
));
5247 memset(&enc_reply
, 0, sizeof(enc_reply
));
5248 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
5252 * Get our encapsulated relay message.
5254 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
5256 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
5257 link_addr
, sizeof(link_addr
));
5258 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
5259 peer_addr
, sizeof(peer_addr
));
5260 log_info("Relay-forward from %s with link address=%s and "
5261 "peer address=%s missing Relay Message option.",
5262 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
5266 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
5267 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
5268 log_error("dhcpv6_forw_relay: error evaluating "
5269 "relayed message.");
5273 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
5274 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
5279 * Build a packet structure from this encapsulated packet.
5282 if (!packet_allocate(&enc_packet
, MDL
)) {
5283 log_error("dhcpv6_forw_relay: "
5284 "no memory for encapsulated packet.");
5288 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
5289 log_error("dhcpv6_forw_relay: "
5290 "no memory for encapsulated packet's options.");
5294 enc_packet
->client_port
= packet
->client_port
;
5295 enc_packet
->client_addr
= packet
->client_addr
;
5296 enc_packet
->dhcpv6_container_packet
= packet
;
5298 msg_type
= enc_opt_data
.data
[0];
5299 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
5300 (msg_type
== DHCPV6_RELAY_REPL
)) {
5301 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
5302 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
5304 /* relay-specific data */
5305 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
5306 memcpy(&enc_packet
->dhcpv6_link_address
,
5307 relay
->link_address
, sizeof(relay
->link_address
));
5308 memcpy(&enc_packet
->dhcpv6_peer_address
,
5309 relay
->peer_address
, sizeof(relay
->peer_address
));
5311 if (!parse_option_buffer(enc_packet
->options
,
5313 enc_opt_data
.len
-sizeof(*relay
),
5314 &dhcpv6_universe
)) {
5315 /* no logging here, as parse_option_buffer() logs all
5316 cases where it fails */
5320 msg
= (struct dhcpv6_packet
*)enc_opt_data
.data
;
5321 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
5323 /* message-specific data */
5324 memcpy(enc_packet
->dhcpv6_transaction_id
,
5325 msg
->transaction_id
,
5326 sizeof(enc_packet
->dhcpv6_transaction_id
));
5328 if (!parse_option_buffer(enc_packet
->options
,
5330 enc_opt_data
.len
-sizeof(*msg
),
5331 &dhcpv6_universe
)) {
5332 /* no logging here, as parse_option_buffer() logs all
5333 cases where it fails */
5339 * This is recursive. It is possible to exceed maximum packet size.
5340 * XXX: This will cause the packet send to fail.
5342 build_dhcpv6_reply(&enc_reply
, enc_packet
);
5345 * If we got no encapsulated data, then it is discarded, and
5346 * our reply-forw is also discarded.
5348 if (enc_reply
.data
== NULL
) {
5353 * Now we can use the reply_data buffer.
5354 * Packet header stuff all comes from the forward message.
5356 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
5357 reply
->msg_type
= DHCPV6_RELAY_REPL
;
5358 reply
->hop_count
= packet
->dhcpv6_hop_count
;
5359 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
5360 sizeof(reply
->link_address
));
5361 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
5362 sizeof(reply
->peer_address
));
5363 reply_ofs
= (int)((char *)reply
->options
- (char *)reply
);
5366 * Get the reply option state.
5369 if (!option_state_allocate(&opt_state
, MDL
)) {
5370 log_error("dhcpv6_relay_forw: no memory for option state.");
5375 * Append the interface-id if present.
5377 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
5380 if (!evaluate_option_cache(&a_opt
, packet
,
5382 packet
->options
, NULL
,
5383 &global_scope
, oc
, MDL
)) {
5384 log_error("dhcpv6_relay_forw: error evaluating "
5388 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5389 (unsigned char *)a_opt
.data
,
5391 D6O_INTERFACE_ID
, 0)) {
5392 log_error("dhcpv6_relay_forw: error saving "
5396 data_string_forget(&a_opt
, MDL
);
5400 * Append our encapsulated stuff for caller.
5402 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5403 (unsigned char *)enc_reply
.data
,
5405 D6O_RELAY_MSG
, 0)) {
5406 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
5411 * Get the ERO if any.
5413 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
5418 if (!evaluate_option_cache(&packet_ero
, packet
,
5420 packet
->options
, NULL
,
5421 &global_scope
, oc
, MDL
) ||
5422 (packet_ero
.len
& 1)) {
5423 log_error("dhcpv6_relay_forw: error evaluating ERO.");
5427 /* Decode and apply the ERO. */
5428 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
5429 req
= getUShort(packet_ero
.data
+ i
);
5430 /* Already in the reply? */
5431 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
5434 /* Get it from the packet if present. */
5435 oc
= lookup_option(&dhcpv6_universe
,
5440 if (!evaluate_option_cache(&a_opt
, packet
,
5442 packet
->options
, NULL
,
5443 &global_scope
, oc
, MDL
)) {
5444 log_error("dhcpv6_relay_forw: error "
5445 "evaluating option %u.", req
);
5448 if (!save_option_buffer(&dhcpv6_universe
,
5451 (unsigned char *)a_opt
.data
,
5455 log_error("dhcpv6_relay_forw: error saving "
5459 data_string_forget(&a_opt
, MDL
);
5463 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
5464 sizeof(reply_data
) - reply_ofs
,
5466 required_opts_agent
, &packet_ero
);
5469 * Return our reply to the caller.
5471 reply_ret
->len
= reply_ofs
;
5472 reply_ret
->buffer
= NULL
;
5473 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
5474 log_fatal("No memory to store reply.");
5476 reply_ret
->data
= reply_ret
->buffer
->data
;
5477 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
5480 if (opt_state
!= NULL
)
5481 option_state_dereference(&opt_state
, MDL
);
5482 if (a_opt
.data
!= NULL
) {
5483 data_string_forget(&a_opt
, MDL
);
5485 if (packet_ero
.data
!= NULL
) {
5486 data_string_forget(&packet_ero
, MDL
);
5488 if (enc_reply
.data
!= NULL
) {
5489 data_string_forget(&enc_reply
, MDL
);
5491 if (enc_opt_data
.data
!= NULL
) {
5492 data_string_forget(&enc_opt_data
, MDL
);
5494 if (enc_packet
!= NULL
) {
5495 packet_dereference(&enc_packet
, MDL
);
5500 dhcpv6_discard(struct packet
*packet
) {
5501 /* INSIST(packet->msg_type > 0); */
5502 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
5504 log_debug("Discarding %s from %s; message type not handled by server",
5505 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
5506 piaddr(packet
->client_addr
));
5510 build_dhcpv6_reply(struct data_string
*reply
, struct packet
*packet
) {
5511 memset(reply
, 0, sizeof(*reply
));
5512 switch (packet
->dhcpv6_msg_type
) {
5513 case DHCPV6_SOLICIT
:
5514 dhcpv6_solicit(reply
, packet
);
5516 case DHCPV6_ADVERTISE
:
5517 dhcpv6_discard(packet
);
5519 case DHCPV6_REQUEST
:
5520 dhcpv6_request(reply
, packet
);
5522 case DHCPV6_CONFIRM
:
5523 dhcpv6_confirm(reply
, packet
);
5526 dhcpv6_renew(reply
, packet
);
5529 dhcpv6_rebind(reply
, packet
);
5532 dhcpv6_discard(packet
);
5534 case DHCPV6_RELEASE
:
5535 dhcpv6_release(reply
, packet
);
5537 case DHCPV6_DECLINE
:
5538 dhcpv6_decline(reply
, packet
);
5540 case DHCPV6_RECONFIGURE
:
5541 dhcpv6_discard(packet
);
5543 case DHCPV6_INFORMATION_REQUEST
:
5544 dhcpv6_information_request(reply
, packet
);
5546 case DHCPV6_RELAY_FORW
:
5547 dhcpv6_relay_forw(reply
, packet
);
5549 case DHCPV6_RELAY_REPL
:
5550 dhcpv6_discard(packet
);
5552 case DHCPV6_LEASEQUERY
:
5553 dhcpv6_leasequery(reply
, packet
);
5555 case DHCPV6_LEASEQUERY_REPLY
:
5556 dhcpv6_discard(packet
);
5559 /* XXX: would be nice if we had "notice" level,
5560 as syslog, for this */
5561 log_info("Discarding unknown DHCPv6 message type %d "
5562 "from %s", packet
->dhcpv6_msg_type
,
5563 piaddr(packet
->client_addr
));
5568 log_packet_in(const struct packet
*packet
) {
5569 struct data_string s
;
5571 char tmp_addr
[INET6_ADDRSTRLEN
];
5574 memset(&s
, 0, sizeof(s
));
5576 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
5577 data_string_sprintfa(&s
, "%s message from %s port %d",
5578 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
5579 piaddr(packet
->client_addr
),
5580 ntohs(packet
->client_port
));
5582 data_string_sprintfa(&s
,
5583 "Unknown message type %d from %s port %d",
5584 packet
->dhcpv6_msg_type
,
5585 piaddr(packet
->client_addr
),
5586 ntohs(packet
->client_port
));
5588 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
5589 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
5590 addr
= &packet
->dhcpv6_link_address
;
5591 data_string_sprintfa(&s
, ", link address %s",
5592 inet_ntop(AF_INET6
, addr
,
5593 tmp_addr
, sizeof(tmp_addr
)));
5594 addr
= &packet
->dhcpv6_peer_address
;
5595 data_string_sprintfa(&s
, ", peer address %s",
5596 inet_ntop(AF_INET6
, addr
,
5597 tmp_addr
, sizeof(tmp_addr
)));
5600 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
5601 data_string_sprintfa(&s
, ", transaction ID 0x%06X", tid
);
5604 oc = lookup_option(&dhcpv6_universe, packet->options,
5607 memset(&tmp_ds, 0, sizeof(tmp_ds_));
5608 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
5609 packet->options, NULL,
5610 &global_scope, oc, MDL)) {
5611 log_error("Error evaluating Client Identifier");
5613 data_strint_sprintf(&s, ", client ID %s",
5615 data_string_forget(&tmp_ds, MDL);
5621 log_info("%s", s
.data
);
5623 data_string_forget(&s
, MDL
);
5627 dhcpv6(struct packet
*packet
) {
5628 struct data_string reply
;
5629 struct sockaddr_in6 to_addr
;
5633 * Log a message that we received this packet.
5635 log_packet_in(packet
);
5638 * Build our reply packet.
5640 build_dhcpv6_reply(&reply
, packet
);
5642 if (reply
.data
!= NULL
) {
5644 * Send our reply, if we have one.
5646 memset(&to_addr
, 0, sizeof(to_addr
));
5647 to_addr
.sin6_family
= AF_INET6
;
5648 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
5649 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
5650 to_addr
.sin6_port
= local_port
;
5652 to_addr
.sin6_port
= remote_port
;
5654 /* For testing, we reply to the sending port, so we don't need a root client */
5655 to_addr
.sin6_port
= packet
->client_port
;
5656 memcpy(&to_addr
.sin6_addr
, packet
->client_addr
.iabuf
,
5657 sizeof(to_addr
.sin6_addr
));
5659 log_info("Sending %s to %s port %d",
5660 dhcpv6_type_names
[reply
.data
[0]],
5661 piaddr(packet
->client_addr
),
5662 ntohs(to_addr
.sin6_port
));
5664 send_ret
= send_packet6(packet
->interface
,
5665 reply
.data
, reply
.len
, &to_addr
);
5666 if (send_ret
!= reply
.len
) {
5667 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
5668 send_ret
, reply
.len
);
5670 data_string_forget(&reply
, MDL
);
5675 seek_shared_host(struct host_decl
**hp
, struct shared_network
*shared
) {
5676 struct host_decl
*nofixed
= NULL
;
5677 struct host_decl
*seek
, *hold
= NULL
;
5680 * Seek forward through fixed addresses for the right link.
5682 * Note: how to do this for fixed prefixes???
5684 host_reference(&hold
, *hp
, MDL
);
5685 host_dereference(hp
, MDL
);
5687 while (seek
!= NULL
) {
5688 if (seek
->fixed_addr
== NULL
)
5690 else if (fixed_matches_shared(seek
, shared
))
5693 seek
= seek
->n_ipaddr
;
5696 if ((seek
== NULL
) && (nofixed
!= NULL
))
5700 host_reference(hp
, seek
, MDL
);
5703 static isc_boolean_t
5704 fixed_matches_shared(struct host_decl
*host
, struct shared_network
*shared
) {
5705 struct subnet
*subnet
;
5706 struct data_string addr
;
5707 isc_boolean_t matched
;
5710 if (host
->fixed_addr
== NULL
)
5713 memset(&addr
, 0, sizeof(addr
));
5714 if (!evaluate_option_cache(&addr
, NULL
, NULL
, NULL
, NULL
, NULL
,
5715 &global_scope
, host
->fixed_addr
, MDL
))
5718 if (addr
.len
< 16) {
5719 data_string_forget(&addr
, MDL
);
5724 memcpy(fixed
.iabuf
, addr
.data
, 16);
5726 matched
= ISC_FALSE
;
5727 for (subnet
= shared
->subnets
; subnet
!= NULL
;
5728 subnet
= subnet
->next_sibling
) {
5729 if (addr_eq(subnet_number(fixed
, subnet
->netmask
),
5736 data_string_forget(&addr
, MDL
);