2 * Copyright (C) 2006-2012 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. */
85 unsigned char data
[65536];
86 struct dhcpv6_packet reply
;
91 * Prototypes local to this file.
93 static int get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
94 struct data_string
*enc_opt_data
,
95 struct packet
*packet
,
96 struct option_cache
*oc
,
98 static void build_dhcpv6_reply(struct data_string
*, struct packet
*);
99 static isc_result_t
shared_network_from_packet6(struct shared_network
**shared
,
100 struct packet
*packet
);
101 static void seek_shared_host(struct host_decl
**hp
,
102 struct shared_network
*shared
);
103 static isc_boolean_t
fixed_matches_shared(struct host_decl
*host
,
104 struct shared_network
*shared
);
105 static isc_result_t
reply_process_ia_na(struct reply_state
*reply
,
106 struct option_cache
*ia
);
107 static isc_result_t
reply_process_ia_ta(struct reply_state
*reply
,
108 struct option_cache
*ia
);
109 static isc_result_t
reply_process_addr(struct reply_state
*reply
,
110 struct option_cache
*addr
);
111 static isc_boolean_t
address_is_owned(struct reply_state
*reply
,
113 static isc_boolean_t
temporary_is_available(struct reply_state
*reply
,
115 static isc_result_t
find_client_temporaries(struct reply_state
*reply
);
116 static isc_result_t
reply_process_try_addr(struct reply_state
*reply
,
118 static isc_result_t
find_client_address(struct reply_state
*reply
);
119 static isc_result_t
reply_process_is_addressed(struct reply_state
*reply
,
120 struct binding_scope
**scope
,
121 struct group
*group
);
122 static isc_result_t
reply_process_send_addr(struct reply_state
*reply
,
124 static struct iasubopt
*lease_compare(struct iasubopt
*alpha
,
125 struct iasubopt
*beta
);
126 static isc_result_t
reply_process_ia_pd(struct reply_state
*reply
,
127 struct option_cache
*ia_pd
);
128 static isc_result_t
reply_process_prefix(struct reply_state
*reply
,
129 struct option_cache
*pref
);
130 static isc_boolean_t
prefix_is_owned(struct reply_state
*reply
,
131 struct iaddrcidrnet
*pref
);
132 static isc_result_t
find_client_prefix(struct reply_state
*reply
);
133 static isc_result_t
reply_process_try_prefix(struct reply_state
*reply
,
134 struct iaddrcidrnet
*pref
);
135 static isc_result_t
reply_process_is_prefixed(struct reply_state
*reply
,
136 struct binding_scope
**scope
,
137 struct group
*group
);
138 static isc_result_t
reply_process_send_prefix(struct reply_state
*reply
,
139 struct iaddrcidrnet
*pref
);
140 static struct iasubopt
*prefix_compare(struct reply_state
*reply
,
141 struct iasubopt
*alpha
,
142 struct iasubopt
*beta
);
143 static int find_hosts_by_duid_chaddr(struct host_decl
**host
,
144 const struct data_string
*client_id
);
146 * This function returns the time since DUID time start for the
147 * given time_t value.
150 duid_time(time_t when
) {
152 * This time is modulo 2^32.
154 while ((when
- DUID_TIME_EPOCH
) > 4294967295u) {
155 /* use 2^31 to avoid spurious compiler warnings */
160 return when
- DUID_TIME_EPOCH
;
167 * This must remain the same for the lifetime of this server, because
168 * clients return the server DUID that we sent them in Request packets.
170 * We pick the server DUID like this:
172 * 1. Check dhcpd.conf - any value the administrator has configured
173 * overrides any possible values.
174 * 2. Check the leases.txt - we want to use the previous value if
176 * 3. Check if dhcpd.conf specifies a type of server DUID to use,
177 * and generate that type.
178 * 4. Generate a type 1 (time + hardware address) DUID.
180 static struct data_string server_duid
;
183 * Check if the server_duid has been set.
186 server_duid_isset(void) {
187 return (server_duid
.data
!= NULL
);
191 * Return the server_duid.
194 copy_server_duid(struct data_string
*ds
, const char *file
, int line
) {
195 data_string_copy(ds
, &server_duid
, file
, line
);
199 * Set the server DUID to a specified value. This is used when
200 * the server DUID is stored in persistent memory (basically the
204 set_server_duid(struct data_string
*new_duid
) {
205 /* INSIST(new_duid != NULL); */
206 /* INSIST(new_duid->data != NULL); */
208 if (server_duid_isset()) {
209 data_string_forget(&server_duid
, MDL
);
211 data_string_copy(&server_duid
, new_duid
, MDL
);
216 * Set the server DUID based on the D6O_SERVERID option. This handles
217 * the case where the administrator explicitly put it in the dhcpd.conf
221 set_server_duid_from_option(void) {
222 struct option_state
*opt_state
;
223 struct option_cache
*oc
;
224 struct data_string option_duid
;
225 isc_result_t ret_val
;
228 if (!option_state_allocate(&opt_state
, MDL
)) {
229 log_fatal("No memory for server DUID.");
232 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
,
233 opt_state
, &global_scope
, root_group
, NULL
);
235 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
237 ret_val
= ISC_R_NOTFOUND
;
239 memset(&option_duid
, 0, sizeof(option_duid
));
240 if (!evaluate_option_cache(&option_duid
, NULL
, NULL
, NULL
,
241 opt_state
, NULL
, &global_scope
,
243 ret_val
= ISC_R_UNEXPECTED
;
245 set_server_duid(&option_duid
);
246 data_string_forget(&option_duid
, MDL
);
247 ret_val
= ISC_R_SUCCESS
;
251 option_state_dereference(&opt_state
, MDL
);
257 * DUID layout, as defined in RFC 3315, section 9.
259 * We support type 1 (hardware address plus time) and type 3 (hardware
262 * We can support type 2 for specific vendors in the future, if they
263 * publish the specification. And of course there may be additional
266 static int server_duid_type
= DUID_LLT
;
272 set_server_duid_type(int type
) {
273 server_duid_type
= type
;
277 * Generate a new server DUID. This is done if there was no DUID in
278 * the leases.txt or in the dhcpd.conf file.
281 generate_new_server_duid(void) {
282 struct interface_info
*p
;
284 struct data_string generated_duid
;
287 * Verify we have a type that we support.
289 if ((server_duid_type
!= DUID_LL
) && (server_duid_type
!= DUID_LLT
)) {
290 log_error("Invalid DUID type %d specified, "
291 "only LL and LLT types supported", server_duid_type
);
292 return DHCP_R_INVALIDARG
;
296 * Find an interface with a hardware address.
299 for (p
= interfaces
; p
!= NULL
; p
= p
->next
) {
300 if (p
->hw_address
.hlen
> 0) {
305 return ISC_R_UNEXPECTED
;
311 memset(&generated_duid
, 0, sizeof(generated_duid
));
312 if (server_duid_type
== DUID_LLT
) {
313 time_val
= duid_time(time(NULL
));
314 generated_duid
.len
= 8 + p
->hw_address
.hlen
- 1;
315 if (!buffer_allocate(&generated_duid
.buffer
,
316 generated_duid
.len
, MDL
)) {
317 log_fatal("No memory for server DUID.");
319 generated_duid
.data
= generated_duid
.buffer
->data
;
320 putUShort(generated_duid
.buffer
->data
, DUID_LLT
);
321 putUShort(generated_duid
.buffer
->data
+ 2,
322 p
->hw_address
.hbuf
[0]);
323 putULong(generated_duid
.buffer
->data
+ 4, time_val
);
324 memcpy(generated_duid
.buffer
->data
+ 8,
325 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
326 } else if (server_duid_type
== DUID_LL
) {
327 generated_duid
.len
= 4 + p
->hw_address
.hlen
- 1;
328 if (!buffer_allocate(&generated_duid
.buffer
,
329 generated_duid
.len
, MDL
)) {
330 log_fatal("No memory for server DUID.");
332 generated_duid
.data
= generated_duid
.buffer
->data
;
333 putUShort(generated_duid
.buffer
->data
, DUID_LL
);
334 putUShort(generated_duid
.buffer
->data
+ 2,
335 p
->hw_address
.hbuf
[0]);
336 memcpy(generated_duid
.buffer
->data
+ 4,
337 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
339 log_fatal("Unsupported server DUID type %d.", server_duid_type
);
342 set_server_duid(&generated_duid
);
343 data_string_forget(&generated_duid
, MDL
);
345 return ISC_R_SUCCESS
;
349 * Get the client identifier from the packet.
352 get_client_id(struct packet
*packet
, struct data_string
*client_id
) {
353 struct option_cache
*oc
;
356 * Verify our client_id structure is empty.
358 if ((client_id
->data
!= NULL
) || (client_id
->len
!= 0)) {
359 return DHCP_R_INVALIDARG
;
362 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_CLIENTID
);
364 return ISC_R_NOTFOUND
;
367 if (!evaluate_option_cache(client_id
, packet
, NULL
, NULL
,
368 packet
->options
, NULL
,
369 &global_scope
, oc
, MDL
)) {
370 return ISC_R_FAILURE
;
373 return ISC_R_SUCCESS
;
377 * Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
379 * Servers MUST discard any Solicit messages that do not include a
380 * Client Identifier option or that do include a Server Identifier
384 valid_client_msg(struct packet
*packet
, struct data_string
*client_id
) {
386 struct option_cache
*oc
;
387 struct data_string data
;
390 memset(client_id
, 0, sizeof(*client_id
));
391 memset(&data
, 0, sizeof(data
));
393 switch (get_client_id(packet
, client_id
)) {
397 log_debug("Discarding %s from %s; "
398 "client identifier missing",
399 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
400 piaddr(packet
->client_addr
));
403 log_error("Error processing %s from %s; "
404 "unable to evaluate Client Identifier",
405 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
406 piaddr(packet
->client_addr
));
411 * Required by RFC 3315, section 15.
413 if (packet
->unicast
) {
414 log_debug("Discarding %s from %s; packet sent unicast "
416 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
417 piaddr(packet
->client_addr
),
418 print_hex_1(client_id
->len
, client_id
->data
, 60));
423 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
425 if (evaluate_option_cache(&data
, packet
, NULL
, NULL
,
426 packet
->options
, NULL
,
427 &global_scope
, oc
, MDL
)) {
428 log_debug("Discarding %s from %s; "
429 "server identifier found "
430 "(CLIENTID %s, SERVERID %s)",
431 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
432 piaddr(packet
->client_addr
),
433 print_hex_1(client_id
->len
,
434 client_id
->data
, 60),
435 print_hex_2(data
.len
,
438 log_debug("Discarding %s from %s; "
439 "server identifier found "
441 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
442 print_hex_1(client_id
->len
,
443 client_id
->data
, 60),
444 piaddr(packet
->client_addr
));
454 data_string_forget(&data
, MDL
);
457 if (client_id
->len
> 0) {
458 data_string_forget(client_id
, MDL
);
465 * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
466 * 15.9 (slightly different wording, but same meaning):
468 * Servers MUST discard any received Request message that meet any of
469 * the following conditions:
471 * - the message does not include a Server Identifier option.
472 * - the contents of the Server Identifier option do not match the
474 * - the message does not include a Client Identifier option.
477 valid_client_resp(struct packet
*packet
,
478 struct data_string
*client_id
,
479 struct data_string
*server_id
)
482 struct option_cache
*oc
;
484 /* INSIST((duid.data != NULL) && (duid.len > 0)); */
487 memset(client_id
, 0, sizeof(*client_id
));
488 memset(server_id
, 0, sizeof(*server_id
));
490 switch (get_client_id(packet
, client_id
)) {
494 log_debug("Discarding %s from %s; "
495 "client identifier missing",
496 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
497 piaddr(packet
->client_addr
));
500 log_error("Error processing %s from %s; "
501 "unable to evaluate Client Identifier",
502 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
503 piaddr(packet
->client_addr
));
507 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
509 log_debug("Discarding %s from %s: "
510 "server identifier missing (CLIENTID %s)",
511 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
512 piaddr(packet
->client_addr
),
513 print_hex_1(client_id
->len
, client_id
->data
, 60));
516 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
517 packet
->options
, NULL
,
518 &global_scope
, oc
, MDL
)) {
519 log_error("Error processing %s from %s; "
520 "unable to evaluate Server Identifier (CLIENTID %s)",
521 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
522 piaddr(packet
->client_addr
),
523 print_hex_1(client_id
->len
, client_id
->data
, 60));
526 if ((server_duid
.len
!= server_id
->len
) ||
527 (memcmp(server_duid
.data
, server_id
->data
, server_duid
.len
) != 0)) {
528 log_debug("Discarding %s from %s; "
529 "not our server identifier "
530 "(CLIENTID %s, SERVERID %s, server DUID %s)",
531 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
532 piaddr(packet
->client_addr
),
533 print_hex_1(client_id
->len
, client_id
->data
, 60),
534 print_hex_2(server_id
->len
, server_id
->data
, 60),
535 print_hex_3(server_duid
.len
, server_duid
.data
, 60));
544 if (server_id
->len
> 0) {
545 data_string_forget(server_id
, MDL
);
547 if (client_id
->len
> 0) {
548 data_string_forget(client_id
, MDL
);
555 * Information request validation, defined in RFC 3315, section 15.12:
557 * Servers MUST discard any received Information-request message that
558 * meets any of the following conditions:
560 * - The message includes a Server Identifier option and the DUID in
561 * the option does not match the server's DUID.
563 * - The message includes an IA option.
566 valid_client_info_req(struct packet
*packet
, struct data_string
*server_id
) {
568 struct option_cache
*oc
;
569 struct data_string client_id
;
570 char client_id_str
[80]; /* print_hex_1() uses maximum 60 characters,
571 plus a few more for extra information */
574 memset(server_id
, 0, sizeof(*server_id
));
575 memset(&client_id
, 0, sizeof(client_id
));
578 * Make a string that we can print out to give more
579 * information about the client if we need to.
581 * By RFC 3315, Section 18.1.5 clients SHOULD have a
582 * client-id on an Information-request packet, but it
583 * is not strictly necessary.
585 if (get_client_id(packet
, &client_id
) == ISC_R_SUCCESS
) {
586 snprintf(client_id_str
, sizeof(client_id_str
), " (CLIENTID %s)",
587 print_hex_1(client_id
.len
, client_id
.data
, 60));
588 data_string_forget(&client_id
, MDL
);
590 client_id_str
[0] = '\0';
594 * Required by RFC 3315, section 15.
596 if (packet
->unicast
) {
597 log_debug("Discarding %s from %s; packet sent unicast%s",
598 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
599 piaddr(packet
->client_addr
), client_id_str
);
603 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
605 log_debug("Discarding %s from %s; "
606 "IA_NA option present%s",
607 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
608 piaddr(packet
->client_addr
), client_id_str
);
611 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
613 log_debug("Discarding %s from %s; "
614 "IA_TA option present%s",
615 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
616 piaddr(packet
->client_addr
), client_id_str
);
619 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
621 log_debug("Discarding %s from %s; "
622 "IA_PD option present%s",
623 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
624 piaddr(packet
->client_addr
), client_id_str
);
628 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
630 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
631 packet
->options
, NULL
,
632 &global_scope
, oc
, MDL
)) {
633 log_error("Error processing %s from %s; "
634 "unable to evaluate Server Identifier%s",
635 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
636 piaddr(packet
->client_addr
), client_id_str
);
639 if ((server_duid
.len
!= server_id
->len
) ||
640 (memcmp(server_duid
.data
, server_id
->data
,
641 server_duid
.len
) != 0)) {
642 log_debug("Discarding %s from %s; "
643 "not our server identifier "
644 "(SERVERID %s, server DUID %s)%s",
645 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
646 piaddr(packet
->client_addr
),
647 print_hex_1(server_id
->len
,
648 server_id
->data
, 60),
649 print_hex_2(server_duid
.len
,
650 server_duid
.data
, 60),
661 if (server_id
->len
> 0) {
662 data_string_forget(server_id
, MDL
);
669 * Options that we want to send, in addition to what was requested
672 static const int required_opts
[] = {
679 static const int required_opts_NAA
[] = {
685 static const int required_opts_solicit
[] = {
697 static const int required_opts_agent
[] = {
702 static const int required_opts_IA
[] = {
707 static const int required_opts_IA_PD
[] = {
712 static const int required_opts_STATUS_CODE
[] = {
718 * Extracts from packet contents an IA_* option, storing the IA structure
719 * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
720 * in enc_opt_state for later lookup and evaluation. The 'offset' indicates
721 * where in the IA_* the DHCPv6 options commence.
724 get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
725 struct data_string
*enc_opt_data
,
726 struct packet
*packet
,
727 struct option_cache
*oc
,
731 * Get the raw data for the encapsulated options.
733 memset(enc_opt_data
, 0, sizeof(*enc_opt_data
));
734 if (!evaluate_option_cache(enc_opt_data
, packet
,
735 NULL
, NULL
, packet
->options
, NULL
,
736 &global_scope
, oc
, MDL
)) {
737 log_error("get_encapsulated_IA_state: "
738 "error evaluating raw option.");
741 if (enc_opt_data
->len
< offset
) {
742 log_error("get_encapsulated_IA_state: raw option too small.");
743 data_string_forget(enc_opt_data
, MDL
);
748 * Now create the option state structure, and pass it to the
749 * function that parses options.
751 *enc_opt_state
= NULL
;
752 if (!option_state_allocate(enc_opt_state
, MDL
)) {
753 log_error("get_encapsulated_IA_state: no memory for options.");
754 data_string_forget(enc_opt_data
, MDL
);
757 if (!parse_option_buffer(*enc_opt_state
,
758 enc_opt_data
->data
+ offset
,
759 enc_opt_data
->len
- offset
,
761 log_error("get_encapsulated_IA_state: error parsing options.");
762 option_state_dereference(enc_opt_state
, MDL
);
763 data_string_forget(enc_opt_data
, MDL
);
771 set_status_code(u_int16_t status_code
, const char *status_message
,
772 struct option_state
*opt_state
)
774 struct data_string d
;
777 memset(&d
, 0, sizeof(d
));
778 d
.len
= sizeof(status_code
) + strlen(status_message
);
779 if (!buffer_allocate(&d
.buffer
, d
.len
, MDL
)) {
780 log_fatal("set_status_code: no memory for status code.");
782 d
.data
= d
.buffer
->data
;
783 putUShort(d
.buffer
->data
, status_code
);
784 memcpy(d
.buffer
->data
+ sizeof(status_code
),
785 status_message
, d
.len
- sizeof(status_code
));
786 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
787 d
.buffer
, (unsigned char *)d
.data
, d
.len
,
788 D6O_STATUS_CODE
, 0)) {
789 log_error("set_status_code: error saving status code.");
794 data_string_forget(&d
, MDL
);
799 * We have a set of operations we do to set up the reply packet, which
800 * is the same for many message types.
803 start_reply(struct packet
*packet
,
804 const struct data_string
*client_id
,
805 const struct data_string
*server_id
,
806 struct option_state
**opt_state
,
807 struct dhcpv6_packet
*reply
)
809 struct option_cache
*oc
;
810 const unsigned char *server_id_data
;
814 * Build our option state for reply.
817 if (!option_state_allocate(opt_state
, MDL
)) {
818 log_error("start_reply: no memory for option_state.");
821 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
822 packet
->options
, *opt_state
,
823 &global_scope
, root_group
, NULL
);
826 * A small bit of special handling for Solicit messages.
828 * We could move the logic into a flag, but for now just check
831 if (packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
832 reply
->msg_type
= DHCPV6_ADVERTISE
;
836 * - this message type supports rapid commit (Solicit), and
837 * - the server is configured to supply a rapid commit, and
838 * - the client requests a rapid commit,
839 * Then we add a rapid commit option, and send Reply (instead
842 oc
= lookup_option(&dhcpv6_universe
,
843 *opt_state
, D6O_RAPID_COMMIT
);
845 oc
= lookup_option(&dhcpv6_universe
,
846 packet
->options
, D6O_RAPID_COMMIT
);
848 /* Rapid-commit in action. */
849 reply
->msg_type
= DHCPV6_REPLY
;
851 /* Don't want a rapid-commit in advertise. */
852 delete_option(&dhcpv6_universe
,
853 *opt_state
, D6O_RAPID_COMMIT
);
857 reply
->msg_type
= DHCPV6_REPLY
;
858 /* Delete the rapid-commit from the sent options. */
859 oc
= lookup_option(&dhcpv6_universe
,
860 *opt_state
, D6O_RAPID_COMMIT
);
862 delete_option(&dhcpv6_universe
,
863 *opt_state
, D6O_RAPID_COMMIT
);
868 * Use the client's transaction identifier for the reply.
870 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
871 sizeof(reply
->transaction_id
));
874 * RFC 3315, section 18.2 says we need server identifier and
877 * If the server ID is defined via the configuration file, then
878 * it will already be present in the option state at this point,
879 * so we don't need to set it.
881 * If we have a server ID passed in from the caller,
882 * use that, otherwise use the global DUID.
884 oc
= lookup_option(&dhcpv6_universe
, *opt_state
, D6O_SERVERID
);
886 if (server_id
== NULL
) {
887 server_id_data
= server_duid
.data
;
888 server_id_len
= server_duid
.len
;
890 server_id_data
= server_id
->data
;
891 server_id_len
= server_id
->len
;
893 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
894 NULL
, (unsigned char *)server_id_data
,
895 server_id_len
, D6O_SERVERID
, 0)) {
896 log_error("start_reply: "
897 "error saving server identifier.");
902 if (client_id
->buffer
!= NULL
) {
903 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
905 (unsigned char *)client_id
->data
,
908 log_error("start_reply: error saving "
909 "client identifier.");
915 * If the client accepts reconfiguration, let it know that we
918 * Note: we don't actually do this yet, but DOCSIS requires we
921 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
924 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
925 NULL
, (unsigned char *)"", 0,
926 D6O_RECONF_ACCEPT
, 0)) {
927 log_error("start_reply: "
928 "error saving RECONF_ACCEPT option.");
929 option_state_dereference(opt_state
, MDL
);
938 * Try to get the IPv6 address the client asked for from the
941 * addr is the result (should be a pointer to NULL on entry)
942 * pool is the pool to search in
943 * requested_addr is the address the client wants
946 try_client_v6_address(struct iasubopt
**addr
,
947 struct ipv6_pool
*pool
,
948 const struct data_string
*requested_addr
)
950 struct in6_addr tmp_addr
;
953 if (requested_addr
->len
< sizeof(tmp_addr
)) {
954 return DHCP_R_INVALIDARG
;
956 memcpy(&tmp_addr
, requested_addr
->data
, sizeof(tmp_addr
));
957 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
)) {
958 return ISC_R_FAILURE
;
962 * The address is not covered by this (or possibly any) dynamic
965 if (!ipv6_in_pool(&tmp_addr
, pool
)) {
966 return ISC_R_ADDRNOTAVAIL
;
969 if (lease6_exists(pool
, &tmp_addr
)) {
970 return ISC_R_ADDRINUSE
;
973 result
= iasubopt_allocate(addr
, MDL
);
974 if (result
!= ISC_R_SUCCESS
) {
977 (*addr
)->addr
= tmp_addr
;
980 /* Default is soft binding for 2 minutes. */
981 result
= add_lease6(pool
, *addr
, cur_time
+ 120);
982 if (result
!= ISC_R_SUCCESS
) {
983 iasubopt_dereference(addr
, MDL
);
989 * Get an IPv6 address for the client.
991 * addr is the result (should be a pointer to NULL on entry)
992 * packet is the information about the packet from the client
993 * requested_iaaddr is a hint from the client
994 * client_id is the DUID for the client
997 pick_v6_address(struct iasubopt
**addr
, struct shared_network
*shared_network
,
998 const struct data_string
*client_id
)
1000 struct ipv6_pool
*p
;
1003 unsigned int attempts
;
1004 char tmp_buf
[INET6_ADDRSTRLEN
];
1007 * No address pools, we're done.
1009 if (shared_network
->ipv6_pools
== NULL
) {
1010 log_debug("Unable to pick client address: "
1011 "no IPv6 pools on this shared network");
1012 return ISC_R_NORESOURCES
;
1015 p
= shared_network
->ipv6_pools
[i
];
1017 log_debug("Unable to pick client address: "
1018 "no IPv6 address pools "
1019 "on this shared network");
1020 return ISC_R_NORESOURCES
;
1022 if (p
->pool_type
== D6O_IA_NA
) {
1028 * Otherwise try to get a lease from the first subnet possible.
1030 * We start looking at the last pool we allocated from, unless
1031 * it had a collision trying to allocate an address. This will
1032 * tend to move us into less-filled pools.
1034 start_pool
= shared_network
->last_ipv6_pool
;
1038 p
= shared_network
->ipv6_pools
[i
];
1039 if ((p
->pool_type
== D6O_IA_NA
) &&
1040 (create_lease6(p
, addr
, &attempts
, client_id
,
1041 cur_time
+ 120) == ISC_R_SUCCESS
)) {
1043 * Record the pool used (or next one if there
1048 if (shared_network
->ipv6_pools
[i
] == NULL
) {
1052 shared_network
->last_ipv6_pool
= i
;
1054 log_debug("Picking pool address %s",
1055 inet_ntop(AF_INET6
, &((*addr
)->addr
),
1056 tmp_buf
, sizeof(tmp_buf
)));
1057 return ISC_R_SUCCESS
;
1061 if (shared_network
->ipv6_pools
[i
] == NULL
) {
1064 } while (i
!= start_pool
);
1067 * If we failed to pick an IPv6 address from any of the subnets.
1068 * Presumably that means we have no addresses for the client.
1070 log_debug("Unable to pick client address: no addresses available");
1071 return ISC_R_NORESOURCES
;
1075 * Try to get the IPv6 prefix the client asked for from the
1078 * pref is the result (should be a pointer to NULL on entry)
1079 * pool is the prefix pool to search in
1080 * requested_pref is the address the client wants
1083 try_client_v6_prefix(struct iasubopt
**pref
,
1084 struct ipv6_pool
*pool
,
1085 const struct data_string
*requested_pref
)
1088 struct in6_addr tmp_pref
;
1090 isc_result_t result
;
1092 if (requested_pref
->len
< sizeof(tmp_plen
) + sizeof(tmp_pref
)) {
1093 return DHCP_R_INVALIDARG
;
1095 tmp_plen
= (int) requested_pref
->data
[0];
1096 if ((tmp_plen
< 3) || (tmp_plen
> 128) ||
1097 ((int)tmp_plen
!= pool
->units
)) {
1098 return ISC_R_FAILURE
;
1100 memcpy(&tmp_pref
, requested_pref
->data
+ 1, sizeof(tmp_pref
));
1101 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref
)) {
1102 return ISC_R_FAILURE
;
1105 memcpy(&ia
.iabuf
, &tmp_pref
, 16);
1106 if (!is_cidr_mask_valid(&ia
, (int) tmp_plen
)) {
1107 return ISC_R_FAILURE
;
1110 if (!ipv6_in_pool(&tmp_pref
, pool
)) {
1111 return ISC_R_ADDRNOTAVAIL
;
1114 if (prefix6_exists(pool
, &tmp_pref
, tmp_plen
)) {
1115 return ISC_R_ADDRINUSE
;
1118 result
= iasubopt_allocate(pref
, MDL
);
1119 if (result
!= ISC_R_SUCCESS
) {
1122 (*pref
)->addr
= tmp_pref
;
1123 (*pref
)->plen
= tmp_plen
;
1125 /* Default is soft binding for 2 minutes. */
1126 result
= add_lease6(pool
, *pref
, cur_time
+ 120);
1127 if (result
!= ISC_R_SUCCESS
) {
1128 iasubopt_dereference(pref
, MDL
);
1134 * Get an IPv6 prefix for the client.
1136 * pref is the result (should be a pointer to NULL on entry)
1137 * packet is the information about the packet from the client
1138 * requested_iaprefix is a hint from the client
1139 * plen is -1 or the requested prefix length
1140 * client_id is the DUID for the client
1143 pick_v6_prefix(struct iasubopt
**pref
, int plen
,
1144 struct shared_network
*shared_network
,
1145 const struct data_string
*client_id
)
1147 struct ipv6_pool
*p
;
1149 unsigned int attempts
;
1150 char tmp_buf
[INET6_ADDRSTRLEN
];
1153 * No prefix pools, we're done.
1155 if (shared_network
->ipv6_pools
== NULL
) {
1156 log_debug("Unable to pick client prefix: "
1157 "no IPv6 pools on this shared network");
1158 return ISC_R_NORESOURCES
;
1161 p
= shared_network
->ipv6_pools
[i
];
1163 log_debug("Unable to pick client prefix: "
1164 "no IPv6 prefix pools "
1165 "on this shared network");
1166 return ISC_R_NORESOURCES
;
1168 if (p
->pool_type
== D6O_IA_PD
) {
1174 * Otherwise try to get a prefix.
1177 p
= shared_network
->ipv6_pools
[i
];
1181 if (p
->pool_type
!= D6O_IA_PD
) {
1186 * Try only pools with the requested prefix length if any.
1188 if ((plen
>= 0) && (p
->units
!= plen
)) {
1192 if (create_prefix6(p
, pref
, &attempts
, client_id
,
1193 cur_time
+ 120) == ISC_R_SUCCESS
) {
1194 log_debug("Picking pool prefix %s/%u",
1195 inet_ntop(AF_INET6
, &((*pref
)->addr
),
1196 tmp_buf
, sizeof(tmp_buf
)),
1197 (unsigned) (*pref
)->plen
);
1198 return ISC_R_SUCCESS
;
1203 * If we failed to pick an IPv6 prefix
1204 * Presumably that means we have no prefixes for the client.
1206 log_debug("Unable to pick client prefix: no prefixes available");
1207 return ISC_R_NORESOURCES
;
1211 *! \file server/dhcpv6.c
1213 * \brief construct a reply containing information about a client's lease
1215 * lease_to_client() is called from several messages to construct a
1216 * reply that contains all that we know about the client's correct lease
1217 * (or projected lease).
1219 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1220 * send what we "may" give them on a request.
1222 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1223 * the client should really use).
1225 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1226 * Rebind out any "wrong" addresses the client sends. This means we send
1227 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1228 * possibly send the address with zeroed lifetimes.
1230 * Information-Request - No binding.
1232 * The basic structure is to traverse the client-supplied data first, and
1233 * validate and echo back any contents that can be. If the client-supplied
1234 * data does not error out (on renew/rebind as above), but we did not send
1235 * any addresses, attempt to allocate one.
1237 * At the end of the this function we call commit_leases_timed() to
1238 * fsync and rotate the file as necessary. commit_leases_timed() will
1239 * check that we have written at least one lease to the file and that
1240 * some time has passed before doing any fsync or file rewrite so we
1241 * don't bother tracking if we did a write_ia during this function.
1243 /* TODO: look at client hints for lease times */
1246 lease_to_client(struct data_string
*reply_ret
,
1247 struct packet
*packet
,
1248 const struct data_string
*client_id
,
1249 const struct data_string
*server_id
)
1251 static struct reply_state reply
;
1252 struct option_cache
*oc
;
1253 struct data_string packet_oro
;
1254 #if defined (RFC3315_PRE_ERRATA_2010_08)
1255 isc_boolean_t no_resources_avail
= ISC_FALSE
;
1258 memset(&packet_oro
, 0, sizeof(packet_oro
));
1260 /* Locate the client. */
1261 if (shared_network_from_packet6(&reply
.shared
,
1262 packet
) != ISC_R_SUCCESS
)
1266 * Initialize the reply.
1268 packet_reference(&reply
.packet
, packet
, MDL
);
1269 data_string_copy(&reply
.client_id
, client_id
, MDL
);
1271 if (!start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
1275 /* Set the write cursor to just past the reply header. */
1276 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1279 * Get the ORO from the packet, if any.
1281 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ORO
);
1283 if (!evaluate_option_cache(&packet_oro
, packet
,
1285 packet
->options
, NULL
,
1286 &global_scope
, oc
, MDL
)) {
1287 log_error("lease_to_client: error evaluating ORO.");
1293 * Find a host record that matches from the packet, if any, and is
1294 * valid for the shared network the client is on.
1296 if (find_hosts_by_uid(&reply
.host
, client_id
->data
, client_id
->len
,
1298 seek_shared_host(&reply
.host
, reply
.shared
);
1300 if ((reply
.host
== NULL
) &&
1301 find_hosts_by_option(&reply
.host
, packet
, packet
->options
, MDL
))
1302 seek_shared_host(&reply
.host
, reply
.shared
);
1305 * Check for 'hardware' matches last, as some of the synthesis methods
1306 * are not considered to be as reliable.
1308 if ((reply
.host
== NULL
) &&
1309 find_hosts_by_duid_chaddr(&reply
.host
, client_id
))
1310 seek_shared_host(&reply
.host
, reply
.shared
);
1312 /* Process the client supplied IA's onto the reply buffer. */
1314 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
1316 for (; oc
!= NULL
; oc
= oc
->next
) {
1317 isc_result_t status
;
1319 /* Start counting resources (addresses) offered. */
1320 reply
.client_resources
= 0;
1321 reply
.resources_included
= ISC_FALSE
;
1323 status
= reply_process_ia_na(&reply
, oc
);
1326 * We continue to try other IA's whether we can address
1327 * this one or not. Any other result is an immediate fail.
1329 if ((status
!= ISC_R_SUCCESS
) &&
1330 (status
!= ISC_R_NORESOURCES
))
1333 #if defined (RFC3315_PRE_ERRATA_2010_08)
1335 * If any address cannot be given to any IA, then set the
1336 * NoAddrsAvail status code.
1338 if (reply
.client_resources
== 0)
1339 no_resources_avail
= ISC_TRUE
;
1342 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
1343 for (; oc
!= NULL
; oc
= oc
->next
) {
1344 isc_result_t status
;
1346 /* Start counting resources (addresses) offered. */
1347 reply
.client_resources
= 0;
1348 reply
.resources_included
= ISC_FALSE
;
1350 status
= reply_process_ia_ta(&reply
, oc
);
1353 * We continue to try other IA's whether we can address
1354 * this one or not. Any other result is an immediate fail.
1356 if ((status
!= ISC_R_SUCCESS
) &&
1357 (status
!= ISC_R_NORESOURCES
))
1360 #if defined (RFC3315_PRE_ERRATA_2010_08)
1362 * If any address cannot be given to any IA, then set the
1363 * NoAddrsAvail status code.
1365 if (reply
.client_resources
== 0)
1366 no_resources_avail
= ISC_TRUE
;
1370 /* Same for IA_PD's. */
1372 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
1373 for (; oc
!= NULL
; oc
= oc
->next
) {
1374 isc_result_t status
;
1376 /* Start counting resources (prefixes) offered. */
1377 reply
.client_resources
= 0;
1378 reply
.resources_included
= ISC_FALSE
;
1380 status
= reply_process_ia_pd(&reply
, oc
);
1383 * We continue to try other IA_PD's whether we can address
1384 * this one or not. Any other result is an immediate fail.
1386 if ((status
!= ISC_R_SUCCESS
) &&
1387 (status
!= ISC_R_NORESOURCES
))
1392 * Make no reply if we gave no resources and is not
1393 * for Information-Request.
1395 if ((reply
.ia_count
== 0) && (reply
.pd_count
== 0)) {
1396 if (reply
.packet
->dhcpv6_msg_type
!=
1397 DHCPV6_INFORMATION_REQUEST
)
1401 * Because we only execute statements on a per-IA basis,
1402 * we need to execute statements in any non-IA reply to
1403 * source configuration.
1405 execute_statements_in_scope(NULL
, reply
.packet
, NULL
, NULL
,
1406 reply
.packet
->options
,
1407 reply
.opt_state
, &global_scope
,
1408 reply
.shared
->group
, root_group
);
1410 /* Bring in any configuration from a host record. */
1411 if (reply
.host
!= NULL
)
1412 execute_statements_in_scope(NULL
, reply
.packet
, NULL
,
1413 NULL
, reply
.packet
->options
,
1417 reply
.shared
->group
);
1421 * RFC3315 section 17.2.2 (Solicit):
1423 * If the server will not assign any addresses to any IAs in a
1424 * subsequent Request from the client, the server MUST send an
1425 * Advertise message to the client that includes only a Status
1426 * Code option with code NoAddrsAvail and a status message for
1427 * the user, a Server Identifier option with the server's DUID,
1428 * and a Client Identifier option with the client's DUID.
1430 * Section 18.2.1 (Request):
1432 * If the server cannot assign any addresses to an IA in the
1433 * message from the client, the server MUST include the IA in
1434 * the Reply message with no addresses in the IA and a Status
1435 * Code option in the IA containing status code NoAddrsAvail.
1437 * Section 18.1.8 (Client Behavior):
1439 * Leave unchanged any information about addresses the client has
1440 * recorded in the IA but that were not included in the IA from
1442 * Sends a Renew/Rebind if the IA is not in the Reply message.
1444 #if defined (RFC3315_PRE_ERRATA_2010_08)
1445 if (no_resources_avail
&& (reply
.ia_count
!= 0) &&
1446 (reply
.packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
))
1448 /* Set the NoAddrsAvail status code. */
1449 if (!set_status_code(STATUS_NoAddrsAvail
,
1450 "No addresses available for this "
1451 "interface.", reply
.opt_state
)) {
1452 log_error("lease_to_client: Unable to set "
1453 "NoAddrsAvail status code.");
1457 /* Rewind the cursor to the start. */
1458 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1461 * Produce an advertise that includes only:
1467 reply
.buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
1468 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+
1472 reply
.opt_state
, reply
.packet
,
1477 * Having stored the client's IA's, store any options that
1478 * will fit in the remaining space.
1480 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+
1484 reply
.opt_state
, reply
.packet
,
1485 required_opts_solicit
,
1488 #else /* defined (RFC3315_PRE_ERRATA_2010_08) */
1490 * Having stored the client's IA's, store any options that
1491 * will fit in the remaining space.
1493 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+ reply
.cursor
,
1494 sizeof(reply
.buf
) - reply
.cursor
,
1495 reply
.opt_state
, reply
.packet
,
1496 required_opts_solicit
,
1498 #endif /* defined (RFC3315_PRE_ERRATA_2010_08) */
1500 /* Return our reply to the caller. */
1501 reply_ret
->len
= reply
.cursor
;
1502 reply_ret
->buffer
= NULL
;
1503 if (!buffer_allocate(&reply_ret
->buffer
, reply
.cursor
, MDL
)) {
1504 log_fatal("No memory to store Reply.");
1506 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
, reply
.cursor
);
1507 reply_ret
->data
= reply_ret
->buffer
->data
;
1509 /* If appropriate commit and rotate the lease file */
1510 (void) commit_leases_timed();
1514 if (reply
.shared
!= NULL
)
1515 shared_network_dereference(&reply
.shared
, MDL
);
1516 if (reply
.host
!= NULL
)
1517 host_dereference(&reply
.host
, MDL
);
1518 if (reply
.opt_state
!= NULL
)
1519 option_state_dereference(&reply
.opt_state
, MDL
);
1520 if (reply
.packet
!= NULL
)
1521 packet_dereference(&reply
.packet
, MDL
);
1522 if (reply
.client_id
.data
!= NULL
)
1523 data_string_forget(&reply
.client_id
, MDL
);
1524 if (packet_oro
.buffer
!= NULL
)
1525 data_string_forget(&packet_oro
, MDL
);
1526 reply
.renew
= reply
.rebind
= reply
.prefer
= reply
.valid
= 0;
1530 /* Process a client-supplied IA_NA. This may append options to the tail of
1531 * the reply packet being built in the reply_state structure.
1534 reply_process_ia_na(struct reply_state
*reply
, struct option_cache
*ia
) {
1535 isc_result_t status
= ISC_R_SUCCESS
;
1538 struct option_state
*packet_ia
;
1539 struct option_cache
*oc
;
1540 struct data_string ia_data
, data
;
1542 /* Initialize values that will get cleaned up on return. */
1544 memset(&ia_data
, 0, sizeof(ia_data
));
1545 memset(&data
, 0, sizeof(data
));
1547 * Note that find_client_address() may set reply->lease.
1550 /* Make sure there is at least room for the header. */
1551 if ((reply
->cursor
+ IA_NA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
1552 log_error("reply_process_ia_na: Reply too long for IA.");
1553 return ISC_R_NOSPACE
;
1557 /* Fetch the IA_NA contents. */
1558 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
1559 ia
, IA_NA_OFFSET
)) {
1560 log_error("reply_process_ia_na: error evaluating ia");
1561 status
= ISC_R_FAILURE
;
1565 /* Extract IA_NA header contents. */
1566 iaid
= getULong(ia_data
.data
);
1567 reply
->renew
= getULong(ia_data
.data
+ 4);
1568 reply
->rebind
= getULong(ia_data
.data
+ 8);
1570 /* Create an IA_NA structure. */
1571 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
1572 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
1573 log_error("reply_process_ia_na: no memory for ia.");
1574 status
= ISC_R_NOMEMORY
;
1577 reply
->ia
->ia_type
= D6O_IA_NA
;
1579 /* Cache pre-existing IA, if any. */
1580 ia_hash_lookup(&reply
->old_ia
, ia_na_active
,
1581 (unsigned char *)reply
->ia
->iaid_duid
.data
,
1582 reply
->ia
->iaid_duid
.len
, MDL
);
1585 * Create an option cache to carry the IA_NA option contents, and
1586 * execute any user-supplied values into it.
1588 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
1589 status
= ISC_R_NOMEMORY
;
1593 /* Check & cache the fixed host record. */
1594 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_addr
!= NULL
)) {
1595 struct iaddr tmp_addr
;
1597 if (!evaluate_option_cache(&reply
->fixed
, NULL
, NULL
, NULL
,
1598 NULL
, NULL
, &global_scope
,
1599 reply
->host
->fixed_addr
, MDL
)) {
1600 log_error("reply_process_ia_na: unable to evaluate "
1602 status
= ISC_R_FAILURE
;
1606 if (reply
->fixed
.len
< 16) {
1607 log_error("reply_process_ia_na: invalid fixed address.");
1608 status
= DHCP_R_INVALIDARG
;
1612 /* Find the static lease's subnet. */
1614 memcpy(tmp_addr
.iabuf
, reply
->fixed
.data
, 16);
1616 if (find_grouped_subnet(&reply
->subnet
, reply
->shared
,
1617 tmp_addr
, MDL
) == 0)
1618 log_fatal("Impossible condition at %s:%d.", MDL
);
1620 reply
->static_lease
= ISC_TRUE
;
1622 reply
->static_lease
= ISC_FALSE
;
1625 * Save the cursor position at the start of the IA, so we can
1626 * set length and adjust t1/t2 values later. We write a temporary
1627 * header out now just in case we decide to adjust the packet
1628 * within sub-process functions.
1630 ia_cursor
= reply
->cursor
;
1632 /* Initialize the IA_NA header. First the code. */
1633 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_NA
);
1636 /* Then option length. */
1637 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
1640 /* Then IA_NA header contents; IAID. */
1641 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
1644 /* We store the client's t1 for now, and may over-ride it later. */
1645 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
1648 /* We store the client's t2 for now, and may over-ride it later. */
1649 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
1653 * For each address in this IA_NA, decide what to do about it.
1657 * The client leaves unchanged any information about addresses
1658 * it has recorded but are not included ("cancel/break" below).
1659 * A not included IA ("cleanup" below) could give a Renew/Rebind.
1661 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
1662 reply
->valid
= reply
->prefer
= 0xffffffff;
1663 reply
->client_valid
= reply
->client_prefer
= 0;
1664 for (; oc
!= NULL
; oc
= oc
->next
) {
1665 status
= reply_process_addr(reply
, oc
);
1668 * Canceled means we did not allocate addresses to the
1669 * client, but we're "done" with this IA - we set a status
1670 * code. So transmit this reply, e.g., move on to the next
1673 if (status
== ISC_R_CANCELED
)
1676 if ((status
!= ISC_R_SUCCESS
) &&
1677 (status
!= ISC_R_ADDRINUSE
) &&
1678 (status
!= ISC_R_ADDRNOTAVAIL
))
1685 * If we fell through the above and never gave the client
1686 * an address, give it one now.
1688 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
1689 status
= find_client_address(reply
);
1691 if (status
== ISC_R_NORESOURCES
) {
1692 switch (reply
->packet
->dhcpv6_msg_type
) {
1693 case DHCPV6_SOLICIT
:
1695 * No address for any IA is handled
1700 case DHCPV6_REQUEST
:
1701 /* Section 18.2.1 (Request):
1703 * If the server cannot assign any addresses to
1704 * an IA in the message from the client, the
1705 * server MUST include the IA in the Reply
1706 * message with no addresses in the IA and a
1707 * Status Code option in the IA containing
1708 * status code NoAddrsAvail.
1710 option_state_dereference(&reply
->reply_ia
, MDL
);
1711 if (!option_state_allocate(&reply
->reply_ia
,
1714 log_error("reply_process_ia_na: No "
1715 "memory for option state "
1717 status
= ISC_R_NOMEMORY
;
1721 if (!set_status_code(STATUS_NoAddrsAvail
,
1722 "No addresses available "
1723 "for this interface.",
1725 log_error("reply_process_ia_na: Unable "
1726 "to set NoAddrsAvail status "
1728 status
= ISC_R_FAILURE
;
1732 status
= ISC_R_SUCCESS
;
1737 * RFC 3315 does not tell us to emit a status
1738 * code in this condition, or anything else.
1740 * If we included non-allocated addresses
1741 * (zeroed lifetimes) in an IA, then the client
1742 * will deconfigure them.
1744 * So we want to include the IA even if we
1745 * can't give it a new address if it includes
1746 * zeroed lifetime addresses.
1748 * We don't want to include the IA if we
1749 * provide zero addresses including zeroed
1752 if (reply
->resources_included
)
1753 status
= ISC_R_SUCCESS
;
1760 if (status
!= ISC_R_SUCCESS
)
1764 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
1765 sizeof(reply
->buf
) - reply
->cursor
,
1766 reply
->reply_ia
, reply
->packet
,
1767 required_opts_IA
, NULL
);
1769 /* Reset the length of this IA to match what was just written. */
1770 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
1771 reply
->cursor
- (ia_cursor
+ 4));
1774 * T1/T2 time selection is kind of weird. We actually use DHCP
1775 * (v4) scoped options as handy existing places where these might
1776 * be configured by an administrator. A value of zero tells the
1777 * client it may choose its own renewal time.
1780 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
1781 DHO_DHCP_RENEWAL_TIME
);
1783 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
1784 reply
->packet
->options
,
1785 reply
->opt_state
, &global_scope
,
1788 log_error("Invalid renewal time.");
1790 reply
->renew
= getULong(data
.data
);
1793 if (data
.data
!= NULL
)
1794 data_string_forget(&data
, MDL
);
1796 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
1800 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
1801 DHO_DHCP_REBINDING_TIME
);
1803 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
1804 reply
->packet
->options
,
1805 reply
->opt_state
, &global_scope
,
1808 log_error("Invalid rebinding time.");
1810 reply
->rebind
= getULong(data
.data
);
1813 if (data
.data
!= NULL
)
1814 data_string_forget(&data
, MDL
);
1816 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
1819 * If this is not a 'soft' binding, consume the new changes into
1820 * the database (if any have been attached to the ia_na).
1822 * Loop through the assigned dynamic addresses, referencing the
1823 * leases onto this IA_NA rather than any old ones, and updating
1824 * pool timers for each (if any).
1826 if ((status
!= ISC_R_CANCELED
) && !reply
->static_lease
&&
1827 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
1828 (reply
->ia
->num_iasubopt
!= 0)) {
1829 struct iasubopt
*tmp
;
1830 struct data_string
*ia_id
;
1833 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
1834 tmp
= reply
->ia
->iasubopt
[i
];
1836 if (tmp
->ia
!= NULL
)
1837 ia_dereference(&tmp
->ia
, MDL
);
1838 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
1840 /* Commit 'hard' bindings. */
1841 renew_lease6(tmp
->ipv6_pool
, tmp
);
1842 schedule_lease_timeout(tmp
->ipv6_pool
);
1844 #if defined (NSUPDATE)
1846 * Perform ddns updates.
1848 oc
= lookup_option(&server_universe
, reply
->opt_state
,
1851 evaluate_boolean_option_cache(NULL
, reply
->packet
,
1853 reply
->packet
->options
,
1857 ddns_updates(reply
->packet
, NULL
, NULL
,
1858 tmp
, NULL
, reply
->opt_state
);
1863 /* Remove any old ia from the hash. */
1864 if (reply
->old_ia
!= NULL
) {
1865 ia_id
= &reply
->old_ia
->iaid_duid
;
1866 ia_hash_delete(ia_na_active
,
1867 (unsigned char *)ia_id
->data
,
1869 ia_dereference(&reply
->old_ia
, MDL
);
1872 /* Put new ia into the hash. */
1873 reply
->ia
->cltt
= cur_time
;
1874 ia_id
= &reply
->ia
->iaid_duid
;
1875 ia_hash_add(ia_na_active
, (unsigned char *)ia_id
->data
,
1876 ia_id
->len
, reply
->ia
, MDL
);
1878 write_ia(reply
->ia
);
1882 if (packet_ia
!= NULL
)
1883 option_state_dereference(&packet_ia
, MDL
);
1884 if (reply
->reply_ia
!= NULL
)
1885 option_state_dereference(&reply
->reply_ia
, MDL
);
1886 if (ia_data
.data
!= NULL
)
1887 data_string_forget(&ia_data
, MDL
);
1888 if (data
.data
!= NULL
)
1889 data_string_forget(&data
, MDL
);
1890 if (reply
->ia
!= NULL
)
1891 ia_dereference(&reply
->ia
, MDL
);
1892 if (reply
->old_ia
!= NULL
)
1893 ia_dereference(&reply
->old_ia
, MDL
);
1894 if (reply
->lease
!= NULL
)
1895 iasubopt_dereference(&reply
->lease
, MDL
);
1896 if (reply
->fixed
.data
!= NULL
)
1897 data_string_forget(&reply
->fixed
, MDL
);
1898 if (reply
->subnet
!= NULL
)
1899 subnet_dereference(&reply
->subnet
, MDL
);
1902 * ISC_R_CANCELED is a status code used by the addr processing to
1903 * indicate we're replying with a status code. This is still a
1904 * success at higher layers.
1906 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
1910 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
1911 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
1912 * in the event we are replying with a status code and do not wish to process
1913 * more IAADDRs within this IA.
1916 reply_process_addr(struct reply_state
*reply
, struct option_cache
*addr
) {
1917 u_int32_t pref_life
, valid_life
;
1918 struct binding_scope
**scope
;
1919 struct group
*group
;
1920 struct subnet
*subnet
;
1921 struct iaddr tmp_addr
;
1922 struct option_cache
*oc
;
1923 struct data_string iaaddr
, data
;
1924 isc_result_t status
= ISC_R_SUCCESS
;
1926 /* Initializes values that will be cleaned up. */
1927 memset(&iaaddr
, 0, sizeof(iaaddr
));
1928 memset(&data
, 0, sizeof(data
));
1929 /* Note that reply->lease may be set by address_is_owned() */
1932 * There is no point trying to process an incoming address if there
1933 * is no room for an outgoing address.
1935 if ((reply
->cursor
+ 28) > sizeof(reply
->buf
)) {
1936 log_error("reply_process_addr: Out of room for address.");
1937 return ISC_R_NOSPACE
;
1940 /* Extract this IAADDR option. */
1941 if (!evaluate_option_cache(&iaaddr
, reply
->packet
, NULL
, NULL
,
1942 reply
->packet
->options
, NULL
, &global_scope
,
1944 (iaaddr
.len
< IAADDR_OFFSET
)) {
1945 log_error("reply_process_addr: error evaluating IAADDR.");
1946 status
= ISC_R_FAILURE
;
1950 /* The first 16 bytes are the IPv6 address. */
1951 pref_life
= getULong(iaaddr
.data
+ 16);
1952 valid_life
= getULong(iaaddr
.data
+ 20);
1954 if ((reply
->client_valid
== 0) ||
1955 (reply
->client_valid
> valid_life
))
1956 reply
->client_valid
= valid_life
;
1958 if ((reply
->client_prefer
== 0) ||
1959 (reply
->client_prefer
> pref_life
))
1960 reply
->client_prefer
= pref_life
;
1963 * Clients may choose to send :: as an address, with the idea to give
1964 * hints about preferred-lifetime or valid-lifetime.
1967 memset(tmp_addr
.iabuf
, 0, 16);
1968 if (!memcmp(iaaddr
.data
, tmp_addr
.iabuf
, 16)) {
1969 /* Status remains success; we just ignore this one. */
1973 /* tmp_addr len remains 16 */
1974 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
1977 * Verify that this address is on the client's network.
1979 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
1980 subnet
= subnet
->next_sibling
) {
1981 if (addr_eq(subnet_number(tmp_addr
, subnet
->netmask
),
1986 /* Address not found on shared network. */
1987 if (subnet
== NULL
) {
1988 /* Ignore this address on 'soft' bindings. */
1989 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
1990 /* disable rapid commit */
1991 reply
->buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
1992 delete_option(&dhcpv6_universe
,
1995 /* status remains success */
2000 * RFC3315 section 18.2.1:
2002 * If the server finds that the prefix on one or more IP
2003 * addresses in any IA in the message from the client is not
2004 * appropriate for the link to which the client is connected,
2005 * the server MUST return the IA to the client with a Status
2006 * Code option with the value NotOnLink.
2008 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) {
2009 /* Rewind the IA_NA to empty. */
2010 option_state_dereference(&reply
->reply_ia
, MDL
);
2011 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2012 log_error("reply_process_addr: No memory for "
2013 "option state wipe.");
2014 status
= ISC_R_NOMEMORY
;
2018 /* Append a NotOnLink status code. */
2019 if (!set_status_code(STATUS_NotOnLink
,
2020 "Address not for use on this "
2021 "link.", reply
->reply_ia
)) {
2022 log_error("reply_process_addr: Failure "
2023 "setting status code.");
2024 status
= ISC_R_FAILURE
;
2028 /* Fin (no more IAADDRs). */
2029 status
= ISC_R_CANCELED
;
2034 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2036 * If the server finds that any of the addresses are not
2037 * appropriate for the link to which the client is attached,
2038 * the server returns the address to the client with lifetimes
2041 if ((reply
->packet
->dhcpv6_msg_type
!= DHCPV6_RENEW
) &&
2042 (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
2043 log_error("It is impossible to lease a client that is "
2044 "not sending a solicit, request, renew, or "
2046 status
= ISC_R_FAILURE
;
2050 reply
->send_prefer
= reply
->send_valid
= 0;
2054 /* Verify the address belongs to the client. */
2055 if (!address_is_owned(reply
, &tmp_addr
)) {
2057 * For solicit and request, any addresses included are
2058 * 'requested' addresses. For rebind, we actually have
2059 * no direction on what to do from 3315 section 18.2.4!
2060 * So I think the best bet is to try and give it out, and if
2061 * we can't, zero lifetimes.
2063 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
2064 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
2065 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
2066 status
= reply_process_try_addr(reply
, &tmp_addr
);
2069 * If the address is in use, or isn't in any dynamic
2070 * range, continue as normal. If any other error was
2073 if ((status
!= ISC_R_SUCCESS
) &&
2074 (status
!= ISC_R_ADDRINUSE
) &&
2075 (status
!= ISC_R_ADDRNOTAVAIL
))
2079 * If we didn't honor this lease, for solicit and
2080 * request we simply omit it from our answer. For
2081 * rebind, we send it with zeroed lifetimes.
2083 if (reply
->lease
== NULL
) {
2084 if (reply
->packet
->dhcpv6_msg_type
==
2086 reply
->send_prefer
= 0;
2087 reply
->send_valid
= 0;
2091 /* status remains success - ignore */
2095 * RFC3315 section 18.2.3:
2097 * If the server cannot find a client entry for the IA the
2098 * server returns the IA containing no addresses with a Status
2099 * Code option set to NoBinding in the Reply message.
2101 * On mismatch we (ab)use this pretending we have not the IA
2102 * as soon as we have not an address.
2104 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
2105 /* Rewind the IA_NA to empty. */
2106 option_state_dereference(&reply
->reply_ia
, MDL
);
2107 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2108 log_error("reply_process_addr: No memory for "
2109 "option state wipe.");
2110 status
= ISC_R_NOMEMORY
;
2114 /* Append a NoBinding status code. */
2115 if (!set_status_code(STATUS_NoBinding
,
2116 "Address not bound to this "
2117 "interface.", reply
->reply_ia
)) {
2118 log_error("reply_process_addr: Unable to "
2119 "attach status code.");
2120 status
= ISC_R_FAILURE
;
2124 /* Fin (no more IAADDRs). */
2125 status
= ISC_R_CANCELED
;
2128 log_error("It is impossible to lease a client that is "
2129 "not sending a solicit, request, renew, or "
2131 status
= ISC_R_FAILURE
;
2136 if (reply
->static_lease
) {
2137 if (reply
->host
== NULL
)
2138 log_fatal("Impossible condition at %s:%d.", MDL
);
2140 scope
= &global_scope
;
2141 group
= reply
->subnet
->group
;
2143 if (reply
->lease
== NULL
)
2144 log_fatal("Impossible condition at %s:%d.", MDL
);
2146 scope
= &reply
->lease
->scope
;
2147 group
= reply
->lease
->ipv6_pool
->subnet
->group
;
2151 * If client_resources is nonzero, then the reply_process_is_addressed
2152 * function has executed configuration state into the reply option
2153 * cache. We will use that valid cache to derive configuration for
2154 * whether or not to engage in additional addresses, and similar.
2156 if (reply
->client_resources
!= 0) {
2160 * Does this client have "enough" addresses already? Default
2161 * to one. Everybody gets one, and one should be enough for
2164 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2165 SV_LIMIT_ADDRS_PER_IA
);
2167 if (!evaluate_option_cache(&data
, reply
->packet
,
2169 reply
->packet
->options
,
2173 log_error("reply_process_addr: unable to "
2174 "evaluate addrs-per-ia value.");
2175 status
= ISC_R_FAILURE
;
2179 limit
= getULong(data
.data
);
2180 data_string_forget(&data
, MDL
);
2184 * If we wish to limit the client to a certain number of
2185 * addresses, then omit the address from the reply.
2187 if (reply
->client_resources
>= limit
)
2191 status
= reply_process_is_addressed(reply
, scope
, group
);
2192 if (status
!= ISC_R_SUCCESS
)
2196 status
= reply_process_send_addr(reply
, &tmp_addr
);
2199 if (iaaddr
.data
!= NULL
)
2200 data_string_forget(&iaaddr
, MDL
);
2201 if (data
.data
!= NULL
)
2202 data_string_forget(&data
, MDL
);
2203 if (reply
->lease
!= NULL
)
2204 iasubopt_dereference(&reply
->lease
, MDL
);
2210 * Verify the address belongs to the client. If we've got a host
2211 * record with a fixed address, it has to be the assigned address
2212 * (fault out all else). Otherwise it's a dynamic address, so lookup
2213 * that address and make sure it belongs to this DUID:IAID pair.
2215 static isc_boolean_t
2216 address_is_owned(struct reply_state
*reply
, struct iaddr
*addr
) {
2220 * This faults out addresses that don't match fixed addresses.
2222 if (reply
->static_lease
) {
2223 if (reply
->fixed
.data
== NULL
)
2224 log_fatal("Impossible condition at %s:%d.", MDL
);
2226 if (memcmp(addr
->iabuf
, reply
->fixed
.data
, 16) == 0)
2232 if ((reply
->old_ia
== NULL
) || (reply
->old_ia
->num_iasubopt
== 0))
2235 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2236 struct iasubopt
*tmp
;
2238 tmp
= reply
->old_ia
->iasubopt
[i
];
2240 if (memcmp(addr
->iabuf
, &tmp
->addr
, 16) == 0) {
2241 if (lease6_usable(tmp
) == ISC_FALSE
) {
2244 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
2252 /* Process a client-supplied IA_TA. This may append options to the tail of
2253 * the reply packet being built in the reply_state structure.
2256 reply_process_ia_ta(struct reply_state
*reply
, struct option_cache
*ia
) {
2257 isc_result_t status
= ISC_R_SUCCESS
;
2260 struct option_state
*packet_ia
;
2261 struct option_cache
*oc
;
2262 struct data_string ia_data
, data
;
2263 struct data_string iaaddr
;
2264 u_int32_t pref_life
, valid_life
;
2265 struct iaddr tmp_addr
;
2267 /* Initialize values that will get cleaned up on return. */
2269 memset(&ia_data
, 0, sizeof(ia_data
));
2270 memset(&data
, 0, sizeof(data
));
2271 memset(&iaaddr
, 0, sizeof(iaaddr
));
2273 /* Make sure there is at least room for the header. */
2274 if ((reply
->cursor
+ IA_TA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2275 log_error("reply_process_ia_ta: Reply too long for IA.");
2276 return ISC_R_NOSPACE
;
2280 /* Fetch the IA_TA contents. */
2281 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2282 ia
, IA_TA_OFFSET
)) {
2283 log_error("reply_process_ia_ta: error evaluating ia");
2284 status
= ISC_R_FAILURE
;
2288 /* Extract IA_TA header contents. */
2289 iaid
= getULong(ia_data
.data
);
2291 /* Create an IA_TA structure. */
2292 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2293 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2294 log_error("reply_process_ia_ta: no memory for ia.");
2295 status
= ISC_R_NOMEMORY
;
2298 reply
->ia
->ia_type
= D6O_IA_TA
;
2300 /* Cache pre-existing IA, if any. */
2301 ia_hash_lookup(&reply
->old_ia
, ia_ta_active
,
2302 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2303 reply
->ia
->iaid_duid
.len
, MDL
);
2306 * Create an option cache to carry the IA_TA option contents, and
2307 * execute any user-supplied values into it.
2309 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2310 status
= ISC_R_NOMEMORY
;
2315 * Temporary leases are dynamic by definition.
2317 reply
->static_lease
= ISC_FALSE
;
2320 * Save the cursor position at the start of the IA, so we can
2321 * set length later. We write a temporary
2322 * header out now just in case we decide to adjust the packet
2323 * within sub-process functions.
2325 ia_cursor
= reply
->cursor
;
2327 /* Initialize the IA_TA header. First the code. */
2328 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_TA
);
2331 /* Then option length. */
2332 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x04u
);
2335 /* Then IA_TA header contents; IAID. */
2336 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2340 * Deal with an IAADDR for lifetimes.
2341 * For all or none, process IAADDRs as hints.
2343 reply
->valid
= reply
->prefer
= 0xffffffff;
2344 reply
->client_valid
= reply
->client_prefer
= 0;
2345 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2346 for (; oc
!= NULL
; oc
= oc
->next
) {
2347 memset(&iaaddr
, 0, sizeof(iaaddr
));
2348 if (!evaluate_option_cache(&iaaddr
, reply
->packet
,
2350 reply
->packet
->options
, NULL
,
2351 &global_scope
, oc
, MDL
) ||
2352 (iaaddr
.len
< IAADDR_OFFSET
)) {
2353 log_error("reply_process_ia_ta: error "
2354 "evaluating IAADDR.");
2355 status
= ISC_R_FAILURE
;
2358 /* The first 16 bytes are the IPv6 address. */
2359 pref_life
= getULong(iaaddr
.data
+ 16);
2360 valid_life
= getULong(iaaddr
.data
+ 20);
2362 if ((reply
->client_valid
== 0) ||
2363 (reply
->client_valid
> valid_life
))
2364 reply
->client_valid
= valid_life
;
2366 if ((reply
->client_prefer
== 0) ||
2367 (reply
->client_prefer
> pref_life
))
2368 reply
->client_prefer
= pref_life
;
2370 /* Nothing more if something has failed. */
2371 if (status
== ISC_R_CANCELED
)
2375 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2376 if (!temporary_is_available(reply
, &tmp_addr
))
2378 status
= reply_process_is_addressed(reply
,
2379 &reply
->lease
->scope
,
2380 reply
->shared
->group
);
2381 if (status
!= ISC_R_SUCCESS
)
2383 status
= reply_process_send_addr(reply
, &tmp_addr
);
2384 if (status
!= ISC_R_SUCCESS
)
2386 if (reply
->lease
!= NULL
)
2387 iasubopt_dereference(&reply
->lease
, MDL
);
2391 /* Rewind the IA_TA to empty. */
2392 option_state_dereference(&reply
->reply_ia
, MDL
);
2393 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2394 status
= ISC_R_NOMEMORY
;
2397 status
= ISC_R_CANCELED
;
2398 reply
->client_resources
= 0;
2399 reply
->resources_included
= ISC_FALSE
;
2400 if (reply
->lease
!= NULL
)
2401 iasubopt_dereference(&reply
->lease
, MDL
);
2406 * Give the client temporary addresses.
2408 if (reply
->client_resources
!= 0)
2410 status
= find_client_temporaries(reply
);
2411 if (status
== ISC_R_NORESOURCES
) {
2412 switch (reply
->packet
->dhcpv6_msg_type
) {
2413 case DHCPV6_SOLICIT
:
2415 * No address for any IA is handled
2420 case DHCPV6_REQUEST
:
2421 /* Section 18.2.1 (Request):
2423 * If the server cannot assign any addresses to
2424 * an IA in the message from the client, the
2425 * server MUST include the IA in the Reply
2426 * message with no addresses in the IA and a
2427 * Status Code option in the IA containing
2428 * status code NoAddrsAvail.
2430 option_state_dereference(&reply
->reply_ia
, MDL
);
2431 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2432 log_error("reply_process_ia_ta: No "
2433 "memory for option state wipe.");
2434 status
= ISC_R_NOMEMORY
;
2438 if (!set_status_code(STATUS_NoAddrsAvail
,
2439 "No addresses available "
2440 "for this interface.",
2442 log_error("reply_process_ia_ta: Unable "
2443 "to set NoAddrsAvail status code.");
2444 status
= ISC_R_FAILURE
;
2448 status
= ISC_R_SUCCESS
;
2453 * We don't want to include the IA if we
2454 * provide zero addresses including zeroed
2457 if (reply
->resources_included
)
2458 status
= ISC_R_SUCCESS
;
2463 } else if (status
!= ISC_R_SUCCESS
)
2467 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2468 sizeof(reply
->buf
) - reply
->cursor
,
2469 reply
->reply_ia
, reply
->packet
,
2470 required_opts_IA
, NULL
);
2472 /* Reset the length of this IA to match what was just written. */
2473 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2474 reply
->cursor
- (ia_cursor
+ 4));
2477 * Consume the new changes into the database (if any have been
2478 * attached to the ia_ta).
2480 * Loop through the assigned dynamic addresses, referencing the
2481 * leases onto this IA_TA rather than any old ones, and updating
2482 * pool timers for each (if any).
2484 if ((status
!= ISC_R_CANCELED
) &&
2485 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
2486 (reply
->ia
->num_iasubopt
!= 0)) {
2487 struct iasubopt
*tmp
;
2488 struct data_string
*ia_id
;
2491 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2492 tmp
= reply
->ia
->iasubopt
[i
];
2494 if (tmp
->ia
!= NULL
)
2495 ia_dereference(&tmp
->ia
, MDL
);
2496 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2498 /* Commit 'hard' bindings. */
2499 renew_lease6(tmp
->ipv6_pool
, tmp
);
2500 schedule_lease_timeout(tmp
->ipv6_pool
);
2502 #if defined (NSUPDATE)
2504 * Perform ddns updates.
2506 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2509 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2511 reply
->packet
->options
,
2515 ddns_updates(reply
->packet
, NULL
, NULL
,
2516 tmp
, NULL
, reply
->opt_state
);
2521 /* Remove any old ia from the hash. */
2522 if (reply
->old_ia
!= NULL
) {
2523 ia_id
= &reply
->old_ia
->iaid_duid
;
2524 ia_hash_delete(ia_ta_active
,
2525 (unsigned char *)ia_id
->data
,
2527 ia_dereference(&reply
->old_ia
, MDL
);
2530 /* Put new ia into the hash. */
2531 reply
->ia
->cltt
= cur_time
;
2532 ia_id
= &reply
->ia
->iaid_duid
;
2533 ia_hash_add(ia_ta_active
, (unsigned char *)ia_id
->data
,
2534 ia_id
->len
, reply
->ia
, MDL
);
2536 write_ia(reply
->ia
);
2540 if (packet_ia
!= NULL
)
2541 option_state_dereference(&packet_ia
, MDL
);
2542 if (iaaddr
.data
!= NULL
)
2543 data_string_forget(&iaaddr
, MDL
);
2544 if (reply
->reply_ia
!= NULL
)
2545 option_state_dereference(&reply
->reply_ia
, MDL
);
2546 if (ia_data
.data
!= NULL
)
2547 data_string_forget(&ia_data
, MDL
);
2548 if (data
.data
!= NULL
)
2549 data_string_forget(&data
, MDL
);
2550 if (reply
->ia
!= NULL
)
2551 ia_dereference(&reply
->ia
, MDL
);
2552 if (reply
->old_ia
!= NULL
)
2553 ia_dereference(&reply
->old_ia
, MDL
);
2554 if (reply
->lease
!= NULL
)
2555 iasubopt_dereference(&reply
->lease
, MDL
);
2558 * ISC_R_CANCELED is a status code used by the addr processing to
2559 * indicate we're replying with other addresses. This is still a
2560 * success at higher layers.
2562 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2566 * Verify the temporary address is available.
2568 static isc_boolean_t
2569 temporary_is_available(struct reply_state
*reply
, struct iaddr
*addr
) {
2570 struct in6_addr tmp_addr
;
2571 struct subnet
*subnet
;
2572 struct ipv6_pool
*pool
;
2575 memcpy(&tmp_addr
, addr
->iabuf
, sizeof(tmp_addr
));
2577 * Clients may choose to send :: as an address, with the idea to give
2578 * hints about preferred-lifetime or valid-lifetime.
2579 * So this is not a request for this address.
2581 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
))
2585 * Verify that this address is on the client's network.
2587 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
2588 subnet
= subnet
->next_sibling
) {
2589 if (addr_eq(subnet_number(*addr
, subnet
->netmask
),
2594 /* Address not found on shared network. */
2599 * Check if this address is owned (must be before next step).
2601 if (address_is_owned(reply
, addr
))
2605 * Verify that this address is in a temporary pool and try to get it.
2607 if (reply
->shared
->ipv6_pools
== NULL
)
2609 for (i
= 0 ; (pool
= reply
->shared
->ipv6_pools
[i
]) != NULL
; i
++) {
2610 if (pool
->pool_type
!= D6O_IA_TA
)
2612 if (ipv6_in_pool(&tmp_addr
, pool
))
2617 if (lease6_exists(pool
, &tmp_addr
))
2619 if (iasubopt_allocate(&reply
->lease
, MDL
) != ISC_R_SUCCESS
)
2621 reply
->lease
->addr
= tmp_addr
;
2622 reply
->lease
->plen
= 0;
2623 /* Default is soft binding for 2 minutes. */
2624 if (add_lease6(pool
, reply
->lease
, cur_time
+ 120) != ISC_R_SUCCESS
)
2631 * Get a temporary address per prefix.
2634 find_client_temporaries(struct reply_state
*reply
) {
2635 struct shared_network
*shared
;
2637 struct ipv6_pool
*p
;
2638 isc_result_t status
;
2639 unsigned int attempts
;
2640 struct iaddr send_addr
;
2643 * No pools, we're done.
2645 shared
= reply
->shared
;
2646 if (shared
->ipv6_pools
== NULL
) {
2647 log_debug("Unable to get client addresses: "
2648 "no IPv6 pools on this shared network");
2649 return ISC_R_NORESOURCES
;
2652 status
= ISC_R_NORESOURCES
;
2654 p
= shared
->ipv6_pools
[i
];
2658 if (p
->pool_type
!= D6O_IA_TA
) {
2663 * Get an address in this temporary pool.
2665 status
= create_lease6(p
, &reply
->lease
, &attempts
,
2666 &reply
->client_id
, cur_time
+ 120);
2667 if (status
!= ISC_R_SUCCESS
) {
2668 log_debug("Unable to get a temporary address.");
2672 status
= reply_process_is_addressed(reply
,
2673 &reply
->lease
->scope
,
2674 reply
->lease
->ipv6_pool
->subnet
->group
);
2675 if (status
!= ISC_R_SUCCESS
) {
2679 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
2680 status
= reply_process_send_addr(reply
, &send_addr
);
2681 if (status
!= ISC_R_SUCCESS
) {
2685 * reply->lease can't be null as we use it above
2686 * add check if that changes
2688 iasubopt_dereference(&reply
->lease
, MDL
);
2692 if (reply
->lease
!= NULL
) {
2693 iasubopt_dereference(&reply
->lease
, MDL
);
2699 * This function only returns failure on 'hard' failures. If it succeeds,
2700 * it will leave a lease structure behind.
2703 reply_process_try_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
2704 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
2705 struct ipv6_pool
*pool
;
2707 struct data_string data_addr
;
2709 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
2710 (addr
== NULL
) || (reply
->lease
!= NULL
))
2711 return (DHCP_R_INVALIDARG
);
2713 if (reply
->shared
->ipv6_pools
== NULL
)
2714 return (ISC_R_ADDRNOTAVAIL
);
2716 memset(&data_addr
, 0, sizeof(data_addr
));
2717 data_addr
.len
= addr
->len
;
2718 data_addr
.data
= addr
->iabuf
;
2720 for (i
= 0 ; (pool
= reply
->shared
->ipv6_pools
[i
]) != NULL
; i
++) {
2721 if (pool
->pool_type
!= D6O_IA_NA
)
2723 status
= try_client_v6_address(&reply
->lease
, pool
,
2725 if (status
== ISC_R_SUCCESS
)
2729 /* Note that this is just pedantry. There is no allocation to free. */
2730 data_string_forget(&data_addr
, MDL
);
2731 /* Return just the most recent status... */
2735 /* Look around for an address to give the client. First, look through the
2736 * old IA for addresses we can extend. Second, try to allocate a new address.
2737 * Finally, actually add that address into the current reply IA.
2740 find_client_address(struct reply_state
*reply
) {
2741 struct iaddr send_addr
;
2742 isc_result_t status
= ISC_R_NORESOURCES
;
2743 struct iasubopt
*lease
, *best_lease
= NULL
;
2744 struct binding_scope
**scope
;
2745 struct group
*group
;
2748 if (reply
->static_lease
) {
2749 if (reply
->host
== NULL
)
2750 return DHCP_R_INVALIDARG
;
2753 memcpy(send_addr
.iabuf
, reply
->fixed
.data
, 16);
2755 status
= ISC_R_SUCCESS
;
2756 scope
= &global_scope
;
2757 group
= reply
->subnet
->group
;
2761 if (reply
->old_ia
!= NULL
) {
2762 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2763 struct shared_network
*candidate_shared
;
2765 lease
= reply
->old_ia
->iasubopt
[i
];
2766 candidate_shared
= lease
->ipv6_pool
->shared_network
;
2769 * Look for the best lease on the client's shared
2772 if ((candidate_shared
== reply
->shared
) &&
2773 (lease6_usable(lease
) == ISC_TRUE
)) {
2774 best_lease
= lease_compare(lease
, best_lease
);
2779 /* Try to pick a new address if we didn't find one, or if we found an
2782 if ((best_lease
== NULL
) || (best_lease
->state
== FTS_ABANDONED
)) {
2783 status
= pick_v6_address(&reply
->lease
, reply
->shared
,
2784 &reply
->ia
->iaid_duid
);
2785 } else if (best_lease
!= NULL
) {
2786 iasubopt_reference(&reply
->lease
, best_lease
, MDL
);
2787 status
= ISC_R_SUCCESS
;
2790 /* Pick the abandoned lease as a last resort. */
2791 if ((status
== ISC_R_NORESOURCES
) && (best_lease
!= NULL
)) {
2792 /* I don't see how this is supposed to be done right now. */
2793 log_error("Reclaiming abandoned addresses is not yet "
2794 "supported. Treating this as an out of space "
2796 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
2799 /* Give up now if we didn't find a lease. */
2800 if (status
!= ISC_R_SUCCESS
)
2803 if (reply
->lease
== NULL
)
2804 log_fatal("Impossible condition at %s:%d.", MDL
);
2806 /* Draw binding scopes from the lease's binding scope, and config
2807 * from the lease's containing subnet and higher. Note that it may
2808 * be desirable to place the group attachment directly in the pool.
2810 scope
= &reply
->lease
->scope
;
2811 group
= reply
->lease
->ipv6_pool
->subnet
->group
;
2814 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
2817 status
= reply_process_is_addressed(reply
, scope
, group
);
2818 if (status
!= ISC_R_SUCCESS
)
2821 status
= reply_process_send_addr(reply
, &send_addr
);
2825 /* Once an address is found for a client, perform several common functions;
2826 * Calculate and store valid and preferred lease times, draw client options
2827 * into the option state.
2830 reply_process_is_addressed(struct reply_state
*reply
,
2831 struct binding_scope
**scope
, struct group
*group
)
2833 isc_result_t status
= ISC_R_SUCCESS
;
2834 struct data_string data
;
2835 struct option_cache
*oc
;
2837 /* Initialize values we will cleanup. */
2838 memset(&data
, 0, sizeof(data
));
2841 * Bring configured options into the root packet level cache - start
2842 * with the lease's closest enclosing group (passed in by the caller
2845 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
2846 reply
->packet
->options
, reply
->opt_state
,
2847 scope
, group
, root_group
);
2850 * If there is a host record, over-ride with values configured there,
2851 * without re-evaluating configuration from the previously executed
2852 * group or its common enclosers.
2854 if (reply
->host
!= NULL
)
2855 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
2856 reply
->packet
->options
,
2857 reply
->opt_state
, scope
,
2858 reply
->host
->group
, group
);
2860 /* Determine valid lifetime. */
2861 if (reply
->client_valid
== 0)
2862 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
2864 reply
->send_valid
= reply
->client_valid
;
2866 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2867 SV_DEFAULT_LEASE_TIME
);
2869 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
2870 reply
->packet
->options
,
2874 log_error("reply_process_is_addressed: unable to "
2875 "evaluate default lease time");
2876 status
= ISC_R_FAILURE
;
2880 reply
->send_valid
= getULong(data
.data
);
2881 data_string_forget(&data
, MDL
);
2884 if (reply
->client_prefer
== 0)
2885 reply
->send_prefer
= reply
->send_valid
;
2887 reply
->send_prefer
= reply
->client_prefer
;
2889 if (reply
->send_prefer
>= reply
->send_valid
)
2890 reply
->send_prefer
= (reply
->send_valid
/ 2) +
2891 (reply
->send_valid
/ 8);
2893 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2894 SV_PREFER_LIFETIME
);
2896 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
2897 reply
->packet
->options
,
2901 log_error("reply_process_is_addressed: unable to "
2902 "evaluate preferred lease time");
2903 status
= ISC_R_FAILURE
;
2907 reply
->send_prefer
= getULong(data
.data
);
2908 data_string_forget(&data
, MDL
);
2911 /* Note lowest values for later calculation of renew/rebind times. */
2912 if (reply
->prefer
> reply
->send_prefer
)
2913 reply
->prefer
= reply
->send_prefer
;
2915 if (reply
->valid
> reply
->send_valid
)
2916 reply
->valid
= reply
->send_valid
;
2920 * XXX: Old 4.0.0 alpha code would change the host {} record
2921 * XXX: uid upon lease assignment. This was intended to cover the
2922 * XXX: case where a client first identifies itself using vendor
2923 * XXX: options in a solicit, or request, but later neglects to include
2924 * XXX: these options in a Renew or Rebind. It is not clear that this
2925 * XXX: is required, and has some startling ramifications (such as
2926 * XXX: how to recover this dynamic host {} state across restarts).
2928 if (reply
->host
!= NULL
)
2929 change_host_uid(host
, reply
->client_id
->data
,
2930 reply
->client_id
->len
);
2933 /* Perform dynamic lease related update work. */
2934 if (reply
->lease
!= NULL
) {
2935 /* Cached lifetimes */
2936 reply
->lease
->prefer
= reply
->send_prefer
;
2937 reply
->lease
->valid
= reply
->send_valid
;
2939 /* Advance (or rewind) the valid lifetime. */
2940 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
2941 reply
->lease
->soft_lifetime_end_time
=
2942 cur_time
+ reply
->send_valid
;
2943 /* Wait before renew! */
2946 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
2947 if (status
!= ISC_R_SUCCESS
) {
2948 log_fatal("reply_process_is_addressed: Unable to "
2949 "attach lease to new IA: %s",
2950 isc_result_totext(status
));
2954 * If this is a new lease, make sure it is attached somewhere.
2956 if (reply
->lease
->ia
== NULL
) {
2957 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
2961 /* Bring a copy of the relevant options into the IA scope. */
2962 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
2963 reply
->packet
->options
, reply
->reply_ia
,
2964 scope
, group
, root_group
);
2967 * And bring in host record configuration, if any, but not to overlap
2968 * the previous group or its common enclosers.
2970 if (reply
->host
!= NULL
)
2971 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
2972 reply
->packet
->options
,
2973 reply
->reply_ia
, scope
,
2974 reply
->host
->group
, group
);
2977 if (data
.data
!= NULL
)
2978 data_string_forget(&data
, MDL
);
2980 if (status
== ISC_R_SUCCESS
)
2981 reply
->client_resources
++;
2986 /* Simply send an IAADDR within the IA scope as described. */
2988 reply_process_send_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
2989 isc_result_t status
= ISC_R_SUCCESS
;
2990 struct data_string data
;
2992 memset(&data
, 0, sizeof(data
));
2994 /* Now append the lease. */
2995 data
.len
= IAADDR_OFFSET
;
2996 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
2997 log_error("reply_process_send_addr: out of memory"
2998 "allocating new IAADDR buffer.");
2999 status
= ISC_R_NOMEMORY
;
3002 data
.data
= data
.buffer
->data
;
3004 memcpy(data
.buffer
->data
, addr
->iabuf
, 16);
3005 putULong(data
.buffer
->data
+ 16, reply
->send_prefer
);
3006 putULong(data
.buffer
->data
+ 20, reply
->send_valid
);
3008 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
3009 data
.buffer
, data
.buffer
->data
,
3010 data
.len
, D6O_IAADDR
, 0)) {
3011 log_error("reply_process_send_addr: unable "
3012 "to save IAADDR option");
3013 status
= ISC_R_FAILURE
;
3017 reply
->resources_included
= ISC_TRUE
;
3020 if (data
.data
!= NULL
)
3021 data_string_forget(&data
, MDL
);
3026 /* Choose the better of two leases. */
3027 static struct iasubopt
*
3028 lease_compare(struct iasubopt
*alpha
, struct iasubopt
*beta
) {
3034 switch(alpha
->state
) {
3036 switch(beta
->state
) {
3038 /* Choose the lease with the longest lifetime (most
3039 * likely the most recently allocated).
3041 if (alpha
->hard_lifetime_end_time
<
3042 beta
->hard_lifetime_end_time
)
3052 log_fatal("Impossible condition at %s:%d.", MDL
);
3057 switch (beta
->state
) {
3062 /* Choose the most recently expired lease. */
3063 if (alpha
->hard_lifetime_end_time
<
3064 beta
->hard_lifetime_end_time
)
3066 else if ((alpha
->hard_lifetime_end_time
==
3067 beta
->hard_lifetime_end_time
) &&
3068 (alpha
->soft_lifetime_end_time
<
3069 beta
->soft_lifetime_end_time
))
3078 log_fatal("Impossible condition at %s:%d.", MDL
);
3083 switch (beta
->state
) {
3089 /* Choose the lease that was abandoned longest ago. */
3090 if (alpha
->hard_lifetime_end_time
<
3091 beta
->hard_lifetime_end_time
)
3095 log_fatal("Impossible condition at %s:%d.", MDL
);
3100 log_fatal("Impossible condition at %s:%d.", MDL
);
3103 log_fatal("Triple impossible condition at %s:%d.", MDL
);
3107 /* Process a client-supplied IA_PD. This may append options to the tail of
3108 * the reply packet being built in the reply_state structure.
3111 reply_process_ia_pd(struct reply_state
*reply
, struct option_cache
*ia
) {
3112 isc_result_t status
= ISC_R_SUCCESS
;
3115 struct option_state
*packet_ia
;
3116 struct option_cache
*oc
;
3117 struct data_string ia_data
, data
;
3119 /* Initialize values that will get cleaned up on return. */
3121 memset(&ia_data
, 0, sizeof(ia_data
));
3122 memset(&data
, 0, sizeof(data
));
3124 * Note that find_client_prefix() may set reply->lease.
3127 /* Make sure there is at least room for the header. */
3128 if ((reply
->cursor
+ IA_PD_OFFSET
+ 4) > sizeof(reply
->buf
)) {
3129 log_error("reply_process_ia_pd: Reply too long for IA.");
3130 return ISC_R_NOSPACE
;
3134 /* Fetch the IA_PD contents. */
3135 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
3136 ia
, IA_PD_OFFSET
)) {
3137 log_error("reply_process_ia_pd: error evaluating ia");
3138 status
= ISC_R_FAILURE
;
3142 /* Extract IA_PD header contents. */
3143 iaid
= getULong(ia_data
.data
);
3144 reply
->renew
= getULong(ia_data
.data
+ 4);
3145 reply
->rebind
= getULong(ia_data
.data
+ 8);
3147 /* Create an IA_PD structure. */
3148 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
3149 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
3150 log_error("reply_process_ia_pd: no memory for ia.");
3151 status
= ISC_R_NOMEMORY
;
3154 reply
->ia
->ia_type
= D6O_IA_PD
;
3156 /* Cache pre-existing IA_PD, if any. */
3157 ia_hash_lookup(&reply
->old_ia
, ia_pd_active
,
3158 (unsigned char *)reply
->ia
->iaid_duid
.data
,
3159 reply
->ia
->iaid_duid
.len
, MDL
);
3162 * Create an option cache to carry the IA_PD option contents, and
3163 * execute any user-supplied values into it.
3165 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
3166 status
= ISC_R_NOMEMORY
;
3170 /* Check & count the fixed prefix host records. */
3171 reply
->static_prefixes
= 0;
3172 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_prefix
!= NULL
)) {
3173 struct iaddrcidrnetlist
*fp
;
3175 for (fp
= reply
->host
->fixed_prefix
; fp
!= NULL
;
3177 reply
->static_prefixes
+= 1;
3182 * Save the cursor position at the start of the IA_PD, so we can
3183 * set length and adjust t1/t2 values later. We write a temporary
3184 * header out now just in case we decide to adjust the packet
3185 * within sub-process functions.
3187 ia_cursor
= reply
->cursor
;
3189 /* Initialize the IA_PD header. First the code. */
3190 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_PD
);
3193 /* Then option length. */
3194 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
3197 /* Then IA_PD header contents; IAID. */
3198 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
3201 /* We store the client's t1 for now, and may over-ride it later. */
3202 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
3205 /* We store the client's t2 for now, and may over-ride it later. */
3206 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
3210 * For each prefix in this IA_PD, decide what to do about it.
3212 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAPREFIX
);
3213 reply
->valid
= reply
->prefer
= 0xffffffff;
3214 reply
->client_valid
= reply
->client_prefer
= 0;
3215 reply
->preflen
= -1;
3216 for (; oc
!= NULL
; oc
= oc
->next
) {
3217 status
= reply_process_prefix(reply
, oc
);
3220 * Canceled means we did not allocate prefixes to the
3221 * client, but we're "done" with this IA - we set a status
3222 * code. So transmit this reply, e.g., move on to the next
3225 if (status
== ISC_R_CANCELED
)
3228 if ((status
!= ISC_R_SUCCESS
) &&
3229 (status
!= ISC_R_ADDRINUSE
) &&
3230 (status
!= ISC_R_ADDRNOTAVAIL
))
3237 * If we fell through the above and never gave the client
3238 * a prefix, give it one now.
3240 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
3241 status
= find_client_prefix(reply
);
3243 if (status
== ISC_R_NORESOURCES
) {
3244 switch (reply
->packet
->dhcpv6_msg_type
) {
3245 case DHCPV6_SOLICIT
:
3247 * No prefix for any IA is handled
3252 case DHCPV6_REQUEST
:
3253 /* Same than for addresses. */
3254 option_state_dereference(&reply
->reply_ia
, MDL
);
3255 if (!option_state_allocate(&reply
->reply_ia
,
3258 log_error("reply_process_ia_pd: No "
3259 "memory for option state "
3261 status
= ISC_R_NOMEMORY
;
3265 if (!set_status_code(STATUS_NoPrefixAvail
,
3266 "No prefixes available "
3267 "for this interface.",
3269 log_error("reply_process_ia_pd: "
3271 "NoPrefixAvail status "
3273 status
= ISC_R_FAILURE
;
3277 status
= ISC_R_SUCCESS
;
3281 if (reply
->resources_included
)
3282 status
= ISC_R_SUCCESS
;
3289 if (status
!= ISC_R_SUCCESS
)
3293 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
3294 sizeof(reply
->buf
) - reply
->cursor
,
3295 reply
->reply_ia
, reply
->packet
,
3296 required_opts_IA_PD
, NULL
);
3298 /* Reset the length of this IA_PD to match what was just written. */
3299 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
3300 reply
->cursor
- (ia_cursor
+ 4));
3303 * T1/T2 time selection is kind of weird. We actually use DHCP
3304 * (v4) scoped options as handy existing places where these might
3305 * be configured by an administrator. A value of zero tells the
3306 * client it may choose its own renewal time.
3309 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
3310 DHO_DHCP_RENEWAL_TIME
);
3312 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3313 reply
->packet
->options
,
3314 reply
->opt_state
, &global_scope
,
3317 log_error("Invalid renewal time.");
3319 reply
->renew
= getULong(data
.data
);
3322 if (data
.data
!= NULL
)
3323 data_string_forget(&data
, MDL
);
3325 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
3329 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
3330 DHO_DHCP_REBINDING_TIME
);
3332 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3333 reply
->packet
->options
,
3334 reply
->opt_state
, &global_scope
,
3337 log_error("Invalid rebinding time.");
3339 reply
->rebind
= getULong(data
.data
);
3342 if (data
.data
!= NULL
)
3343 data_string_forget(&data
, MDL
);
3345 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
3348 * If this is not a 'soft' binding, consume the new changes into
3349 * the database (if any have been attached to the ia_pd).
3351 * Loop through the assigned dynamic prefixes, referencing the
3352 * prefixes onto this IA_PD rather than any old ones, and updating
3353 * prefix pool timers for each (if any).
3355 if ((status
!= ISC_R_CANCELED
) && (reply
->static_prefixes
== 0) &&
3356 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
3357 (reply
->ia
->num_iasubopt
!= 0)) {
3358 struct iasubopt
*tmp
;
3359 struct data_string
*ia_id
;
3362 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3363 tmp
= reply
->ia
->iasubopt
[i
];
3365 if (tmp
->ia
!= NULL
)
3366 ia_dereference(&tmp
->ia
, MDL
);
3367 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
3369 /* Commit 'hard' bindings. */
3370 renew_lease6(tmp
->ipv6_pool
, tmp
);
3371 schedule_lease_timeout(tmp
->ipv6_pool
);
3374 /* Remove any old ia from the hash. */
3375 if (reply
->old_ia
!= NULL
) {
3376 ia_id
= &reply
->old_ia
->iaid_duid
;
3377 ia_hash_delete(ia_pd_active
,
3378 (unsigned char *)ia_id
->data
,
3380 ia_dereference(&reply
->old_ia
, MDL
);
3383 /* Put new ia into the hash. */
3384 reply
->ia
->cltt
= cur_time
;
3385 ia_id
= &reply
->ia
->iaid_duid
;
3386 ia_hash_add(ia_pd_active
, (unsigned char *)ia_id
->data
,
3387 ia_id
->len
, reply
->ia
, MDL
);
3389 write_ia(reply
->ia
);
3393 if (packet_ia
!= NULL
)
3394 option_state_dereference(&packet_ia
, MDL
);
3395 if (reply
->reply_ia
!= NULL
)
3396 option_state_dereference(&reply
->reply_ia
, MDL
);
3397 if (ia_data
.data
!= NULL
)
3398 data_string_forget(&ia_data
, MDL
);
3399 if (data
.data
!= NULL
)
3400 data_string_forget(&data
, MDL
);
3401 if (reply
->ia
!= NULL
)
3402 ia_dereference(&reply
->ia
, MDL
);
3403 if (reply
->old_ia
!= NULL
)
3404 ia_dereference(&reply
->old_ia
, MDL
);
3405 if (reply
->lease
!= NULL
)
3406 iasubopt_dereference(&reply
->lease
, MDL
);
3409 * ISC_R_CANCELED is a status code used by the prefix processing to
3410 * indicate we're replying with a status code. This is still a
3411 * success at higher layers.
3413 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
3417 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
3418 * contents into the reply's current ia_pd-scoped option cache. Returns
3419 * ISC_R_CANCELED in the event we are replying with a status code and do
3420 * not wish to process more IAPREFIXes within this IA_PD.
3423 reply_process_prefix(struct reply_state
*reply
, struct option_cache
*pref
) {
3424 u_int32_t pref_life
, valid_life
;
3425 struct binding_scope
**scope
;
3426 struct iaddrcidrnet tmp_pref
;
3427 struct option_cache
*oc
;
3428 struct data_string iapref
, data
;
3429 isc_result_t status
= ISC_R_SUCCESS
;
3431 /* Initializes values that will be cleaned up. */
3432 memset(&iapref
, 0, sizeof(iapref
));
3433 memset(&data
, 0, sizeof(data
));
3434 /* Note that reply->lease may be set by prefix_is_owned() */
3437 * There is no point trying to process an incoming prefix if there
3438 * is no room for an outgoing prefix.
3440 if ((reply
->cursor
+ 29) > sizeof(reply
->buf
)) {
3441 log_error("reply_process_prefix: Out of room for prefix.");
3442 return ISC_R_NOSPACE
;
3445 /* Extract this IAPREFIX option. */
3446 if (!evaluate_option_cache(&iapref
, reply
->packet
, NULL
, NULL
,
3447 reply
->packet
->options
, NULL
, &global_scope
,
3449 (iapref
.len
< IAPREFIX_OFFSET
)) {
3450 log_error("reply_process_prefix: error evaluating IAPREFIX.");
3451 status
= ISC_R_FAILURE
;
3456 * Layout: preferred and valid lifetimes followed by the prefix
3457 * length and the IPv6 address.
3459 pref_life
= getULong(iapref
.data
);
3460 valid_life
= getULong(iapref
.data
+ 4);
3462 if ((reply
->client_valid
== 0) ||
3463 (reply
->client_valid
> valid_life
))
3464 reply
->client_valid
= valid_life
;
3466 if ((reply
->client_prefer
== 0) ||
3467 (reply
->client_prefer
> pref_life
))
3468 reply
->client_prefer
= pref_life
;
3471 * Clients may choose to send ::/0 as a prefix, with the idea to give
3472 * hints about preferred-lifetime or valid-lifetime.
3474 tmp_pref
.lo_addr
.len
= 16;
3475 memset(tmp_pref
.lo_addr
.iabuf
, 0, 16);
3476 if ((iapref
.data
[8] == 0) &&
3477 (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0)) {
3478 /* Status remains success; we just ignore this one. */
3483 * Clients may choose to send ::/X as a prefix to specify a
3484 * preferred/requested prefix length. Note X is never zero here.
3486 tmp_pref
.bits
= (int) iapref
.data
[8];
3487 if (reply
->preflen
< 0) {
3488 /* Cache the first preferred prefix length. */
3489 reply
->preflen
= tmp_pref
.bits
;
3491 if (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0) {
3495 memcpy(tmp_pref
.lo_addr
.iabuf
, iapref
.data
+ 9, 16);
3497 /* Verify the prefix belongs to the client. */
3498 if (!prefix_is_owned(reply
, &tmp_pref
)) {
3499 /* Same than for addresses. */
3500 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
3501 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
3502 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
3503 status
= reply_process_try_prefix(reply
, &tmp_pref
);
3505 /* Either error out or skip this prefix. */
3506 if ((status
!= ISC_R_SUCCESS
) &&
3507 (status
!= ISC_R_ADDRINUSE
) &&
3508 (status
!= ISC_R_ADDRNOTAVAIL
))
3511 if (reply
->lease
== NULL
) {
3512 if (reply
->packet
->dhcpv6_msg_type
==
3514 reply
->send_prefer
= 0;
3515 reply
->send_valid
= 0;
3519 /* status remains success - ignore */
3523 * RFC3633 section 18.2.3:
3525 * If the delegating router cannot find a binding
3526 * for the requesting router's IA_PD the delegating
3527 * router returns the IA_PD containing no prefixes
3528 * with a Status Code option set to NoBinding in the
3531 * On mismatch we (ab)use this pretending we have not the IA
3532 * as soon as we have not a prefix.
3534 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
3535 /* Rewind the IA_PD to empty. */
3536 option_state_dereference(&reply
->reply_ia
, MDL
);
3537 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
3538 log_error("reply_process_prefix: No memory "
3539 "for option state wipe.");
3540 status
= ISC_R_NOMEMORY
;
3544 /* Append a NoBinding status code. */
3545 if (!set_status_code(STATUS_NoBinding
,
3546 "Prefix not bound to this "
3547 "interface.", reply
->reply_ia
)) {
3548 log_error("reply_process_prefix: Unable to "
3549 "attach status code.");
3550 status
= ISC_R_FAILURE
;
3554 /* Fin (no more IAPREFIXes). */
3555 status
= ISC_R_CANCELED
;
3558 log_error("It is impossible to lease a client that is "
3559 "not sending a solicit, request, renew, or "
3561 status
= ISC_R_FAILURE
;
3566 if (reply
->static_prefixes
> 0) {
3567 if (reply
->host
== NULL
)
3568 log_fatal("Impossible condition at %s:%d.", MDL
);
3570 scope
= &global_scope
;
3572 if (reply
->lease
== NULL
)
3573 log_fatal("Impossible condition at %s:%d.", MDL
);
3575 scope
= &reply
->lease
->scope
;
3579 * If client_resources is nonzero, then the reply_process_is_prefixed
3580 * function has executed configuration state into the reply option
3581 * cache. We will use that valid cache to derive configuration for
3582 * whether or not to engage in additional prefixes, and similar.
3584 if (reply
->client_resources
!= 0) {
3588 * Does this client have "enough" prefixes already? Default
3589 * to one. Everybody gets one, and one should be enough for
3592 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3593 SV_LIMIT_PREFS_PER_IA
);
3595 if (!evaluate_option_cache(&data
, reply
->packet
,
3597 reply
->packet
->options
,
3601 log_error("reply_process_prefix: unable to "
3602 "evaluate prefs-per-ia value.");
3603 status
= ISC_R_FAILURE
;
3607 limit
= getULong(data
.data
);
3608 data_string_forget(&data
, MDL
);
3612 * If we wish to limit the client to a certain number of
3613 * prefixes, then omit the prefix from the reply.
3615 if (reply
->client_resources
>= limit
)
3619 status
= reply_process_is_prefixed(reply
, scope
, reply
->shared
->group
);
3620 if (status
!= ISC_R_SUCCESS
)
3624 status
= reply_process_send_prefix(reply
, &tmp_pref
);
3627 if (iapref
.data
!= NULL
)
3628 data_string_forget(&iapref
, MDL
);
3629 if (data
.data
!= NULL
)
3630 data_string_forget(&data
, MDL
);
3631 if (reply
->lease
!= NULL
)
3632 iasubopt_dereference(&reply
->lease
, MDL
);
3638 * Verify the prefix belongs to the client. If we've got a host
3639 * record with fixed prefixes, it has to be an assigned prefix
3640 * (fault out all else). Otherwise it's a dynamic prefix, so lookup
3641 * that prefix and make sure it belongs to this DUID:IAID pair.
3643 static isc_boolean_t
3644 prefix_is_owned(struct reply_state
*reply
, struct iaddrcidrnet
*pref
) {
3645 struct iaddrcidrnetlist
*l
;
3649 * This faults out prefixes that don't match fixed prefixes.
3651 if (reply
->static_prefixes
> 0) {
3652 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
3653 if ((pref
->bits
== l
->cidrnet
.bits
) &&
3654 (memcmp(pref
->lo_addr
.iabuf
,
3655 l
->cidrnet
.lo_addr
.iabuf
, 16) == 0))
3661 if ((reply
->old_ia
== NULL
) ||
3662 (reply
->old_ia
->num_iasubopt
== 0))
3665 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3666 struct iasubopt
*tmp
;
3668 tmp
= reply
->old_ia
->iasubopt
[i
];
3670 if ((pref
->bits
== (int) tmp
->plen
) &&
3671 (memcmp(pref
->lo_addr
.iabuf
, &tmp
->addr
, 16) == 0)) {
3672 if (lease6_usable(tmp
) == ISC_FALSE
) {
3675 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
3684 * This function only returns failure on 'hard' failures. If it succeeds,
3685 * it will leave a prefix structure behind.
3688 reply_process_try_prefix(struct reply_state
*reply
,
3689 struct iaddrcidrnet
*pref
) {
3690 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
3691 struct ipv6_pool
*pool
;
3693 struct data_string data_pref
;
3695 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
3696 (pref
== NULL
) || (reply
->lease
!= NULL
))
3697 return (DHCP_R_INVALIDARG
);
3699 if (reply
->shared
->ipv6_pools
== NULL
)
3700 return (ISC_R_ADDRNOTAVAIL
);
3702 memset(&data_pref
, 0, sizeof(data_pref
));
3704 if (!buffer_allocate(&data_pref
.buffer
, data_pref
.len
, MDL
)) {
3705 log_error("reply_process_try_prefix: out of memory.");
3706 return (ISC_R_NOMEMORY
);
3708 data_pref
.data
= data_pref
.buffer
->data
;
3709 data_pref
.buffer
->data
[0] = (u_int8_t
) pref
->bits
;
3710 memcpy(data_pref
.buffer
->data
+ 1, pref
->lo_addr
.iabuf
, 16);
3712 for (i
= 0 ; (pool
= reply
->shared
->ipv6_pools
[i
]) != NULL
; i
++) {
3713 if (pool
->pool_type
!= D6O_IA_PD
)
3715 status
= try_client_v6_prefix(&reply
->lease
, pool
,
3717 /* If we found it in this pool (either in use or available),
3718 there is no need to look further. */
3719 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
3723 data_string_forget(&data_pref
, MDL
);
3724 /* Return just the most recent status... */
3728 /* Look around for a prefix to give the client. First, look through the old
3729 * IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
3730 * Finally, actually add that prefix into the current reply IA_PD.
3733 find_client_prefix(struct reply_state
*reply
) {
3734 struct iaddrcidrnet send_pref
;
3735 isc_result_t status
= ISC_R_NORESOURCES
;
3736 struct iasubopt
*prefix
, *best_prefix
= NULL
;
3737 struct binding_scope
**scope
;
3740 if (reply
->static_prefixes
> 0) {
3741 struct iaddrcidrnetlist
*l
;
3743 if (reply
->host
== NULL
)
3744 return DHCP_R_INVALIDARG
;
3746 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
3747 if (l
->cidrnet
.bits
== reply
->preflen
)
3752 * If no fixed prefix has the preferred length,
3753 * get the first one.
3755 l
= reply
->host
->fixed_prefix
;
3757 memcpy(&send_pref
, &l
->cidrnet
, sizeof(send_pref
));
3759 status
= ISC_R_SUCCESS
;
3760 scope
= &global_scope
;
3764 if (reply
->old_ia
!= NULL
) {
3765 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3766 struct shared_network
*candidate_shared
;
3768 prefix
= reply
->old_ia
->iasubopt
[i
];
3769 candidate_shared
= prefix
->ipv6_pool
->shared_network
;
3772 * Consider this prefix if it is in a global pool or
3773 * if it is scoped in a pool under the client's shared
3776 if (((candidate_shared
== NULL
) ||
3777 (candidate_shared
== reply
->shared
)) &&
3778 (lease6_usable(prefix
) == ISC_TRUE
)) {
3779 best_prefix
= prefix_compare(reply
, prefix
,
3785 /* Try to pick a new prefix if we didn't find one, or if we found an
3788 if ((best_prefix
== NULL
) || (best_prefix
->state
== FTS_ABANDONED
)) {
3789 status
= pick_v6_prefix(&reply
->lease
, reply
->preflen
,
3790 reply
->shared
, &reply
->client_id
);
3791 } else if (best_prefix
!= NULL
) {
3792 iasubopt_reference(&reply
->lease
, best_prefix
, MDL
);
3793 status
= ISC_R_SUCCESS
;
3796 /* Pick the abandoned prefix as a last resort. */
3797 if ((status
== ISC_R_NORESOURCES
) && (best_prefix
!= NULL
)) {
3798 /* I don't see how this is supposed to be done right now. */
3799 log_error("Reclaiming abandoned prefixes is not yet "
3800 "supported. Treating this as an out of space "
3802 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
3805 /* Give up now if we didn't find a prefix. */
3806 if (status
!= ISC_R_SUCCESS
)
3809 if (reply
->lease
== NULL
)
3810 log_fatal("Impossible condition at %s:%d.", MDL
);
3812 scope
= &reply
->lease
->scope
;
3814 send_pref
.lo_addr
.len
= 16;
3815 memcpy(send_pref
.lo_addr
.iabuf
, &reply
->lease
->addr
, 16);
3816 send_pref
.bits
= (int) reply
->lease
->plen
;
3819 status
= reply_process_is_prefixed(reply
, scope
, reply
->shared
->group
);
3820 if (status
!= ISC_R_SUCCESS
)
3823 status
= reply_process_send_prefix(reply
, &send_pref
);
3827 /* Once a prefix is found for a client, perform several common functions;
3828 * Calculate and store valid and preferred prefix times, draw client options
3829 * into the option state.
3832 reply_process_is_prefixed(struct reply_state
*reply
,
3833 struct binding_scope
**scope
, struct group
*group
)
3835 isc_result_t status
= ISC_R_SUCCESS
;
3836 struct data_string data
;
3837 struct option_cache
*oc
;
3839 /* Initialize values we will cleanup. */
3840 memset(&data
, 0, sizeof(data
));
3843 * Bring configured options into the root packet level cache - start
3844 * with the lease's closest enclosing group (passed in by the caller
3847 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3848 reply
->packet
->options
, reply
->opt_state
,
3849 scope
, group
, root_group
);
3852 * If there is a host record, over-ride with values configured there,
3853 * without re-evaluating configuration from the previously executed
3854 * group or its common enclosers.
3856 if (reply
->host
!= NULL
)
3857 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3858 reply
->packet
->options
,
3859 reply
->opt_state
, scope
,
3860 reply
->host
->group
, group
);
3862 /* Determine valid lifetime. */
3863 if (reply
->client_valid
== 0)
3864 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
3866 reply
->send_valid
= reply
->client_valid
;
3868 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3869 SV_DEFAULT_LEASE_TIME
);
3871 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3872 reply
->packet
->options
,
3876 log_error("reply_process_is_prefixed: unable to "
3877 "evaluate default prefix time");
3878 status
= ISC_R_FAILURE
;
3882 reply
->send_valid
= getULong(data
.data
);
3883 data_string_forget(&data
, MDL
);
3886 if (reply
->client_prefer
== 0)
3887 reply
->send_prefer
= reply
->send_valid
;
3889 reply
->send_prefer
= reply
->client_prefer
;
3891 if (reply
->send_prefer
>= reply
->send_valid
)
3892 reply
->send_prefer
= (reply
->send_valid
/ 2) +
3893 (reply
->send_valid
/ 8);
3895 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3896 SV_PREFER_LIFETIME
);
3898 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3899 reply
->packet
->options
,
3903 log_error("reply_process_is_prefixed: unable to "
3904 "evaluate preferred prefix time");
3905 status
= ISC_R_FAILURE
;
3909 reply
->send_prefer
= getULong(data
.data
);
3910 data_string_forget(&data
, MDL
);
3913 /* Note lowest values for later calculation of renew/rebind times. */
3914 if (reply
->prefer
> reply
->send_prefer
)
3915 reply
->prefer
= reply
->send_prefer
;
3917 if (reply
->valid
> reply
->send_valid
)
3918 reply
->valid
= reply
->send_valid
;
3920 /* Perform dynamic prefix related update work. */
3921 if (reply
->lease
!= NULL
) {
3922 /* Cached lifetimes */
3923 reply
->lease
->prefer
= reply
->send_prefer
;
3924 reply
->lease
->valid
= reply
->send_valid
;
3926 /* Advance (or rewind) the valid lifetime. */
3927 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
3928 reply
->lease
->soft_lifetime_end_time
=
3929 cur_time
+ reply
->send_valid
;
3930 /* Wait before renew! */
3933 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
3934 if (status
!= ISC_R_SUCCESS
) {
3935 log_fatal("reply_process_is_prefixed: Unable to "
3936 "attach prefix to new IA_PD: %s",
3937 isc_result_totext(status
));
3941 * If this is a new prefix, make sure it is attached somewhere.
3943 if (reply
->lease
->ia
== NULL
) {
3944 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
3948 /* Bring a copy of the relevant options into the IA_PD scope. */
3949 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3950 reply
->packet
->options
, reply
->reply_ia
,
3951 scope
, group
, root_group
);
3954 * And bring in host record configuration, if any, but not to overlap
3955 * the previous group or its common enclosers.
3957 if (reply
->host
!= NULL
)
3958 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3959 reply
->packet
->options
,
3960 reply
->reply_ia
, scope
,
3961 reply
->host
->group
, group
);
3964 if (data
.data
!= NULL
)
3965 data_string_forget(&data
, MDL
);
3967 if (status
== ISC_R_SUCCESS
)
3968 reply
->client_resources
++;
3973 /* Simply send an IAPREFIX within the IA_PD scope as described. */
3975 reply_process_send_prefix(struct reply_state
*reply
,
3976 struct iaddrcidrnet
*pref
) {
3977 isc_result_t status
= ISC_R_SUCCESS
;
3978 struct data_string data
;
3980 memset(&data
, 0, sizeof(data
));
3982 /* Now append the prefix. */
3983 data
.len
= IAPREFIX_OFFSET
;
3984 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
3985 log_error("reply_process_send_prefix: out of memory"
3986 "allocating new IAPREFIX buffer.");
3987 status
= ISC_R_NOMEMORY
;
3990 data
.data
= data
.buffer
->data
;
3992 putULong(data
.buffer
->data
, reply
->send_prefer
);
3993 putULong(data
.buffer
->data
+ 4, reply
->send_valid
);
3994 data
.buffer
->data
[8] = pref
->bits
;
3995 memcpy(data
.buffer
->data
+ 9, pref
->lo_addr
.iabuf
, 16);
3997 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
3998 data
.buffer
, data
.buffer
->data
,
3999 data
.len
, D6O_IAPREFIX
, 0)) {
4000 log_error("reply_process_send_prefix: unable "
4001 "to save IAPREFIX option");
4002 status
= ISC_R_FAILURE
;
4006 reply
->resources_included
= ISC_TRUE
;
4009 if (data
.data
!= NULL
)
4010 data_string_forget(&data
, MDL
);
4015 /* Choose the better of two prefixes. */
4016 static struct iasubopt
*
4017 prefix_compare(struct reply_state
*reply
,
4018 struct iasubopt
*alpha
, struct iasubopt
*beta
) {
4024 if (reply
->preflen
>= 0) {
4025 if ((alpha
->plen
== reply
->preflen
) &&
4026 (beta
->plen
!= reply
->preflen
))
4028 if ((beta
->plen
== reply
->preflen
) &&
4029 (alpha
->plen
!= reply
->preflen
))
4033 switch(alpha
->state
) {
4035 switch(beta
->state
) {
4037 /* Choose the prefix with the longest lifetime (most
4038 * likely the most recently allocated).
4040 if (alpha
->hard_lifetime_end_time
<
4041 beta
->hard_lifetime_end_time
)
4051 log_fatal("Impossible condition at %s:%d.", MDL
);
4056 switch (beta
->state
) {
4061 /* Choose the most recently expired prefix. */
4062 if (alpha
->hard_lifetime_end_time
<
4063 beta
->hard_lifetime_end_time
)
4065 else if ((alpha
->hard_lifetime_end_time
==
4066 beta
->hard_lifetime_end_time
) &&
4067 (alpha
->soft_lifetime_end_time
<
4068 beta
->soft_lifetime_end_time
))
4077 log_fatal("Impossible condition at %s:%d.", MDL
);
4082 switch (beta
->state
) {
4088 /* Choose the prefix that was abandoned longest ago. */
4089 if (alpha
->hard_lifetime_end_time
<
4090 beta
->hard_lifetime_end_time
)
4094 log_fatal("Impossible condition at %s:%d.", MDL
);
4099 log_fatal("Impossible condition at %s:%d.", MDL
);
4102 log_fatal("Triple impossible condition at %s:%d.", MDL
);
4107 * Solicit is how a client starts requesting addresses.
4109 * If the client asks for rapid commit, and we support it, we will
4110 * allocate the addresses and reply.
4112 * Otherwise we will send an advertise message.
4116 dhcpv6_solicit(struct data_string
*reply_ret
, struct packet
*packet
) {
4117 struct data_string client_id
;
4120 * Validate our input.
4122 if (!valid_client_msg(packet
, &client_id
)) {
4126 lease_to_client(reply_ret
, packet
, &client_id
, NULL
);
4131 data_string_forget(&client_id
, MDL
);
4135 * Request is how a client actually requests addresses.
4137 * Very similar to Solicit handling, except the server DUID is required.
4140 /* TODO: reject unicast messages, unless we set unicast option */
4142 dhcpv6_request(struct data_string
*reply_ret
, struct packet
*packet
) {
4143 struct data_string client_id
;
4144 struct data_string server_id
;
4147 * Validate our input.
4149 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
4156 lease_to_client(reply_ret
, packet
, &client_id
, &server_id
);
4161 data_string_forget(&client_id
, MDL
);
4162 data_string_forget(&server_id
, MDL
);
4165 /* Find a DHCPv6 packet's shared network from hints in the packet.
4168 shared_network_from_packet6(struct shared_network
**shared
,
4169 struct packet
*packet
)
4171 const struct packet
*chk_packet
;
4172 const struct in6_addr
*link_addr
, *first_link_addr
;
4173 struct iaddr tmp_addr
;
4174 struct subnet
*subnet
;
4175 isc_result_t status
;
4177 if ((shared
== NULL
) || (*shared
!= NULL
) || (packet
== NULL
))
4178 return DHCP_R_INVALIDARG
;
4181 * First, find the link address where the packet from the client
4182 * first appeared (if this packet was relayed).
4184 first_link_addr
= NULL
;
4185 chk_packet
= packet
->dhcpv6_container_packet
;
4186 while (chk_packet
!= NULL
) {
4187 link_addr
= &chk_packet
->dhcpv6_link_address
;
4188 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
4189 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
4190 first_link_addr
= link_addr
;
4193 chk_packet
= chk_packet
->dhcpv6_container_packet
;
4197 * If there is a relayed link address, find the subnet associated
4198 * with that, and use that to get the appropriate
4201 if (first_link_addr
!= NULL
) {
4202 tmp_addr
.len
= sizeof(*first_link_addr
);
4203 memcpy(tmp_addr
.iabuf
,
4204 first_link_addr
, sizeof(*first_link_addr
));
4206 if (!find_subnet(&subnet
, tmp_addr
, MDL
)) {
4207 log_debug("No subnet found for link-address %s.",
4209 return ISC_R_NOTFOUND
;
4211 status
= shared_network_reference(shared
,
4212 subnet
->shared_network
, MDL
);
4213 subnet_dereference(&subnet
, MDL
);
4216 * If there is no link address, we will use the interface
4217 * that this packet came in on to pick the shared_network.
4219 } else if (packet
->interface
!= NULL
) {
4220 status
= shared_network_reference(shared
,
4221 packet
->interface
->shared_network
,
4223 if (packet
->dhcpv6_container_packet
!= NULL
) {
4224 log_info("[L2 Relay] No link address in relay packet "
4225 "assuming L2 relay and using receiving "
4231 * We shouldn't be able to get here but if there is no link
4232 * address and no interface we don't know where to get the
4233 * pool from log an error and return an error.
4235 log_error("No interface and no link address "
4236 "can't determine pool");
4237 status
= DHCP_R_INVALIDARG
;
4244 * When a client thinks it might be on a new link, it sends a
4247 * From RFC3315 section 18.2.2:
4249 * When the server receives a Confirm message, the server determines
4250 * whether the addresses in the Confirm message are appropriate for the
4251 * link to which the client is attached. If all of the addresses in the
4252 * Confirm message pass this test, the server returns a status of
4253 * Success. If any of the addresses do not pass this test, the server
4254 * returns a status of NotOnLink. If the server is unable to perform
4255 * this test (for example, the server does not have information about
4256 * prefixes on the link to which the client is connected), or there were
4257 * no addresses in any of the IAs sent by the client, the server MUST
4258 * NOT send a reply to the client.
4262 dhcpv6_confirm(struct data_string
*reply_ret
, struct packet
*packet
) {
4263 struct shared_network
*shared
;
4264 struct subnet
*subnet
;
4265 struct option_cache
*ia
, *ta
, *oc
;
4266 struct data_string cli_enc_opt_data
, iaaddr
, client_id
, packet_oro
;
4267 struct option_state
*cli_enc_opt_state
, *opt_state
;
4268 struct iaddr cli_addr
;
4270 isc_boolean_t inappropriate
, has_addrs
;
4271 char reply_data
[65536];
4272 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
4273 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
4276 * Basic client message validation.
4278 memset(&client_id
, 0, sizeof(client_id
));
4279 if (!valid_client_msg(packet
, &client_id
)) {
4284 * Do not process Confirms that do not have IA's we do not recognize.
4286 ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
4287 ta
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
4288 if ((ia
== NULL
) && (ta
== NULL
))
4292 * IA_PD's are simply ignored.
4294 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
4297 * Bit of variable initialization.
4299 opt_state
= cli_enc_opt_state
= NULL
;
4300 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
4301 memset(&iaaddr
, 0, sizeof(iaaddr
));
4302 memset(&packet_oro
, 0, sizeof(packet_oro
));
4304 /* Determine what shared network the client is connected to. We
4305 * must not respond if we don't have any information about the
4306 * network the client is on.
4309 if ((shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
) ||
4313 /* If there are no recorded subnets, then we have no
4314 * information about this subnet - ignore Confirms.
4316 subnet
= shared
->subnets
;
4320 /* Are the addresses in all the IA's appropriate for that link? */
4321 has_addrs
= inappropriate
= ISC_FALSE
;
4323 while(!inappropriate
) {
4324 /* If we've reached the end of the IA_NA pass, move to the
4327 if ((pass
== D6O_IA_NA
) && (ia
== NULL
)) {
4332 /* If we've reached the end of all passes, we're done. */
4336 if (((pass
== D6O_IA_NA
) &&
4337 !get_encapsulated_IA_state(&cli_enc_opt_state
,
4339 packet
, ia
, IA_NA_OFFSET
)) ||
4340 ((pass
== D6O_IA_TA
) &&
4341 !get_encapsulated_IA_state(&cli_enc_opt_state
,
4343 packet
, ia
, IA_TA_OFFSET
))) {
4347 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
4350 for ( ; oc
!= NULL
; oc
= oc
->next
) {
4351 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
4352 packet
->options
, NULL
,
4353 &global_scope
, oc
, MDL
) ||
4354 (iaaddr
.len
< IAADDR_OFFSET
)) {
4355 log_error("dhcpv6_confirm: "
4356 "error evaluating IAADDR.");
4360 /* Copy out the IPv6 address for processing. */
4362 memcpy(cli_addr
.iabuf
, iaaddr
.data
, 16);
4364 data_string_forget(&iaaddr
, MDL
);
4366 /* Record that we've processed at least one address. */
4367 has_addrs
= ISC_TRUE
;
4369 /* Find out if any subnets cover this address. */
4370 for (subnet
= shared
->subnets
; subnet
!= NULL
;
4371 subnet
= subnet
->next_sibling
) {
4372 if (addr_eq(subnet_number(cli_addr
,
4378 /* If we reach the end of the subnet list, and no
4379 * subnet matches the client address, then it must
4380 * be inappropriate to the link (so far as our
4381 * configuration says). Once we've found one
4382 * inappropriate address, there is no reason to
4383 * continue searching.
4385 if (subnet
== NULL
) {
4386 inappropriate
= ISC_TRUE
;
4391 option_state_dereference(&cli_enc_opt_state
, MDL
);
4392 data_string_forget(&cli_enc_opt_data
, MDL
);
4394 /* Advance to the next IA_*. */
4398 /* If the client supplied no addresses, do not reply. */
4405 if (!start_reply(packet
, &client_id
, NULL
, &opt_state
, reply
)) {
4412 if (inappropriate
) {
4413 if (!set_status_code(STATUS_NotOnLink
,
4414 "Some of the addresses are not on link.",
4419 if (!set_status_code(STATUS_Success
,
4420 "All addresses still on link.",
4427 * Only one option: add it.
4429 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
4430 sizeof(reply_data
)-reply_ofs
,
4432 required_opts
, &packet_oro
);
4435 * Return our reply to the caller.
4437 reply_ret
->len
= reply_ofs
;
4438 reply_ret
->buffer
= NULL
;
4439 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
4440 log_fatal("No memory to store reply.");
4442 reply_ret
->data
= reply_ret
->buffer
->data
;
4443 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
4446 /* Cleanup any stale data strings. */
4447 if (cli_enc_opt_data
.buffer
!= NULL
)
4448 data_string_forget(&cli_enc_opt_data
, MDL
);
4449 if (iaaddr
.buffer
!= NULL
)
4450 data_string_forget(&iaaddr
, MDL
);
4451 if (client_id
.buffer
!= NULL
)
4452 data_string_forget(&client_id
, MDL
);
4453 if (packet_oro
.buffer
!= NULL
)
4454 data_string_forget(&packet_oro
, MDL
);
4456 /* Release any stale option states. */
4457 if (cli_enc_opt_state
!= NULL
)
4458 option_state_dereference(&cli_enc_opt_state
, MDL
);
4459 if (opt_state
!= NULL
)
4460 option_state_dereference(&opt_state
, MDL
);
4464 * Renew is when a client wants to extend its lease/prefix, at time T1.
4466 * We handle this the same as if the client wants a new lease/prefix,
4467 * except for the error code of when addresses don't match.
4470 /* TODO: reject unicast messages, unless we set unicast option */
4472 dhcpv6_renew(struct data_string
*reply
, struct packet
*packet
) {
4473 struct data_string client_id
;
4474 struct data_string server_id
;
4477 * Validate the request.
4479 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
4486 lease_to_client(reply
, packet
, &client_id
, &server_id
);
4491 data_string_forget(&server_id
, MDL
);
4492 data_string_forget(&client_id
, MDL
);
4496 * Rebind is when a client wants to extend its lease, at time T2.
4498 * We handle this the same as if the client wants a new lease, except
4499 * for the error code of when addresses don't match.
4503 dhcpv6_rebind(struct data_string
*reply
, struct packet
*packet
) {
4504 struct data_string client_id
;
4506 if (!valid_client_msg(packet
, &client_id
)) {
4510 lease_to_client(reply
, packet
, &client_id
, NULL
);
4512 data_string_forget(&client_id
, MDL
);
4516 ia_na_match_decline(const struct data_string
*client_id
,
4517 const struct data_string
*iaaddr
,
4518 struct iasubopt
*lease
)
4520 char tmp_addr
[INET6_ADDRSTRLEN
];
4522 log_error("Client %s reports address %s is "
4523 "already in use by another host!",
4524 print_hex_1(client_id
->len
, client_id
->data
, 60),
4525 inet_ntop(AF_INET6
, iaaddr
->data
,
4526 tmp_addr
, sizeof(tmp_addr
)));
4527 if (lease
!= NULL
) {
4528 decline_lease6(lease
->ipv6_pool
, lease
);
4529 lease
->ia
->cltt
= cur_time
;
4530 write_ia(lease
->ia
);
4535 ia_na_nomatch_decline(const struct data_string
*client_id
,
4536 const struct data_string
*iaaddr
,
4537 u_int32_t
*ia_na_id
,
4538 struct packet
*packet
,
4543 char tmp_addr
[INET6_ADDRSTRLEN
];
4544 struct option_state
*host_opt_state
;
4547 log_info("Client %s declines address %s, which is not offered to it.",
4548 print_hex_1(client_id
->len
, client_id
->data
, 60),
4549 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
4552 * Create state for this IA_NA.
4554 host_opt_state
= NULL
;
4555 if (!option_state_allocate(&host_opt_state
, MDL
)) {
4556 log_error("ia_na_nomatch_decline: out of memory "
4557 "allocating option_state.");
4561 if (!set_status_code(STATUS_NoBinding
, "Decline for unknown address.",
4567 * Insure we have enough space
4569 if (reply_len
< (*reply_ofs
+ 16)) {
4570 log_error("ia_na_nomatch_decline: "
4571 "out of space for reply packet.");
4576 * Put our status code into the reply packet.
4578 len
= store_options6(reply_data
+(*reply_ofs
)+16,
4579 reply_len
-(*reply_ofs
)-16,
4580 host_opt_state
, packet
,
4581 required_opts_STATUS_CODE
, NULL
);
4584 * Store the non-encapsulated option data for this
4585 * IA_NA into our reply packet. Defined in RFC 3315,
4589 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
4591 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
4592 /* IA_NA, copied from the client */
4593 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
4594 /* t1 and t2, odd that we need them, but here it is */
4595 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
4596 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
4599 * Get ready for next IA_NA.
4601 *reply_ofs
+= (len
+ 16);
4604 option_state_dereference(&host_opt_state
, MDL
);
4608 iterate_over_ia_na(struct data_string
*reply_ret
,
4609 struct packet
*packet
,
4610 const struct data_string
*client_id
,
4611 const struct data_string
*server_id
,
4612 const char *packet_type
,
4613 void (*ia_na_match
)(),
4614 void (*ia_na_nomatch
)())
4616 struct option_state
*opt_state
;
4617 struct host_decl
*packet_host
;
4618 struct option_cache
*ia
;
4619 struct option_cache
*oc
;
4620 /* cli_enc_... variables come from the IA_NA/IA_TA options */
4621 struct data_string cli_enc_opt_data
;
4622 struct option_state
*cli_enc_opt_state
;
4623 struct host_decl
*host
;
4624 struct option_state
*host_opt_state
;
4625 struct data_string iaaddr
;
4626 struct data_string fixed_addr
;
4627 char reply_data
[65536];
4628 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
4629 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
4630 char status_msg
[32];
4631 struct iasubopt
*lease
;
4632 struct ia_xx
*existing_ia_na
;
4634 struct data_string key
;
4638 * Initialize to empty values, in case we have to exit early.
4641 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
4642 cli_enc_opt_state
= NULL
;
4643 memset(&iaaddr
, 0, sizeof(iaaddr
));
4644 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
4645 host_opt_state
= NULL
;
4649 * Find the host record that matches from the packet, if any.
4652 if (!find_hosts_by_uid(&packet_host
,
4653 client_id
->data
, client_id
->len
, MDL
)) {
4656 * Note: In general, we don't expect a client to provide
4657 * enough information to match by option for these
4658 * types of messages, but if we don't have a UID
4659 * match we can check anyway.
4661 if (!find_hosts_by_option(&packet_host
,
4662 packet
, packet
->options
, MDL
)) {
4665 if (!find_hosts_by_duid_chaddr(&packet_host
,
4672 * Set our reply information.
4674 reply
->msg_type
= DHCPV6_REPLY
;
4675 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
4676 sizeof(reply
->transaction_id
));
4679 * Build our option state for reply.
4682 if (!option_state_allocate(&opt_state
, MDL
)) {
4683 log_error("iterate_over_ia_na: no memory for option_state.");
4686 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
4687 packet
->options
, opt_state
,
4688 &global_scope
, root_group
, NULL
);
4691 * RFC 3315, section 18.2.7 tells us which options to include.
4693 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
4695 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
4696 (unsigned char *)server_duid
.data
,
4697 server_duid
.len
, D6O_SERVERID
, 0)) {
4698 log_error("iterate_over_ia_na: "
4699 "error saving server identifier.");
4704 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
4706 (unsigned char *)client_id
->data
,
4709 log_error("iterate_over_ia_na: "
4710 "error saving client identifier.");
4714 snprintf(status_msg
, sizeof(status_msg
), "%s received.", packet_type
);
4715 if (!set_status_code(STATUS_Success
, status_msg
, opt_state
)) {
4720 * Add our options that are not associated with any IA_NA or IA_TA.
4722 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
4723 sizeof(reply_data
)-reply_ofs
,
4725 required_opts
, NULL
);
4728 * Loop through the IA_NA reported by the client, and deal with
4729 * addresses reported as already in use.
4731 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
4732 ia
!= NULL
; ia
= ia
->next
) {
4734 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
4736 packet
, ia
, IA_NA_OFFSET
)) {
4740 iaid
= getULong(cli_enc_opt_data
.data
);
4743 * XXX: It is possible that we can get multiple addresses
4744 * sent by the client. We don't send multiple
4745 * addresses, so this indicates a client error.
4746 * We should check for multiple IAADDR options, log
4747 * if found, and set as an error.
4749 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
4752 /* no address given for this IA, ignore */
4753 option_state_dereference(&cli_enc_opt_state
, MDL
);
4754 data_string_forget(&cli_enc_opt_data
, MDL
);
4758 memset(&iaaddr
, 0, sizeof(iaaddr
));
4759 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
4760 packet
->options
, NULL
,
4761 &global_scope
, oc
, MDL
)) {
4762 log_error("iterate_over_ia_na: "
4763 "error evaluating IAADDR.");
4768 * Now we need to figure out which host record matches
4769 * this IA_NA and IAADDR (encapsulated option contents
4770 * matching a host record by option).
4772 * XXX: We don't currently track IA_NA separately, but
4773 * we will need to do this!
4776 if (!find_hosts_by_option(&host
, packet
,
4777 cli_enc_opt_state
, MDL
)) {
4778 if (packet_host
!= NULL
) {
4784 while (host
!= NULL
) {
4785 if (host
->fixed_addr
!= NULL
) {
4786 if (!evaluate_option_cache(&fixed_addr
, NULL
,
4788 NULL
, &global_scope
,
4791 log_error("iterate_over_ia_na: error "
4792 "evaluating host address.");
4795 if ((iaaddr
.len
>= 16) &&
4796 !memcmp(fixed_addr
.data
, iaaddr
.data
, 16)) {
4797 data_string_forget(&fixed_addr
, MDL
);
4800 data_string_forget(&fixed_addr
, MDL
);
4802 host
= host
->n_ipaddr
;
4805 if ((host
== NULL
) && (iaaddr
.len
>= IAADDR_OFFSET
)) {
4807 * Find existing IA_NA.
4809 if (ia_make_key(&key
, iaid
,
4810 (char *)client_id
->data
,
4812 MDL
) != ISC_R_SUCCESS
) {
4813 log_fatal("iterate_over_ia_na: no memory for "
4817 existing_ia_na
= NULL
;
4818 if (ia_hash_lookup(&existing_ia_na
, ia_na_active
,
4819 (unsigned char *)key
.data
,
4822 * Make sure this address is in the IA_NA.
4824 for (i
=0; i
<existing_ia_na
->num_iasubopt
; i
++) {
4825 struct iasubopt
*tmp
;
4826 struct in6_addr
*in6_addr
;
4828 tmp
= existing_ia_na
->iasubopt
[i
];
4829 in6_addr
= &tmp
->addr
;
4830 if (memcmp(in6_addr
,
4831 iaaddr
.data
, 16) == 0) {
4832 iasubopt_reference(&lease
,
4839 data_string_forget(&key
, MDL
);
4842 if ((host
!= NULL
) || (lease
!= NULL
)) {
4843 ia_na_match(client_id
, &iaaddr
, lease
);
4845 ia_na_nomatch(client_id
, &iaaddr
,
4846 (u_int32_t
*)cli_enc_opt_data
.data
,
4847 packet
, reply_data
, &reply_ofs
,
4848 sizeof(reply_data
));
4851 if (lease
!= NULL
) {
4852 iasubopt_dereference(&lease
, MDL
);
4855 data_string_forget(&iaaddr
, MDL
);
4856 option_state_dereference(&cli_enc_opt_state
, MDL
);
4857 data_string_forget(&cli_enc_opt_data
, MDL
);
4861 * Return our reply to the caller.
4863 reply_ret
->len
= reply_ofs
;
4864 reply_ret
->buffer
= NULL
;
4865 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
4866 log_fatal("No memory to store reply.");
4868 reply_ret
->data
= reply_ret
->buffer
->data
;
4869 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
4872 if (lease
!= NULL
) {
4873 iasubopt_dereference(&lease
, MDL
);
4875 if (host_opt_state
!= NULL
) {
4876 option_state_dereference(&host_opt_state
, MDL
);
4878 if (fixed_addr
.buffer
!= NULL
) {
4879 data_string_forget(&fixed_addr
, MDL
);
4881 if (iaaddr
.buffer
!= NULL
) {
4882 data_string_forget(&iaaddr
, MDL
);
4884 if (cli_enc_opt_state
!= NULL
) {
4885 option_state_dereference(&cli_enc_opt_state
, MDL
);
4887 if (cli_enc_opt_data
.buffer
!= NULL
) {
4888 data_string_forget(&cli_enc_opt_data
, MDL
);
4890 if (opt_state
!= NULL
) {
4891 option_state_dereference(&opt_state
, MDL
);
4896 * Decline means a client has detected that something else is using an
4897 * address we gave it.
4899 * Since we're only dealing with fixed leases for now, there's not
4900 * much we can do, other that log the occurrence.
4902 * When we start issuing addresses from pools, then we will have to
4903 * record our declined addresses and issue another. In general with
4904 * IPv6 there is no worry about DoS by clients exhausting space, but
4905 * we still need to be aware of this possibility.
4908 /* TODO: reject unicast messages, unless we set unicast option */
4911 dhcpv6_decline(struct data_string
*reply
, struct packet
*packet
) {
4912 struct data_string client_id
;
4913 struct data_string server_id
;
4916 * Validate our input.
4918 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
4923 * Undefined for IA_PD.
4925 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
4928 * And operate on each IA_NA in this packet.
4930 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
, "Decline",
4931 ia_na_match_decline
, ia_na_nomatch_decline
);
4933 data_string_forget(&server_id
, MDL
);
4934 data_string_forget(&client_id
, MDL
);
4938 ia_na_match_release(const struct data_string
*client_id
,
4939 const struct data_string
*iaaddr
,
4940 struct iasubopt
*lease
)
4942 char tmp_addr
[INET6_ADDRSTRLEN
];
4944 log_info("Client %s releases address %s",
4945 print_hex_1(client_id
->len
, client_id
->data
, 60),
4946 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
4947 if (lease
!= NULL
) {
4948 release_lease6(lease
->ipv6_pool
, lease
);
4949 lease
->ia
->cltt
= cur_time
;
4950 write_ia(lease
->ia
);
4955 ia_na_nomatch_release(const struct data_string
*client_id
,
4956 const struct data_string
*iaaddr
,
4957 u_int32_t
*ia_na_id
,
4958 struct packet
*packet
,
4963 char tmp_addr
[INET6_ADDRSTRLEN
];
4964 struct option_state
*host_opt_state
;
4967 log_info("Client %s releases address %s, which is not leased to it.",
4968 print_hex_1(client_id
->len
, client_id
->data
, 60),
4969 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
4972 * Create state for this IA_NA.
4974 host_opt_state
= NULL
;
4975 if (!option_state_allocate(&host_opt_state
, MDL
)) {
4976 log_error("ia_na_nomatch_release: out of memory "
4977 "allocating option_state.");
4981 if (!set_status_code(STATUS_NoBinding
,
4982 "Release for non-leased address.",
4988 * Insure we have enough space
4990 if (reply_len
< (*reply_ofs
+ 16)) {
4991 log_error("ia_na_nomatch_release: "
4992 "out of space for reply packet.");
4997 * Put our status code into the reply packet.
4999 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5000 reply_len
-(*reply_ofs
)-16,
5001 host_opt_state
, packet
,
5002 required_opts_STATUS_CODE
, NULL
);
5005 * Store the non-encapsulated option data for this
5006 * IA_NA into our reply packet. Defined in RFC 3315,
5010 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5012 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5013 /* IA_NA, copied from the client */
5014 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5015 /* t1 and t2, odd that we need them, but here it is */
5016 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5017 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5020 * Get ready for next IA_NA.
5022 *reply_ofs
+= (len
+ 16);
5025 option_state_dereference(&host_opt_state
, MDL
);
5029 ia_pd_match_release(const struct data_string
*client_id
,
5030 const struct data_string
*iapref
,
5031 struct iasubopt
*prefix
)
5033 char tmp_addr
[INET6_ADDRSTRLEN
];
5035 log_info("Client %s releases prefix %s/%u",
5036 print_hex_1(client_id
->len
, client_id
->data
, 60),
5037 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5038 tmp_addr
, sizeof(tmp_addr
)),
5039 (unsigned) getUChar(iapref
->data
+ 8));
5040 if (prefix
!= NULL
) {
5041 release_lease6(prefix
->ipv6_pool
, prefix
);
5042 prefix
->ia
->cltt
= cur_time
;
5043 write_ia(prefix
->ia
);
5048 ia_pd_nomatch_release(const struct data_string
*client_id
,
5049 const struct data_string
*iapref
,
5050 u_int32_t
*ia_pd_id
,
5051 struct packet
*packet
,
5056 char tmp_addr
[INET6_ADDRSTRLEN
];
5057 struct option_state
*host_opt_state
;
5060 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
5061 print_hex_1(client_id
->len
, client_id
->data
, 60),
5062 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5063 tmp_addr
, sizeof(tmp_addr
)),
5064 (unsigned) getUChar(iapref
->data
+ 8));
5067 * Create state for this IA_PD.
5069 host_opt_state
= NULL
;
5070 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5071 log_error("ia_pd_nomatch_release: out of memory "
5072 "allocating option_state.");
5076 if (!set_status_code(STATUS_NoBinding
,
5077 "Release for non-leased prefix.",
5083 * Insure we have enough space
5085 if (reply_len
< (*reply_ofs
+ 16)) {
5086 log_error("ia_pd_nomatch_release: "
5087 "out of space for reply packet.");
5092 * Put our status code into the reply packet.
5094 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5095 reply_len
-(*reply_ofs
)-16,
5096 host_opt_state
, packet
,
5097 required_opts_STATUS_CODE
, NULL
);
5100 * Store the non-encapsulated option data for this
5101 * IA_PD into our reply packet. Defined in RFC 3315,
5105 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_PD
);
5107 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5108 /* IA_PD, copied from the client */
5109 memcpy(reply_data
+(*reply_ofs
)+4, ia_pd_id
, 4);
5110 /* t1 and t2, odd that we need them, but here it is */
5111 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5112 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5115 * Get ready for next IA_PD.
5117 *reply_ofs
+= (len
+ 16);
5120 option_state_dereference(&host_opt_state
, MDL
);
5124 iterate_over_ia_pd(struct data_string
*reply_ret
,
5125 struct packet
*packet
,
5126 const struct data_string
*client_id
,
5127 const struct data_string
*server_id
,
5128 const char *packet_type
,
5129 void (*ia_pd_match
)(),
5130 void (*ia_pd_nomatch
)())
5132 struct data_string reply_new
;
5134 struct option_state
*opt_state
;
5135 struct host_decl
*packet_host
;
5136 struct option_cache
*ia
;
5137 struct option_cache
*oc
;
5138 /* cli_enc_... variables come from the IA_PD options */
5139 struct data_string cli_enc_opt_data
;
5140 struct option_state
*cli_enc_opt_state
;
5141 struct host_decl
*host
;
5142 struct option_state
*host_opt_state
;
5143 struct data_string iaprefix
;
5144 char reply_data
[65536];
5146 struct iasubopt
*prefix
;
5147 struct ia_xx
*existing_ia_pd
;
5149 struct data_string key
;
5153 * Initialize to empty values, in case we have to exit early.
5155 memset(&reply_new
, 0, sizeof(reply_new
));
5157 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5158 cli_enc_opt_state
= NULL
;
5159 memset(&iaprefix
, 0, sizeof(iaprefix
));
5160 host_opt_state
= NULL
;
5164 * Compute the available length for the reply.
5166 reply_len
= sizeof(reply_data
) - reply_ret
->len
;
5170 * Find the host record that matches from the packet, if any.
5173 if (!find_hosts_by_uid(&packet_host
,
5174 client_id
->data
, client_id
->len
, MDL
)) {
5177 * Note: In general, we don't expect a client to provide
5178 * enough information to match by option for these
5179 * types of messages, but if we don't have a UID
5180 * match we can check anyway.
5182 if (!find_hosts_by_option(&packet_host
,
5183 packet
, packet
->options
, MDL
)) {
5186 if (!find_hosts_by_duid_chaddr(&packet_host
,
5193 * Build our option state for reply.
5196 if (!option_state_allocate(&opt_state
, MDL
)) {
5197 log_error("iterate_over_ia_pd: no memory for option_state.");
5200 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5201 packet
->options
, opt_state
,
5202 &global_scope
, root_group
, NULL
);
5205 * Loop through the IA_PD reported by the client, and deal with
5206 * prefixes reported as already in use.
5208 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5209 ia
!= NULL
; ia
= ia
->next
) {
5211 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
5213 packet
, ia
, IA_PD_OFFSET
)) {
5217 iaid
= getULong(cli_enc_opt_data
.data
);
5219 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5222 /* no prefix given for this IA_PD, ignore */
5223 option_state_dereference(&cli_enc_opt_state
, MDL
);
5224 data_string_forget(&cli_enc_opt_data
, MDL
);
5228 for (; oc
!= NULL
; oc
= oc
->next
) {
5229 memset(&iaprefix
, 0, sizeof(iaprefix
));
5230 if (!evaluate_option_cache(&iaprefix
, packet
, NULL
, NULL
,
5231 packet
->options
, NULL
,
5232 &global_scope
, oc
, MDL
)) {
5233 log_error("iterate_over_ia_pd: "
5234 "error evaluating IAPREFIX.");
5239 * Now we need to figure out which host record matches
5240 * this IA_PD and IAPREFIX (encapsulated option contents
5241 * matching a host record by option).
5243 * XXX: We don't currently track IA_PD separately, but
5244 * we will need to do this!
5247 if (!find_hosts_by_option(&host
, packet
,
5248 cli_enc_opt_state
, MDL
)) {
5249 if (packet_host
!= NULL
) {
5255 while (host
!= NULL
) {
5256 if (host
->fixed_prefix
!= NULL
) {
5257 struct iaddrcidrnetlist
*l
;
5258 int plen
= (int) getUChar(iaprefix
.data
+ 8);
5260 for (l
= host
->fixed_prefix
; l
!= NULL
;
5262 if (plen
!= l
->cidrnet
.bits
)
5264 if (memcmp(iaprefix
.data
+ 9,
5265 l
->cidrnet
.lo_addr
.iabuf
,
5269 if ((l
!= NULL
) && (iaprefix
.len
>= 17))
5272 host
= host
->n_ipaddr
;
5275 if ((host
== NULL
) && (iaprefix
.len
>= IAPREFIX_OFFSET
)) {
5277 * Find existing IA_PD.
5279 if (ia_make_key(&key
, iaid
,
5280 (char *)client_id
->data
,
5282 MDL
) != ISC_R_SUCCESS
) {
5283 log_fatal("iterate_over_ia_pd: no memory for "
5287 existing_ia_pd
= NULL
;
5288 if (ia_hash_lookup(&existing_ia_pd
, ia_pd_active
,
5289 (unsigned char *)key
.data
,
5292 * Make sure this prefix is in the IA_PD.
5295 i
< existing_ia_pd
->num_iasubopt
;
5297 struct iasubopt
*tmp
;
5300 plen
= getUChar(iaprefix
.data
+ 8);
5301 tmp
= existing_ia_pd
->iasubopt
[i
];
5302 if ((tmp
->plen
== plen
) &&
5306 iasubopt_reference(&prefix
,
5313 data_string_forget(&key
, MDL
);
5316 if ((host
!= NULL
) || (prefix
!= NULL
)) {
5317 ia_pd_match(client_id
, &iaprefix
, prefix
);
5319 ia_pd_nomatch(client_id
, &iaprefix
,
5320 (u_int32_t
*)cli_enc_opt_data
.data
,
5321 packet
, reply_data
, &reply_ofs
,
5322 reply_len
- reply_ofs
);
5325 if (prefix
!= NULL
) {
5326 iasubopt_dereference(&prefix
, MDL
);
5329 data_string_forget(&iaprefix
, MDL
);
5332 option_state_dereference(&cli_enc_opt_state
, MDL
);
5333 data_string_forget(&cli_enc_opt_data
, MDL
);
5337 * Return our reply to the caller.
5338 * The IA_NA routine has already filled at least the header.
5340 reply_new
.len
= reply_ret
->len
+ reply_ofs
;
5341 if (!buffer_allocate(&reply_new
.buffer
, reply_new
.len
, MDL
)) {
5342 log_fatal("No memory to store reply.");
5344 reply_new
.data
= reply_new
.buffer
->data
;
5345 memcpy(reply_new
.buffer
->data
,
5346 reply_ret
->buffer
->data
, reply_ret
->len
);
5347 memcpy(reply_new
.buffer
->data
+ reply_ret
->len
,
5348 reply_data
, reply_ofs
);
5349 data_string_forget(reply_ret
, MDL
);
5350 data_string_copy(reply_ret
, &reply_new
, MDL
);
5351 data_string_forget(&reply_new
, MDL
);
5354 if (prefix
!= NULL
) {
5355 iasubopt_dereference(&prefix
, MDL
);
5357 if (host_opt_state
!= NULL
) {
5358 option_state_dereference(&host_opt_state
, MDL
);
5360 if (iaprefix
.buffer
!= NULL
) {
5361 data_string_forget(&iaprefix
, MDL
);
5363 if (cli_enc_opt_state
!= NULL
) {
5364 option_state_dereference(&cli_enc_opt_state
, MDL
);
5366 if (cli_enc_opt_data
.buffer
!= NULL
) {
5367 data_string_forget(&cli_enc_opt_data
, MDL
);
5369 if (opt_state
!= NULL
) {
5370 option_state_dereference(&opt_state
, MDL
);
5375 * Release means a client is done with the leases.
5378 /* TODO: reject unicast messages, unless we set unicast option */
5380 dhcpv6_release(struct data_string
*reply
, struct packet
*packet
) {
5381 struct data_string client_id
;
5382 struct data_string server_id
;
5385 * Validate our input.
5387 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5392 * And operate on each IA_NA in this packet.
5394 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
, "Release",
5395 ia_na_match_release
, ia_na_nomatch_release
);
5398 * And operate on each IA_PD in this packet.
5400 iterate_over_ia_pd(reply
, packet
, &client_id
, &server_id
, "Release",
5401 ia_pd_match_release
, ia_pd_nomatch_release
);
5403 data_string_forget(&server_id
, MDL
);
5404 data_string_forget(&client_id
, MDL
);
5408 * Information-Request is used by clients who have obtained an address
5409 * from other means, but want configuration information from the server.
5413 dhcpv6_information_request(struct data_string
*reply
, struct packet
*packet
) {
5414 struct data_string client_id
;
5415 struct data_string server_id
;
5418 * Validate our input.
5420 if (!valid_client_info_req(packet
, &server_id
)) {
5425 * Get our client ID, if there is one.
5427 memset(&client_id
, 0, sizeof(client_id
));
5428 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
) {
5429 data_string_forget(&client_id
, MDL
);
5433 * Use the lease_to_client() function. This will work fine,
5434 * because the valid_client_info_req() insures that we
5435 * don't have any IA that would cause us to allocate
5436 * resources to the client.
5438 lease_to_client(reply
, packet
, &client_id
,
5439 server_id
.data
!= NULL
? &server_id
: NULL
);
5444 if (client_id
.data
!= NULL
) {
5445 data_string_forget(&client_id
, MDL
);
5447 data_string_forget(&server_id
, MDL
);
5451 * The Relay-forw message is sent by relays. It typically contains a
5452 * single option, which encapsulates an entire packet.
5454 * We need to build an encapsulated reply.
5457 /* XXX: this is very, very similar to do_packet6(), and should probably
5458 be combined in a clever way */
5460 dhcpv6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
5461 struct option_cache
*oc
;
5462 struct data_string enc_opt_data
;
5463 struct packet
*enc_packet
;
5464 unsigned char msg_type
;
5465 const struct dhcpv6_packet
*msg
;
5466 const struct dhcpv6_relay_packet
*relay
;
5467 struct data_string enc_reply
;
5468 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
5469 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
5470 struct data_string a_opt
, packet_ero
;
5471 struct option_state
*opt_state
;
5472 static char reply_data
[65536];
5473 struct dhcpv6_relay_packet
*reply
;
5477 * Initialize variables for early exit.
5480 memset(&a_opt
, 0, sizeof(a_opt
));
5481 memset(&packet_ero
, 0, sizeof(packet_ero
));
5482 memset(&enc_reply
, 0, sizeof(enc_reply
));
5483 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
5487 * Get our encapsulated relay message.
5489 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
5491 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
5492 link_addr
, sizeof(link_addr
));
5493 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
5494 peer_addr
, sizeof(peer_addr
));
5495 log_info("Relay-forward from %s with link address=%s and "
5496 "peer address=%s missing Relay Message option.",
5497 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
5501 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
5502 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
5503 log_error("dhcpv6_forw_relay: error evaluating "
5504 "relayed message.");
5508 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
5509 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
5514 * Build a packet structure from this encapsulated packet.
5517 if (!packet_allocate(&enc_packet
, MDL
)) {
5518 log_error("dhcpv6_forw_relay: "
5519 "no memory for encapsulated packet.");
5523 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
5524 log_error("dhcpv6_forw_relay: "
5525 "no memory for encapsulated packet's options.");
5529 enc_packet
->client_port
= packet
->client_port
;
5530 enc_packet
->client_addr
= packet
->client_addr
;
5531 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
5532 enc_packet
->dhcpv6_container_packet
= packet
;
5534 msg_type
= enc_opt_data
.data
[0];
5535 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
5536 (msg_type
== DHCPV6_RELAY_REPL
)) {
5537 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
5538 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
5539 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
5541 /* relay-specific data */
5542 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
5543 memcpy(&enc_packet
->dhcpv6_link_address
,
5544 relay
->link_address
, sizeof(relay
->link_address
));
5545 memcpy(&enc_packet
->dhcpv6_peer_address
,
5546 relay
->peer_address
, sizeof(relay
->peer_address
));
5548 if (!parse_option_buffer(enc_packet
->options
,
5550 enc_opt_data
.len
- relaylen
,
5551 &dhcpv6_universe
)) {
5552 /* no logging here, as parse_option_buffer() logs all
5553 cases where it fails */
5557 int msglen
= (int)(offsetof(struct dhcpv6_packet
, options
));
5558 msg
= (struct dhcpv6_packet
*)enc_opt_data
.data
;
5559 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
5561 /* message-specific data */
5562 memcpy(enc_packet
->dhcpv6_transaction_id
,
5563 msg
->transaction_id
,
5564 sizeof(enc_packet
->dhcpv6_transaction_id
));
5566 if (!parse_option_buffer(enc_packet
->options
,
5568 enc_opt_data
.len
- msglen
,
5569 &dhcpv6_universe
)) {
5570 /* no logging here, as parse_option_buffer() logs all
5571 cases where it fails */
5577 * This is recursive. It is possible to exceed maximum packet size.
5578 * XXX: This will cause the packet send to fail.
5580 build_dhcpv6_reply(&enc_reply
, enc_packet
);
5583 * If we got no encapsulated data, then it is discarded, and
5584 * our reply-forw is also discarded.
5586 if (enc_reply
.data
== NULL
) {
5591 * Now we can use the reply_data buffer.
5592 * Packet header stuff all comes from the forward message.
5594 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
5595 reply
->msg_type
= DHCPV6_RELAY_REPL
;
5596 reply
->hop_count
= packet
->dhcpv6_hop_count
;
5597 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
5598 sizeof(reply
->link_address
));
5599 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
5600 sizeof(reply
->peer_address
));
5601 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
5604 * Get the reply option state.
5607 if (!option_state_allocate(&opt_state
, MDL
)) {
5608 log_error("dhcpv6_relay_forw: no memory for option state.");
5613 * Append the interface-id if present.
5615 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
5618 if (!evaluate_option_cache(&a_opt
, packet
,
5620 packet
->options
, NULL
,
5621 &global_scope
, oc
, MDL
)) {
5622 log_error("dhcpv6_relay_forw: error evaluating "
5626 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5627 (unsigned char *)a_opt
.data
,
5629 D6O_INTERFACE_ID
, 0)) {
5630 log_error("dhcpv6_relay_forw: error saving "
5634 data_string_forget(&a_opt
, MDL
);
5638 * Append our encapsulated stuff for caller.
5640 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5641 (unsigned char *)enc_reply
.data
,
5643 D6O_RELAY_MSG
, 0)) {
5644 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
5649 * Get the ERO if any.
5651 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
5656 if (!evaluate_option_cache(&packet_ero
, packet
,
5658 packet
->options
, NULL
,
5659 &global_scope
, oc
, MDL
) ||
5660 (packet_ero
.len
& 1)) {
5661 log_error("dhcpv6_relay_forw: error evaluating ERO.");
5665 /* Decode and apply the ERO. */
5666 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
5667 req
= getUShort(packet_ero
.data
+ i
);
5668 /* Already in the reply? */
5669 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
5672 /* Get it from the packet if present. */
5673 oc
= lookup_option(&dhcpv6_universe
,
5678 if (!evaluate_option_cache(&a_opt
, packet
,
5680 packet
->options
, NULL
,
5681 &global_scope
, oc
, MDL
)) {
5682 log_error("dhcpv6_relay_forw: error "
5683 "evaluating option %u.", req
);
5686 if (!save_option_buffer(&dhcpv6_universe
,
5689 (unsigned char *)a_opt
.data
,
5693 log_error("dhcpv6_relay_forw: error saving "
5697 data_string_forget(&a_opt
, MDL
);
5701 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
5702 sizeof(reply_data
) - reply_ofs
,
5704 required_opts_agent
, &packet_ero
);
5707 * Return our reply to the caller.
5709 reply_ret
->len
= reply_ofs
;
5710 reply_ret
->buffer
= NULL
;
5711 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
5712 log_fatal("No memory to store reply.");
5714 reply_ret
->data
= reply_ret
->buffer
->data
;
5715 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
5718 if (opt_state
!= NULL
)
5719 option_state_dereference(&opt_state
, MDL
);
5720 if (a_opt
.data
!= NULL
) {
5721 data_string_forget(&a_opt
, MDL
);
5723 if (packet_ero
.data
!= NULL
) {
5724 data_string_forget(&packet_ero
, MDL
);
5726 if (enc_reply
.data
!= NULL
) {
5727 data_string_forget(&enc_reply
, MDL
);
5729 if (enc_opt_data
.data
!= NULL
) {
5730 data_string_forget(&enc_opt_data
, MDL
);
5732 if (enc_packet
!= NULL
) {
5733 packet_dereference(&enc_packet
, MDL
);
5738 dhcpv6_discard(struct packet
*packet
) {
5739 /* INSIST(packet->msg_type > 0); */
5740 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
5742 log_debug("Discarding %s from %s; message type not handled by server",
5743 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
5744 piaddr(packet
->client_addr
));
5748 build_dhcpv6_reply(struct data_string
*reply
, struct packet
*packet
) {
5749 memset(reply
, 0, sizeof(*reply
));
5750 switch (packet
->dhcpv6_msg_type
) {
5751 case DHCPV6_SOLICIT
:
5752 dhcpv6_solicit(reply
, packet
);
5754 case DHCPV6_ADVERTISE
:
5755 dhcpv6_discard(packet
);
5757 case DHCPV6_REQUEST
:
5758 dhcpv6_request(reply
, packet
);
5760 case DHCPV6_CONFIRM
:
5761 dhcpv6_confirm(reply
, packet
);
5764 dhcpv6_renew(reply
, packet
);
5767 dhcpv6_rebind(reply
, packet
);
5770 dhcpv6_discard(packet
);
5772 case DHCPV6_RELEASE
:
5773 dhcpv6_release(reply
, packet
);
5775 case DHCPV6_DECLINE
:
5776 dhcpv6_decline(reply
, packet
);
5778 case DHCPV6_RECONFIGURE
:
5779 dhcpv6_discard(packet
);
5781 case DHCPV6_INFORMATION_REQUEST
:
5782 dhcpv6_information_request(reply
, packet
);
5784 case DHCPV6_RELAY_FORW
:
5785 dhcpv6_relay_forw(reply
, packet
);
5787 case DHCPV6_RELAY_REPL
:
5788 dhcpv6_discard(packet
);
5790 case DHCPV6_LEASEQUERY
:
5791 dhcpv6_leasequery(reply
, packet
);
5793 case DHCPV6_LEASEQUERY_REPLY
:
5794 dhcpv6_discard(packet
);
5797 /* XXX: would be nice if we had "notice" level,
5798 as syslog, for this */
5799 log_info("Discarding unknown DHCPv6 message type %d "
5800 "from %s", packet
->dhcpv6_msg_type
,
5801 piaddr(packet
->client_addr
));
5806 log_packet_in(const struct packet
*packet
) {
5807 struct data_string s
;
5809 char tmp_addr
[INET6_ADDRSTRLEN
];
5812 memset(&s
, 0, sizeof(s
));
5814 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
5815 data_string_sprintfa(&s
, "%s message from %s port %d",
5816 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
5817 piaddr(packet
->client_addr
),
5818 ntohs(packet
->client_port
));
5820 data_string_sprintfa(&s
,
5821 "Unknown message type %d from %s port %d",
5822 packet
->dhcpv6_msg_type
,
5823 piaddr(packet
->client_addr
),
5824 ntohs(packet
->client_port
));
5826 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
5827 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
5828 addr
= &packet
->dhcpv6_link_address
;
5829 data_string_sprintfa(&s
, ", link address %s",
5830 inet_ntop(AF_INET6
, addr
,
5831 tmp_addr
, sizeof(tmp_addr
)));
5832 addr
= &packet
->dhcpv6_peer_address
;
5833 data_string_sprintfa(&s
, ", peer address %s",
5834 inet_ntop(AF_INET6
, addr
,
5835 tmp_addr
, sizeof(tmp_addr
)));
5838 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
5839 data_string_sprintfa(&s
, ", transaction ID 0x%06X", tid
);
5842 oc = lookup_option(&dhcpv6_universe, packet->options,
5845 memset(&tmp_ds, 0, sizeof(tmp_ds_));
5846 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
5847 packet->options, NULL,
5848 &global_scope, oc, MDL)) {
5849 log_error("Error evaluating Client Identifier");
5851 data_strint_sprintf(&s, ", client ID %s",
5853 data_string_forget(&tmp_ds, MDL);
5859 log_info("%s", s
.data
);
5861 data_string_forget(&s
, MDL
);
5865 dhcpv6(struct packet
*packet
) {
5866 struct data_string reply
;
5867 struct sockaddr_in6 to_addr
;
5871 * Log a message that we received this packet.
5873 log_packet_in(packet
);
5876 * Build our reply packet.
5878 build_dhcpv6_reply(&reply
, packet
);
5880 if (reply
.data
!= NULL
) {
5882 * Send our reply, if we have one.
5884 memset(&to_addr
, 0, sizeof(to_addr
));
5885 to_addr
.sin6_family
= AF_INET6
;
5886 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
5887 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
5888 to_addr
.sin6_port
= local_port
;
5890 to_addr
.sin6_port
= remote_port
;
5893 #if defined (REPLY_TO_SOURCE_PORT)
5895 * This appears to have been included for testing so we would
5896 * not need a root client, but was accidently left in the
5897 * final code. We continue to include it in case
5898 * some users have come to rely upon it, but leave
5899 * it off by default as it's a bad idea.
5901 to_addr
.sin6_port
= packet
->client_port
;
5904 memcpy(&to_addr
.sin6_addr
, packet
->client_addr
.iabuf
,
5905 sizeof(to_addr
.sin6_addr
));
5907 log_info("Sending %s to %s port %d",
5908 dhcpv6_type_names
[reply
.data
[0]],
5909 piaddr(packet
->client_addr
),
5910 ntohs(to_addr
.sin6_port
));
5912 send_ret
= send_packet6(packet
->interface
,
5913 reply
.data
, reply
.len
, &to_addr
);
5914 if (send_ret
!= reply
.len
) {
5915 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
5916 send_ret
, reply
.len
);
5918 data_string_forget(&reply
, MDL
);
5923 seek_shared_host(struct host_decl
**hp
, struct shared_network
*shared
) {
5924 struct host_decl
*nofixed
= NULL
;
5925 struct host_decl
*seek
, *hold
= NULL
;
5928 * Seek forward through fixed addresses for the right link.
5930 * Note: how to do this for fixed prefixes???
5932 host_reference(&hold
, *hp
, MDL
);
5933 host_dereference(hp
, MDL
);
5935 while (seek
!= NULL
) {
5936 if (seek
->fixed_addr
== NULL
)
5938 else if (fixed_matches_shared(seek
, shared
))
5941 seek
= seek
->n_ipaddr
;
5944 if ((seek
== NULL
) && (nofixed
!= NULL
))
5948 host_reference(hp
, seek
, MDL
);
5951 static isc_boolean_t
5952 fixed_matches_shared(struct host_decl
*host
, struct shared_network
*shared
) {
5953 struct subnet
*subnet
;
5954 struct data_string addr
;
5955 isc_boolean_t matched
;
5958 if (host
->fixed_addr
== NULL
)
5961 memset(&addr
, 0, sizeof(addr
));
5962 if (!evaluate_option_cache(&addr
, NULL
, NULL
, NULL
, NULL
, NULL
,
5963 &global_scope
, host
->fixed_addr
, MDL
))
5966 if (addr
.len
< 16) {
5967 data_string_forget(&addr
, MDL
);
5972 memcpy(fixed
.iabuf
, addr
.data
, 16);
5974 matched
= ISC_FALSE
;
5975 for (subnet
= shared
->subnets
; subnet
!= NULL
;
5976 subnet
= subnet
->next_sibling
) {
5977 if (addr_eq(subnet_number(fixed
, subnet
->netmask
),
5984 data_string_forget(&addr
, MDL
);
5989 * find_host_by_duid_chaddr() synthesizes a DHCPv4-like 'hardware'
5990 * parameter from a DHCPv6 supplied DUID (client-identifier option),
5991 * and may seek to use client or relay supplied hardware addresses.
5994 find_hosts_by_duid_chaddr(struct host_decl
**host
,
5995 const struct data_string
*client_id
) {
5996 static int once_htype
;
5998 const unsigned char *chaddr
;
6001 * The DUID-LL and DUID-LLT must have a 2-byte DUID type and 2-byte
6004 if (client_id
->len
< 4)
6008 * The third and fourth octets of the DUID-LL and DUID-LLT
6009 * is the hardware type, but in 16 bits.
6011 htype
= getUShort(client_id
->data
+ 2);
6015 /* The first two octets of the DUID identify the type. */
6016 switch(getUShort(client_id
->data
)) {
6018 if (client_id
->len
> 8) {
6019 hlen
= client_id
->len
- 8;
6020 chaddr
= client_id
->data
+ 8;
6026 * Note that client_id->len must be greater than or equal
6027 * to four to get to this point in the function.
6029 hlen
= client_id
->len
- 4;
6030 chaddr
= client_id
->data
+ 4;
6037 if ((hlen
== 0) || (hlen
> HARDWARE_ADDR_LEN
))
6041 * XXX: DHCPv6 gives a 16-bit field for the htype. DHCPv4 gives an
6042 * 8-bit field. To change the semantics of the generic 'hardware'
6043 * structure, we would have to adjust many DHCPv4 sources (from
6044 * interface to DHCPv4 lease code), and we would have to update the
6045 * 'hardware' config directive (probably being reverse compatible and
6046 * providing a new upgrade/replacement primitive). This is a little
6047 * too much to change for now. Hopefully we will revisit this before
6048 * hardware types exceeding 8 bits are assigned.
6050 if ((htype
& 0xFF00) && !once_htype
) {
6052 log_error("Attention: At least one client advertises a "
6053 "hardware type of %d, which exceeds the software "
6054 "limitation of 255.", htype
);
6057 return find_hosts_by_haddr(host
, htype
, chaddr
, hlen
, MDL
);