2 * Copyright (C) 2006-2013 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 subnet
*subnet
; /* Used to match fixed-addrs to subnet scopes. */
47 struct option_state
*opt_state
;
48 struct packet
*packet
;
49 struct data_string client_id
;
51 /* IA level persistent state */
54 unsigned client_resources
;
55 isc_boolean_t resources_included
;
56 isc_boolean_t static_lease
;
57 unsigned static_prefixes
;
60 struct option_state
*reply_ia
;
61 struct data_string fixed
;
63 /* IAADDR/PREFIX level persistent state */
64 struct iasubopt
*lease
;
67 * "t1", "t2", preferred, and valid lifetimes records for calculating
68 * t1 and t2 (min/max).
70 u_int32_t renew
, rebind
, prefer
, valid
;
72 /* Client-requested valid and preferred lifetimes. */
73 u_int32_t client_valid
, client_prefer
;
75 /* Chosen values to transmit for valid and preferred lifetimes. */
76 u_int32_t send_valid
, send_prefer
;
78 /* Preferred prefix length (-1 is any). */
81 /* Index into the data field that has been consumed. */
84 /* Space for the on commit statements for a fixed host */
85 struct on_star on_star
;
88 unsigned char data
[65536];
89 struct dhcpv6_packet reply
;
94 * Prototypes local to this file.
96 static int get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
97 struct data_string
*enc_opt_data
,
98 struct packet
*packet
,
99 struct option_cache
*oc
,
101 static void build_dhcpv6_reply(struct data_string
*, struct packet
*);
102 static isc_result_t
shared_network_from_packet6(struct shared_network
**shared
,
103 struct packet
*packet
);
104 static void seek_shared_host(struct host_decl
**hp
,
105 struct shared_network
*shared
);
106 static isc_boolean_t
fixed_matches_shared(struct host_decl
*host
,
107 struct shared_network
*shared
);
108 static isc_result_t
reply_process_ia_na(struct reply_state
*reply
,
109 struct option_cache
*ia
);
110 static isc_result_t
reply_process_ia_ta(struct reply_state
*reply
,
111 struct option_cache
*ia
);
112 static isc_result_t
reply_process_addr(struct reply_state
*reply
,
113 struct option_cache
*addr
);
114 static isc_boolean_t
address_is_owned(struct reply_state
*reply
,
116 static isc_boolean_t
temporary_is_available(struct reply_state
*reply
,
118 static isc_result_t
find_client_temporaries(struct reply_state
*reply
);
119 static isc_result_t
reply_process_try_addr(struct reply_state
*reply
,
121 static isc_result_t
find_client_address(struct reply_state
*reply
);
122 static isc_result_t
reply_process_is_addressed(struct reply_state
*reply
,
123 struct binding_scope
**scope
,
124 struct group
*group
);
125 static isc_result_t
reply_process_send_addr(struct reply_state
*reply
,
127 static struct iasubopt
*lease_compare(struct iasubopt
*alpha
,
128 struct iasubopt
*beta
);
129 static isc_result_t
reply_process_ia_pd(struct reply_state
*reply
,
130 struct option_cache
*ia_pd
);
131 static isc_result_t
reply_process_prefix(struct reply_state
*reply
,
132 struct option_cache
*pref
);
133 static isc_boolean_t
prefix_is_owned(struct reply_state
*reply
,
134 struct iaddrcidrnet
*pref
);
135 static isc_result_t
find_client_prefix(struct reply_state
*reply
);
136 static isc_result_t
reply_process_try_prefix(struct reply_state
*reply
,
137 struct iaddrcidrnet
*pref
);
138 static isc_result_t
reply_process_is_prefixed(struct reply_state
*reply
,
139 struct binding_scope
**scope
,
140 struct group
*group
);
141 static isc_result_t
reply_process_send_prefix(struct reply_state
*reply
,
142 struct iaddrcidrnet
*pref
);
143 static struct iasubopt
*prefix_compare(struct reply_state
*reply
,
144 struct iasubopt
*alpha
,
145 struct iasubopt
*beta
);
146 static int find_hosts_by_duid_chaddr(struct host_decl
**host
,
147 const struct data_string
*client_id
);
149 * This function returns the time since DUID time start for the
150 * given time_t value.
153 duid_time(time_t when
) {
155 * This time is modulo 2^32.
157 while ((when
- DUID_TIME_EPOCH
) > 4294967295u) {
158 /* use 2^31 to avoid spurious compiler warnings */
163 return when
- DUID_TIME_EPOCH
;
170 * This must remain the same for the lifetime of this server, because
171 * clients return the server DUID that we sent them in Request packets.
173 * We pick the server DUID like this:
175 * 1. Check dhcpd.conf - any value the administrator has configured
176 * overrides any possible values.
177 * 2. Check the leases.txt - we want to use the previous value if
179 * 3. Check if dhcpd.conf specifies a type of server DUID to use,
180 * and generate that type.
181 * 4. Generate a type 1 (time + hardware address) DUID.
183 static struct data_string server_duid
;
186 * Check if the server_duid has been set.
189 server_duid_isset(void) {
190 return (server_duid
.data
!= NULL
);
194 * Return the server_duid.
197 copy_server_duid(struct data_string
*ds
, const char *file
, int line
) {
198 data_string_copy(ds
, &server_duid
, file
, line
);
202 * Set the server DUID to a specified value. This is used when
203 * the server DUID is stored in persistent memory (basically the
207 set_server_duid(struct data_string
*new_duid
) {
208 /* INSIST(new_duid != NULL); */
209 /* INSIST(new_duid->data != NULL); */
211 if (server_duid_isset()) {
212 data_string_forget(&server_duid
, MDL
);
214 data_string_copy(&server_duid
, new_duid
, MDL
);
219 * Set the server DUID based on the D6O_SERVERID option. This handles
220 * the case where the administrator explicitly put it in the dhcpd.conf
224 set_server_duid_from_option(void) {
225 struct option_state
*opt_state
;
226 struct option_cache
*oc
;
227 struct data_string option_duid
;
228 isc_result_t ret_val
;
231 if (!option_state_allocate(&opt_state
, MDL
)) {
232 log_fatal("No memory for server DUID.");
235 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
,
236 opt_state
, &global_scope
, root_group
,
239 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
241 ret_val
= ISC_R_NOTFOUND
;
243 memset(&option_duid
, 0, sizeof(option_duid
));
244 if (!evaluate_option_cache(&option_duid
, NULL
, NULL
, NULL
,
245 opt_state
, NULL
, &global_scope
,
247 ret_val
= ISC_R_UNEXPECTED
;
249 set_server_duid(&option_duid
);
250 data_string_forget(&option_duid
, MDL
);
251 ret_val
= ISC_R_SUCCESS
;
255 option_state_dereference(&opt_state
, MDL
);
261 * DUID layout, as defined in RFC 3315, section 9.
263 * We support type 1 (hardware address plus time) and type 3 (hardware
266 * We can support type 2 for specific vendors in the future, if they
267 * publish the specification. And of course there may be additional
270 static int server_duid_type
= DUID_LLT
;
276 set_server_duid_type(int type
) {
277 server_duid_type
= type
;
281 * Generate a new server DUID. This is done if there was no DUID in
282 * the leases.txt or in the dhcpd.conf file.
285 generate_new_server_duid(void) {
286 struct interface_info
*p
;
288 struct data_string generated_duid
;
291 * Verify we have a type that we support.
293 if ((server_duid_type
!= DUID_LL
) && (server_duid_type
!= DUID_LLT
)) {
294 log_error("Invalid DUID type %d specified, "
295 "only LL and LLT types supported", server_duid_type
);
296 return DHCP_R_INVALIDARG
;
300 * Find an interface with a hardware address.
303 for (p
= interfaces
; p
!= NULL
; p
= p
->next
) {
304 if (p
->hw_address
.hlen
> 0) {
309 return ISC_R_UNEXPECTED
;
315 memset(&generated_duid
, 0, sizeof(generated_duid
));
316 if (server_duid_type
== DUID_LLT
) {
317 time_val
= duid_time(time(NULL
));
318 generated_duid
.len
= 8 + p
->hw_address
.hlen
- 1;
319 if (!buffer_allocate(&generated_duid
.buffer
,
320 generated_duid
.len
, MDL
)) {
321 log_fatal("No memory for server DUID.");
323 generated_duid
.data
= generated_duid
.buffer
->data
;
324 putUShort(generated_duid
.buffer
->data
, DUID_LLT
);
325 putUShort(generated_duid
.buffer
->data
+ 2,
326 p
->hw_address
.hbuf
[0]);
327 putULong(generated_duid
.buffer
->data
+ 4, time_val
);
328 memcpy(generated_duid
.buffer
->data
+ 8,
329 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
330 } else if (server_duid_type
== DUID_LL
) {
331 generated_duid
.len
= 4 + p
->hw_address
.hlen
- 1;
332 if (!buffer_allocate(&generated_duid
.buffer
,
333 generated_duid
.len
, MDL
)) {
334 log_fatal("No memory for server DUID.");
336 generated_duid
.data
= generated_duid
.buffer
->data
;
337 putUShort(generated_duid
.buffer
->data
, DUID_LL
);
338 putUShort(generated_duid
.buffer
->data
+ 2,
339 p
->hw_address
.hbuf
[0]);
340 memcpy(generated_duid
.buffer
->data
+ 4,
341 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
343 log_fatal("Unsupported server DUID type %d.", server_duid_type
);
346 set_server_duid(&generated_duid
);
347 data_string_forget(&generated_duid
, MDL
);
349 return ISC_R_SUCCESS
;
353 * Get the client identifier from the packet.
356 get_client_id(struct packet
*packet
, struct data_string
*client_id
) {
357 struct option_cache
*oc
;
360 * Verify our client_id structure is empty.
362 if ((client_id
->data
!= NULL
) || (client_id
->len
!= 0)) {
363 return DHCP_R_INVALIDARG
;
366 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_CLIENTID
);
368 return ISC_R_NOTFOUND
;
371 if (!evaluate_option_cache(client_id
, packet
, NULL
, NULL
,
372 packet
->options
, NULL
,
373 &global_scope
, oc
, MDL
)) {
374 return ISC_R_FAILURE
;
377 return ISC_R_SUCCESS
;
381 * Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
383 * Servers MUST discard any Solicit messages that do not include a
384 * Client Identifier option or that do include a Server Identifier
388 valid_client_msg(struct packet
*packet
, struct data_string
*client_id
) {
390 struct option_cache
*oc
;
391 struct data_string data
;
394 memset(client_id
, 0, sizeof(*client_id
));
395 memset(&data
, 0, sizeof(data
));
397 switch (get_client_id(packet
, client_id
)) {
401 log_debug("Discarding %s from %s; "
402 "client identifier missing",
403 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
404 piaddr(packet
->client_addr
));
407 log_error("Error processing %s from %s; "
408 "unable to evaluate Client Identifier",
409 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
410 piaddr(packet
->client_addr
));
415 * Required by RFC 3315, section 15.
417 if (packet
->unicast
) {
418 log_debug("Discarding %s from %s; packet sent unicast "
420 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
421 piaddr(packet
->client_addr
),
422 print_hex_1(client_id
->len
, client_id
->data
, 60));
427 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
429 if (evaluate_option_cache(&data
, packet
, NULL
, NULL
,
430 packet
->options
, NULL
,
431 &global_scope
, oc
, MDL
)) {
432 log_debug("Discarding %s from %s; "
433 "server identifier found "
434 "(CLIENTID %s, SERVERID %s)",
435 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
436 piaddr(packet
->client_addr
),
437 print_hex_1(client_id
->len
,
438 client_id
->data
, 60),
439 print_hex_2(data
.len
,
442 log_debug("Discarding %s from %s; "
443 "server identifier found "
445 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
446 print_hex_1(client_id
->len
,
447 client_id
->data
, 60),
448 piaddr(packet
->client_addr
));
458 data_string_forget(&data
, MDL
);
461 if (client_id
->len
> 0) {
462 data_string_forget(client_id
, MDL
);
469 * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
470 * 15.9 (slightly different wording, but same meaning):
472 * Servers MUST discard any received Request message that meet any of
473 * the following conditions:
475 * - the message does not include a Server Identifier option.
476 * - the contents of the Server Identifier option do not match the
478 * - the message does not include a Client Identifier option.
481 valid_client_resp(struct packet
*packet
,
482 struct data_string
*client_id
,
483 struct data_string
*server_id
)
486 struct option_cache
*oc
;
488 /* INSIST((duid.data != NULL) && (duid.len > 0)); */
491 memset(client_id
, 0, sizeof(*client_id
));
492 memset(server_id
, 0, sizeof(*server_id
));
494 switch (get_client_id(packet
, client_id
)) {
498 log_debug("Discarding %s from %s; "
499 "client identifier missing",
500 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
501 piaddr(packet
->client_addr
));
504 log_error("Error processing %s from %s; "
505 "unable to evaluate Client Identifier",
506 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
507 piaddr(packet
->client_addr
));
511 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
513 log_debug("Discarding %s from %s: "
514 "server identifier missing (CLIENTID %s)",
515 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
516 piaddr(packet
->client_addr
),
517 print_hex_1(client_id
->len
, client_id
->data
, 60));
520 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
521 packet
->options
, NULL
,
522 &global_scope
, oc
, MDL
)) {
523 log_error("Error processing %s from %s; "
524 "unable to evaluate Server Identifier (CLIENTID %s)",
525 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
526 piaddr(packet
->client_addr
),
527 print_hex_1(client_id
->len
, client_id
->data
, 60));
530 if ((server_duid
.len
!= server_id
->len
) ||
531 (memcmp(server_duid
.data
, server_id
->data
, server_duid
.len
) != 0)) {
532 log_debug("Discarding %s from %s; "
533 "not our server identifier "
534 "(CLIENTID %s, SERVERID %s, server DUID %s)",
535 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
536 piaddr(packet
->client_addr
),
537 print_hex_1(client_id
->len
, client_id
->data
, 60),
538 print_hex_2(server_id
->len
, server_id
->data
, 60),
539 print_hex_3(server_duid
.len
, server_duid
.data
, 60));
548 if (server_id
->len
> 0) {
549 data_string_forget(server_id
, MDL
);
551 if (client_id
->len
> 0) {
552 data_string_forget(client_id
, MDL
);
559 * Information request validation, defined in RFC 3315, section 15.12:
561 * Servers MUST discard any received Information-request message that
562 * meets any of the following conditions:
564 * - The message includes a Server Identifier option and the DUID in
565 * the option does not match the server's DUID.
567 * - The message includes an IA option.
570 valid_client_info_req(struct packet
*packet
, struct data_string
*server_id
) {
572 struct option_cache
*oc
;
573 struct data_string client_id
;
574 char client_id_str
[80]; /* print_hex_1() uses maximum 60 characters,
575 plus a few more for extra information */
578 memset(server_id
, 0, sizeof(*server_id
));
579 memset(&client_id
, 0, sizeof(client_id
));
582 * Make a string that we can print out to give more
583 * information about the client if we need to.
585 * By RFC 3315, Section 18.1.5 clients SHOULD have a
586 * client-id on an Information-request packet, but it
587 * is not strictly necessary.
589 if (get_client_id(packet
, &client_id
) == ISC_R_SUCCESS
) {
590 snprintf(client_id_str
, sizeof(client_id_str
), " (CLIENTID %s)",
591 print_hex_1(client_id
.len
, client_id
.data
, 60));
592 data_string_forget(&client_id
, MDL
);
594 client_id_str
[0] = '\0';
598 * Required by RFC 3315, section 15.
600 if (packet
->unicast
) {
601 log_debug("Discarding %s from %s; packet sent unicast%s",
602 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
603 piaddr(packet
->client_addr
), client_id_str
);
607 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
609 log_debug("Discarding %s from %s; "
610 "IA_NA option present%s",
611 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
612 piaddr(packet
->client_addr
), client_id_str
);
615 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
617 log_debug("Discarding %s from %s; "
618 "IA_TA option present%s",
619 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
620 piaddr(packet
->client_addr
), client_id_str
);
623 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
625 log_debug("Discarding %s from %s; "
626 "IA_PD option present%s",
627 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
628 piaddr(packet
->client_addr
), client_id_str
);
632 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
634 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
635 packet
->options
, NULL
,
636 &global_scope
, oc
, MDL
)) {
637 log_error("Error processing %s from %s; "
638 "unable to evaluate Server Identifier%s",
639 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
640 piaddr(packet
->client_addr
), client_id_str
);
643 if ((server_duid
.len
!= server_id
->len
) ||
644 (memcmp(server_duid
.data
, server_id
->data
,
645 server_duid
.len
) != 0)) {
646 log_debug("Discarding %s from %s; "
647 "not our server identifier "
648 "(SERVERID %s, server DUID %s)%s",
649 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
650 piaddr(packet
->client_addr
),
651 print_hex_1(server_id
->len
,
652 server_id
->data
, 60),
653 print_hex_2(server_duid
.len
,
654 server_duid
.data
, 60),
665 if (server_id
->len
> 0) {
666 data_string_forget(server_id
, MDL
);
673 * Options that we want to send, in addition to what was requested
676 static const int required_opts
[] = {
683 static const int required_opts_NAA
[] = {
689 static const int required_opts_solicit
[] = {
701 static const int required_opts_agent
[] = {
706 static const int required_opts_IA
[] = {
711 static const int required_opts_IA_PD
[] = {
716 static const int required_opts_STATUS_CODE
[] = {
722 * Extracts from packet contents an IA_* option, storing the IA structure
723 * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
724 * in enc_opt_state for later lookup and evaluation. The 'offset' indicates
725 * where in the IA_* the DHCPv6 options commence.
728 get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
729 struct data_string
*enc_opt_data
,
730 struct packet
*packet
,
731 struct option_cache
*oc
,
735 * Get the raw data for the encapsulated options.
737 memset(enc_opt_data
, 0, sizeof(*enc_opt_data
));
738 if (!evaluate_option_cache(enc_opt_data
, packet
,
739 NULL
, NULL
, packet
->options
, NULL
,
740 &global_scope
, oc
, MDL
)) {
741 log_error("get_encapsulated_IA_state: "
742 "error evaluating raw option.");
745 if (enc_opt_data
->len
< offset
) {
746 log_error("get_encapsulated_IA_state: raw option too small.");
747 data_string_forget(enc_opt_data
, MDL
);
752 * Now create the option state structure, and pass it to the
753 * function that parses options.
755 *enc_opt_state
= NULL
;
756 if (!option_state_allocate(enc_opt_state
, MDL
)) {
757 log_error("get_encapsulated_IA_state: no memory for options.");
758 data_string_forget(enc_opt_data
, MDL
);
761 if (!parse_option_buffer(*enc_opt_state
,
762 enc_opt_data
->data
+ offset
,
763 enc_opt_data
->len
- offset
,
765 log_error("get_encapsulated_IA_state: error parsing options.");
766 option_state_dereference(enc_opt_state
, MDL
);
767 data_string_forget(enc_opt_data
, MDL
);
775 set_status_code(u_int16_t status_code
, const char *status_message
,
776 struct option_state
*opt_state
)
778 struct data_string d
;
781 memset(&d
, 0, sizeof(d
));
782 d
.len
= sizeof(status_code
) + strlen(status_message
);
783 if (!buffer_allocate(&d
.buffer
, d
.len
, MDL
)) {
784 log_fatal("set_status_code: no memory for status code.");
786 d
.data
= d
.buffer
->data
;
787 putUShort(d
.buffer
->data
, status_code
);
788 memcpy(d
.buffer
->data
+ sizeof(status_code
),
789 status_message
, d
.len
- sizeof(status_code
));
790 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
791 d
.buffer
, (unsigned char *)d
.data
, d
.len
,
792 D6O_STATUS_CODE
, 0)) {
793 log_error("set_status_code: error saving status code.");
798 data_string_forget(&d
, MDL
);
803 * We have a set of operations we do to set up the reply packet, which
804 * is the same for many message types.
807 start_reply(struct packet
*packet
,
808 const struct data_string
*client_id
,
809 const struct data_string
*server_id
,
810 struct option_state
**opt_state
,
811 struct dhcpv6_packet
*reply
)
813 struct option_cache
*oc
;
814 const unsigned char *server_id_data
;
818 * Build our option state for reply.
821 if (!option_state_allocate(opt_state
, MDL
)) {
822 log_error("start_reply: no memory for option_state.");
825 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
826 packet
->options
, *opt_state
,
827 &global_scope
, root_group
, NULL
, NULL
);
830 * A small bit of special handling for Solicit messages.
832 * We could move the logic into a flag, but for now just check
835 if (packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
836 reply
->msg_type
= DHCPV6_ADVERTISE
;
840 * - this message type supports rapid commit (Solicit), and
841 * - the server is configured to supply a rapid commit, and
842 * - the client requests a rapid commit,
843 * Then we add a rapid commit option, and send Reply (instead
846 oc
= lookup_option(&dhcpv6_universe
,
847 *opt_state
, D6O_RAPID_COMMIT
);
849 oc
= lookup_option(&dhcpv6_universe
,
850 packet
->options
, D6O_RAPID_COMMIT
);
852 /* Rapid-commit in action. */
853 reply
->msg_type
= DHCPV6_REPLY
;
855 /* Don't want a rapid-commit in advertise. */
856 delete_option(&dhcpv6_universe
,
857 *opt_state
, D6O_RAPID_COMMIT
);
861 reply
->msg_type
= DHCPV6_REPLY
;
862 /* Delete the rapid-commit from the sent options. */
863 oc
= lookup_option(&dhcpv6_universe
,
864 *opt_state
, D6O_RAPID_COMMIT
);
866 delete_option(&dhcpv6_universe
,
867 *opt_state
, D6O_RAPID_COMMIT
);
872 * Use the client's transaction identifier for the reply.
874 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
875 sizeof(reply
->transaction_id
));
878 * RFC 3315, section 18.2 says we need server identifier and
881 * If the server ID is defined via the configuration file, then
882 * it will already be present in the option state at this point,
883 * so we don't need to set it.
885 * If we have a server ID passed in from the caller,
886 * use that, otherwise use the global DUID.
888 oc
= lookup_option(&dhcpv6_universe
, *opt_state
, D6O_SERVERID
);
890 if (server_id
== NULL
) {
891 server_id_data
= server_duid
.data
;
892 server_id_len
= server_duid
.len
;
894 server_id_data
= server_id
->data
;
895 server_id_len
= server_id
->len
;
897 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
898 NULL
, (unsigned char *)server_id_data
,
899 server_id_len
, D6O_SERVERID
, 0)) {
900 log_error("start_reply: "
901 "error saving server identifier.");
906 if (client_id
->buffer
!= NULL
) {
907 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
909 (unsigned char *)client_id
->data
,
912 log_error("start_reply: error saving "
913 "client identifier.");
919 * If the client accepts reconfiguration, let it know that we
922 * Note: we don't actually do this yet, but DOCSIS requires we
925 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
928 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
929 NULL
, (unsigned char *)"", 0,
930 D6O_RECONF_ACCEPT
, 0)) {
931 log_error("start_reply: "
932 "error saving RECONF_ACCEPT option.");
933 option_state_dereference(opt_state
, MDL
);
942 * Try to get the IPv6 address the client asked for from the
945 * addr is the result (should be a pointer to NULL on entry)
946 * pool is the pool to search in
947 * requested_addr is the address the client wants
950 try_client_v6_address(struct iasubopt
**addr
,
951 struct ipv6_pool
*pool
,
952 const struct data_string
*requested_addr
)
954 struct in6_addr tmp_addr
;
957 if (requested_addr
->len
< sizeof(tmp_addr
)) {
958 return DHCP_R_INVALIDARG
;
960 memcpy(&tmp_addr
, requested_addr
->data
, sizeof(tmp_addr
));
961 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
)) {
962 return ISC_R_FAILURE
;
966 * The address is not covered by this (or possibly any) dynamic
969 if (!ipv6_in_pool(&tmp_addr
, pool
)) {
970 return ISC_R_ADDRNOTAVAIL
;
973 if (lease6_exists(pool
, &tmp_addr
)) {
974 return ISC_R_ADDRINUSE
;
977 result
= iasubopt_allocate(addr
, MDL
);
978 if (result
!= ISC_R_SUCCESS
) {
981 (*addr
)->addr
= tmp_addr
;
984 /* Default is soft binding for 2 minutes. */
985 result
= add_lease6(pool
, *addr
, cur_time
+ 120);
986 if (result
!= ISC_R_SUCCESS
) {
987 iasubopt_dereference(addr
, MDL
);
993 * Get an IPv6 address for the client.
995 * addr is the result (should be a pointer to NULL on entry)
996 * packet is the information about the packet from the client
997 * requested_iaaddr is a hint from the client
998 * client_id is the DUID for the client
1001 pick_v6_address(struct iasubopt
**addr
, struct shared_network
*shared_network
,
1002 const struct data_string
*client_id
)
1004 struct ipv6_pool
*p
;
1007 unsigned int attempts
;
1008 char tmp_buf
[INET6_ADDRSTRLEN
];
1011 * No address pools, we're done.
1013 if (shared_network
->ipv6_pools
== NULL
) {
1014 log_debug("Unable to pick client address: "
1015 "no IPv6 pools on this shared network");
1016 return ISC_R_NORESOURCES
;
1019 p
= shared_network
->ipv6_pools
[i
];
1021 log_debug("Unable to pick client address: "
1022 "no IPv6 address pools "
1023 "on this shared network");
1024 return ISC_R_NORESOURCES
;
1026 if (p
->pool_type
== D6O_IA_NA
) {
1032 * Otherwise try to get a lease from the first subnet possible.
1034 * We start looking at the last pool we allocated from, unless
1035 * it had a collision trying to allocate an address. This will
1036 * tend to move us into less-filled pools.
1038 start_pool
= shared_network
->last_ipv6_pool
;
1042 p
= shared_network
->ipv6_pools
[i
];
1043 if ((p
->pool_type
== D6O_IA_NA
) &&
1044 (create_lease6(p
, addr
, &attempts
, client_id
,
1045 cur_time
+ 120) == ISC_R_SUCCESS
)) {
1047 * Record the pool used (or next one if there
1052 if (shared_network
->ipv6_pools
[i
] == NULL
) {
1056 shared_network
->last_ipv6_pool
= i
;
1058 log_debug("Picking pool address %s",
1059 inet_ntop(AF_INET6
, &((*addr
)->addr
),
1060 tmp_buf
, sizeof(tmp_buf
)));
1061 return ISC_R_SUCCESS
;
1065 if (shared_network
->ipv6_pools
[i
] == NULL
) {
1068 } while (i
!= start_pool
);
1071 * If we failed to pick an IPv6 address from any of the subnets.
1072 * Presumably that means we have no addresses for the client.
1074 log_debug("Unable to pick client address: no addresses available");
1075 return ISC_R_NORESOURCES
;
1079 * Try to get the IPv6 prefix the client asked for from the
1082 * pref is the result (should be a pointer to NULL on entry)
1083 * pool is the prefix pool to search in
1084 * requested_pref is the address the client wants
1087 try_client_v6_prefix(struct iasubopt
**pref
,
1088 struct ipv6_pool
*pool
,
1089 const struct data_string
*requested_pref
)
1092 struct in6_addr tmp_pref
;
1094 isc_result_t result
;
1096 if (requested_pref
->len
< sizeof(tmp_plen
) + sizeof(tmp_pref
)) {
1097 return DHCP_R_INVALIDARG
;
1099 tmp_plen
= (int) requested_pref
->data
[0];
1100 if ((tmp_plen
< 3) || (tmp_plen
> 128) ||
1101 ((int)tmp_plen
!= pool
->units
)) {
1102 return ISC_R_FAILURE
;
1104 memcpy(&tmp_pref
, requested_pref
->data
+ 1, sizeof(tmp_pref
));
1105 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref
)) {
1106 return ISC_R_FAILURE
;
1109 memcpy(&ia
.iabuf
, &tmp_pref
, 16);
1110 if (!is_cidr_mask_valid(&ia
, (int) tmp_plen
)) {
1111 return ISC_R_FAILURE
;
1114 if (!ipv6_in_pool(&tmp_pref
, pool
)) {
1115 return ISC_R_ADDRNOTAVAIL
;
1118 if (prefix6_exists(pool
, &tmp_pref
, tmp_plen
)) {
1119 return ISC_R_ADDRINUSE
;
1122 result
= iasubopt_allocate(pref
, MDL
);
1123 if (result
!= ISC_R_SUCCESS
) {
1126 (*pref
)->addr
= tmp_pref
;
1127 (*pref
)->plen
= tmp_plen
;
1129 /* Default is soft binding for 2 minutes. */
1130 result
= add_lease6(pool
, *pref
, cur_time
+ 120);
1131 if (result
!= ISC_R_SUCCESS
) {
1132 iasubopt_dereference(pref
, MDL
);
1138 * Get an IPv6 prefix for the client.
1140 * pref is the result (should be a pointer to NULL on entry)
1141 * packet is the information about the packet from the client
1142 * requested_iaprefix is a hint from the client
1143 * plen is -1 or the requested prefix length
1144 * client_id is the DUID for the client
1147 pick_v6_prefix(struct iasubopt
**pref
, int plen
,
1148 struct shared_network
*shared_network
,
1149 const struct data_string
*client_id
)
1151 struct ipv6_pool
*p
;
1153 unsigned int attempts
;
1154 char tmp_buf
[INET6_ADDRSTRLEN
];
1157 * No prefix pools, we're done.
1159 if (shared_network
->ipv6_pools
== NULL
) {
1160 log_debug("Unable to pick client prefix: "
1161 "no IPv6 pools on this shared network");
1162 return ISC_R_NORESOURCES
;
1165 p
= shared_network
->ipv6_pools
[i
];
1167 log_debug("Unable to pick client prefix: "
1168 "no IPv6 prefix pools "
1169 "on this shared network");
1170 return ISC_R_NORESOURCES
;
1172 if (p
->pool_type
== D6O_IA_PD
) {
1178 * Otherwise try to get a prefix.
1181 p
= shared_network
->ipv6_pools
[i
];
1185 if (p
->pool_type
!= D6O_IA_PD
) {
1190 * Try only pools with the requested prefix length if any.
1192 if ((plen
>= 0) && (p
->units
!= plen
)) {
1196 if (create_prefix6(p
, pref
, &attempts
, client_id
,
1197 cur_time
+ 120) == ISC_R_SUCCESS
) {
1198 log_debug("Picking pool prefix %s/%u",
1199 inet_ntop(AF_INET6
, &((*pref
)->addr
),
1200 tmp_buf
, sizeof(tmp_buf
)),
1201 (unsigned) (*pref
)->plen
);
1202 return ISC_R_SUCCESS
;
1207 * If we failed to pick an IPv6 prefix
1208 * Presumably that means we have no prefixes for the client.
1210 log_debug("Unable to pick client prefix: no prefixes available");
1211 return ISC_R_NORESOURCES
;
1215 *! \file server/dhcpv6.c
1217 * \brief construct a reply containing information about a client's lease
1219 * lease_to_client() is called from several messages to construct a
1220 * reply that contains all that we know about the client's correct lease
1221 * (or projected lease).
1223 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1224 * send what we "may" give them on a request.
1226 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1227 * the client should really use).
1229 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1230 * Rebind out any "wrong" addresses the client sends. This means we send
1231 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1232 * possibly send the address with zeroed lifetimes.
1234 * Information-Request - No binding.
1236 * The basic structure is to traverse the client-supplied data first, and
1237 * validate and echo back any contents that can be. If the client-supplied
1238 * data does not error out (on renew/rebind as above), but we did not send
1239 * any addresses, attempt to allocate one.
1241 * At the end of the this function we call commit_leases_timed() to
1242 * fsync and rotate the file as necessary. commit_leases_timed() will
1243 * check that we have written at least one lease to the file and that
1244 * some time has passed before doing any fsync or file rewrite so we
1245 * don't bother tracking if we did a write_ia during this function.
1247 /* TODO: look at client hints for lease times */
1250 lease_to_client(struct data_string
*reply_ret
,
1251 struct packet
*packet
,
1252 const struct data_string
*client_id
,
1253 const struct data_string
*server_id
)
1255 static struct reply_state reply
;
1256 struct option_cache
*oc
;
1257 struct data_string packet_oro
;
1258 #if defined (RFC3315_PRE_ERRATA_2010_08)
1259 isc_boolean_t no_resources_avail
= ISC_FALSE
;
1262 memset(&packet_oro
, 0, sizeof(packet_oro
));
1264 /* Locate the client. */
1265 if (shared_network_from_packet6(&reply
.shared
,
1266 packet
) != ISC_R_SUCCESS
)
1270 * Initialize the reply.
1272 packet_reference(&reply
.packet
, packet
, MDL
);
1273 data_string_copy(&reply
.client_id
, client_id
, MDL
);
1275 if (!start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
1279 /* Set the write cursor to just past the reply header. */
1280 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1283 * Get the ORO from the packet, if any.
1285 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ORO
);
1287 if (!evaluate_option_cache(&packet_oro
, packet
,
1289 packet
->options
, NULL
,
1290 &global_scope
, oc
, MDL
)) {
1291 log_error("lease_to_client: error evaluating ORO.");
1297 * Find a host record that matches from the packet, if any, and is
1298 * valid for the shared network the client is on.
1300 if (find_hosts_by_uid(&reply
.host
, client_id
->data
, client_id
->len
,
1302 seek_shared_host(&reply
.host
, reply
.shared
);
1304 if ((reply
.host
== NULL
) &&
1305 find_hosts_by_option(&reply
.host
, packet
, packet
->options
, MDL
))
1306 seek_shared_host(&reply
.host
, reply
.shared
);
1309 * Check for 'hardware' matches last, as some of the synthesis methods
1310 * are not considered to be as reliable.
1312 if ((reply
.host
== NULL
) &&
1313 find_hosts_by_duid_chaddr(&reply
.host
, client_id
))
1314 seek_shared_host(&reply
.host
, reply
.shared
);
1316 /* Process the client supplied IA's onto the reply buffer. */
1318 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
1320 for (; oc
!= NULL
; oc
= oc
->next
) {
1321 isc_result_t status
;
1323 /* Start counting resources (addresses) offered. */
1324 reply
.client_resources
= 0;
1325 reply
.resources_included
= ISC_FALSE
;
1327 status
= reply_process_ia_na(&reply
, oc
);
1330 * We continue to try other IA's whether we can address
1331 * this one or not. Any other result is an immediate fail.
1333 if ((status
!= ISC_R_SUCCESS
) &&
1334 (status
!= ISC_R_NORESOURCES
))
1337 #if defined (RFC3315_PRE_ERRATA_2010_08)
1339 * If any address cannot be given to any IA, then set the
1340 * NoAddrsAvail status code.
1342 if (reply
.client_resources
== 0)
1343 no_resources_avail
= ISC_TRUE
;
1346 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
1347 for (; oc
!= NULL
; oc
= oc
->next
) {
1348 isc_result_t status
;
1350 /* Start counting resources (addresses) offered. */
1351 reply
.client_resources
= 0;
1352 reply
.resources_included
= ISC_FALSE
;
1354 status
= reply_process_ia_ta(&reply
, oc
);
1357 * We continue to try other IA's whether we can address
1358 * this one or not. Any other result is an immediate fail.
1360 if ((status
!= ISC_R_SUCCESS
) &&
1361 (status
!= ISC_R_NORESOURCES
))
1364 #if defined (RFC3315_PRE_ERRATA_2010_08)
1366 * If any address cannot be given to any IA, then set the
1367 * NoAddrsAvail status code.
1369 if (reply
.client_resources
== 0)
1370 no_resources_avail
= ISC_TRUE
;
1374 /* Same for IA_PD's. */
1376 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
1377 for (; oc
!= NULL
; oc
= oc
->next
) {
1378 isc_result_t status
;
1380 /* Start counting resources (prefixes) offered. */
1381 reply
.client_resources
= 0;
1382 reply
.resources_included
= ISC_FALSE
;
1384 status
= reply_process_ia_pd(&reply
, oc
);
1387 * We continue to try other IA_PD's whether we can address
1388 * this one or not. Any other result is an immediate fail.
1390 if ((status
!= ISC_R_SUCCESS
) &&
1391 (status
!= ISC_R_NORESOURCES
))
1396 * Make no reply if we gave no resources and is not
1397 * for Information-Request.
1399 if ((reply
.ia_count
== 0) && (reply
.pd_count
== 0)) {
1400 if (reply
.packet
->dhcpv6_msg_type
!=
1401 DHCPV6_INFORMATION_REQUEST
)
1405 * Because we only execute statements on a per-IA basis,
1406 * we need to execute statements in any non-IA reply to
1407 * source configuration.
1409 execute_statements_in_scope(NULL
, reply
.packet
, NULL
, NULL
,
1410 reply
.packet
->options
,
1411 reply
.opt_state
, &global_scope
,
1412 reply
.shared
->group
, root_group
,
1415 /* Bring in any configuration from a host record. */
1416 if (reply
.host
!= NULL
)
1417 execute_statements_in_scope(NULL
, reply
.packet
,
1419 reply
.packet
->options
,
1423 reply
.shared
->group
, NULL
);
1427 * RFC3315 section 17.2.2 (Solicit):
1429 * If the server will not assign any addresses to any IAs in a
1430 * subsequent Request from the client, the server MUST send an
1431 * Advertise message to the client that includes only a Status
1432 * Code option with code NoAddrsAvail and a status message for
1433 * the user, a Server Identifier option with the server's DUID,
1434 * and a Client Identifier option with the client's DUID.
1436 * Section 18.2.1 (Request):
1438 * If the server cannot assign any addresses to an IA in the
1439 * message from the client, the server MUST include the IA in
1440 * the Reply message with no addresses in the IA and a Status
1441 * Code option in the IA containing status code NoAddrsAvail.
1443 * Section 18.1.8 (Client Behavior):
1445 * Leave unchanged any information about addresses the client has
1446 * recorded in the IA but that were not included in the IA from
1448 * Sends a Renew/Rebind if the IA is not in the Reply message.
1450 #if defined (RFC3315_PRE_ERRATA_2010_08)
1451 if (no_resources_avail
&& (reply
.ia_count
!= 0) &&
1452 (reply
.packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
))
1454 /* Set the NoAddrsAvail status code. */
1455 if (!set_status_code(STATUS_NoAddrsAvail
,
1456 "No addresses available for this "
1457 "interface.", reply
.opt_state
)) {
1458 log_error("lease_to_client: Unable to set "
1459 "NoAddrsAvail status code.");
1463 /* Rewind the cursor to the start. */
1464 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1467 * Produce an advertise that includes only:
1473 reply
.buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
1474 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+
1478 reply
.opt_state
, reply
.packet
,
1483 * Having stored the client's IA's, store any options that
1484 * will fit in the remaining space.
1486 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+
1490 reply
.opt_state
, reply
.packet
,
1491 required_opts_solicit
,
1494 #else /* defined (RFC3315_PRE_ERRATA_2010_08) */
1496 * Having stored the client's IA's, store any options that
1497 * will fit in the remaining space.
1499 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+ reply
.cursor
,
1500 sizeof(reply
.buf
) - reply
.cursor
,
1501 reply
.opt_state
, reply
.packet
,
1502 required_opts_solicit
,
1504 #endif /* defined (RFC3315_PRE_ERRATA_2010_08) */
1506 /* Return our reply to the caller. */
1507 reply_ret
->len
= reply
.cursor
;
1508 reply_ret
->buffer
= NULL
;
1509 if (!buffer_allocate(&reply_ret
->buffer
, reply
.cursor
, MDL
)) {
1510 log_fatal("No memory to store Reply.");
1512 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
, reply
.cursor
);
1513 reply_ret
->data
= reply_ret
->buffer
->data
;
1515 /* If appropriate commit and rotate the lease file */
1516 (void) commit_leases_timed();
1520 if (reply
.shared
!= NULL
)
1521 shared_network_dereference(&reply
.shared
, MDL
);
1522 if (reply
.host
!= NULL
)
1523 host_dereference(&reply
.host
, MDL
);
1524 if (reply
.opt_state
!= NULL
)
1525 option_state_dereference(&reply
.opt_state
, MDL
);
1526 if (reply
.packet
!= NULL
)
1527 packet_dereference(&reply
.packet
, MDL
);
1528 if (reply
.client_id
.data
!= NULL
)
1529 data_string_forget(&reply
.client_id
, MDL
);
1530 if (packet_oro
.buffer
!= NULL
)
1531 data_string_forget(&packet_oro
, MDL
);
1532 reply
.renew
= reply
.rebind
= reply
.prefer
= reply
.valid
= 0;
1536 /* Process a client-supplied IA_NA. This may append options to the tail of
1537 * the reply packet being built in the reply_state structure.
1540 reply_process_ia_na(struct reply_state
*reply
, struct option_cache
*ia
) {
1541 isc_result_t status
= ISC_R_SUCCESS
;
1544 struct option_state
*packet_ia
;
1545 struct option_cache
*oc
;
1546 struct data_string ia_data
, data
;
1548 /* Initialize values that will get cleaned up on return. */
1550 memset(&ia_data
, 0, sizeof(ia_data
));
1551 memset(&data
, 0, sizeof(data
));
1553 * Note that find_client_address() may set reply->lease.
1556 /* Make sure there is at least room for the header. */
1557 if ((reply
->cursor
+ IA_NA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
1558 log_error("reply_process_ia_na: Reply too long for IA.");
1559 return ISC_R_NOSPACE
;
1563 /* Fetch the IA_NA contents. */
1564 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
1565 ia
, IA_NA_OFFSET
)) {
1566 log_error("reply_process_ia_na: error evaluating ia");
1567 status
= ISC_R_FAILURE
;
1571 /* Extract IA_NA header contents. */
1572 iaid
= getULong(ia_data
.data
);
1573 reply
->renew
= getULong(ia_data
.data
+ 4);
1574 reply
->rebind
= getULong(ia_data
.data
+ 8);
1576 /* Create an IA_NA structure. */
1577 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
1578 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
1579 log_error("reply_process_ia_na: no memory for ia.");
1580 status
= ISC_R_NOMEMORY
;
1583 reply
->ia
->ia_type
= D6O_IA_NA
;
1585 /* Cache pre-existing IA, if any. */
1586 ia_hash_lookup(&reply
->old_ia
, ia_na_active
,
1587 (unsigned char *)reply
->ia
->iaid_duid
.data
,
1588 reply
->ia
->iaid_duid
.len
, MDL
);
1591 * Create an option cache to carry the IA_NA option contents, and
1592 * execute any user-supplied values into it.
1594 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
1595 status
= ISC_R_NOMEMORY
;
1599 /* Check & cache the fixed host record. */
1600 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_addr
!= NULL
)) {
1601 struct iaddr tmp_addr
;
1603 if (!evaluate_option_cache(&reply
->fixed
, NULL
, NULL
, NULL
,
1604 NULL
, NULL
, &global_scope
,
1605 reply
->host
->fixed_addr
, MDL
)) {
1606 log_error("reply_process_ia_na: unable to evaluate "
1608 status
= ISC_R_FAILURE
;
1612 if (reply
->fixed
.len
< 16) {
1613 log_error("reply_process_ia_na: invalid fixed address.");
1614 status
= DHCP_R_INVALIDARG
;
1618 /* Find the static lease's subnet. */
1620 memcpy(tmp_addr
.iabuf
, reply
->fixed
.data
, 16);
1622 if (find_grouped_subnet(&reply
->subnet
, reply
->shared
,
1623 tmp_addr
, MDL
) == 0)
1624 log_fatal("Impossible condition at %s:%d.", MDL
);
1626 reply
->static_lease
= ISC_TRUE
;
1628 reply
->static_lease
= ISC_FALSE
;
1631 * Save the cursor position at the start of the IA, so we can
1632 * set length and adjust t1/t2 values later. We write a temporary
1633 * header out now just in case we decide to adjust the packet
1634 * within sub-process functions.
1636 ia_cursor
= reply
->cursor
;
1638 /* Initialize the IA_NA header. First the code. */
1639 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_NA
);
1642 /* Then option length. */
1643 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
1646 /* Then IA_NA header contents; IAID. */
1647 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
1650 /* We store the client's t1 for now, and may over-ride it later. */
1651 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
1654 /* We store the client's t2 for now, and may over-ride it later. */
1655 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
1659 * For each address in this IA_NA, decide what to do about it.
1663 * The client leaves unchanged any information about addresses
1664 * it has recorded but are not included ("cancel/break" below).
1665 * A not included IA ("cleanup" below) could give a Renew/Rebind.
1667 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
1668 reply
->valid
= reply
->prefer
= 0xffffffff;
1669 reply
->client_valid
= reply
->client_prefer
= 0;
1670 for (; oc
!= NULL
; oc
= oc
->next
) {
1671 status
= reply_process_addr(reply
, oc
);
1674 * Canceled means we did not allocate addresses to the
1675 * client, but we're "done" with this IA - we set a status
1676 * code. So transmit this reply, e.g., move on to the next
1679 if (status
== ISC_R_CANCELED
)
1682 if ((status
!= ISC_R_SUCCESS
) &&
1683 (status
!= ISC_R_ADDRINUSE
) &&
1684 (status
!= ISC_R_ADDRNOTAVAIL
))
1691 * If we fell through the above and never gave the client
1692 * an address, give it one now.
1694 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
1695 status
= find_client_address(reply
);
1697 if (status
== ISC_R_NORESOURCES
) {
1698 switch (reply
->packet
->dhcpv6_msg_type
) {
1699 case DHCPV6_SOLICIT
:
1701 * No address for any IA is handled
1706 case DHCPV6_REQUEST
:
1707 /* Section 18.2.1 (Request):
1709 * If the server cannot assign any addresses to
1710 * an IA in the message from the client, the
1711 * server MUST include the IA in the Reply
1712 * message with no addresses in the IA and a
1713 * Status Code option in the IA containing
1714 * status code NoAddrsAvail.
1716 option_state_dereference(&reply
->reply_ia
, MDL
);
1717 if (!option_state_allocate(&reply
->reply_ia
,
1720 log_error("reply_process_ia_na: No "
1721 "memory for option state "
1723 status
= ISC_R_NOMEMORY
;
1727 if (!set_status_code(STATUS_NoAddrsAvail
,
1728 "No addresses available "
1729 "for this interface.",
1731 log_error("reply_process_ia_na: Unable "
1732 "to set NoAddrsAvail status "
1734 status
= ISC_R_FAILURE
;
1738 status
= ISC_R_SUCCESS
;
1743 * RFC 3315 does not tell us to emit a status
1744 * code in this condition, or anything else.
1746 * If we included non-allocated addresses
1747 * (zeroed lifetimes) in an IA, then the client
1748 * will deconfigure them.
1750 * So we want to include the IA even if we
1751 * can't give it a new address if it includes
1752 * zeroed lifetime addresses.
1754 * We don't want to include the IA if we
1755 * provide zero addresses including zeroed
1758 if (reply
->resources_included
)
1759 status
= ISC_R_SUCCESS
;
1766 if (status
!= ISC_R_SUCCESS
)
1770 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
1771 sizeof(reply
->buf
) - reply
->cursor
,
1772 reply
->reply_ia
, reply
->packet
,
1773 required_opts_IA
, NULL
);
1775 /* Reset the length of this IA to match what was just written. */
1776 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
1777 reply
->cursor
- (ia_cursor
+ 4));
1780 * T1/T2 time selection is kind of weird. We actually use DHCP
1781 * (v4) scoped options as handy existing places where these might
1782 * be configured by an administrator. A value of zero tells the
1783 * client it may choose its own renewal time.
1786 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
1787 DHO_DHCP_RENEWAL_TIME
);
1789 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
1790 reply
->packet
->options
,
1791 reply
->opt_state
, &global_scope
,
1794 log_error("Invalid renewal time.");
1796 reply
->renew
= getULong(data
.data
);
1799 if (data
.data
!= NULL
)
1800 data_string_forget(&data
, MDL
);
1802 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
1806 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
1807 DHO_DHCP_REBINDING_TIME
);
1809 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
1810 reply
->packet
->options
,
1811 reply
->opt_state
, &global_scope
,
1814 log_error("Invalid rebinding time.");
1816 reply
->rebind
= getULong(data
.data
);
1819 if (data
.data
!= NULL
)
1820 data_string_forget(&data
, MDL
);
1822 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
1825 * If this is not a 'soft' binding, consume the new changes into
1826 * the database (if any have been attached to the ia_na).
1828 * Loop through the assigned dynamic addresses, referencing the
1829 * leases onto this IA_NA rather than any old ones, and updating
1830 * pool timers for each (if any).
1832 if ((status
!= ISC_R_CANCELED
) && !reply
->static_lease
&&
1833 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
1834 (reply
->ia
->num_iasubopt
!= 0)) {
1835 struct iasubopt
*tmp
;
1836 struct data_string
*ia_id
;
1839 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
1840 tmp
= reply
->ia
->iasubopt
[i
];
1842 if (tmp
->ia
!= NULL
)
1843 ia_dereference(&tmp
->ia
, MDL
);
1844 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
1846 /* Commit 'hard' bindings. */
1847 renew_lease6(tmp
->ipv6_pool
, tmp
);
1848 schedule_lease_timeout(tmp
->ipv6_pool
);
1850 /* If we have anything to do on commit do it now */
1851 if (tmp
->on_star
.on_commit
!= NULL
) {
1852 execute_statements(NULL
, reply
->packet
,
1854 reply
->packet
->options
,
1856 &reply
->lease
->scope
,
1857 tmp
->on_star
.on_commit
,
1859 executable_statement_dereference
1860 (&tmp
->on_star
.on_commit
, MDL
);
1863 #if defined (NSUPDATE)
1865 * Perform ddns updates.
1867 oc
= lookup_option(&server_universe
, reply
->opt_state
,
1870 evaluate_boolean_option_cache(NULL
, reply
->packet
,
1872 reply
->packet
->options
,
1876 ddns_updates(reply
->packet
, NULL
, NULL
,
1877 tmp
, NULL
, reply
->opt_state
);
1882 /* Remove any old ia from the hash. */
1883 if (reply
->old_ia
!= NULL
) {
1884 ia_id
= &reply
->old_ia
->iaid_duid
;
1885 ia_hash_delete(ia_na_active
,
1886 (unsigned char *)ia_id
->data
,
1888 ia_dereference(&reply
->old_ia
, MDL
);
1891 /* Put new ia into the hash. */
1892 reply
->ia
->cltt
= cur_time
;
1893 ia_id
= &reply
->ia
->iaid_duid
;
1894 ia_hash_add(ia_na_active
, (unsigned char *)ia_id
->data
,
1895 ia_id
->len
, reply
->ia
, MDL
);
1897 write_ia(reply
->ia
);
1901 * If this would be a hard binding for a static lease
1902 * run any commit statements that we have
1904 if ((status
!= ISC_R_CANCELED
) && reply
->static_lease
&&
1905 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
1906 (reply
->on_star
.on_commit
!= NULL
)) {
1907 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
1908 reply
->packet
->options
, reply
->opt_state
,
1909 NULL
, reply
->on_star
.on_commit
, NULL
);
1910 executable_statement_dereference
1911 (&reply
->on_star
.on_commit
, MDL
);
1915 if (packet_ia
!= NULL
)
1916 option_state_dereference(&packet_ia
, MDL
);
1917 if (reply
->reply_ia
!= NULL
)
1918 option_state_dereference(&reply
->reply_ia
, MDL
);
1919 if (ia_data
.data
!= NULL
)
1920 data_string_forget(&ia_data
, MDL
);
1921 if (data
.data
!= NULL
)
1922 data_string_forget(&data
, MDL
);
1923 if (reply
->ia
!= NULL
)
1924 ia_dereference(&reply
->ia
, MDL
);
1925 if (reply
->old_ia
!= NULL
)
1926 ia_dereference(&reply
->old_ia
, MDL
);
1927 if (reply
->lease
!= NULL
)
1928 iasubopt_dereference(&reply
->lease
, MDL
);
1929 if (reply
->fixed
.data
!= NULL
)
1930 data_string_forget(&reply
->fixed
, MDL
);
1931 if (reply
->subnet
!= NULL
)
1932 subnet_dereference(&reply
->subnet
, MDL
);
1933 if (reply
->on_star
.on_expiry
!= NULL
)
1934 executable_statement_dereference
1935 (&reply
->on_star
.on_expiry
, MDL
);
1936 if (reply
->on_star
.on_release
!= NULL
)
1937 executable_statement_dereference
1938 (&reply
->on_star
.on_release
, MDL
);
1941 * ISC_R_CANCELED is a status code used by the addr processing to
1942 * indicate we're replying with a status code. This is still a
1943 * success at higher layers.
1945 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
1949 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
1950 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
1951 * in the event we are replying with a status code and do not wish to process
1952 * more IAADDRs within this IA.
1955 reply_process_addr(struct reply_state
*reply
, struct option_cache
*addr
) {
1956 u_int32_t pref_life
, valid_life
;
1957 struct binding_scope
**scope
;
1958 struct group
*group
;
1959 struct subnet
*subnet
;
1960 struct iaddr tmp_addr
;
1961 struct option_cache
*oc
;
1962 struct data_string iaaddr
, data
;
1963 isc_result_t status
= ISC_R_SUCCESS
;
1965 /* Initializes values that will be cleaned up. */
1966 memset(&iaaddr
, 0, sizeof(iaaddr
));
1967 memset(&data
, 0, sizeof(data
));
1968 /* Note that reply->lease may be set by address_is_owned() */
1971 * There is no point trying to process an incoming address if there
1972 * is no room for an outgoing address.
1974 if ((reply
->cursor
+ 28) > sizeof(reply
->buf
)) {
1975 log_error("reply_process_addr: Out of room for address.");
1976 return ISC_R_NOSPACE
;
1979 /* Extract this IAADDR option. */
1980 if (!evaluate_option_cache(&iaaddr
, reply
->packet
, NULL
, NULL
,
1981 reply
->packet
->options
, NULL
, &global_scope
,
1983 (iaaddr
.len
< IAADDR_OFFSET
)) {
1984 log_error("reply_process_addr: error evaluating IAADDR.");
1985 status
= ISC_R_FAILURE
;
1989 /* The first 16 bytes are the IPv6 address. */
1990 pref_life
= getULong(iaaddr
.data
+ 16);
1991 valid_life
= getULong(iaaddr
.data
+ 20);
1993 if ((reply
->client_valid
== 0) ||
1994 (reply
->client_valid
> valid_life
))
1995 reply
->client_valid
= valid_life
;
1997 if ((reply
->client_prefer
== 0) ||
1998 (reply
->client_prefer
> pref_life
))
1999 reply
->client_prefer
= pref_life
;
2002 * Clients may choose to send :: as an address, with the idea to give
2003 * hints about preferred-lifetime or valid-lifetime.
2006 memset(tmp_addr
.iabuf
, 0, 16);
2007 if (!memcmp(iaaddr
.data
, tmp_addr
.iabuf
, 16)) {
2008 /* Status remains success; we just ignore this one. */
2012 /* tmp_addr len remains 16 */
2013 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2016 * Verify that this address is on the client's network.
2018 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
2019 subnet
= subnet
->next_sibling
) {
2020 if (addr_eq(subnet_number(tmp_addr
, subnet
->netmask
),
2025 /* Address not found on shared network. */
2026 if (subnet
== NULL
) {
2027 /* Ignore this address on 'soft' bindings. */
2028 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
2029 /* disable rapid commit */
2030 reply
->buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
2031 delete_option(&dhcpv6_universe
,
2034 /* status remains success */
2039 * RFC3315 section 18.2.1:
2041 * If the server finds that the prefix on one or more IP
2042 * addresses in any IA in the message from the client is not
2043 * appropriate for the link to which the client is connected,
2044 * the server MUST return the IA to the client with a Status
2045 * Code option with the value NotOnLink.
2047 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) {
2048 /* Rewind the IA_NA to empty. */
2049 option_state_dereference(&reply
->reply_ia
, MDL
);
2050 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2051 log_error("reply_process_addr: No memory for "
2052 "option state wipe.");
2053 status
= ISC_R_NOMEMORY
;
2057 /* Append a NotOnLink status code. */
2058 if (!set_status_code(STATUS_NotOnLink
,
2059 "Address not for use on this "
2060 "link.", reply
->reply_ia
)) {
2061 log_error("reply_process_addr: Failure "
2062 "setting status code.");
2063 status
= ISC_R_FAILURE
;
2067 /* Fin (no more IAADDRs). */
2068 status
= ISC_R_CANCELED
;
2073 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2075 * If the server finds that any of the addresses are not
2076 * appropriate for the link to which the client is attached,
2077 * the server returns the address to the client with lifetimes
2080 if ((reply
->packet
->dhcpv6_msg_type
!= DHCPV6_RENEW
) &&
2081 (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
2082 log_error("It is impossible to lease a client that is "
2083 "not sending a solicit, request, renew, or "
2085 status
= ISC_R_FAILURE
;
2089 reply
->send_prefer
= reply
->send_valid
= 0;
2093 /* Verify the address belongs to the client. */
2094 if (!address_is_owned(reply
, &tmp_addr
)) {
2096 * For solicit and request, any addresses included are
2097 * 'requested' addresses. For rebind, we actually have
2098 * no direction on what to do from 3315 section 18.2.4!
2099 * So I think the best bet is to try and give it out, and if
2100 * we can't, zero lifetimes.
2102 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
2103 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
2104 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
2105 status
= reply_process_try_addr(reply
, &tmp_addr
);
2108 * If the address is in use, or isn't in any dynamic
2109 * range, continue as normal. If any other error was
2112 if ((status
!= ISC_R_SUCCESS
) &&
2113 (status
!= ISC_R_ADDRINUSE
) &&
2114 (status
!= ISC_R_ADDRNOTAVAIL
))
2118 * If we didn't honor this lease, for solicit and
2119 * request we simply omit it from our answer. For
2120 * rebind, we send it with zeroed lifetimes.
2122 if (reply
->lease
== NULL
) {
2123 if (reply
->packet
->dhcpv6_msg_type
==
2125 reply
->send_prefer
= 0;
2126 reply
->send_valid
= 0;
2130 /* status remains success - ignore */
2134 * RFC3315 section 18.2.3:
2136 * If the server cannot find a client entry for the IA the
2137 * server returns the IA containing no addresses with a Status
2138 * Code option set to NoBinding in the Reply message.
2140 * On mismatch we (ab)use this pretending we have not the IA
2141 * as soon as we have not an address.
2143 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
2144 /* Rewind the IA_NA to empty. */
2145 option_state_dereference(&reply
->reply_ia
, MDL
);
2146 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2147 log_error("reply_process_addr: No memory for "
2148 "option state wipe.");
2149 status
= ISC_R_NOMEMORY
;
2153 /* Append a NoBinding status code. */
2154 if (!set_status_code(STATUS_NoBinding
,
2155 "Address not bound to this "
2156 "interface.", reply
->reply_ia
)) {
2157 log_error("reply_process_addr: Unable to "
2158 "attach status code.");
2159 status
= ISC_R_FAILURE
;
2163 /* Fin (no more IAADDRs). */
2164 status
= ISC_R_CANCELED
;
2167 log_error("It is impossible to lease a client that is "
2168 "not sending a solicit, request, renew, or "
2170 status
= ISC_R_FAILURE
;
2175 if (reply
->static_lease
) {
2176 if (reply
->host
== NULL
)
2177 log_fatal("Impossible condition at %s:%d.", MDL
);
2179 scope
= &global_scope
;
2180 group
= reply
->subnet
->group
;
2182 if (reply
->lease
== NULL
)
2183 log_fatal("Impossible condition at %s:%d.", MDL
);
2185 scope
= &reply
->lease
->scope
;
2186 group
= reply
->lease
->ipv6_pool
->subnet
->group
;
2190 * If client_resources is nonzero, then the reply_process_is_addressed
2191 * function has executed configuration state into the reply option
2192 * cache. We will use that valid cache to derive configuration for
2193 * whether or not to engage in additional addresses, and similar.
2195 if (reply
->client_resources
!= 0) {
2199 * Does this client have "enough" addresses already? Default
2200 * to one. Everybody gets one, and one should be enough for
2203 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2204 SV_LIMIT_ADDRS_PER_IA
);
2206 if (!evaluate_option_cache(&data
, reply
->packet
,
2208 reply
->packet
->options
,
2212 log_error("reply_process_addr: unable to "
2213 "evaluate addrs-per-ia value.");
2214 status
= ISC_R_FAILURE
;
2218 limit
= getULong(data
.data
);
2219 data_string_forget(&data
, MDL
);
2223 * If we wish to limit the client to a certain number of
2224 * addresses, then omit the address from the reply.
2226 if (reply
->client_resources
>= limit
)
2230 status
= reply_process_is_addressed(reply
, scope
, group
);
2231 if (status
!= ISC_R_SUCCESS
)
2235 status
= reply_process_send_addr(reply
, &tmp_addr
);
2238 if (iaaddr
.data
!= NULL
)
2239 data_string_forget(&iaaddr
, MDL
);
2240 if (data
.data
!= NULL
)
2241 data_string_forget(&data
, MDL
);
2242 if (reply
->lease
!= NULL
)
2243 iasubopt_dereference(&reply
->lease
, MDL
);
2249 * Verify the address belongs to the client. If we've got a host
2250 * record with a fixed address, it has to be the assigned address
2251 * (fault out all else). Otherwise it's a dynamic address, so lookup
2252 * that address and make sure it belongs to this DUID:IAID pair.
2254 static isc_boolean_t
2255 address_is_owned(struct reply_state
*reply
, struct iaddr
*addr
) {
2259 * This faults out addresses that don't match fixed addresses.
2261 if (reply
->static_lease
) {
2262 if (reply
->fixed
.data
== NULL
)
2263 log_fatal("Impossible condition at %s:%d.", MDL
);
2265 if (memcmp(addr
->iabuf
, reply
->fixed
.data
, 16) == 0)
2271 if ((reply
->old_ia
== NULL
) || (reply
->old_ia
->num_iasubopt
== 0))
2274 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2275 struct iasubopt
*tmp
;
2277 tmp
= reply
->old_ia
->iasubopt
[i
];
2279 if (memcmp(addr
->iabuf
, &tmp
->addr
, 16) == 0) {
2280 if (lease6_usable(tmp
) == ISC_FALSE
) {
2283 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
2291 /* Process a client-supplied IA_TA. This may append options to the tail of
2292 * the reply packet being built in the reply_state structure.
2295 reply_process_ia_ta(struct reply_state
*reply
, struct option_cache
*ia
) {
2296 isc_result_t status
= ISC_R_SUCCESS
;
2299 struct option_state
*packet_ia
;
2300 struct option_cache
*oc
;
2301 struct data_string ia_data
, data
;
2302 struct data_string iaaddr
;
2303 u_int32_t pref_life
, valid_life
;
2304 struct iaddr tmp_addr
;
2306 /* Initialize values that will get cleaned up on return. */
2308 memset(&ia_data
, 0, sizeof(ia_data
));
2309 memset(&data
, 0, sizeof(data
));
2310 memset(&iaaddr
, 0, sizeof(iaaddr
));
2312 /* Make sure there is at least room for the header. */
2313 if ((reply
->cursor
+ IA_TA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2314 log_error("reply_process_ia_ta: Reply too long for IA.");
2315 return ISC_R_NOSPACE
;
2319 /* Fetch the IA_TA contents. */
2320 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2321 ia
, IA_TA_OFFSET
)) {
2322 log_error("reply_process_ia_ta: error evaluating ia");
2323 status
= ISC_R_FAILURE
;
2327 /* Extract IA_TA header contents. */
2328 iaid
= getULong(ia_data
.data
);
2330 /* Create an IA_TA structure. */
2331 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2332 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2333 log_error("reply_process_ia_ta: no memory for ia.");
2334 status
= ISC_R_NOMEMORY
;
2337 reply
->ia
->ia_type
= D6O_IA_TA
;
2339 /* Cache pre-existing IA, if any. */
2340 ia_hash_lookup(&reply
->old_ia
, ia_ta_active
,
2341 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2342 reply
->ia
->iaid_duid
.len
, MDL
);
2345 * Create an option cache to carry the IA_TA option contents, and
2346 * execute any user-supplied values into it.
2348 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2349 status
= ISC_R_NOMEMORY
;
2354 * Temporary leases are dynamic by definition.
2356 reply
->static_lease
= ISC_FALSE
;
2359 * Save the cursor position at the start of the IA, so we can
2360 * set length later. We write a temporary
2361 * header out now just in case we decide to adjust the packet
2362 * within sub-process functions.
2364 ia_cursor
= reply
->cursor
;
2366 /* Initialize the IA_TA header. First the code. */
2367 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_TA
);
2370 /* Then option length. */
2371 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x04u
);
2374 /* Then IA_TA header contents; IAID. */
2375 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2379 * Deal with an IAADDR for lifetimes.
2380 * For all or none, process IAADDRs as hints.
2382 reply
->valid
= reply
->prefer
= 0xffffffff;
2383 reply
->client_valid
= reply
->client_prefer
= 0;
2384 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2385 for (; oc
!= NULL
; oc
= oc
->next
) {
2386 memset(&iaaddr
, 0, sizeof(iaaddr
));
2387 if (!evaluate_option_cache(&iaaddr
, reply
->packet
,
2389 reply
->packet
->options
, NULL
,
2390 &global_scope
, oc
, MDL
) ||
2391 (iaaddr
.len
< IAADDR_OFFSET
)) {
2392 log_error("reply_process_ia_ta: error "
2393 "evaluating IAADDR.");
2394 status
= ISC_R_FAILURE
;
2397 /* The first 16 bytes are the IPv6 address. */
2398 pref_life
= getULong(iaaddr
.data
+ 16);
2399 valid_life
= getULong(iaaddr
.data
+ 20);
2401 if ((reply
->client_valid
== 0) ||
2402 (reply
->client_valid
> valid_life
))
2403 reply
->client_valid
= valid_life
;
2405 if ((reply
->client_prefer
== 0) ||
2406 (reply
->client_prefer
> pref_life
))
2407 reply
->client_prefer
= pref_life
;
2409 /* Nothing more if something has failed. */
2410 if (status
== ISC_R_CANCELED
)
2414 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2415 if (!temporary_is_available(reply
, &tmp_addr
))
2417 status
= reply_process_is_addressed(reply
,
2418 &reply
->lease
->scope
,
2419 reply
->shared
->group
);
2420 if (status
!= ISC_R_SUCCESS
)
2422 status
= reply_process_send_addr(reply
, &tmp_addr
);
2423 if (status
!= ISC_R_SUCCESS
)
2425 if (reply
->lease
!= NULL
)
2426 iasubopt_dereference(&reply
->lease
, MDL
);
2430 /* Rewind the IA_TA to empty. */
2431 option_state_dereference(&reply
->reply_ia
, MDL
);
2432 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2433 status
= ISC_R_NOMEMORY
;
2436 status
= ISC_R_CANCELED
;
2437 reply
->client_resources
= 0;
2438 reply
->resources_included
= ISC_FALSE
;
2439 if (reply
->lease
!= NULL
)
2440 iasubopt_dereference(&reply
->lease
, MDL
);
2445 * Give the client temporary addresses.
2447 if (reply
->client_resources
!= 0)
2449 status
= find_client_temporaries(reply
);
2450 if (status
== ISC_R_NORESOURCES
) {
2451 switch (reply
->packet
->dhcpv6_msg_type
) {
2452 case DHCPV6_SOLICIT
:
2454 * No address for any IA is handled
2459 case DHCPV6_REQUEST
:
2460 /* Section 18.2.1 (Request):
2462 * If the server cannot assign any addresses to
2463 * an IA in the message from the client, the
2464 * server MUST include the IA in the Reply
2465 * message with no addresses in the IA and a
2466 * Status Code option in the IA containing
2467 * status code NoAddrsAvail.
2469 option_state_dereference(&reply
->reply_ia
, MDL
);
2470 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2471 log_error("reply_process_ia_ta: No "
2472 "memory for option state wipe.");
2473 status
= ISC_R_NOMEMORY
;
2477 if (!set_status_code(STATUS_NoAddrsAvail
,
2478 "No addresses available "
2479 "for this interface.",
2481 log_error("reply_process_ia_ta: Unable "
2482 "to set NoAddrsAvail status code.");
2483 status
= ISC_R_FAILURE
;
2487 status
= ISC_R_SUCCESS
;
2492 * We don't want to include the IA if we
2493 * provide zero addresses including zeroed
2496 if (reply
->resources_included
)
2497 status
= ISC_R_SUCCESS
;
2502 } else if (status
!= ISC_R_SUCCESS
)
2506 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2507 sizeof(reply
->buf
) - reply
->cursor
,
2508 reply
->reply_ia
, reply
->packet
,
2509 required_opts_IA
, NULL
);
2511 /* Reset the length of this IA to match what was just written. */
2512 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2513 reply
->cursor
- (ia_cursor
+ 4));
2516 * Consume the new changes into the database (if any have been
2517 * attached to the ia_ta).
2519 * Loop through the assigned dynamic addresses, referencing the
2520 * leases onto this IA_TA rather than any old ones, and updating
2521 * pool timers for each (if any).
2523 if ((status
!= ISC_R_CANCELED
) &&
2524 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
2525 (reply
->ia
->num_iasubopt
!= 0)) {
2526 struct iasubopt
*tmp
;
2527 struct data_string
*ia_id
;
2530 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2531 tmp
= reply
->ia
->iasubopt
[i
];
2533 if (tmp
->ia
!= NULL
)
2534 ia_dereference(&tmp
->ia
, MDL
);
2535 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2537 /* Commit 'hard' bindings. */
2538 renew_lease6(tmp
->ipv6_pool
, tmp
);
2539 schedule_lease_timeout(tmp
->ipv6_pool
);
2541 /* If we have anything to do on commit do it now */
2542 if (tmp
->on_star
.on_commit
!= NULL
) {
2543 execute_statements(NULL
, reply
->packet
,
2545 reply
->packet
->options
,
2547 &reply
->lease
->scope
,
2548 tmp
->on_star
.on_commit
,
2550 executable_statement_dereference
2551 (&tmp
->on_star
.on_commit
, MDL
);
2554 #if defined (NSUPDATE)
2556 * Perform ddns updates.
2558 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2561 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2563 reply
->packet
->options
,
2567 ddns_updates(reply
->packet
, NULL
, NULL
,
2568 tmp
, NULL
, reply
->opt_state
);
2573 /* Remove any old ia from the hash. */
2574 if (reply
->old_ia
!= NULL
) {
2575 ia_id
= &reply
->old_ia
->iaid_duid
;
2576 ia_hash_delete(ia_ta_active
,
2577 (unsigned char *)ia_id
->data
,
2579 ia_dereference(&reply
->old_ia
, MDL
);
2582 /* Put new ia into the hash. */
2583 reply
->ia
->cltt
= cur_time
;
2584 ia_id
= &reply
->ia
->iaid_duid
;
2585 ia_hash_add(ia_ta_active
, (unsigned char *)ia_id
->data
,
2586 ia_id
->len
, reply
->ia
, MDL
);
2588 write_ia(reply
->ia
);
2592 if (packet_ia
!= NULL
)
2593 option_state_dereference(&packet_ia
, MDL
);
2594 if (iaaddr
.data
!= NULL
)
2595 data_string_forget(&iaaddr
, MDL
);
2596 if (reply
->reply_ia
!= NULL
)
2597 option_state_dereference(&reply
->reply_ia
, MDL
);
2598 if (ia_data
.data
!= NULL
)
2599 data_string_forget(&ia_data
, MDL
);
2600 if (data
.data
!= NULL
)
2601 data_string_forget(&data
, MDL
);
2602 if (reply
->ia
!= NULL
)
2603 ia_dereference(&reply
->ia
, MDL
);
2604 if (reply
->old_ia
!= NULL
)
2605 ia_dereference(&reply
->old_ia
, MDL
);
2606 if (reply
->lease
!= NULL
)
2607 iasubopt_dereference(&reply
->lease
, MDL
);
2610 * ISC_R_CANCELED is a status code used by the addr processing to
2611 * indicate we're replying with other addresses. This is still a
2612 * success at higher layers.
2614 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2618 * Verify the temporary address is available.
2620 static isc_boolean_t
2621 temporary_is_available(struct reply_state
*reply
, struct iaddr
*addr
) {
2622 struct in6_addr tmp_addr
;
2623 struct subnet
*subnet
;
2624 struct ipv6_pool
*pool
;
2627 memcpy(&tmp_addr
, addr
->iabuf
, sizeof(tmp_addr
));
2629 * Clients may choose to send :: as an address, with the idea to give
2630 * hints about preferred-lifetime or valid-lifetime.
2631 * So this is not a request for this address.
2633 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
))
2637 * Verify that this address is on the client's network.
2639 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
2640 subnet
= subnet
->next_sibling
) {
2641 if (addr_eq(subnet_number(*addr
, subnet
->netmask
),
2646 /* Address not found on shared network. */
2651 * Check if this address is owned (must be before next step).
2653 if (address_is_owned(reply
, addr
))
2657 * Verify that this address is in a temporary pool and try to get it.
2659 if (reply
->shared
->ipv6_pools
== NULL
)
2661 for (i
= 0 ; (pool
= reply
->shared
->ipv6_pools
[i
]) != NULL
; i
++) {
2662 if (pool
->pool_type
!= D6O_IA_TA
)
2664 if (ipv6_in_pool(&tmp_addr
, pool
))
2669 if (lease6_exists(pool
, &tmp_addr
))
2671 if (iasubopt_allocate(&reply
->lease
, MDL
) != ISC_R_SUCCESS
)
2673 reply
->lease
->addr
= tmp_addr
;
2674 reply
->lease
->plen
= 0;
2675 /* Default is soft binding for 2 minutes. */
2676 if (add_lease6(pool
, reply
->lease
, cur_time
+ 120) != ISC_R_SUCCESS
)
2683 * Get a temporary address per prefix.
2686 find_client_temporaries(struct reply_state
*reply
) {
2687 struct shared_network
*shared
;
2689 struct ipv6_pool
*p
;
2690 isc_result_t status
;
2691 unsigned int attempts
;
2692 struct iaddr send_addr
;
2695 * No pools, we're done.
2697 shared
= reply
->shared
;
2698 if (shared
->ipv6_pools
== NULL
) {
2699 log_debug("Unable to get client addresses: "
2700 "no IPv6 pools on this shared network");
2701 return ISC_R_NORESOURCES
;
2704 status
= ISC_R_NORESOURCES
;
2706 p
= shared
->ipv6_pools
[i
];
2710 if (p
->pool_type
!= D6O_IA_TA
) {
2715 * Get an address in this temporary pool.
2717 status
= create_lease6(p
, &reply
->lease
, &attempts
,
2718 &reply
->client_id
, cur_time
+ 120);
2719 if (status
!= ISC_R_SUCCESS
) {
2720 log_debug("Unable to get a temporary address.");
2724 status
= reply_process_is_addressed(reply
,
2725 &reply
->lease
->scope
,
2726 reply
->lease
->ipv6_pool
->subnet
->group
);
2727 if (status
!= ISC_R_SUCCESS
) {
2731 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
2732 status
= reply_process_send_addr(reply
, &send_addr
);
2733 if (status
!= ISC_R_SUCCESS
) {
2737 * reply->lease can't be null as we use it above
2738 * add check if that changes
2740 iasubopt_dereference(&reply
->lease
, MDL
);
2744 if (reply
->lease
!= NULL
) {
2745 iasubopt_dereference(&reply
->lease
, MDL
);
2751 * This function only returns failure on 'hard' failures. If it succeeds,
2752 * it will leave a lease structure behind.
2755 reply_process_try_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
2756 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
2757 struct ipv6_pool
*pool
;
2759 struct data_string data_addr
;
2761 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
2762 (addr
== NULL
) || (reply
->lease
!= NULL
))
2763 return (DHCP_R_INVALIDARG
);
2765 if (reply
->shared
->ipv6_pools
== NULL
)
2766 return (ISC_R_ADDRNOTAVAIL
);
2768 memset(&data_addr
, 0, sizeof(data_addr
));
2769 data_addr
.len
= addr
->len
;
2770 data_addr
.data
= addr
->iabuf
;
2772 for (i
= 0 ; (pool
= reply
->shared
->ipv6_pools
[i
]) != NULL
; i
++) {
2773 if (pool
->pool_type
!= D6O_IA_NA
)
2775 status
= try_client_v6_address(&reply
->lease
, pool
,
2777 if (status
== ISC_R_SUCCESS
)
2781 /* Note that this is just pedantry. There is no allocation to free. */
2782 data_string_forget(&data_addr
, MDL
);
2783 /* Return just the most recent status... */
2787 /* Look around for an address to give the client. First, look through the
2788 * old IA for addresses we can extend. Second, try to allocate a new address.
2789 * Finally, actually add that address into the current reply IA.
2792 find_client_address(struct reply_state
*reply
) {
2793 struct iaddr send_addr
;
2794 isc_result_t status
= ISC_R_NORESOURCES
;
2795 struct iasubopt
*lease
, *best_lease
= NULL
;
2796 struct binding_scope
**scope
;
2797 struct group
*group
;
2800 if (reply
->static_lease
) {
2801 if (reply
->host
== NULL
)
2802 return DHCP_R_INVALIDARG
;
2805 memcpy(send_addr
.iabuf
, reply
->fixed
.data
, 16);
2807 scope
= &global_scope
;
2808 group
= reply
->subnet
->group
;
2812 if (reply
->old_ia
!= NULL
) {
2813 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2814 struct shared_network
*candidate_shared
;
2816 lease
= reply
->old_ia
->iasubopt
[i
];
2817 candidate_shared
= lease
->ipv6_pool
->shared_network
;
2820 * Look for the best lease on the client's shared
2823 if ((candidate_shared
== reply
->shared
) &&
2824 (lease6_usable(lease
) == ISC_TRUE
)) {
2825 best_lease
= lease_compare(lease
, best_lease
);
2830 /* Try to pick a new address if we didn't find one, or if we found an
2833 if ((best_lease
== NULL
) || (best_lease
->state
== FTS_ABANDONED
)) {
2834 status
= pick_v6_address(&reply
->lease
, reply
->shared
,
2835 &reply
->ia
->iaid_duid
);
2836 } else if (best_lease
!= NULL
) {
2837 iasubopt_reference(&reply
->lease
, best_lease
, MDL
);
2838 status
= ISC_R_SUCCESS
;
2841 /* Pick the abandoned lease as a last resort. */
2842 if ((status
== ISC_R_NORESOURCES
) && (best_lease
!= NULL
)) {
2843 /* I don't see how this is supposed to be done right now. */
2844 log_error("Reclaiming abandoned addresses is not yet "
2845 "supported. Treating this as an out of space "
2847 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
2850 /* Give up now if we didn't find a lease. */
2851 if (status
!= ISC_R_SUCCESS
)
2854 if (reply
->lease
== NULL
)
2855 log_fatal("Impossible condition at %s:%d.", MDL
);
2857 /* Draw binding scopes from the lease's binding scope, and config
2858 * from the lease's containing subnet and higher. Note that it may
2859 * be desirable to place the group attachment directly in the pool.
2861 scope
= &reply
->lease
->scope
;
2862 group
= reply
->lease
->ipv6_pool
->subnet
->group
;
2865 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
2868 status
= reply_process_is_addressed(reply
, scope
, group
);
2869 if (status
!= ISC_R_SUCCESS
)
2872 status
= reply_process_send_addr(reply
, &send_addr
);
2876 /* Once an address is found for a client, perform several common functions;
2877 * Calculate and store valid and preferred lease times, draw client options
2878 * into the option state.
2881 reply_process_is_addressed(struct reply_state
*reply
,
2882 struct binding_scope
**scope
, struct group
*group
)
2884 isc_result_t status
= ISC_R_SUCCESS
;
2885 struct data_string data
;
2886 struct option_cache
*oc
;
2887 struct option_state
*tmp_options
= NULL
;
2888 struct on_star
*on_star
;
2890 /* Initialize values we will cleanup. */
2891 memset(&data
, 0, sizeof(data
));
2894 * Find the proper on_star block to use. We use the
2895 * one in the lease if we have a lease or the one in
2896 * the reply if we don't have a lease because this is
2900 on_star
= &reply
->lease
->on_star
;
2902 on_star
= &reply
->on_star
;
2906 * Bring in the root configuration. We only do this to bring
2907 * in the on * statements, as we didn't have the lease available
2908 * we did it the first time.
2910 option_state_allocate(&tmp_options
, MDL
);
2911 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
2912 reply
->packet
->options
, tmp_options
,
2913 &global_scope
, root_group
, NULL
,
2915 if (tmp_options
!= NULL
) {
2916 option_state_dereference(&tmp_options
, MDL
);
2920 * Bring configured options into the root packet level cache - start
2921 * with the lease's closest enclosing group (passed in by the caller
2924 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
2925 reply
->packet
->options
, reply
->opt_state
,
2926 scope
, group
, root_group
, on_star
);
2929 * If there is a host record, over-ride with values configured there,
2930 * without re-evaluating configuration from the previously executed
2931 * group or its common enclosers.
2933 if (reply
->host
!= NULL
)
2934 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
2935 reply
->packet
->options
,
2936 reply
->opt_state
, scope
,
2937 reply
->host
->group
, group
,
2940 /* Determine valid lifetime. */
2941 if (reply
->client_valid
== 0)
2942 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
2944 reply
->send_valid
= reply
->client_valid
;
2946 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2947 SV_DEFAULT_LEASE_TIME
);
2949 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
2950 reply
->packet
->options
,
2954 log_error("reply_process_is_addressed: unable to "
2955 "evaluate default lease time");
2956 status
= ISC_R_FAILURE
;
2960 reply
->send_valid
= getULong(data
.data
);
2961 data_string_forget(&data
, MDL
);
2964 if (reply
->client_prefer
== 0)
2965 reply
->send_prefer
= reply
->send_valid
;
2967 reply
->send_prefer
= reply
->client_prefer
;
2969 if (reply
->send_prefer
>= reply
->send_valid
)
2970 reply
->send_prefer
= (reply
->send_valid
/ 2) +
2971 (reply
->send_valid
/ 8);
2973 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2974 SV_PREFER_LIFETIME
);
2976 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
2977 reply
->packet
->options
,
2981 log_error("reply_process_is_addressed: unable to "
2982 "evaluate preferred lease time");
2983 status
= ISC_R_FAILURE
;
2987 reply
->send_prefer
= getULong(data
.data
);
2988 data_string_forget(&data
, MDL
);
2991 /* Note lowest values for later calculation of renew/rebind times. */
2992 if (reply
->prefer
> reply
->send_prefer
)
2993 reply
->prefer
= reply
->send_prefer
;
2995 if (reply
->valid
> reply
->send_valid
)
2996 reply
->valid
= reply
->send_valid
;
3000 * XXX: Old 4.0.0 alpha code would change the host {} record
3001 * XXX: uid upon lease assignment. This was intended to cover the
3002 * XXX: case where a client first identifies itself using vendor
3003 * XXX: options in a solicit, or request, but later neglects to include
3004 * XXX: these options in a Renew or Rebind. It is not clear that this
3005 * XXX: is required, and has some startling ramifications (such as
3006 * XXX: how to recover this dynamic host {} state across restarts).
3008 if (reply
->host
!= NULL
)
3009 change_host_uid(host
, reply
->client_id
->data
,
3010 reply
->client_id
->len
);
3013 /* Perform dynamic lease related update work. */
3014 if (reply
->lease
!= NULL
) {
3015 /* Cached lifetimes */
3016 reply
->lease
->prefer
= reply
->send_prefer
;
3017 reply
->lease
->valid
= reply
->send_valid
;
3019 /* Advance (or rewind) the valid lifetime. */
3020 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
3021 reply
->lease
->soft_lifetime_end_time
=
3022 cur_time
+ reply
->send_valid
;
3023 /* Wait before renew! */
3026 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
3027 if (status
!= ISC_R_SUCCESS
) {
3028 log_fatal("reply_process_is_addressed: Unable to "
3029 "attach lease to new IA: %s",
3030 isc_result_totext(status
));
3034 * If this is a new lease, make sure it is attached somewhere.
3036 if (reply
->lease
->ia
== NULL
) {
3037 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
3041 /* Bring a copy of the relevant options into the IA scope. */
3042 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3043 reply
->packet
->options
, reply
->reply_ia
,
3044 scope
, group
, root_group
, NULL
);
3047 * And bring in host record configuration, if any, but not to overlap
3048 * the previous group or its common enclosers.
3050 if (reply
->host
!= NULL
)
3051 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3052 reply
->packet
->options
,
3053 reply
->reply_ia
, scope
,
3054 reply
->host
->group
, group
, NULL
);
3057 if (data
.data
!= NULL
)
3058 data_string_forget(&data
, MDL
);
3060 if (status
== ISC_R_SUCCESS
)
3061 reply
->client_resources
++;
3066 /* Simply send an IAADDR within the IA scope as described. */
3068 reply_process_send_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3069 isc_result_t status
= ISC_R_SUCCESS
;
3070 struct data_string data
;
3072 memset(&data
, 0, sizeof(data
));
3074 /* Now append the lease. */
3075 data
.len
= IAADDR_OFFSET
;
3076 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
3077 log_error("reply_process_send_addr: out of memory"
3078 "allocating new IAADDR buffer.");
3079 status
= ISC_R_NOMEMORY
;
3082 data
.data
= data
.buffer
->data
;
3084 memcpy(data
.buffer
->data
, addr
->iabuf
, 16);
3085 putULong(data
.buffer
->data
+ 16, reply
->send_prefer
);
3086 putULong(data
.buffer
->data
+ 20, reply
->send_valid
);
3088 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
3089 data
.buffer
, data
.buffer
->data
,
3090 data
.len
, D6O_IAADDR
, 0)) {
3091 log_error("reply_process_send_addr: unable "
3092 "to save IAADDR option");
3093 status
= ISC_R_FAILURE
;
3097 reply
->resources_included
= ISC_TRUE
;
3100 if (data
.data
!= NULL
)
3101 data_string_forget(&data
, MDL
);
3106 /* Choose the better of two leases. */
3107 static struct iasubopt
*
3108 lease_compare(struct iasubopt
*alpha
, struct iasubopt
*beta
) {
3114 switch(alpha
->state
) {
3116 switch(beta
->state
) {
3118 /* Choose the lease with the longest lifetime (most
3119 * likely the most recently allocated).
3121 if (alpha
->hard_lifetime_end_time
<
3122 beta
->hard_lifetime_end_time
)
3132 log_fatal("Impossible condition at %s:%d.", MDL
);
3137 switch (beta
->state
) {
3142 /* Choose the most recently expired lease. */
3143 if (alpha
->hard_lifetime_end_time
<
3144 beta
->hard_lifetime_end_time
)
3146 else if ((alpha
->hard_lifetime_end_time
==
3147 beta
->hard_lifetime_end_time
) &&
3148 (alpha
->soft_lifetime_end_time
<
3149 beta
->soft_lifetime_end_time
))
3158 log_fatal("Impossible condition at %s:%d.", MDL
);
3163 switch (beta
->state
) {
3169 /* Choose the lease that was abandoned longest ago. */
3170 if (alpha
->hard_lifetime_end_time
<
3171 beta
->hard_lifetime_end_time
)
3175 log_fatal("Impossible condition at %s:%d.", MDL
);
3180 log_fatal("Impossible condition at %s:%d.", MDL
);
3183 log_fatal("Triple impossible condition at %s:%d.", MDL
);
3187 /* Process a client-supplied IA_PD. This may append options to the tail of
3188 * the reply packet being built in the reply_state structure.
3191 reply_process_ia_pd(struct reply_state
*reply
, struct option_cache
*ia
) {
3192 isc_result_t status
= ISC_R_SUCCESS
;
3195 struct option_state
*packet_ia
;
3196 struct option_cache
*oc
;
3197 struct data_string ia_data
, data
;
3199 /* Initialize values that will get cleaned up on return. */
3201 memset(&ia_data
, 0, sizeof(ia_data
));
3202 memset(&data
, 0, sizeof(data
));
3204 * Note that find_client_prefix() may set reply->lease.
3207 /* Make sure there is at least room for the header. */
3208 if ((reply
->cursor
+ IA_PD_OFFSET
+ 4) > sizeof(reply
->buf
)) {
3209 log_error("reply_process_ia_pd: Reply too long for IA.");
3210 return ISC_R_NOSPACE
;
3214 /* Fetch the IA_PD contents. */
3215 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
3216 ia
, IA_PD_OFFSET
)) {
3217 log_error("reply_process_ia_pd: error evaluating ia");
3218 status
= ISC_R_FAILURE
;
3222 /* Extract IA_PD header contents. */
3223 iaid
= getULong(ia_data
.data
);
3224 reply
->renew
= getULong(ia_data
.data
+ 4);
3225 reply
->rebind
= getULong(ia_data
.data
+ 8);
3227 /* Create an IA_PD structure. */
3228 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
3229 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
3230 log_error("reply_process_ia_pd: no memory for ia.");
3231 status
= ISC_R_NOMEMORY
;
3234 reply
->ia
->ia_type
= D6O_IA_PD
;
3236 /* Cache pre-existing IA_PD, if any. */
3237 ia_hash_lookup(&reply
->old_ia
, ia_pd_active
,
3238 (unsigned char *)reply
->ia
->iaid_duid
.data
,
3239 reply
->ia
->iaid_duid
.len
, MDL
);
3242 * Create an option cache to carry the IA_PD option contents, and
3243 * execute any user-supplied values into it.
3245 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
3246 status
= ISC_R_NOMEMORY
;
3250 /* Check & count the fixed prefix host records. */
3251 reply
->static_prefixes
= 0;
3252 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_prefix
!= NULL
)) {
3253 struct iaddrcidrnetlist
*fp
;
3255 for (fp
= reply
->host
->fixed_prefix
; fp
!= NULL
;
3257 reply
->static_prefixes
+= 1;
3262 * Save the cursor position at the start of the IA_PD, so we can
3263 * set length and adjust t1/t2 values later. We write a temporary
3264 * header out now just in case we decide to adjust the packet
3265 * within sub-process functions.
3267 ia_cursor
= reply
->cursor
;
3269 /* Initialize the IA_PD header. First the code. */
3270 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_PD
);
3273 /* Then option length. */
3274 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
3277 /* Then IA_PD header contents; IAID. */
3278 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
3281 /* We store the client's t1 for now, and may over-ride it later. */
3282 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
3285 /* We store the client's t2 for now, and may over-ride it later. */
3286 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
3290 * For each prefix in this IA_PD, decide what to do about it.
3292 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAPREFIX
);
3293 reply
->valid
= reply
->prefer
= 0xffffffff;
3294 reply
->client_valid
= reply
->client_prefer
= 0;
3295 reply
->preflen
= -1;
3296 for (; oc
!= NULL
; oc
= oc
->next
) {
3297 status
= reply_process_prefix(reply
, oc
);
3300 * Canceled means we did not allocate prefixes to the
3301 * client, but we're "done" with this IA - we set a status
3302 * code. So transmit this reply, e.g., move on to the next
3305 if (status
== ISC_R_CANCELED
)
3308 if ((status
!= ISC_R_SUCCESS
) &&
3309 (status
!= ISC_R_ADDRINUSE
) &&
3310 (status
!= ISC_R_ADDRNOTAVAIL
))
3317 * If we fell through the above and never gave the client
3318 * a prefix, give it one now.
3320 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
3321 status
= find_client_prefix(reply
);
3323 if (status
== ISC_R_NORESOURCES
) {
3324 switch (reply
->packet
->dhcpv6_msg_type
) {
3325 case DHCPV6_SOLICIT
:
3327 * No prefix for any IA is handled
3332 case DHCPV6_REQUEST
:
3333 /* Same than for addresses. */
3334 option_state_dereference(&reply
->reply_ia
, MDL
);
3335 if (!option_state_allocate(&reply
->reply_ia
,
3338 log_error("reply_process_ia_pd: No "
3339 "memory for option state "
3341 status
= ISC_R_NOMEMORY
;
3345 if (!set_status_code(STATUS_NoPrefixAvail
,
3346 "No prefixes available "
3347 "for this interface.",
3349 log_error("reply_process_ia_pd: "
3351 "NoPrefixAvail status "
3353 status
= ISC_R_FAILURE
;
3357 status
= ISC_R_SUCCESS
;
3361 if (reply
->resources_included
)
3362 status
= ISC_R_SUCCESS
;
3369 if (status
!= ISC_R_SUCCESS
)
3373 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
3374 sizeof(reply
->buf
) - reply
->cursor
,
3375 reply
->reply_ia
, reply
->packet
,
3376 required_opts_IA_PD
, NULL
);
3378 /* Reset the length of this IA_PD to match what was just written. */
3379 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
3380 reply
->cursor
- (ia_cursor
+ 4));
3383 * T1/T2 time selection is kind of weird. We actually use DHCP
3384 * (v4) scoped options as handy existing places where these might
3385 * be configured by an administrator. A value of zero tells the
3386 * client it may choose its own renewal time.
3389 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
3390 DHO_DHCP_RENEWAL_TIME
);
3392 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3393 reply
->packet
->options
,
3394 reply
->opt_state
, &global_scope
,
3397 log_error("Invalid renewal time.");
3399 reply
->renew
= getULong(data
.data
);
3402 if (data
.data
!= NULL
)
3403 data_string_forget(&data
, MDL
);
3405 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
3409 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
3410 DHO_DHCP_REBINDING_TIME
);
3412 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3413 reply
->packet
->options
,
3414 reply
->opt_state
, &global_scope
,
3417 log_error("Invalid rebinding time.");
3419 reply
->rebind
= getULong(data
.data
);
3422 if (data
.data
!= NULL
)
3423 data_string_forget(&data
, MDL
);
3425 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
3428 * If this is not a 'soft' binding, consume the new changes into
3429 * the database (if any have been attached to the ia_pd).
3431 * Loop through the assigned dynamic prefixes, referencing the
3432 * prefixes onto this IA_PD rather than any old ones, and updating
3433 * prefix pool timers for each (if any).
3435 if ((status
!= ISC_R_CANCELED
) && (reply
->static_prefixes
== 0) &&
3436 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
3437 (reply
->ia
->num_iasubopt
!= 0)) {
3438 struct iasubopt
*tmp
;
3439 struct data_string
*ia_id
;
3442 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3443 tmp
= reply
->ia
->iasubopt
[i
];
3445 if (tmp
->ia
!= NULL
)
3446 ia_dereference(&tmp
->ia
, MDL
);
3447 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
3449 /* Commit 'hard' bindings. */
3450 renew_lease6(tmp
->ipv6_pool
, tmp
);
3451 schedule_lease_timeout(tmp
->ipv6_pool
);
3453 /* If we have anything to do on commit do it now */
3454 if (tmp
->on_star
.on_commit
!= NULL
) {
3455 execute_statements(NULL
, reply
->packet
,
3457 reply
->packet
->options
,
3459 &reply
->lease
->scope
,
3460 tmp
->on_star
.on_commit
,
3462 executable_statement_dereference
3463 (&tmp
->on_star
.on_commit
, MDL
);
3467 /* Remove any old ia from the hash. */
3468 if (reply
->old_ia
!= NULL
) {
3469 ia_id
= &reply
->old_ia
->iaid_duid
;
3470 ia_hash_delete(ia_pd_active
,
3471 (unsigned char *)ia_id
->data
,
3473 ia_dereference(&reply
->old_ia
, MDL
);
3476 /* Put new ia into the hash. */
3477 reply
->ia
->cltt
= cur_time
;
3478 ia_id
= &reply
->ia
->iaid_duid
;
3479 ia_hash_add(ia_pd_active
, (unsigned char *)ia_id
->data
,
3480 ia_id
->len
, reply
->ia
, MDL
);
3482 write_ia(reply
->ia
);
3486 * If this would be a hard binding for a static lease
3487 * run any commit statements that we have
3489 if ((status
!= ISC_R_CANCELED
) && reply
->static_prefixes
!= 0 &&
3490 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
3491 (reply
->on_star
.on_commit
!= NULL
)) {
3492 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
3493 reply
->packet
->options
, reply
->opt_state
,
3494 NULL
, reply
->on_star
.on_commit
, NULL
);
3495 executable_statement_dereference
3496 (&reply
->on_star
.on_commit
, MDL
);
3500 if (packet_ia
!= NULL
)
3501 option_state_dereference(&packet_ia
, MDL
);
3502 if (reply
->reply_ia
!= NULL
)
3503 option_state_dereference(&reply
->reply_ia
, MDL
);
3504 if (ia_data
.data
!= NULL
)
3505 data_string_forget(&ia_data
, MDL
);
3506 if (data
.data
!= NULL
)
3507 data_string_forget(&data
, MDL
);
3508 if (reply
->ia
!= NULL
)
3509 ia_dereference(&reply
->ia
, MDL
);
3510 if (reply
->old_ia
!= NULL
)
3511 ia_dereference(&reply
->old_ia
, MDL
);
3512 if (reply
->lease
!= NULL
)
3513 iasubopt_dereference(&reply
->lease
, MDL
);
3514 if (reply
->on_star
.on_expiry
!= NULL
)
3515 executable_statement_dereference
3516 (&reply
->on_star
.on_expiry
, MDL
);
3517 if (reply
->on_star
.on_release
!= NULL
)
3518 executable_statement_dereference
3519 (&reply
->on_star
.on_release
, MDL
);
3522 * ISC_R_CANCELED is a status code used by the prefix processing to
3523 * indicate we're replying with a status code. This is still a
3524 * success at higher layers.
3526 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
3530 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
3531 * contents into the reply's current ia_pd-scoped option cache. Returns
3532 * ISC_R_CANCELED in the event we are replying with a status code and do
3533 * not wish to process more IAPREFIXes within this IA_PD.
3536 reply_process_prefix(struct reply_state
*reply
, struct option_cache
*pref
) {
3537 u_int32_t pref_life
, valid_life
;
3538 struct binding_scope
**scope
;
3539 struct iaddrcidrnet tmp_pref
;
3540 struct option_cache
*oc
;
3541 struct data_string iapref
, data
;
3542 isc_result_t status
= ISC_R_SUCCESS
;
3544 /* Initializes values that will be cleaned up. */
3545 memset(&iapref
, 0, sizeof(iapref
));
3546 memset(&data
, 0, sizeof(data
));
3547 /* Note that reply->lease may be set by prefix_is_owned() */
3550 * There is no point trying to process an incoming prefix if there
3551 * is no room for an outgoing prefix.
3553 if ((reply
->cursor
+ 29) > sizeof(reply
->buf
)) {
3554 log_error("reply_process_prefix: Out of room for prefix.");
3555 return ISC_R_NOSPACE
;
3558 /* Extract this IAPREFIX option. */
3559 if (!evaluate_option_cache(&iapref
, reply
->packet
, NULL
, NULL
,
3560 reply
->packet
->options
, NULL
, &global_scope
,
3562 (iapref
.len
< IAPREFIX_OFFSET
)) {
3563 log_error("reply_process_prefix: error evaluating IAPREFIX.");
3564 status
= ISC_R_FAILURE
;
3569 * Layout: preferred and valid lifetimes followed by the prefix
3570 * length and the IPv6 address.
3572 pref_life
= getULong(iapref
.data
);
3573 valid_life
= getULong(iapref
.data
+ 4);
3575 if ((reply
->client_valid
== 0) ||
3576 (reply
->client_valid
> valid_life
))
3577 reply
->client_valid
= valid_life
;
3579 if ((reply
->client_prefer
== 0) ||
3580 (reply
->client_prefer
> pref_life
))
3581 reply
->client_prefer
= pref_life
;
3584 * Clients may choose to send ::/0 as a prefix, with the idea to give
3585 * hints about preferred-lifetime or valid-lifetime.
3587 tmp_pref
.lo_addr
.len
= 16;
3588 memset(tmp_pref
.lo_addr
.iabuf
, 0, 16);
3589 if ((iapref
.data
[8] == 0) &&
3590 (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0)) {
3591 /* Status remains success; we just ignore this one. */
3596 * Clients may choose to send ::/X as a prefix to specify a
3597 * preferred/requested prefix length. Note X is never zero here.
3599 tmp_pref
.bits
= (int) iapref
.data
[8];
3600 if (reply
->preflen
< 0) {
3601 /* Cache the first preferred prefix length. */
3602 reply
->preflen
= tmp_pref
.bits
;
3604 if (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0) {
3608 memcpy(tmp_pref
.lo_addr
.iabuf
, iapref
.data
+ 9, 16);
3610 /* Verify the prefix belongs to the client. */
3611 if (!prefix_is_owned(reply
, &tmp_pref
)) {
3612 /* Same than for addresses. */
3613 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
3614 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
3615 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
3616 status
= reply_process_try_prefix(reply
, &tmp_pref
);
3618 /* Either error out or skip this prefix. */
3619 if ((status
!= ISC_R_SUCCESS
) &&
3620 (status
!= ISC_R_ADDRINUSE
) &&
3621 (status
!= ISC_R_ADDRNOTAVAIL
))
3624 if (reply
->lease
== NULL
) {
3625 if (reply
->packet
->dhcpv6_msg_type
==
3627 reply
->send_prefer
= 0;
3628 reply
->send_valid
= 0;
3632 /* status remains success - ignore */
3636 * RFC3633 section 18.2.3:
3638 * If the delegating router cannot find a binding
3639 * for the requesting router's IA_PD the delegating
3640 * router returns the IA_PD containing no prefixes
3641 * with a Status Code option set to NoBinding in the
3644 * On mismatch we (ab)use this pretending we have not the IA
3645 * as soon as we have not a prefix.
3647 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
3648 /* Rewind the IA_PD to empty. */
3649 option_state_dereference(&reply
->reply_ia
, MDL
);
3650 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
3651 log_error("reply_process_prefix: No memory "
3652 "for option state wipe.");
3653 status
= ISC_R_NOMEMORY
;
3657 /* Append a NoBinding status code. */
3658 if (!set_status_code(STATUS_NoBinding
,
3659 "Prefix not bound to this "
3660 "interface.", reply
->reply_ia
)) {
3661 log_error("reply_process_prefix: Unable to "
3662 "attach status code.");
3663 status
= ISC_R_FAILURE
;
3667 /* Fin (no more IAPREFIXes). */
3668 status
= ISC_R_CANCELED
;
3671 log_error("It is impossible to lease a client that is "
3672 "not sending a solicit, request, renew, or "
3674 status
= ISC_R_FAILURE
;
3679 if (reply
->static_prefixes
> 0) {
3680 if (reply
->host
== NULL
)
3681 log_fatal("Impossible condition at %s:%d.", MDL
);
3683 scope
= &global_scope
;
3685 if (reply
->lease
== NULL
)
3686 log_fatal("Impossible condition at %s:%d.", MDL
);
3688 scope
= &reply
->lease
->scope
;
3692 * If client_resources is nonzero, then the reply_process_is_prefixed
3693 * function has executed configuration state into the reply option
3694 * cache. We will use that valid cache to derive configuration for
3695 * whether or not to engage in additional prefixes, and similar.
3697 if (reply
->client_resources
!= 0) {
3701 * Does this client have "enough" prefixes already? Default
3702 * to one. Everybody gets one, and one should be enough for
3705 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3706 SV_LIMIT_PREFS_PER_IA
);
3708 if (!evaluate_option_cache(&data
, reply
->packet
,
3710 reply
->packet
->options
,
3714 log_error("reply_process_prefix: unable to "
3715 "evaluate prefs-per-ia value.");
3716 status
= ISC_R_FAILURE
;
3720 limit
= getULong(data
.data
);
3721 data_string_forget(&data
, MDL
);
3725 * If we wish to limit the client to a certain number of
3726 * prefixes, then omit the prefix from the reply.
3728 if (reply
->client_resources
>= limit
)
3732 status
= reply_process_is_prefixed(reply
, scope
, reply
->shared
->group
);
3733 if (status
!= ISC_R_SUCCESS
)
3737 status
= reply_process_send_prefix(reply
, &tmp_pref
);
3740 if (iapref
.data
!= NULL
)
3741 data_string_forget(&iapref
, MDL
);
3742 if (data
.data
!= NULL
)
3743 data_string_forget(&data
, MDL
);
3744 if (reply
->lease
!= NULL
)
3745 iasubopt_dereference(&reply
->lease
, MDL
);
3751 * Verify the prefix belongs to the client. If we've got a host
3752 * record with fixed prefixes, it has to be an assigned prefix
3753 * (fault out all else). Otherwise it's a dynamic prefix, so lookup
3754 * that prefix and make sure it belongs to this DUID:IAID pair.
3756 static isc_boolean_t
3757 prefix_is_owned(struct reply_state
*reply
, struct iaddrcidrnet
*pref
) {
3758 struct iaddrcidrnetlist
*l
;
3762 * This faults out prefixes that don't match fixed prefixes.
3764 if (reply
->static_prefixes
> 0) {
3765 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
3766 if ((pref
->bits
== l
->cidrnet
.bits
) &&
3767 (memcmp(pref
->lo_addr
.iabuf
,
3768 l
->cidrnet
.lo_addr
.iabuf
, 16) == 0))
3774 if ((reply
->old_ia
== NULL
) ||
3775 (reply
->old_ia
->num_iasubopt
== 0))
3778 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3779 struct iasubopt
*tmp
;
3781 tmp
= reply
->old_ia
->iasubopt
[i
];
3783 if ((pref
->bits
== (int) tmp
->plen
) &&
3784 (memcmp(pref
->lo_addr
.iabuf
, &tmp
->addr
, 16) == 0)) {
3785 if (lease6_usable(tmp
) == ISC_FALSE
) {
3788 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
3797 * This function only returns failure on 'hard' failures. If it succeeds,
3798 * it will leave a prefix structure behind.
3801 reply_process_try_prefix(struct reply_state
*reply
,
3802 struct iaddrcidrnet
*pref
) {
3803 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
3804 struct ipv6_pool
*pool
;
3806 struct data_string data_pref
;
3808 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
3809 (pref
== NULL
) || (reply
->lease
!= NULL
))
3810 return (DHCP_R_INVALIDARG
);
3812 if (reply
->shared
->ipv6_pools
== NULL
)
3813 return (ISC_R_ADDRNOTAVAIL
);
3815 memset(&data_pref
, 0, sizeof(data_pref
));
3817 if (!buffer_allocate(&data_pref
.buffer
, data_pref
.len
, MDL
)) {
3818 log_error("reply_process_try_prefix: out of memory.");
3819 return (ISC_R_NOMEMORY
);
3821 data_pref
.data
= data_pref
.buffer
->data
;
3822 data_pref
.buffer
->data
[0] = (u_int8_t
) pref
->bits
;
3823 memcpy(data_pref
.buffer
->data
+ 1, pref
->lo_addr
.iabuf
, 16);
3825 for (i
= 0 ; (pool
= reply
->shared
->ipv6_pools
[i
]) != NULL
; i
++) {
3826 if (pool
->pool_type
!= D6O_IA_PD
)
3828 status
= try_client_v6_prefix(&reply
->lease
, pool
,
3830 /* If we found it in this pool (either in use or available),
3831 there is no need to look further. */
3832 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
3836 data_string_forget(&data_pref
, MDL
);
3837 /* Return just the most recent status... */
3841 /* Look around for a prefix to give the client. First, look through the old
3842 * IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
3843 * Finally, actually add that prefix into the current reply IA_PD.
3846 find_client_prefix(struct reply_state
*reply
) {
3847 struct iaddrcidrnet send_pref
;
3848 isc_result_t status
= ISC_R_NORESOURCES
;
3849 struct iasubopt
*prefix
, *best_prefix
= NULL
;
3850 struct binding_scope
**scope
;
3853 if (reply
->static_prefixes
> 0) {
3854 struct iaddrcidrnetlist
*l
;
3856 if (reply
->host
== NULL
)
3857 return DHCP_R_INVALIDARG
;
3859 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
3860 if (l
->cidrnet
.bits
== reply
->preflen
)
3865 * If no fixed prefix has the preferred length,
3866 * get the first one.
3868 l
= reply
->host
->fixed_prefix
;
3870 memcpy(&send_pref
, &l
->cidrnet
, sizeof(send_pref
));
3872 scope
= &global_scope
;
3876 if (reply
->old_ia
!= NULL
) {
3877 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3878 struct shared_network
*candidate_shared
;
3880 prefix
= reply
->old_ia
->iasubopt
[i
];
3881 candidate_shared
= prefix
->ipv6_pool
->shared_network
;
3884 * Consider this prefix if it is in a global pool or
3885 * if it is scoped in a pool under the client's shared
3888 if (((candidate_shared
== NULL
) ||
3889 (candidate_shared
== reply
->shared
)) &&
3890 (lease6_usable(prefix
) == ISC_TRUE
)) {
3891 best_prefix
= prefix_compare(reply
, prefix
,
3897 /* Try to pick a new prefix if we didn't find one, or if we found an
3900 if ((best_prefix
== NULL
) || (best_prefix
->state
== FTS_ABANDONED
)) {
3901 status
= pick_v6_prefix(&reply
->lease
, reply
->preflen
,
3902 reply
->shared
, &reply
->client_id
);
3903 } else if (best_prefix
!= NULL
) {
3904 iasubopt_reference(&reply
->lease
, best_prefix
, MDL
);
3905 status
= ISC_R_SUCCESS
;
3908 /* Pick the abandoned prefix as a last resort. */
3909 if ((status
== ISC_R_NORESOURCES
) && (best_prefix
!= NULL
)) {
3910 /* I don't see how this is supposed to be done right now. */
3911 log_error("Reclaiming abandoned prefixes is not yet "
3912 "supported. Treating this as an out of space "
3914 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
3917 /* Give up now if we didn't find a prefix. */
3918 if (status
!= ISC_R_SUCCESS
)
3921 if (reply
->lease
== NULL
)
3922 log_fatal("Impossible condition at %s:%d.", MDL
);
3924 scope
= &reply
->lease
->scope
;
3926 send_pref
.lo_addr
.len
= 16;
3927 memcpy(send_pref
.lo_addr
.iabuf
, &reply
->lease
->addr
, 16);
3928 send_pref
.bits
= (int) reply
->lease
->plen
;
3931 status
= reply_process_is_prefixed(reply
, scope
, reply
->shared
->group
);
3932 if (status
!= ISC_R_SUCCESS
)
3935 status
= reply_process_send_prefix(reply
, &send_pref
);
3939 /* Once a prefix is found for a client, perform several common functions;
3940 * Calculate and store valid and preferred prefix times, draw client options
3941 * into the option state.
3944 reply_process_is_prefixed(struct reply_state
*reply
,
3945 struct binding_scope
**scope
, struct group
*group
)
3947 isc_result_t status
= ISC_R_SUCCESS
;
3948 struct data_string data
;
3949 struct option_cache
*oc
;
3950 struct option_state
*tmp_options
= NULL
;
3951 struct on_star
*on_star
;
3953 /* Initialize values we will cleanup. */
3954 memset(&data
, 0, sizeof(data
));
3957 * Find the proper on_star block to use. We use the
3958 * one in the lease if we have a lease or the one in
3959 * the reply if we don't have a lease because this is
3963 on_star
= &reply
->lease
->on_star
;
3965 on_star
= &reply
->on_star
;
3969 * Bring in the root configuration. We only do this to bring
3970 * in the on * statements, as we didn't have the lease available
3971 * we we did it the first time.
3973 option_state_allocate(&tmp_options
, MDL
);
3974 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3975 reply
->packet
->options
, tmp_options
,
3976 &global_scope
, root_group
, NULL
,
3978 if (tmp_options
!= NULL
) {
3979 option_state_dereference(&tmp_options
, MDL
);
3983 * Bring configured options into the root packet level cache - start
3984 * with the lease's closest enclosing group (passed in by the caller
3987 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3988 reply
->packet
->options
, reply
->opt_state
,
3989 scope
, group
, root_group
, on_star
);
3992 * If there is a host record, over-ride with values configured there,
3993 * without re-evaluating configuration from the previously executed
3994 * group or its common enclosers.
3996 if (reply
->host
!= NULL
)
3997 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3998 reply
->packet
->options
,
3999 reply
->opt_state
, scope
,
4000 reply
->host
->group
, group
,
4003 /* Determine valid lifetime. */
4004 if (reply
->client_valid
== 0)
4005 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
4007 reply
->send_valid
= reply
->client_valid
;
4009 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4010 SV_DEFAULT_LEASE_TIME
);
4012 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4013 reply
->packet
->options
,
4017 log_error("reply_process_is_prefixed: unable to "
4018 "evaluate default prefix time");
4019 status
= ISC_R_FAILURE
;
4023 reply
->send_valid
= getULong(data
.data
);
4024 data_string_forget(&data
, MDL
);
4027 if (reply
->client_prefer
== 0)
4028 reply
->send_prefer
= reply
->send_valid
;
4030 reply
->send_prefer
= reply
->client_prefer
;
4032 if (reply
->send_prefer
>= reply
->send_valid
)
4033 reply
->send_prefer
= (reply
->send_valid
/ 2) +
4034 (reply
->send_valid
/ 8);
4036 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4037 SV_PREFER_LIFETIME
);
4039 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4040 reply
->packet
->options
,
4044 log_error("reply_process_is_prefixed: unable to "
4045 "evaluate preferred prefix time");
4046 status
= ISC_R_FAILURE
;
4050 reply
->send_prefer
= getULong(data
.data
);
4051 data_string_forget(&data
, MDL
);
4054 /* Note lowest values for later calculation of renew/rebind times. */
4055 if (reply
->prefer
> reply
->send_prefer
)
4056 reply
->prefer
= reply
->send_prefer
;
4058 if (reply
->valid
> reply
->send_valid
)
4059 reply
->valid
= reply
->send_valid
;
4061 /* Perform dynamic prefix related update work. */
4062 if (reply
->lease
!= NULL
) {
4063 /* Cached lifetimes */
4064 reply
->lease
->prefer
= reply
->send_prefer
;
4065 reply
->lease
->valid
= reply
->send_valid
;
4067 /* Advance (or rewind) the valid lifetime. */
4068 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
4069 reply
->lease
->soft_lifetime_end_time
=
4070 cur_time
+ reply
->send_valid
;
4071 /* Wait before renew! */
4074 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
4075 if (status
!= ISC_R_SUCCESS
) {
4076 log_fatal("reply_process_is_prefixed: Unable to "
4077 "attach prefix to new IA_PD: %s",
4078 isc_result_totext(status
));
4082 * If this is a new prefix, make sure it is attached somewhere.
4084 if (reply
->lease
->ia
== NULL
) {
4085 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
4089 /* Bring a copy of the relevant options into the IA_PD scope. */
4090 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4091 reply
->packet
->options
, reply
->reply_ia
,
4092 scope
, group
, root_group
, NULL
);
4095 * And bring in host record configuration, if any, but not to overlap
4096 * the previous group or its common enclosers.
4098 if (reply
->host
!= NULL
)
4099 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4100 reply
->packet
->options
,
4101 reply
->reply_ia
, scope
,
4102 reply
->host
->group
, group
, NULL
);
4105 if (data
.data
!= NULL
)
4106 data_string_forget(&data
, MDL
);
4108 if (status
== ISC_R_SUCCESS
)
4109 reply
->client_resources
++;
4114 /* Simply send an IAPREFIX within the IA_PD scope as described. */
4116 reply_process_send_prefix(struct reply_state
*reply
,
4117 struct iaddrcidrnet
*pref
) {
4118 isc_result_t status
= ISC_R_SUCCESS
;
4119 struct data_string data
;
4121 memset(&data
, 0, sizeof(data
));
4123 /* Now append the prefix. */
4124 data
.len
= IAPREFIX_OFFSET
;
4125 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
4126 log_error("reply_process_send_prefix: out of memory"
4127 "allocating new IAPREFIX buffer.");
4128 status
= ISC_R_NOMEMORY
;
4131 data
.data
= data
.buffer
->data
;
4133 putULong(data
.buffer
->data
, reply
->send_prefer
);
4134 putULong(data
.buffer
->data
+ 4, reply
->send_valid
);
4135 data
.buffer
->data
[8] = pref
->bits
;
4136 memcpy(data
.buffer
->data
+ 9, pref
->lo_addr
.iabuf
, 16);
4138 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
4139 data
.buffer
, data
.buffer
->data
,
4140 data
.len
, D6O_IAPREFIX
, 0)) {
4141 log_error("reply_process_send_prefix: unable "
4142 "to save IAPREFIX option");
4143 status
= ISC_R_FAILURE
;
4147 reply
->resources_included
= ISC_TRUE
;
4150 if (data
.data
!= NULL
)
4151 data_string_forget(&data
, MDL
);
4156 /* Choose the better of two prefixes. */
4157 static struct iasubopt
*
4158 prefix_compare(struct reply_state
*reply
,
4159 struct iasubopt
*alpha
, struct iasubopt
*beta
) {
4165 if (reply
->preflen
>= 0) {
4166 if ((alpha
->plen
== reply
->preflen
) &&
4167 (beta
->plen
!= reply
->preflen
))
4169 if ((beta
->plen
== reply
->preflen
) &&
4170 (alpha
->plen
!= reply
->preflen
))
4174 switch(alpha
->state
) {
4176 switch(beta
->state
) {
4178 /* Choose the prefix with the longest lifetime (most
4179 * likely the most recently allocated).
4181 if (alpha
->hard_lifetime_end_time
<
4182 beta
->hard_lifetime_end_time
)
4192 log_fatal("Impossible condition at %s:%d.", MDL
);
4197 switch (beta
->state
) {
4202 /* Choose the most recently expired prefix. */
4203 if (alpha
->hard_lifetime_end_time
<
4204 beta
->hard_lifetime_end_time
)
4206 else if ((alpha
->hard_lifetime_end_time
==
4207 beta
->hard_lifetime_end_time
) &&
4208 (alpha
->soft_lifetime_end_time
<
4209 beta
->soft_lifetime_end_time
))
4218 log_fatal("Impossible condition at %s:%d.", MDL
);
4223 switch (beta
->state
) {
4229 /* Choose the prefix that was abandoned longest ago. */
4230 if (alpha
->hard_lifetime_end_time
<
4231 beta
->hard_lifetime_end_time
)
4235 log_fatal("Impossible condition at %s:%d.", MDL
);
4240 log_fatal("Impossible condition at %s:%d.", MDL
);
4243 log_fatal("Triple impossible condition at %s:%d.", MDL
);
4248 * Solicit is how a client starts requesting addresses.
4250 * If the client asks for rapid commit, and we support it, we will
4251 * allocate the addresses and reply.
4253 * Otherwise we will send an advertise message.
4257 dhcpv6_solicit(struct data_string
*reply_ret
, struct packet
*packet
) {
4258 struct data_string client_id
;
4261 * Validate our input.
4263 if (!valid_client_msg(packet
, &client_id
)) {
4267 lease_to_client(reply_ret
, packet
, &client_id
, NULL
);
4272 data_string_forget(&client_id
, MDL
);
4276 * Request is how a client actually requests addresses.
4278 * Very similar to Solicit handling, except the server DUID is required.
4281 /* TODO: reject unicast messages, unless we set unicast option */
4283 dhcpv6_request(struct data_string
*reply_ret
, struct packet
*packet
) {
4284 struct data_string client_id
;
4285 struct data_string server_id
;
4288 * Validate our input.
4290 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
4297 lease_to_client(reply_ret
, packet
, &client_id
, &server_id
);
4302 data_string_forget(&client_id
, MDL
);
4303 data_string_forget(&server_id
, MDL
);
4306 /* Find a DHCPv6 packet's shared network from hints in the packet.
4309 shared_network_from_packet6(struct shared_network
**shared
,
4310 struct packet
*packet
)
4312 const struct packet
*chk_packet
;
4313 const struct in6_addr
*link_addr
, *first_link_addr
;
4314 struct iaddr tmp_addr
;
4315 struct subnet
*subnet
;
4316 isc_result_t status
;
4318 if ((shared
== NULL
) || (*shared
!= NULL
) || (packet
== NULL
))
4319 return DHCP_R_INVALIDARG
;
4322 * First, find the link address where the packet from the client
4323 * first appeared (if this packet was relayed).
4325 first_link_addr
= NULL
;
4326 chk_packet
= packet
->dhcpv6_container_packet
;
4327 while (chk_packet
!= NULL
) {
4328 link_addr
= &chk_packet
->dhcpv6_link_address
;
4329 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
4330 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
4331 first_link_addr
= link_addr
;
4334 chk_packet
= chk_packet
->dhcpv6_container_packet
;
4338 * If there is a relayed link address, find the subnet associated
4339 * with that, and use that to get the appropriate
4342 if (first_link_addr
!= NULL
) {
4343 tmp_addr
.len
= sizeof(*first_link_addr
);
4344 memcpy(tmp_addr
.iabuf
,
4345 first_link_addr
, sizeof(*first_link_addr
));
4347 if (!find_subnet(&subnet
, tmp_addr
, MDL
)) {
4348 log_debug("No subnet found for link-address %s.",
4350 return ISC_R_NOTFOUND
;
4352 status
= shared_network_reference(shared
,
4353 subnet
->shared_network
, MDL
);
4354 subnet_dereference(&subnet
, MDL
);
4357 * If there is no link address, we will use the interface
4358 * that this packet came in on to pick the shared_network.
4360 } else if (packet
->interface
!= NULL
) {
4361 status
= shared_network_reference(shared
,
4362 packet
->interface
->shared_network
,
4364 if (packet
->dhcpv6_container_packet
!= NULL
) {
4365 log_info("[L2 Relay] No link address in relay packet "
4366 "assuming L2 relay and using receiving "
4372 * We shouldn't be able to get here but if there is no link
4373 * address and no interface we don't know where to get the
4374 * pool from log an error and return an error.
4376 log_error("No interface and no link address "
4377 "can't determine pool");
4378 status
= DHCP_R_INVALIDARG
;
4385 * When a client thinks it might be on a new link, it sends a
4388 * From RFC3315 section 18.2.2:
4390 * When the server receives a Confirm message, the server determines
4391 * whether the addresses in the Confirm message are appropriate for the
4392 * link to which the client is attached. If all of the addresses in the
4393 * Confirm message pass this test, the server returns a status of
4394 * Success. If any of the addresses do not pass this test, the server
4395 * returns a status of NotOnLink. If the server is unable to perform
4396 * this test (for example, the server does not have information about
4397 * prefixes on the link to which the client is connected), or there were
4398 * no addresses in any of the IAs sent by the client, the server MUST
4399 * NOT send a reply to the client.
4403 dhcpv6_confirm(struct data_string
*reply_ret
, struct packet
*packet
) {
4404 struct shared_network
*shared
;
4405 struct subnet
*subnet
;
4406 struct option_cache
*ia
, *ta
, *oc
;
4407 struct data_string cli_enc_opt_data
, iaaddr
, client_id
, packet_oro
;
4408 struct option_state
*cli_enc_opt_state
, *opt_state
;
4409 struct iaddr cli_addr
;
4411 isc_boolean_t inappropriate
, has_addrs
;
4412 char reply_data
[65536];
4413 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
4414 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
4417 * Basic client message validation.
4419 memset(&client_id
, 0, sizeof(client_id
));
4420 if (!valid_client_msg(packet
, &client_id
)) {
4425 * Do not process Confirms that do not have IA's we do not recognize.
4427 ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
4428 ta
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
4429 if ((ia
== NULL
) && (ta
== NULL
))
4433 * IA_PD's are simply ignored.
4435 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
4438 * Bit of variable initialization.
4440 opt_state
= cli_enc_opt_state
= NULL
;
4441 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
4442 memset(&iaaddr
, 0, sizeof(iaaddr
));
4443 memset(&packet_oro
, 0, sizeof(packet_oro
));
4445 /* Determine what shared network the client is connected to. We
4446 * must not respond if we don't have any information about the
4447 * network the client is on.
4450 if ((shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
) ||
4454 /* If there are no recorded subnets, then we have no
4455 * information about this subnet - ignore Confirms.
4457 subnet
= shared
->subnets
;
4461 /* Are the addresses in all the IA's appropriate for that link? */
4462 has_addrs
= inappropriate
= ISC_FALSE
;
4464 while(!inappropriate
) {
4465 /* If we've reached the end of the IA_NA pass, move to the
4468 if ((pass
== D6O_IA_NA
) && (ia
== NULL
)) {
4473 /* If we've reached the end of all passes, we're done. */
4477 if (((pass
== D6O_IA_NA
) &&
4478 !get_encapsulated_IA_state(&cli_enc_opt_state
,
4480 packet
, ia
, IA_NA_OFFSET
)) ||
4481 ((pass
== D6O_IA_TA
) &&
4482 !get_encapsulated_IA_state(&cli_enc_opt_state
,
4484 packet
, ia
, IA_TA_OFFSET
))) {
4488 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
4491 for ( ; oc
!= NULL
; oc
= oc
->next
) {
4492 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
4493 packet
->options
, NULL
,
4494 &global_scope
, oc
, MDL
) ||
4495 (iaaddr
.len
< IAADDR_OFFSET
)) {
4496 log_error("dhcpv6_confirm: "
4497 "error evaluating IAADDR.");
4501 /* Copy out the IPv6 address for processing. */
4503 memcpy(cli_addr
.iabuf
, iaaddr
.data
, 16);
4505 data_string_forget(&iaaddr
, MDL
);
4507 /* Record that we've processed at least one address. */
4508 has_addrs
= ISC_TRUE
;
4510 /* Find out if any subnets cover this address. */
4511 for (subnet
= shared
->subnets
; subnet
!= NULL
;
4512 subnet
= subnet
->next_sibling
) {
4513 if (addr_eq(subnet_number(cli_addr
,
4519 /* If we reach the end of the subnet list, and no
4520 * subnet matches the client address, then it must
4521 * be inappropriate to the link (so far as our
4522 * configuration says). Once we've found one
4523 * inappropriate address, there is no reason to
4524 * continue searching.
4526 if (subnet
== NULL
) {
4527 inappropriate
= ISC_TRUE
;
4532 option_state_dereference(&cli_enc_opt_state
, MDL
);
4533 data_string_forget(&cli_enc_opt_data
, MDL
);
4535 /* Advance to the next IA_*. */
4539 /* If the client supplied no addresses, do not reply. */
4546 if (!start_reply(packet
, &client_id
, NULL
, &opt_state
, reply
)) {
4553 if (inappropriate
) {
4554 if (!set_status_code(STATUS_NotOnLink
,
4555 "Some of the addresses are not on link.",
4560 if (!set_status_code(STATUS_Success
,
4561 "All addresses still on link.",
4568 * Only one option: add it.
4570 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
4571 sizeof(reply_data
)-reply_ofs
,
4573 required_opts
, &packet_oro
);
4576 * Return our reply to the caller.
4578 reply_ret
->len
= reply_ofs
;
4579 reply_ret
->buffer
= NULL
;
4580 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
4581 log_fatal("No memory to store reply.");
4583 reply_ret
->data
= reply_ret
->buffer
->data
;
4584 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
4587 /* Cleanup any stale data strings. */
4588 if (cli_enc_opt_data
.buffer
!= NULL
)
4589 data_string_forget(&cli_enc_opt_data
, MDL
);
4590 if (iaaddr
.buffer
!= NULL
)
4591 data_string_forget(&iaaddr
, MDL
);
4592 if (client_id
.buffer
!= NULL
)
4593 data_string_forget(&client_id
, MDL
);
4594 if (packet_oro
.buffer
!= NULL
)
4595 data_string_forget(&packet_oro
, MDL
);
4597 /* Release any stale option states. */
4598 if (cli_enc_opt_state
!= NULL
)
4599 option_state_dereference(&cli_enc_opt_state
, MDL
);
4600 if (opt_state
!= NULL
)
4601 option_state_dereference(&opt_state
, MDL
);
4605 * Renew is when a client wants to extend its lease/prefix, at time T1.
4607 * We handle this the same as if the client wants a new lease/prefix,
4608 * except for the error code of when addresses don't match.
4611 /* TODO: reject unicast messages, unless we set unicast option */
4613 dhcpv6_renew(struct data_string
*reply
, struct packet
*packet
) {
4614 struct data_string client_id
;
4615 struct data_string server_id
;
4618 * Validate the request.
4620 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
4627 lease_to_client(reply
, packet
, &client_id
, &server_id
);
4632 data_string_forget(&server_id
, MDL
);
4633 data_string_forget(&client_id
, MDL
);
4637 * Rebind is when a client wants to extend its lease, at time T2.
4639 * We handle this the same as if the client wants a new lease, except
4640 * for the error code of when addresses don't match.
4644 dhcpv6_rebind(struct data_string
*reply
, struct packet
*packet
) {
4645 struct data_string client_id
;
4647 if (!valid_client_msg(packet
, &client_id
)) {
4651 lease_to_client(reply
, packet
, &client_id
, NULL
);
4653 data_string_forget(&client_id
, MDL
);
4657 ia_na_match_decline(const struct data_string
*client_id
,
4658 const struct data_string
*iaaddr
,
4659 struct iasubopt
*lease
)
4661 char tmp_addr
[INET6_ADDRSTRLEN
];
4663 log_error("Client %s reports address %s is "
4664 "already in use by another host!",
4665 print_hex_1(client_id
->len
, client_id
->data
, 60),
4666 inet_ntop(AF_INET6
, iaaddr
->data
,
4667 tmp_addr
, sizeof(tmp_addr
)));
4668 if (lease
!= NULL
) {
4669 decline_lease6(lease
->ipv6_pool
, lease
);
4670 lease
->ia
->cltt
= cur_time
;
4671 write_ia(lease
->ia
);
4676 ia_na_nomatch_decline(const struct data_string
*client_id
,
4677 const struct data_string
*iaaddr
,
4678 u_int32_t
*ia_na_id
,
4679 struct packet
*packet
,
4684 char tmp_addr
[INET6_ADDRSTRLEN
];
4685 struct option_state
*host_opt_state
;
4688 log_info("Client %s declines address %s, which is not offered to it.",
4689 print_hex_1(client_id
->len
, client_id
->data
, 60),
4690 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
4693 * Create state for this IA_NA.
4695 host_opt_state
= NULL
;
4696 if (!option_state_allocate(&host_opt_state
, MDL
)) {
4697 log_error("ia_na_nomatch_decline: out of memory "
4698 "allocating option_state.");
4702 if (!set_status_code(STATUS_NoBinding
, "Decline for unknown address.",
4708 * Insure we have enough space
4710 if (reply_len
< (*reply_ofs
+ 16)) {
4711 log_error("ia_na_nomatch_decline: "
4712 "out of space for reply packet.");
4717 * Put our status code into the reply packet.
4719 len
= store_options6(reply_data
+(*reply_ofs
)+16,
4720 reply_len
-(*reply_ofs
)-16,
4721 host_opt_state
, packet
,
4722 required_opts_STATUS_CODE
, NULL
);
4725 * Store the non-encapsulated option data for this
4726 * IA_NA into our reply packet. Defined in RFC 3315,
4730 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
4732 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
4733 /* IA_NA, copied from the client */
4734 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
4735 /* t1 and t2, odd that we need them, but here it is */
4736 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
4737 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
4740 * Get ready for next IA_NA.
4742 *reply_ofs
+= (len
+ 16);
4745 option_state_dereference(&host_opt_state
, MDL
);
4749 iterate_over_ia_na(struct data_string
*reply_ret
,
4750 struct packet
*packet
,
4751 const struct data_string
*client_id
,
4752 const struct data_string
*server_id
,
4753 const char *packet_type
,
4754 void (*ia_na_match
)(),
4755 void (*ia_na_nomatch
)())
4757 struct option_state
*opt_state
;
4758 struct host_decl
*packet_host
;
4759 struct option_cache
*ia
;
4760 struct option_cache
*oc
;
4761 /* cli_enc_... variables come from the IA_NA/IA_TA options */
4762 struct data_string cli_enc_opt_data
;
4763 struct option_state
*cli_enc_opt_state
;
4764 struct host_decl
*host
;
4765 struct option_state
*host_opt_state
;
4766 struct data_string iaaddr
;
4767 struct data_string fixed_addr
;
4768 char reply_data
[65536];
4769 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
4770 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
4771 char status_msg
[32];
4772 struct iasubopt
*lease
;
4773 struct ia_xx
*existing_ia_na
;
4775 struct data_string key
;
4779 * Initialize to empty values, in case we have to exit early.
4782 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
4783 cli_enc_opt_state
= NULL
;
4784 memset(&iaaddr
, 0, sizeof(iaaddr
));
4785 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
4786 host_opt_state
= NULL
;
4790 * Find the host record that matches from the packet, if any.
4793 if (!find_hosts_by_uid(&packet_host
,
4794 client_id
->data
, client_id
->len
, MDL
)) {
4797 * Note: In general, we don't expect a client to provide
4798 * enough information to match by option for these
4799 * types of messages, but if we don't have a UID
4800 * match we can check anyway.
4802 if (!find_hosts_by_option(&packet_host
,
4803 packet
, packet
->options
, MDL
)) {
4806 if (!find_hosts_by_duid_chaddr(&packet_host
,
4813 * Set our reply information.
4815 reply
->msg_type
= DHCPV6_REPLY
;
4816 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
4817 sizeof(reply
->transaction_id
));
4820 * Build our option state for reply.
4823 if (!option_state_allocate(&opt_state
, MDL
)) {
4824 log_error("iterate_over_ia_na: no memory for option_state.");
4827 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
4828 packet
->options
, opt_state
,
4829 &global_scope
, root_group
, NULL
, NULL
);
4832 * RFC 3315, section 18.2.7 tells us which options to include.
4834 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
4836 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
4837 (unsigned char *)server_duid
.data
,
4838 server_duid
.len
, D6O_SERVERID
, 0)) {
4839 log_error("iterate_over_ia_na: "
4840 "error saving server identifier.");
4845 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
4847 (unsigned char *)client_id
->data
,
4850 log_error("iterate_over_ia_na: "
4851 "error saving client identifier.");
4855 snprintf(status_msg
, sizeof(status_msg
), "%s received.", packet_type
);
4856 if (!set_status_code(STATUS_Success
, status_msg
, opt_state
)) {
4861 * Add our options that are not associated with any IA_NA or IA_TA.
4863 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
4864 sizeof(reply_data
)-reply_ofs
,
4866 required_opts
, NULL
);
4869 * Loop through the IA_NA reported by the client, and deal with
4870 * addresses reported as already in use.
4872 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
4873 ia
!= NULL
; ia
= ia
->next
) {
4875 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
4877 packet
, ia
, IA_NA_OFFSET
)) {
4881 iaid
= getULong(cli_enc_opt_data
.data
);
4884 * XXX: It is possible that we can get multiple addresses
4885 * sent by the client. We don't send multiple
4886 * addresses, so this indicates a client error.
4887 * We should check for multiple IAADDR options, log
4888 * if found, and set as an error.
4890 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
4893 /* no address given for this IA, ignore */
4894 option_state_dereference(&cli_enc_opt_state
, MDL
);
4895 data_string_forget(&cli_enc_opt_data
, MDL
);
4899 memset(&iaaddr
, 0, sizeof(iaaddr
));
4900 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
4901 packet
->options
, NULL
,
4902 &global_scope
, oc
, MDL
)) {
4903 log_error("iterate_over_ia_na: "
4904 "error evaluating IAADDR.");
4909 * Now we need to figure out which host record matches
4910 * this IA_NA and IAADDR (encapsulated option contents
4911 * matching a host record by option).
4913 * XXX: We don't currently track IA_NA separately, but
4914 * we will need to do this!
4917 if (!find_hosts_by_option(&host
, packet
,
4918 cli_enc_opt_state
, MDL
)) {
4919 if (packet_host
!= NULL
) {
4925 while (host
!= NULL
) {
4926 if (host
->fixed_addr
!= NULL
) {
4927 if (!evaluate_option_cache(&fixed_addr
, NULL
,
4929 NULL
, &global_scope
,
4932 log_error("iterate_over_ia_na: error "
4933 "evaluating host address.");
4936 if ((iaaddr
.len
>= 16) &&
4937 !memcmp(fixed_addr
.data
, iaaddr
.data
, 16)) {
4938 data_string_forget(&fixed_addr
, MDL
);
4941 data_string_forget(&fixed_addr
, MDL
);
4943 host
= host
->n_ipaddr
;
4946 if ((host
== NULL
) && (iaaddr
.len
>= IAADDR_OFFSET
)) {
4948 * Find existing IA_NA.
4950 if (ia_make_key(&key
, iaid
,
4951 (char *)client_id
->data
,
4953 MDL
) != ISC_R_SUCCESS
) {
4954 log_fatal("iterate_over_ia_na: no memory for "
4958 existing_ia_na
= NULL
;
4959 if (ia_hash_lookup(&existing_ia_na
, ia_na_active
,
4960 (unsigned char *)key
.data
,
4963 * Make sure this address is in the IA_NA.
4965 for (i
=0; i
<existing_ia_na
->num_iasubopt
; i
++) {
4966 struct iasubopt
*tmp
;
4967 struct in6_addr
*in6_addr
;
4969 tmp
= existing_ia_na
->iasubopt
[i
];
4970 in6_addr
= &tmp
->addr
;
4971 if (memcmp(in6_addr
,
4972 iaaddr
.data
, 16) == 0) {
4973 iasubopt_reference(&lease
,
4980 data_string_forget(&key
, MDL
);
4983 if ((host
!= NULL
) || (lease
!= NULL
)) {
4984 ia_na_match(client_id
, &iaaddr
, lease
);
4986 ia_na_nomatch(client_id
, &iaaddr
,
4987 (u_int32_t
*)cli_enc_opt_data
.data
,
4988 packet
, reply_data
, &reply_ofs
,
4989 sizeof(reply_data
));
4992 if (lease
!= NULL
) {
4993 iasubopt_dereference(&lease
, MDL
);
4996 data_string_forget(&iaaddr
, MDL
);
4997 option_state_dereference(&cli_enc_opt_state
, MDL
);
4998 data_string_forget(&cli_enc_opt_data
, MDL
);
5002 * Return our reply to the caller.
5004 reply_ret
->len
= reply_ofs
;
5005 reply_ret
->buffer
= NULL
;
5006 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5007 log_fatal("No memory to store reply.");
5009 reply_ret
->data
= reply_ret
->buffer
->data
;
5010 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5013 if (lease
!= NULL
) {
5014 iasubopt_dereference(&lease
, MDL
);
5016 if (host_opt_state
!= NULL
) {
5017 option_state_dereference(&host_opt_state
, MDL
);
5019 if (fixed_addr
.buffer
!= NULL
) {
5020 data_string_forget(&fixed_addr
, MDL
);
5022 if (iaaddr
.buffer
!= NULL
) {
5023 data_string_forget(&iaaddr
, MDL
);
5025 if (cli_enc_opt_state
!= NULL
) {
5026 option_state_dereference(&cli_enc_opt_state
, MDL
);
5028 if (cli_enc_opt_data
.buffer
!= NULL
) {
5029 data_string_forget(&cli_enc_opt_data
, MDL
);
5031 if (opt_state
!= NULL
) {
5032 option_state_dereference(&opt_state
, MDL
);
5037 * Decline means a client has detected that something else is using an
5038 * address we gave it.
5040 * Since we're only dealing with fixed leases for now, there's not
5041 * much we can do, other that log the occurrence.
5043 * When we start issuing addresses from pools, then we will have to
5044 * record our declined addresses and issue another. In general with
5045 * IPv6 there is no worry about DoS by clients exhausting space, but
5046 * we still need to be aware of this possibility.
5049 /* TODO: reject unicast messages, unless we set unicast option */
5052 dhcpv6_decline(struct data_string
*reply
, struct packet
*packet
) {
5053 struct data_string client_id
;
5054 struct data_string server_id
;
5057 * Validate our input.
5059 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5064 * Undefined for IA_PD.
5066 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5069 * And operate on each IA_NA in this packet.
5071 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
, "Decline",
5072 ia_na_match_decline
, ia_na_nomatch_decline
);
5074 data_string_forget(&server_id
, MDL
);
5075 data_string_forget(&client_id
, MDL
);
5079 ia_na_match_release(const struct data_string
*client_id
,
5080 const struct data_string
*iaaddr
,
5081 struct iasubopt
*lease
)
5083 char tmp_addr
[INET6_ADDRSTRLEN
];
5085 log_info("Client %s releases address %s",
5086 print_hex_1(client_id
->len
, client_id
->data
, 60),
5087 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5088 if (lease
!= NULL
) {
5089 release_lease6(lease
->ipv6_pool
, lease
);
5090 lease
->ia
->cltt
= cur_time
;
5091 write_ia(lease
->ia
);
5096 ia_na_nomatch_release(const struct data_string
*client_id
,
5097 const struct data_string
*iaaddr
,
5098 u_int32_t
*ia_na_id
,
5099 struct packet
*packet
,
5104 char tmp_addr
[INET6_ADDRSTRLEN
];
5105 struct option_state
*host_opt_state
;
5108 log_info("Client %s releases address %s, which is not leased to it.",
5109 print_hex_1(client_id
->len
, client_id
->data
, 60),
5110 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5113 * Create state for this IA_NA.
5115 host_opt_state
= NULL
;
5116 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5117 log_error("ia_na_nomatch_release: out of memory "
5118 "allocating option_state.");
5122 if (!set_status_code(STATUS_NoBinding
,
5123 "Release for non-leased address.",
5129 * Insure we have enough space
5131 if (reply_len
< (*reply_ofs
+ 16)) {
5132 log_error("ia_na_nomatch_release: "
5133 "out of space for reply packet.");
5138 * Put our status code into the reply packet.
5140 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5141 reply_len
-(*reply_ofs
)-16,
5142 host_opt_state
, packet
,
5143 required_opts_STATUS_CODE
, NULL
);
5146 * Store the non-encapsulated option data for this
5147 * IA_NA into our reply packet. Defined in RFC 3315,
5151 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5153 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5154 /* IA_NA, copied from the client */
5155 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5156 /* t1 and t2, odd that we need them, but here it is */
5157 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5158 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5161 * Get ready for next IA_NA.
5163 *reply_ofs
+= (len
+ 16);
5166 option_state_dereference(&host_opt_state
, MDL
);
5170 ia_pd_match_release(const struct data_string
*client_id
,
5171 const struct data_string
*iapref
,
5172 struct iasubopt
*prefix
)
5174 char tmp_addr
[INET6_ADDRSTRLEN
];
5176 log_info("Client %s releases prefix %s/%u",
5177 print_hex_1(client_id
->len
, client_id
->data
, 60),
5178 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5179 tmp_addr
, sizeof(tmp_addr
)),
5180 (unsigned) getUChar(iapref
->data
+ 8));
5181 if (prefix
!= NULL
) {
5182 release_lease6(prefix
->ipv6_pool
, prefix
);
5183 prefix
->ia
->cltt
= cur_time
;
5184 write_ia(prefix
->ia
);
5189 ia_pd_nomatch_release(const struct data_string
*client_id
,
5190 const struct data_string
*iapref
,
5191 u_int32_t
*ia_pd_id
,
5192 struct packet
*packet
,
5197 char tmp_addr
[INET6_ADDRSTRLEN
];
5198 struct option_state
*host_opt_state
;
5201 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
5202 print_hex_1(client_id
->len
, client_id
->data
, 60),
5203 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5204 tmp_addr
, sizeof(tmp_addr
)),
5205 (unsigned) getUChar(iapref
->data
+ 8));
5208 * Create state for this IA_PD.
5210 host_opt_state
= NULL
;
5211 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5212 log_error("ia_pd_nomatch_release: out of memory "
5213 "allocating option_state.");
5217 if (!set_status_code(STATUS_NoBinding
,
5218 "Release for non-leased prefix.",
5224 * Insure we have enough space
5226 if (reply_len
< (*reply_ofs
+ 16)) {
5227 log_error("ia_pd_nomatch_release: "
5228 "out of space for reply packet.");
5233 * Put our status code into the reply packet.
5235 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5236 reply_len
-(*reply_ofs
)-16,
5237 host_opt_state
, packet
,
5238 required_opts_STATUS_CODE
, NULL
);
5241 * Store the non-encapsulated option data for this
5242 * IA_PD into our reply packet. Defined in RFC 3315,
5246 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_PD
);
5248 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5249 /* IA_PD, copied from the client */
5250 memcpy(reply_data
+(*reply_ofs
)+4, ia_pd_id
, 4);
5251 /* t1 and t2, odd that we need them, but here it is */
5252 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5253 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5256 * Get ready for next IA_PD.
5258 *reply_ofs
+= (len
+ 16);
5261 option_state_dereference(&host_opt_state
, MDL
);
5265 iterate_over_ia_pd(struct data_string
*reply_ret
,
5266 struct packet
*packet
,
5267 const struct data_string
*client_id
,
5268 const struct data_string
*server_id
,
5269 const char *packet_type
,
5270 void (*ia_pd_match
)(),
5271 void (*ia_pd_nomatch
)())
5273 struct data_string reply_new
;
5275 struct option_state
*opt_state
;
5276 struct host_decl
*packet_host
;
5277 struct option_cache
*ia
;
5278 struct option_cache
*oc
;
5279 /* cli_enc_... variables come from the IA_PD options */
5280 struct data_string cli_enc_opt_data
;
5281 struct option_state
*cli_enc_opt_state
;
5282 struct host_decl
*host
;
5283 struct option_state
*host_opt_state
;
5284 struct data_string iaprefix
;
5285 char reply_data
[65536];
5287 struct iasubopt
*prefix
;
5288 struct ia_xx
*existing_ia_pd
;
5290 struct data_string key
;
5294 * Initialize to empty values, in case we have to exit early.
5296 memset(&reply_new
, 0, sizeof(reply_new
));
5298 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5299 cli_enc_opt_state
= NULL
;
5300 memset(&iaprefix
, 0, sizeof(iaprefix
));
5301 host_opt_state
= NULL
;
5305 * Compute the available length for the reply.
5307 reply_len
= sizeof(reply_data
) - reply_ret
->len
;
5311 * Find the host record that matches from the packet, if any.
5314 if (!find_hosts_by_uid(&packet_host
,
5315 client_id
->data
, client_id
->len
, MDL
)) {
5318 * Note: In general, we don't expect a client to provide
5319 * enough information to match by option for these
5320 * types of messages, but if we don't have a UID
5321 * match we can check anyway.
5323 if (!find_hosts_by_option(&packet_host
,
5324 packet
, packet
->options
, MDL
)) {
5327 if (!find_hosts_by_duid_chaddr(&packet_host
,
5334 * Build our option state for reply.
5337 if (!option_state_allocate(&opt_state
, MDL
)) {
5338 log_error("iterate_over_ia_pd: no memory for option_state.");
5341 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5342 packet
->options
, opt_state
,
5343 &global_scope
, root_group
, NULL
, NULL
);
5346 * Loop through the IA_PD reported by the client, and deal with
5347 * prefixes reported as already in use.
5349 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5350 ia
!= NULL
; ia
= ia
->next
) {
5352 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
5354 packet
, ia
, IA_PD_OFFSET
)) {
5358 iaid
= getULong(cli_enc_opt_data
.data
);
5360 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5363 /* no prefix given for this IA_PD, ignore */
5364 option_state_dereference(&cli_enc_opt_state
, MDL
);
5365 data_string_forget(&cli_enc_opt_data
, MDL
);
5369 for (; oc
!= NULL
; oc
= oc
->next
) {
5370 memset(&iaprefix
, 0, sizeof(iaprefix
));
5371 if (!evaluate_option_cache(&iaprefix
, packet
, NULL
, NULL
,
5372 packet
->options
, NULL
,
5373 &global_scope
, oc
, MDL
)) {
5374 log_error("iterate_over_ia_pd: "
5375 "error evaluating IAPREFIX.");
5380 * Now we need to figure out which host record matches
5381 * this IA_PD and IAPREFIX (encapsulated option contents
5382 * matching a host record by option).
5384 * XXX: We don't currently track IA_PD separately, but
5385 * we will need to do this!
5388 if (!find_hosts_by_option(&host
, packet
,
5389 cli_enc_opt_state
, MDL
)) {
5390 if (packet_host
!= NULL
) {
5396 while (host
!= NULL
) {
5397 if (host
->fixed_prefix
!= NULL
) {
5398 struct iaddrcidrnetlist
*l
;
5399 int plen
= (int) getUChar(iaprefix
.data
+ 8);
5401 for (l
= host
->fixed_prefix
; l
!= NULL
;
5403 if (plen
!= l
->cidrnet
.bits
)
5405 if (memcmp(iaprefix
.data
+ 9,
5406 l
->cidrnet
.lo_addr
.iabuf
,
5410 if ((l
!= NULL
) && (iaprefix
.len
>= 17))
5413 host
= host
->n_ipaddr
;
5416 if ((host
== NULL
) && (iaprefix
.len
>= IAPREFIX_OFFSET
)) {
5418 * Find existing IA_PD.
5420 if (ia_make_key(&key
, iaid
,
5421 (char *)client_id
->data
,
5423 MDL
) != ISC_R_SUCCESS
) {
5424 log_fatal("iterate_over_ia_pd: no memory for "
5428 existing_ia_pd
= NULL
;
5429 if (ia_hash_lookup(&existing_ia_pd
, ia_pd_active
,
5430 (unsigned char *)key
.data
,
5433 * Make sure this prefix is in the IA_PD.
5436 i
< existing_ia_pd
->num_iasubopt
;
5438 struct iasubopt
*tmp
;
5441 plen
= getUChar(iaprefix
.data
+ 8);
5442 tmp
= existing_ia_pd
->iasubopt
[i
];
5443 if ((tmp
->plen
== plen
) &&
5447 iasubopt_reference(&prefix
,
5454 data_string_forget(&key
, MDL
);
5457 if ((host
!= NULL
) || (prefix
!= NULL
)) {
5458 ia_pd_match(client_id
, &iaprefix
, prefix
);
5460 ia_pd_nomatch(client_id
, &iaprefix
,
5461 (u_int32_t
*)cli_enc_opt_data
.data
,
5462 packet
, reply_data
, &reply_ofs
,
5463 reply_len
- reply_ofs
);
5466 if (prefix
!= NULL
) {
5467 iasubopt_dereference(&prefix
, MDL
);
5470 data_string_forget(&iaprefix
, MDL
);
5473 option_state_dereference(&cli_enc_opt_state
, MDL
);
5474 data_string_forget(&cli_enc_opt_data
, MDL
);
5478 * Return our reply to the caller.
5479 * The IA_NA routine has already filled at least the header.
5481 reply_new
.len
= reply_ret
->len
+ reply_ofs
;
5482 if (!buffer_allocate(&reply_new
.buffer
, reply_new
.len
, MDL
)) {
5483 log_fatal("No memory to store reply.");
5485 reply_new
.data
= reply_new
.buffer
->data
;
5486 memcpy(reply_new
.buffer
->data
,
5487 reply_ret
->buffer
->data
, reply_ret
->len
);
5488 memcpy(reply_new
.buffer
->data
+ reply_ret
->len
,
5489 reply_data
, reply_ofs
);
5490 data_string_forget(reply_ret
, MDL
);
5491 data_string_copy(reply_ret
, &reply_new
, MDL
);
5492 data_string_forget(&reply_new
, MDL
);
5495 if (prefix
!= NULL
) {
5496 iasubopt_dereference(&prefix
, MDL
);
5498 if (host_opt_state
!= NULL
) {
5499 option_state_dereference(&host_opt_state
, MDL
);
5501 if (iaprefix
.buffer
!= NULL
) {
5502 data_string_forget(&iaprefix
, MDL
);
5504 if (cli_enc_opt_state
!= NULL
) {
5505 option_state_dereference(&cli_enc_opt_state
, MDL
);
5507 if (cli_enc_opt_data
.buffer
!= NULL
) {
5508 data_string_forget(&cli_enc_opt_data
, MDL
);
5510 if (opt_state
!= NULL
) {
5511 option_state_dereference(&opt_state
, MDL
);
5516 * Release means a client is done with the leases.
5519 /* TODO: reject unicast messages, unless we set unicast option */
5521 dhcpv6_release(struct data_string
*reply
, struct packet
*packet
) {
5522 struct data_string client_id
;
5523 struct data_string server_id
;
5526 * Validate our input.
5528 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5533 * And operate on each IA_NA in this packet.
5535 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
, "Release",
5536 ia_na_match_release
, ia_na_nomatch_release
);
5539 * And operate on each IA_PD in this packet.
5541 iterate_over_ia_pd(reply
, packet
, &client_id
, &server_id
, "Release",
5542 ia_pd_match_release
, ia_pd_nomatch_release
);
5544 data_string_forget(&server_id
, MDL
);
5545 data_string_forget(&client_id
, MDL
);
5549 * Information-Request is used by clients who have obtained an address
5550 * from other means, but want configuration information from the server.
5554 dhcpv6_information_request(struct data_string
*reply
, struct packet
*packet
) {
5555 struct data_string client_id
;
5556 struct data_string server_id
;
5559 * Validate our input.
5561 if (!valid_client_info_req(packet
, &server_id
)) {
5566 * Get our client ID, if there is one.
5568 memset(&client_id
, 0, sizeof(client_id
));
5569 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
) {
5570 data_string_forget(&client_id
, MDL
);
5574 * Use the lease_to_client() function. This will work fine,
5575 * because the valid_client_info_req() insures that we
5576 * don't have any IA that would cause us to allocate
5577 * resources to the client.
5579 lease_to_client(reply
, packet
, &client_id
,
5580 server_id
.data
!= NULL
? &server_id
: NULL
);
5585 if (client_id
.data
!= NULL
) {
5586 data_string_forget(&client_id
, MDL
);
5588 data_string_forget(&server_id
, MDL
);
5592 * The Relay-forw message is sent by relays. It typically contains a
5593 * single option, which encapsulates an entire packet.
5595 * We need to build an encapsulated reply.
5598 /* XXX: this is very, very similar to do_packet6(), and should probably
5599 be combined in a clever way */
5601 dhcpv6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
5602 struct option_cache
*oc
;
5603 struct data_string enc_opt_data
;
5604 struct packet
*enc_packet
;
5605 unsigned char msg_type
;
5606 const struct dhcpv6_packet
*msg
;
5607 const struct dhcpv6_relay_packet
*relay
;
5608 struct data_string enc_reply
;
5609 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
5610 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
5611 struct data_string a_opt
, packet_ero
;
5612 struct option_state
*opt_state
;
5613 static char reply_data
[65536];
5614 struct dhcpv6_relay_packet
*reply
;
5618 * Initialize variables for early exit.
5621 memset(&a_opt
, 0, sizeof(a_opt
));
5622 memset(&packet_ero
, 0, sizeof(packet_ero
));
5623 memset(&enc_reply
, 0, sizeof(enc_reply
));
5624 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
5628 * Get our encapsulated relay message.
5630 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
5632 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
5633 link_addr
, sizeof(link_addr
));
5634 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
5635 peer_addr
, sizeof(peer_addr
));
5636 log_info("Relay-forward from %s with link address=%s and "
5637 "peer address=%s missing Relay Message option.",
5638 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
5642 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
5643 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
5644 log_error("dhcpv6_forw_relay: error evaluating "
5645 "relayed message.");
5649 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
5650 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
5655 * Build a packet structure from this encapsulated packet.
5658 if (!packet_allocate(&enc_packet
, MDL
)) {
5659 log_error("dhcpv6_forw_relay: "
5660 "no memory for encapsulated packet.");
5664 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
5665 log_error("dhcpv6_forw_relay: "
5666 "no memory for encapsulated packet's options.");
5670 enc_packet
->client_port
= packet
->client_port
;
5671 enc_packet
->client_addr
= packet
->client_addr
;
5672 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
5673 enc_packet
->dhcpv6_container_packet
= packet
;
5675 msg_type
= enc_opt_data
.data
[0];
5676 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
5677 (msg_type
== DHCPV6_RELAY_REPL
)) {
5678 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
5679 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
5680 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
5682 /* relay-specific data */
5683 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
5684 memcpy(&enc_packet
->dhcpv6_link_address
,
5685 relay
->link_address
, sizeof(relay
->link_address
));
5686 memcpy(&enc_packet
->dhcpv6_peer_address
,
5687 relay
->peer_address
, sizeof(relay
->peer_address
));
5689 if (!parse_option_buffer(enc_packet
->options
,
5691 enc_opt_data
.len
- relaylen
,
5692 &dhcpv6_universe
)) {
5693 /* no logging here, as parse_option_buffer() logs all
5694 cases where it fails */
5698 int msglen
= (int)(offsetof(struct dhcpv6_packet
, options
));
5699 msg
= (struct dhcpv6_packet
*)enc_opt_data
.data
;
5700 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
5702 /* message-specific data */
5703 memcpy(enc_packet
->dhcpv6_transaction_id
,
5704 msg
->transaction_id
,
5705 sizeof(enc_packet
->dhcpv6_transaction_id
));
5707 if (!parse_option_buffer(enc_packet
->options
,
5709 enc_opt_data
.len
- msglen
,
5710 &dhcpv6_universe
)) {
5711 /* no logging here, as parse_option_buffer() logs all
5712 cases where it fails */
5718 * This is recursive. It is possible to exceed maximum packet size.
5719 * XXX: This will cause the packet send to fail.
5721 build_dhcpv6_reply(&enc_reply
, enc_packet
);
5724 * If we got no encapsulated data, then it is discarded, and
5725 * our reply-forw is also discarded.
5727 if (enc_reply
.data
== NULL
) {
5732 * Now we can use the reply_data buffer.
5733 * Packet header stuff all comes from the forward message.
5735 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
5736 reply
->msg_type
= DHCPV6_RELAY_REPL
;
5737 reply
->hop_count
= packet
->dhcpv6_hop_count
;
5738 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
5739 sizeof(reply
->link_address
));
5740 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
5741 sizeof(reply
->peer_address
));
5742 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
5745 * Get the reply option state.
5748 if (!option_state_allocate(&opt_state
, MDL
)) {
5749 log_error("dhcpv6_relay_forw: no memory for option state.");
5754 * Append the interface-id if present.
5756 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
5759 if (!evaluate_option_cache(&a_opt
, packet
,
5761 packet
->options
, NULL
,
5762 &global_scope
, oc
, MDL
)) {
5763 log_error("dhcpv6_relay_forw: error evaluating "
5767 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5768 (unsigned char *)a_opt
.data
,
5770 D6O_INTERFACE_ID
, 0)) {
5771 log_error("dhcpv6_relay_forw: error saving "
5775 data_string_forget(&a_opt
, MDL
);
5779 * Append our encapsulated stuff for caller.
5781 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5782 (unsigned char *)enc_reply
.data
,
5784 D6O_RELAY_MSG
, 0)) {
5785 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
5790 * Get the ERO if any.
5792 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
5797 if (!evaluate_option_cache(&packet_ero
, packet
,
5799 packet
->options
, NULL
,
5800 &global_scope
, oc
, MDL
) ||
5801 (packet_ero
.len
& 1)) {
5802 log_error("dhcpv6_relay_forw: error evaluating ERO.");
5806 /* Decode and apply the ERO. */
5807 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
5808 req
= getUShort(packet_ero
.data
+ i
);
5809 /* Already in the reply? */
5810 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
5813 /* Get it from the packet if present. */
5814 oc
= lookup_option(&dhcpv6_universe
,
5819 if (!evaluate_option_cache(&a_opt
, packet
,
5821 packet
->options
, NULL
,
5822 &global_scope
, oc
, MDL
)) {
5823 log_error("dhcpv6_relay_forw: error "
5824 "evaluating option %u.", req
);
5827 if (!save_option_buffer(&dhcpv6_universe
,
5830 (unsigned char *)a_opt
.data
,
5834 log_error("dhcpv6_relay_forw: error saving "
5838 data_string_forget(&a_opt
, MDL
);
5842 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
5843 sizeof(reply_data
) - reply_ofs
,
5845 required_opts_agent
, &packet_ero
);
5848 * Return our reply to the caller.
5850 reply_ret
->len
= reply_ofs
;
5851 reply_ret
->buffer
= NULL
;
5852 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
5853 log_fatal("No memory to store reply.");
5855 reply_ret
->data
= reply_ret
->buffer
->data
;
5856 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
5859 if (opt_state
!= NULL
)
5860 option_state_dereference(&opt_state
, MDL
);
5861 if (a_opt
.data
!= NULL
) {
5862 data_string_forget(&a_opt
, MDL
);
5864 if (packet_ero
.data
!= NULL
) {
5865 data_string_forget(&packet_ero
, MDL
);
5867 if (enc_reply
.data
!= NULL
) {
5868 data_string_forget(&enc_reply
, MDL
);
5870 if (enc_opt_data
.data
!= NULL
) {
5871 data_string_forget(&enc_opt_data
, MDL
);
5873 if (enc_packet
!= NULL
) {
5874 packet_dereference(&enc_packet
, MDL
);
5879 dhcpv6_discard(struct packet
*packet
) {
5880 /* INSIST(packet->msg_type > 0); */
5881 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
5883 log_debug("Discarding %s from %s; message type not handled by server",
5884 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
5885 piaddr(packet
->client_addr
));
5889 build_dhcpv6_reply(struct data_string
*reply
, struct packet
*packet
) {
5890 memset(reply
, 0, sizeof(*reply
));
5891 switch (packet
->dhcpv6_msg_type
) {
5892 case DHCPV6_SOLICIT
:
5893 dhcpv6_solicit(reply
, packet
);
5895 case DHCPV6_ADVERTISE
:
5896 dhcpv6_discard(packet
);
5898 case DHCPV6_REQUEST
:
5899 dhcpv6_request(reply
, packet
);
5901 case DHCPV6_CONFIRM
:
5902 dhcpv6_confirm(reply
, packet
);
5905 dhcpv6_renew(reply
, packet
);
5908 dhcpv6_rebind(reply
, packet
);
5911 dhcpv6_discard(packet
);
5913 case DHCPV6_RELEASE
:
5914 dhcpv6_release(reply
, packet
);
5916 case DHCPV6_DECLINE
:
5917 dhcpv6_decline(reply
, packet
);
5919 case DHCPV6_RECONFIGURE
:
5920 dhcpv6_discard(packet
);
5922 case DHCPV6_INFORMATION_REQUEST
:
5923 dhcpv6_information_request(reply
, packet
);
5925 case DHCPV6_RELAY_FORW
:
5926 dhcpv6_relay_forw(reply
, packet
);
5928 case DHCPV6_RELAY_REPL
:
5929 dhcpv6_discard(packet
);
5931 case DHCPV6_LEASEQUERY
:
5932 dhcpv6_leasequery(reply
, packet
);
5934 case DHCPV6_LEASEQUERY_REPLY
:
5935 dhcpv6_discard(packet
);
5938 /* XXX: would be nice if we had "notice" level,
5939 as syslog, for this */
5940 log_info("Discarding unknown DHCPv6 message type %d "
5941 "from %s", packet
->dhcpv6_msg_type
,
5942 piaddr(packet
->client_addr
));
5947 log_packet_in(const struct packet
*packet
) {
5948 struct data_string s
;
5950 char tmp_addr
[INET6_ADDRSTRLEN
];
5953 memset(&s
, 0, sizeof(s
));
5955 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
5956 data_string_sprintfa(&s
, "%s message from %s port %d",
5957 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
5958 piaddr(packet
->client_addr
),
5959 ntohs(packet
->client_port
));
5961 data_string_sprintfa(&s
,
5962 "Unknown message type %d from %s port %d",
5963 packet
->dhcpv6_msg_type
,
5964 piaddr(packet
->client_addr
),
5965 ntohs(packet
->client_port
));
5967 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
5968 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
5969 addr
= &packet
->dhcpv6_link_address
;
5970 data_string_sprintfa(&s
, ", link address %s",
5971 inet_ntop(AF_INET6
, addr
,
5972 tmp_addr
, sizeof(tmp_addr
)));
5973 addr
= &packet
->dhcpv6_peer_address
;
5974 data_string_sprintfa(&s
, ", peer address %s",
5975 inet_ntop(AF_INET6
, addr
,
5976 tmp_addr
, sizeof(tmp_addr
)));
5979 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
5980 data_string_sprintfa(&s
, ", transaction ID 0x%06X", tid
);
5983 oc = lookup_option(&dhcpv6_universe, packet->options,
5986 memset(&tmp_ds, 0, sizeof(tmp_ds_));
5987 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
5988 packet->options, NULL,
5989 &global_scope, oc, MDL)) {
5990 log_error("Error evaluating Client Identifier");
5992 data_strint_sprintf(&s, ", client ID %s",
5994 data_string_forget(&tmp_ds, MDL);
6000 log_info("%s", s
.data
);
6002 data_string_forget(&s
, MDL
);
6006 dhcpv6(struct packet
*packet
) {
6007 struct data_string reply
;
6008 struct sockaddr_in6 to_addr
;
6012 * Log a message that we received this packet.
6014 log_packet_in(packet
);
6017 * Build our reply packet.
6019 build_dhcpv6_reply(&reply
, packet
);
6021 if (reply
.data
!= NULL
) {
6023 * Send our reply, if we have one.
6025 memset(&to_addr
, 0, sizeof(to_addr
));
6026 to_addr
.sin6_family
= AF_INET6
;
6027 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
6028 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
6029 to_addr
.sin6_port
= local_port
;
6031 to_addr
.sin6_port
= remote_port
;
6034 #if defined (REPLY_TO_SOURCE_PORT)
6036 * This appears to have been included for testing so we would
6037 * not need a root client, but was accidently left in the
6038 * final code. We continue to include it in case
6039 * some users have come to rely upon it, but leave
6040 * it off by default as it's a bad idea.
6042 to_addr
.sin6_port
= packet
->client_port
;
6045 memcpy(&to_addr
.sin6_addr
, packet
->client_addr
.iabuf
,
6046 sizeof(to_addr
.sin6_addr
));
6048 log_info("Sending %s to %s port %d",
6049 dhcpv6_type_names
[reply
.data
[0]],
6050 piaddr(packet
->client_addr
),
6051 ntohs(to_addr
.sin6_port
));
6053 send_ret
= send_packet6(packet
->interface
,
6054 reply
.data
, reply
.len
, &to_addr
);
6055 if (send_ret
!= reply
.len
) {
6056 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
6057 send_ret
, reply
.len
);
6059 data_string_forget(&reply
, MDL
);
6064 seek_shared_host(struct host_decl
**hp
, struct shared_network
*shared
) {
6065 struct host_decl
*nofixed
= NULL
;
6066 struct host_decl
*seek
, *hold
= NULL
;
6069 * Seek forward through fixed addresses for the right link.
6071 * Note: how to do this for fixed prefixes???
6073 host_reference(&hold
, *hp
, MDL
);
6074 host_dereference(hp
, MDL
);
6076 while (seek
!= NULL
) {
6077 if (seek
->fixed_addr
== NULL
)
6079 else if (fixed_matches_shared(seek
, shared
))
6082 seek
= seek
->n_ipaddr
;
6085 if ((seek
== NULL
) && (nofixed
!= NULL
))
6089 host_reference(hp
, seek
, MDL
);
6092 static isc_boolean_t
6093 fixed_matches_shared(struct host_decl
*host
, struct shared_network
*shared
) {
6094 struct subnet
*subnet
;
6095 struct data_string addr
;
6096 isc_boolean_t matched
;
6099 if (host
->fixed_addr
== NULL
)
6102 memset(&addr
, 0, sizeof(addr
));
6103 if (!evaluate_option_cache(&addr
, NULL
, NULL
, NULL
, NULL
, NULL
,
6104 &global_scope
, host
->fixed_addr
, MDL
))
6107 if (addr
.len
< 16) {
6108 data_string_forget(&addr
, MDL
);
6113 memcpy(fixed
.iabuf
, addr
.data
, 16);
6115 matched
= ISC_FALSE
;
6116 for (subnet
= shared
->subnets
; subnet
!= NULL
;
6117 subnet
= subnet
->next_sibling
) {
6118 if (addr_eq(subnet_number(fixed
, subnet
->netmask
),
6125 data_string_forget(&addr
, MDL
);
6130 * find_host_by_duid_chaddr() synthesizes a DHCPv4-like 'hardware'
6131 * parameter from a DHCPv6 supplied DUID (client-identifier option),
6132 * and may seek to use client or relay supplied hardware addresses.
6135 find_hosts_by_duid_chaddr(struct host_decl
**host
,
6136 const struct data_string
*client_id
) {
6137 static int once_htype
;
6139 const unsigned char *chaddr
;
6142 * The DUID-LL and DUID-LLT must have a 2-byte DUID type and 2-byte
6145 if (client_id
->len
< 4)
6149 * The third and fourth octets of the DUID-LL and DUID-LLT
6150 * is the hardware type, but in 16 bits.
6152 htype
= getUShort(client_id
->data
+ 2);
6156 /* The first two octets of the DUID identify the type. */
6157 switch(getUShort(client_id
->data
)) {
6159 if (client_id
->len
> 8) {
6160 hlen
= client_id
->len
- 8;
6161 chaddr
= client_id
->data
+ 8;
6167 * Note that client_id->len must be greater than or equal
6168 * to four to get to this point in the function.
6170 hlen
= client_id
->len
- 4;
6171 chaddr
= client_id
->data
+ 4;
6178 if ((hlen
== 0) || (hlen
> HARDWARE_ADDR_LEN
))
6182 * XXX: DHCPv6 gives a 16-bit field for the htype. DHCPv4 gives an
6183 * 8-bit field. To change the semantics of the generic 'hardware'
6184 * structure, we would have to adjust many DHCPv4 sources (from
6185 * interface to DHCPv4 lease code), and we would have to update the
6186 * 'hardware' config directive (probably being reverse compatible and
6187 * providing a new upgrade/replacement primitive). This is a little
6188 * too much to change for now. Hopefully we will revisit this before
6189 * hardware types exceeding 8 bits are assigned.
6191 if ((htype
& 0xFF00) && !once_htype
) {
6193 log_error("Attention: At least one client advertises a "
6194 "hardware type of %d, which exceeds the software "
6195 "limitation of 255.", htype
);
6198 return find_hosts_by_haddr(host
, htype
, chaddr
, hlen
, MDL
);