2 * Copyright (C) 2006-2016 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.
17 /*! \file server/dhcpv6.c */
24 * We use print_hex_1() to output DUID values. We could actually output
25 * the DUID with more information... MAC address if using type 1 or 3,
26 * and so on. However, RFC 3315 contains Grave Warnings against actually
27 * attempting to understand a DUID.
31 * TODO: gettext() or other method of localization for the messages
32 * for status codes (and probably for log formats eventually)
33 * TODO: refactoring (simplify, simplify, simplify)
34 * TODO: support multiple shared_networks on each interface (this
35 * will allow the server to issue multiple IPv6 addresses to
40 * DHCPv6 Reply workflow assist. A Reply packet is built by various
41 * different functions; this gives us one location where we keep state
45 /* root level persistent state */
46 struct shared_network
*shared
;
47 struct host_decl
*host
;
48 struct subnet
*subnet
; /* Used to match fixed-addrs to subnet scopes. */
49 struct option_state
*opt_state
;
50 struct packet
*packet
;
51 struct data_string client_id
;
53 /* IA level persistent state */
56 unsigned client_resources
;
57 isc_boolean_t resources_included
;
58 isc_boolean_t static_lease
;
59 unsigned static_prefixes
;
62 struct option_state
*reply_ia
;
63 struct data_string fixed
;
64 struct iaddrcidrnet fixed_pref
; /* static prefix for logging */
66 /* IAADDR/PREFIX level persistent state */
67 struct iasubopt
*lease
;
70 * "t1", "t2", preferred, and valid lifetimes records for calculating
71 * t1 and t2 (min/max).
73 u_int32_t renew
, rebind
, prefer
, valid
;
75 /* Client-requested valid and preferred lifetimes. */
76 u_int32_t client_valid
, client_prefer
;
78 /* Chosen values to transmit for valid and preferred lifetimes. */
79 u_int32_t send_valid
, send_prefer
;
81 /* Preferred prefix length (-1 is any). */
84 /* Index into the data field that has been consumed. */
87 /* Space for the on commit statements for a fixed host */
88 struct on_star on_star
;
91 unsigned char data
[65536];
92 struct dhcpv6_packet reply
;
97 * Prototypes local to this file.
99 static int get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
100 struct data_string
*enc_opt_data
,
101 struct packet
*packet
,
102 struct option_cache
*oc
,
104 static void build_dhcpv6_reply(struct data_string
*, struct packet
*);
105 static isc_result_t
shared_network_from_packet6(struct shared_network
**shared
,
106 struct packet
*packet
);
107 static void seek_shared_host(struct host_decl
**hp
,
108 struct shared_network
*shared
);
109 static isc_boolean_t
fixed_matches_shared(struct host_decl
*host
,
110 struct shared_network
*shared
);
111 static isc_result_t
reply_process_ia_na(struct reply_state
*reply
,
112 struct option_cache
*ia
);
113 static isc_result_t
reply_process_ia_ta(struct reply_state
*reply
,
114 struct option_cache
*ia
);
115 static isc_result_t
reply_process_addr(struct reply_state
*reply
,
116 struct option_cache
*addr
);
117 static isc_boolean_t
address_is_owned(struct reply_state
*reply
,
119 static isc_boolean_t
temporary_is_available(struct reply_state
*reply
,
121 static isc_result_t
find_client_temporaries(struct reply_state
*reply
);
122 static isc_result_t
reply_process_try_addr(struct reply_state
*reply
,
124 static isc_result_t
find_client_address(struct reply_state
*reply
);
125 static isc_result_t
reply_process_is_addressed(struct reply_state
*reply
,
126 struct binding_scope
**scope
,
127 struct group
*group
);
128 static isc_result_t
reply_process_send_addr(struct reply_state
*reply
,
130 static struct iasubopt
*lease_compare(struct iasubopt
*alpha
,
131 struct iasubopt
*beta
);
132 static isc_result_t
reply_process_ia_pd(struct reply_state
*reply
,
133 struct option_cache
*ia_pd
);
134 static struct group
*find_group_by_prefix(struct reply_state
*reply
);
135 static isc_result_t
reply_process_prefix(struct reply_state
*reply
,
136 struct option_cache
*pref
);
137 static isc_boolean_t
prefix_is_owned(struct reply_state
*reply
,
138 struct iaddrcidrnet
*pref
);
139 static isc_result_t
find_client_prefix(struct reply_state
*reply
);
140 static isc_result_t
reply_process_try_prefix(struct reply_state
*reply
,
141 struct iaddrcidrnet
*pref
);
142 static isc_result_t
reply_process_is_prefixed(struct reply_state
*reply
,
143 struct binding_scope
**scope
,
144 struct group
*group
);
145 static isc_result_t
reply_process_send_prefix(struct reply_state
*reply
,
146 struct iaddrcidrnet
*pref
);
147 static struct iasubopt
*prefix_compare(struct reply_state
*reply
,
148 struct iasubopt
*alpha
,
149 struct iasubopt
*beta
);
150 static int find_hosts_by_duid_chaddr(struct host_decl
**host
,
151 const struct data_string
*client_id
);
152 static void schedule_lease_timeout_reply(struct reply_state
*reply
);
154 static int eval_prefix_mode(int thislen
, int preflen
, int prefix_mode
);
155 static isc_result_t
pick_v6_prefix_helper(struct reply_state
*reply
,
158 static void unicast_reject(struct data_string
*reply_ret
, struct packet
*packet
,
159 const struct data_string
*client_id
,
160 const struct data_string
*server_id
);
162 static isc_boolean_t
is_unicast_option_defined(struct packet
*packet
);
163 static isc_result_t
shared_network_from_requested_addr (struct shared_network
165 struct packet
* packet
);
166 static isc_result_t
get_first_ia_addr_val (struct packet
* packet
, int addr_type
,
167 struct iaddr
* iaddr
);
170 * Schedule lease timeouts for all of the iasubopts in the reply.
171 * This is currently used to schedule timeouts for soft leases.
175 schedule_lease_timeout_reply(struct reply_state
*reply
) {
176 struct iasubopt
*tmp
;
179 /* sanity check the reply */
180 if ((reply
== NULL
) || (reply
->ia
== NULL
) || (reply
->ia
->iasubopt
== NULL
))
183 /* walk through the list, scheduling as we go */
184 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
185 tmp
= reply
->ia
->iasubopt
[i
];
186 schedule_lease_timeout(tmp
->ipv6_pool
);
191 * This function returns the time since DUID time start for the
192 * given time_t value.
195 duid_time(time_t when
) {
197 * This time is modulo 2^32.
199 while ((when
- DUID_TIME_EPOCH
) > 4294967295u) {
200 /* use 2^31 to avoid spurious compiler warnings */
205 return when
- DUID_TIME_EPOCH
;
212 * This must remain the same for the lifetime of this server, because
213 * clients return the server DUID that we sent them in Request packets.
215 * We pick the server DUID like this:
217 * 1. Check dhcpd.conf - any value the administrator has configured
218 * overrides any possible values.
219 * 2. Check the leases.txt - we want to use the previous value if
221 * 3. Check if dhcpd.conf specifies a type of server DUID to use,
222 * and generate that type.
223 * 4. Generate a type 1 (time + hardware address) DUID.
225 static struct data_string server_duid
;
228 * Check if the server_duid has been set.
231 server_duid_isset(void) {
232 return (server_duid
.data
!= NULL
);
236 * Return the server_duid.
239 copy_server_duid(struct data_string
*ds
, const char *file
, int line
) {
240 data_string_copy(ds
, &server_duid
, file
, line
);
244 * Set the server DUID to a specified value. This is used when
245 * the server DUID is stored in persistent memory (basically the
249 set_server_duid(struct data_string
*new_duid
) {
250 /* INSIST(new_duid != NULL); */
251 /* INSIST(new_duid->data != NULL); */
253 if (server_duid_isset()) {
254 data_string_forget(&server_duid
, MDL
);
256 data_string_copy(&server_duid
, new_duid
, MDL
);
261 * Set the server DUID based on the D6O_SERVERID option. This handles
262 * the case where the administrator explicitly put it in the dhcpd.conf
266 set_server_duid_from_option(void) {
267 struct option_state
*opt_state
;
268 struct option_cache
*oc
;
269 struct data_string option_duid
;
270 isc_result_t ret_val
;
273 if (!option_state_allocate(&opt_state
, MDL
)) {
274 log_fatal("No memory for server DUID.");
277 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
,
278 opt_state
, &global_scope
, root_group
,
281 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
283 ret_val
= ISC_R_NOTFOUND
;
285 memset(&option_duid
, 0, sizeof(option_duid
));
286 if (!evaluate_option_cache(&option_duid
, NULL
, NULL
, NULL
,
287 opt_state
, NULL
, &global_scope
,
289 ret_val
= ISC_R_UNEXPECTED
;
291 set_server_duid(&option_duid
);
292 data_string_forget(&option_duid
, MDL
);
293 ret_val
= ISC_R_SUCCESS
;
297 option_state_dereference(&opt_state
, MDL
);
303 * DUID layout, as defined in RFC 3315, section 9.
305 * We support type 1 (hardware address plus time) and type 3 (hardware
308 * We can support type 2 for specific vendors in the future, if they
309 * publish the specification. And of course there may be additional
312 static int server_duid_type
= DUID_LLT
;
318 set_server_duid_type(int type
) {
319 server_duid_type
= type
;
323 * Generate a new server DUID. This is done if there was no DUID in
324 * the leases.txt or in the dhcpd.conf file.
327 generate_new_server_duid(void) {
328 struct interface_info
*p
;
330 struct data_string generated_duid
;
333 * Verify we have a type that we support.
335 if ((server_duid_type
!= DUID_LL
) && (server_duid_type
!= DUID_LLT
)) {
336 log_error("Invalid DUID type %d specified, "
337 "only LL and LLT types supported", server_duid_type
);
338 return DHCP_R_INVALIDARG
;
342 * Find an interface with a hardware address.
345 for (p
= interfaces
; p
!= NULL
; p
= p
->next
) {
346 if (p
->hw_address
.hlen
> 0) {
351 return ISC_R_UNEXPECTED
;
357 memset(&generated_duid
, 0, sizeof(generated_duid
));
358 if (server_duid_type
== DUID_LLT
) {
359 time_val
= duid_time(time(NULL
));
360 generated_duid
.len
= 8 + p
->hw_address
.hlen
- 1;
361 if (!buffer_allocate(&generated_duid
.buffer
,
362 generated_duid
.len
, MDL
)) {
363 log_fatal("No memory for server DUID.");
365 generated_duid
.data
= generated_duid
.buffer
->data
;
366 putUShort(generated_duid
.buffer
->data
, DUID_LLT
);
367 putUShort(generated_duid
.buffer
->data
+ 2,
368 p
->hw_address
.hbuf
[0]);
369 putULong(generated_duid
.buffer
->data
+ 4, time_val
);
370 memcpy(generated_duid
.buffer
->data
+ 8,
371 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
372 } else if (server_duid_type
== DUID_LL
) {
373 generated_duid
.len
= 4 + p
->hw_address
.hlen
- 1;
374 if (!buffer_allocate(&generated_duid
.buffer
,
375 generated_duid
.len
, MDL
)) {
376 log_fatal("No memory for server DUID.");
378 generated_duid
.data
= generated_duid
.buffer
->data
;
379 putUShort(generated_duid
.buffer
->data
, DUID_LL
);
380 putUShort(generated_duid
.buffer
->data
+ 2,
381 p
->hw_address
.hbuf
[0]);
382 memcpy(generated_duid
.buffer
->data
+ 4,
383 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
385 log_fatal("Unsupported server DUID type %d.", server_duid_type
);
388 set_server_duid(&generated_duid
);
389 data_string_forget(&generated_duid
, MDL
);
391 return ISC_R_SUCCESS
;
395 * Get the client identifier from the packet.
398 get_client_id(struct packet
*packet
, struct data_string
*client_id
) {
399 struct option_cache
*oc
;
402 * Verify our client_id structure is empty.
404 if ((client_id
->data
!= NULL
) || (client_id
->len
!= 0)) {
405 return DHCP_R_INVALIDARG
;
408 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_CLIENTID
);
410 return ISC_R_NOTFOUND
;
413 if (!evaluate_option_cache(client_id
, packet
, NULL
, NULL
,
414 packet
->options
, NULL
,
415 &global_scope
, oc
, MDL
)) {
416 return ISC_R_FAILURE
;
419 return ISC_R_SUCCESS
;
423 * Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
425 * Servers MUST discard any Solicit messages that do not include a
426 * Client Identifier option or that do include a Server Identifier
430 valid_client_msg(struct packet
*packet
, struct data_string
*client_id
) {
432 struct option_cache
*oc
;
433 struct data_string data
;
436 memset(client_id
, 0, sizeof(*client_id
));
437 memset(&data
, 0, sizeof(data
));
439 switch (get_client_id(packet
, client_id
)) {
443 log_debug("Discarding %s from %s; "
444 "client identifier missing",
445 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
446 piaddr(packet
->client_addr
));
449 log_error("Error processing %s from %s; "
450 "unable to evaluate Client Identifier",
451 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
452 piaddr(packet
->client_addr
));
457 * Required by RFC 3315, section 15.
459 if (packet
->unicast
) {
460 log_debug("Discarding %s from %s; packet sent unicast "
462 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
463 piaddr(packet
->client_addr
),
464 print_hex_1(client_id
->len
, client_id
->data
, 60));
469 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
471 if (evaluate_option_cache(&data
, packet
, NULL
, NULL
,
472 packet
->options
, NULL
,
473 &global_scope
, oc
, MDL
)) {
474 log_debug("Discarding %s from %s; "
475 "server identifier found "
476 "(CLIENTID %s, SERVERID %s)",
477 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
478 piaddr(packet
->client_addr
),
479 print_hex_1(client_id
->len
,
480 client_id
->data
, 60),
481 print_hex_2(data
.len
,
484 log_debug("Discarding %s from %s; "
485 "server identifier found "
487 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
488 print_hex_1(client_id
->len
,
489 client_id
->data
, 60),
490 piaddr(packet
->client_addr
));
500 data_string_forget(&data
, MDL
);
503 if (client_id
->len
> 0) {
504 data_string_forget(client_id
, MDL
);
511 * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
512 * 15.9 (slightly different wording, but same meaning):
514 * Servers MUST discard any received Request message that meet any of
515 * the following conditions:
517 * - the message does not include a Server Identifier option.
518 * - the contents of the Server Identifier option do not match the
520 * - the message does not include a Client Identifier option.
523 valid_client_resp(struct packet
*packet
,
524 struct data_string
*client_id
,
525 struct data_string
*server_id
)
528 struct option_cache
*oc
;
530 /* INSIST((duid.data != NULL) && (duid.len > 0)); */
533 memset(client_id
, 0, sizeof(*client_id
));
534 memset(server_id
, 0, sizeof(*server_id
));
536 switch (get_client_id(packet
, client_id
)) {
540 log_debug("Discarding %s from %s; "
541 "client identifier missing",
542 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
543 piaddr(packet
->client_addr
));
546 log_error("Error processing %s from %s; "
547 "unable to evaluate Client Identifier",
548 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
549 piaddr(packet
->client_addr
));
553 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
555 log_debug("Discarding %s from %s: "
556 "server identifier missing (CLIENTID %s)",
557 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
558 piaddr(packet
->client_addr
),
559 print_hex_1(client_id
->len
, client_id
->data
, 60));
562 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
563 packet
->options
, NULL
,
564 &global_scope
, oc
, MDL
)) {
565 log_error("Error processing %s from %s; "
566 "unable to evaluate Server Identifier (CLIENTID %s)",
567 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
568 piaddr(packet
->client_addr
),
569 print_hex_1(client_id
->len
, client_id
->data
, 60));
572 if ((server_duid
.len
!= server_id
->len
) ||
573 (memcmp(server_duid
.data
, server_id
->data
, server_duid
.len
) != 0)) {
574 log_debug("Discarding %s from %s; "
575 "not our server identifier "
576 "(CLIENTID %s, SERVERID %s, server DUID %s)",
577 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
578 piaddr(packet
->client_addr
),
579 print_hex_1(client_id
->len
, client_id
->data
, 60),
580 print_hex_2(server_id
->len
, server_id
->data
, 60),
581 print_hex_3(server_duid
.len
, server_duid
.data
, 60));
590 if (server_id
->len
> 0) {
591 data_string_forget(server_id
, MDL
);
593 if (client_id
->len
> 0) {
594 data_string_forget(client_id
, MDL
);
601 * Information request validation, defined in RFC 3315, section 15.12:
603 * Servers MUST discard any received Information-request message that
604 * meets any of the following conditions:
606 * - The message includes a Server Identifier option and the DUID in
607 * the option does not match the server's DUID.
609 * - The message includes an IA option.
612 valid_client_info_req(struct packet
*packet
, struct data_string
*server_id
) {
614 struct option_cache
*oc
;
615 struct data_string client_id
;
616 char client_id_str
[80]; /* print_hex_1() uses maximum 60 characters,
617 plus a few more for extra information */
620 memset(server_id
, 0, sizeof(*server_id
));
621 memset(&client_id
, 0, sizeof(client_id
));
624 * Make a string that we can print out to give more
625 * information about the client if we need to.
627 * By RFC 3315, Section 18.1.5 clients SHOULD have a
628 * client-id on an Information-request packet, but it
629 * is not strictly necessary.
631 if (get_client_id(packet
, &client_id
) == ISC_R_SUCCESS
) {
632 snprintf(client_id_str
, sizeof(client_id_str
), " (CLIENTID %s)",
633 print_hex_1(client_id
.len
, client_id
.data
, 60));
634 data_string_forget(&client_id
, MDL
);
636 client_id_str
[0] = '\0';
640 * Required by RFC 3315, section 15.
642 if (packet
->unicast
) {
643 log_debug("Discarding %s from %s; packet sent unicast%s",
644 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
645 piaddr(packet
->client_addr
), client_id_str
);
649 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
651 log_debug("Discarding %s from %s; "
652 "IA_NA option present%s",
653 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
654 piaddr(packet
->client_addr
), client_id_str
);
657 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
659 log_debug("Discarding %s from %s; "
660 "IA_TA option present%s",
661 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
662 piaddr(packet
->client_addr
), client_id_str
);
665 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
667 log_debug("Discarding %s from %s; "
668 "IA_PD option present%s",
669 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
670 piaddr(packet
->client_addr
), client_id_str
);
674 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
676 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
677 packet
->options
, NULL
,
678 &global_scope
, oc
, MDL
)) {
679 log_error("Error processing %s from %s; "
680 "unable to evaluate Server Identifier%s",
681 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
682 piaddr(packet
->client_addr
), client_id_str
);
685 if ((server_duid
.len
!= server_id
->len
) ||
686 (memcmp(server_duid
.data
, server_id
->data
,
687 server_duid
.len
) != 0)) {
688 log_debug("Discarding %s from %s; "
689 "not our server identifier "
690 "(SERVERID %s, server DUID %s)%s",
691 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
692 piaddr(packet
->client_addr
),
693 print_hex_1(server_id
->len
,
694 server_id
->data
, 60),
695 print_hex_2(server_duid
.len
,
696 server_duid
.data
, 60),
707 if (server_id
->len
> 0) {
708 data_string_forget(server_id
, MDL
);
715 * Options that we want to send, in addition to what was requested
718 static const int required_opts
[] = {
725 static const int required_opts_solicit
[] = {
737 static const int required_opts_agent
[] = {
742 static const int required_opts_IA
[] = {
747 static const int required_opts_IA_PD
[] = {
752 static const int required_opts_STATUS_CODE
[] = {
757 static const int unicast_reject_opts
[] = {
766 * Extracts from packet contents an IA_* option, storing the IA structure
767 * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
768 * in enc_opt_state for later lookup and evaluation. The 'offset' indicates
769 * where in the IA_* the DHCPv6 options commence.
772 get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
773 struct data_string
*enc_opt_data
,
774 struct packet
*packet
,
775 struct option_cache
*oc
,
779 * Get the raw data for the encapsulated options.
781 memset(enc_opt_data
, 0, sizeof(*enc_opt_data
));
782 if (!evaluate_option_cache(enc_opt_data
, packet
,
783 NULL
, NULL
, packet
->options
, NULL
,
784 &global_scope
, oc
, MDL
)) {
785 log_error("get_encapsulated_IA_state: "
786 "error evaluating raw option.");
789 if (enc_opt_data
->len
< offset
) {
790 log_error("get_encapsulated_IA_state: raw option too small.");
791 data_string_forget(enc_opt_data
, MDL
);
796 * Now create the option state structure, and pass it to the
797 * function that parses options.
799 *enc_opt_state
= NULL
;
800 if (!option_state_allocate(enc_opt_state
, MDL
)) {
801 log_error("get_encapsulated_IA_state: no memory for options.");
802 data_string_forget(enc_opt_data
, MDL
);
805 if (!parse_option_buffer(*enc_opt_state
,
806 enc_opt_data
->data
+ offset
,
807 enc_opt_data
->len
- offset
,
809 log_error("get_encapsulated_IA_state: error parsing options.");
810 option_state_dereference(enc_opt_state
, MDL
);
811 data_string_forget(enc_opt_data
, MDL
);
819 set_status_code(u_int16_t status_code
, const char *status_message
,
820 struct option_state
*opt_state
)
822 struct data_string d
;
825 memset(&d
, 0, sizeof(d
));
826 d
.len
= sizeof(status_code
) + strlen(status_message
);
827 if (!buffer_allocate(&d
.buffer
, d
.len
, MDL
)) {
828 log_fatal("set_status_code: no memory for status code.");
830 d
.data
= d
.buffer
->data
;
831 putUShort(d
.buffer
->data
, status_code
);
832 memcpy(d
.buffer
->data
+ sizeof(status_code
),
833 status_message
, d
.len
- sizeof(status_code
));
834 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
835 d
.buffer
, (unsigned char *)d
.data
, d
.len
,
836 D6O_STATUS_CODE
, 0)) {
837 log_error("set_status_code: error saving status code.");
842 data_string_forget(&d
, MDL
);
846 void check_pool6_threshold(struct reply_state
*reply
,
847 struct iasubopt
*lease
)
849 struct ipv6_pond
*pond
;
850 isc_uint64_t used
, count
, high_threshold
;
851 int poolhigh
= 0, poollow
= 0;
852 char *shared_name
= "no name";
853 char tmp_addr
[INET6_ADDRSTRLEN
];
855 if ((lease
->ipv6_pool
== NULL
) || (lease
->ipv6_pool
->ipv6_pond
== NULL
))
857 pond
= lease
->ipv6_pool
->ipv6_pond
;
859 /* If the address range is too large to track, just skip all this. */
860 if (pond
->jumbo_range
== 1) {
864 count
= pond
->num_total
;
865 used
= pond
->num_active
;
867 /* get network name for logging */
868 if ((pond
->shared_network
!= NULL
) &&
869 (pond
->shared_network
->name
!= NULL
)) {
870 shared_name
= pond
->shared_network
->name
;
873 /* The logged flag indicates if we have already crossed the high
874 * threshold and emitted a log message. If it is set we check to
875 * see if we have re-crossed the low threshold and need to reset
876 * things. When we cross the high threshold we determine what
877 * the low threshold is and save it into the low_threshold value.
878 * When we cross that threshold we reset the logged flag and
879 * the low_threshold to 0 which allows the high threshold message
880 * to be emitted once again.
881 * if we haven't recrossed the boundry we don't need to do anything.
883 if (pond
->logged
!=0) {
884 if (used
<= pond
->low_threshold
) {
885 pond
->low_threshold
= 0;
887 log_error("Pool threshold reset - shared subnet: %s; "
888 "address: %s; low threshold %llu/%llu.",
890 inet_ntop(AF_INET6
, &lease
->addr
,
891 tmp_addr
, sizeof(tmp_addr
)),
897 /* find the high threshold */
898 if (get_option_int(&poolhigh
, &server_universe
, reply
->packet
, NULL
,
899 NULL
, reply
->packet
->options
, reply
->opt_state
,
900 reply
->opt_state
, &lease
->scope
,
901 SV_LOG_THRESHOLD_HIGH
, MDL
) == 0) {
902 /* no threshold bail out */
906 /* We do have a threshold for this pool, see if its valid */
907 if ((poolhigh
<= 0) || (poolhigh
> 100)) {
912 /* we have a valid value, have we exceeded it */
913 high_threshold
= FIND_POND6_PERCENT(count
, poolhigh
);
914 if (used
< high_threshold
) {
915 /* nope, no more to do */
919 /* we've exceeded it, output a message */
920 log_error("Pool threshold exceeded - shared subnet: %s; "
921 "address: %s; high threshold %d%% %llu/%llu.",
923 inet_ntop(AF_INET6
, &lease
->addr
, tmp_addr
, sizeof(tmp_addr
)),
924 poolhigh
, used
, count
);
926 /* handle the low threshold now, if we don't
927 * have one we default to 0. */
928 if ((get_option_int(&poollow
, &server_universe
, reply
->packet
, NULL
,
929 NULL
, reply
->packet
->options
, reply
->opt_state
,
930 reply
->opt_state
, &lease
->scope
,
931 SV_LOG_THRESHOLD_LOW
, MDL
) == 0) ||
937 * If the low theshold is higher than the high threshold we continue to log
938 * If it isn't then we set the flag saying we already logged and determine
939 * what the reset threshold is.
941 if (poollow
< poolhigh
) {
943 pond
->low_threshold
= FIND_POND6_PERCENT(count
, poollow
);
948 * We have a set of operations we do to set up the reply packet, which
949 * is the same for many message types.
952 start_reply(struct packet
*packet
,
953 const struct data_string
*client_id
,
954 const struct data_string
*server_id
,
955 struct option_state
**opt_state
,
956 struct dhcpv6_packet
*reply
)
958 struct option_cache
*oc
;
959 const unsigned char *server_id_data
;
963 * Build our option state for reply.
966 if (!option_state_allocate(opt_state
, MDL
)) {
967 log_error("start_reply: no memory for option_state.");
970 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
971 packet
->options
, *opt_state
,
972 &global_scope
, root_group
, NULL
, NULL
);
975 * A small bit of special handling for Solicit messages.
977 * We could move the logic into a flag, but for now just check
980 if (packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
981 reply
->msg_type
= DHCPV6_ADVERTISE
;
985 * - this message type supports rapid commit (Solicit), and
986 * - the server is configured to supply a rapid commit, and
987 * - the client requests a rapid commit,
988 * Then we add a rapid commit option, and send Reply (instead
991 oc
= lookup_option(&dhcpv6_universe
,
992 *opt_state
, D6O_RAPID_COMMIT
);
994 oc
= lookup_option(&dhcpv6_universe
,
995 packet
->options
, D6O_RAPID_COMMIT
);
997 /* Rapid-commit in action. */
998 reply
->msg_type
= DHCPV6_REPLY
;
1000 /* Don't want a rapid-commit in advertise. */
1001 delete_option(&dhcpv6_universe
,
1002 *opt_state
, D6O_RAPID_COMMIT
);
1006 reply
->msg_type
= DHCPV6_REPLY
;
1007 /* Delete the rapid-commit from the sent options. */
1008 oc
= lookup_option(&dhcpv6_universe
,
1009 *opt_state
, D6O_RAPID_COMMIT
);
1011 delete_option(&dhcpv6_universe
,
1012 *opt_state
, D6O_RAPID_COMMIT
);
1017 * Use the client's transaction identifier for the reply.
1019 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
1020 sizeof(reply
->transaction_id
));
1023 * RFC 3315, section 18.2 says we need server identifier and
1024 * client identifier.
1026 * If the server ID is defined via the configuration file, then
1027 * it will already be present in the option state at this point,
1028 * so we don't need to set it.
1030 * If we have a server ID passed in from the caller,
1031 * use that, otherwise use the global DUID.
1033 oc
= lookup_option(&dhcpv6_universe
, *opt_state
, D6O_SERVERID
);
1035 if (server_id
== NULL
) {
1036 server_id_data
= server_duid
.data
;
1037 server_id_len
= server_duid
.len
;
1039 server_id_data
= server_id
->data
;
1040 server_id_len
= server_id
->len
;
1042 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1043 NULL
, (unsigned char *)server_id_data
,
1044 server_id_len
, D6O_SERVERID
, 0)) {
1045 log_error("start_reply: "
1046 "error saving server identifier.");
1051 if (client_id
->buffer
!= NULL
) {
1052 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1054 (unsigned char *)client_id
->data
,
1057 log_error("start_reply: error saving "
1058 "client identifier.");
1064 * If the client accepts reconfiguration, let it know that we
1067 * Note: we don't actually do this yet, but DOCSIS requires we
1070 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
1073 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1074 NULL
, (unsigned char *)"", 0,
1075 D6O_RECONF_ACCEPT
, 0)) {
1076 log_error("start_reply: "
1077 "error saving RECONF_ACCEPT option.");
1078 option_state_dereference(opt_state
, MDL
);
1087 * Try to get the IPv6 address the client asked for from the
1090 * addr is the result (should be a pointer to NULL on entry)
1091 * pool is the pool to search in
1092 * requested_addr is the address the client wants
1095 try_client_v6_address(struct iasubopt
**addr
,
1096 struct ipv6_pool
*pool
,
1097 const struct data_string
*requested_addr
)
1099 struct in6_addr tmp_addr
;
1100 isc_result_t result
;
1102 if (requested_addr
->len
< sizeof(tmp_addr
)) {
1103 return DHCP_R_INVALIDARG
;
1105 memcpy(&tmp_addr
, requested_addr
->data
, sizeof(tmp_addr
));
1106 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
)) {
1107 return ISC_R_FAILURE
;
1111 * The address is not covered by this (or possibly any) dynamic
1114 if (!ipv6_in_pool(&tmp_addr
, pool
)) {
1115 return ISC_R_ADDRNOTAVAIL
;
1118 if (lease6_exists(pool
, &tmp_addr
)) {
1119 return ISC_R_ADDRINUSE
;
1122 result
= iasubopt_allocate(addr
, MDL
);
1123 if (result
!= ISC_R_SUCCESS
) {
1126 (*addr
)->addr
= tmp_addr
;
1129 /* Default is soft binding for 2 minutes. */
1130 result
= add_lease6(pool
, *addr
, cur_time
+ 120);
1131 if (result
!= ISC_R_SUCCESS
) {
1132 iasubopt_dereference(addr
, MDL
);
1140 * \brief Get an IPv6 address for the client.
1142 * Attempt to find a usable address for the client. We walk through
1143 * the ponds checking for permit and deny then through the pools
1144 * seeing if they have an available address.
1146 * \param reply = the state structure for the current work on this request
1147 * if we create a lease we return it using reply->lease
1150 * ISC_R_SUCCESS = we were able to find an address and are returning a
1151 * pointer to the lease
1152 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1153 * is probabalistic. We don't exhaustively try the
1154 * address range, instead we hash the duid and if
1155 * the address derived from the hash is in use we
1156 * hash the address. After a number of failures we
1157 * conclude the pool is basically full.
1160 pick_v6_address(struct reply_state
*reply
)
1162 struct ipv6_pool
*p
= NULL
;
1163 struct ipv6_pond
*pond
;
1166 unsigned int attempts
;
1167 char tmp_buf
[INET6_ADDRSTRLEN
];
1168 struct iasubopt
**addr
= &reply
->lease
;
1169 isc_uint64_t total
= 0;
1170 isc_uint64_t active
= 0;
1171 isc_uint64_t abandoned
= 0;
1172 int jumbo_range
= 0;
1173 char *shared_name
= (reply
->shared
->name
?
1174 reply
->shared
->name
: "(no name)");
1177 * Do a quick walk through of the ponds and pools
1178 * to see if we have any NA address pools
1180 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1181 if (pond
->ipv6_pools
== NULL
)
1184 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1185 if (p
->pool_type
== D6O_IA_NA
)
1192 /* If we get here and p is NULL we have no useful pools */
1194 log_debug("Unable to pick client address: "
1195 "no IPv6 pools on this shared network");
1196 return ISC_R_NORESOURCES
;
1200 * We have at least one pool that could provide an address
1201 * Now we walk through the ponds and pools again and check
1202 * to see if the client is permitted and if an address is
1205 * Within a given pond we start looking at the last pool we
1206 * allocated from, unless it had a collision trying to allocate
1207 * an address. This will tend to move us into less-filled pools.
1210 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1211 isc_result_t result
= ISC_R_FAILURE
;
1213 if (((pond
->prohibit_list
!= NULL
) &&
1214 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1215 ((pond
->permit_list
!= NULL
) &&
1216 (!permitted(reply
->packet
, pond
->permit_list
))))
1219 start_pool
= pond
->last_ipv6_pool
;
1222 p
= pond
->ipv6_pools
[i
];
1223 if (p
->pool_type
== D6O_IA_NA
) {
1224 result
= create_lease6(p
, addr
, &attempts
,
1225 &reply
->ia
->iaid_duid
,
1227 if (result
== ISC_R_SUCCESS
) {
1229 * Record the pool used (or next one if
1230 * there was a collision).
1234 if (pond
->ipv6_pools
[i
]
1240 pond
->last_ipv6_pool
= i
;
1242 log_debug("Picking pool address %s",
1245 tmp_buf
, sizeof(tmp_buf
)));
1246 return (ISC_R_SUCCESS
);
1251 if (pond
->ipv6_pools
[i
] == NULL
) {
1254 } while (i
!= start_pool
);
1256 if (result
== ISC_R_NORESOURCES
) {
1257 jumbo_range
+= pond
->jumbo_range
;
1258 total
+= pond
->num_total
;
1259 active
+= pond
->num_active
;
1260 abandoned
+= pond
->num_abandoned
;
1265 * If we failed to pick an IPv6 address from any of the subnets.
1266 * Presumably that means we have no addresses for the client.
1268 if (jumbo_range
!= 0) {
1269 log_debug("Unable to pick client address: "
1270 "no addresses available - shared network %s: "
1271 " 2^64-1 < total, %llu active, %llu abandoned",
1272 shared_name
, active
- abandoned
, abandoned
);
1274 log_debug("Unable to pick client address: "
1275 "no addresses available - shared network %s: "
1276 "%llu total, %llu active, %llu abandoned",
1277 shared_name
, total
, active
- abandoned
, abandoned
);
1280 return ISC_R_NORESOURCES
;
1284 * Try to get the IPv6 prefix the client asked for from the
1287 * pref is the result (should be a pointer to NULL on entry)
1288 * pool is the prefix pool to search in
1289 * requested_pref is the address the client wants
1292 try_client_v6_prefix(struct iasubopt
**pref
,
1293 struct ipv6_pool
*pool
,
1294 const struct data_string
*requested_pref
)
1297 struct in6_addr tmp_pref
;
1299 isc_result_t result
;
1301 if (requested_pref
->len
< sizeof(tmp_plen
) + sizeof(tmp_pref
)) {
1302 return DHCP_R_INVALIDARG
;
1304 tmp_plen
= (int) requested_pref
->data
[0];
1305 if ((tmp_plen
< 3) || (tmp_plen
> 128) ||
1306 ((int)tmp_plen
!= pool
->units
)) {
1307 return ISC_R_FAILURE
;
1309 memcpy(&tmp_pref
, requested_pref
->data
+ 1, sizeof(tmp_pref
));
1310 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref
)) {
1311 return ISC_R_FAILURE
;
1314 memcpy(&ia
.iabuf
, &tmp_pref
, 16);
1315 if (!is_cidr_mask_valid(&ia
, (int) tmp_plen
)) {
1316 return ISC_R_FAILURE
;
1319 if (!ipv6_in_pool(&tmp_pref
, pool
)) {
1320 return ISC_R_ADDRNOTAVAIL
;
1323 if (prefix6_exists(pool
, &tmp_pref
, tmp_plen
)) {
1324 return ISC_R_ADDRINUSE
;
1327 result
= iasubopt_allocate(pref
, MDL
);
1328 if (result
!= ISC_R_SUCCESS
) {
1331 (*pref
)->addr
= tmp_pref
;
1332 (*pref
)->plen
= tmp_plen
;
1334 /* Default is soft binding for 2 minutes. */
1335 result
= add_lease6(pool
, *pref
, cur_time
+ 120);
1336 if (result
!= ISC_R_SUCCESS
) {
1337 iasubopt_dereference(pref
, MDL
);
1344 * \brief Get an IPv6 prefix for the client.
1346 * Attempt to find a usable prefix for the client. Based upon the prefix
1347 * length mode and the plen supplied by the client (if one), we make one
1348 * or more calls to pick_v6_prefix_helper() to find a prefix as follows:
1350 * PLM_IGNORE or client specifies a plen of zero, use the first available
1351 * prefix regardless of it's length.
1353 * PLM_PREFER – look for an exact match to client's plen first, if none
1354 * found, use the first available prefix of any length
1356 * PLM_EXACT – look for an exact match first, if none found then fail. This
1357 * is the default behavior.
1359 * PLM_MAXIMUM - look for an exact match first, then the first available whose
1360 * prefix length is less than client's plen, otherwise fail.
1362 * PLM_MINIMUM - look for an exact match first, then the first available whose
1363 * prefix length is greater than client's plen, otherwise fail.
1365 * Note that the selection mode is configurable at the global scope only via
1368 * \param reply = the state structure for the current work on this request
1369 * if we create a lease we return it using reply->lease
1372 * ISC_R_SUCCESS = we were able to find an prefix and are returning a
1373 * pointer to the lease
1374 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1375 * is probabalistic. We don't exhaustively try the
1376 * address range, instead we hash the duid and if
1377 * the address derived from the hash is in use we
1378 * hash the address. After a number of failures we
1379 * conclude the pool is basically full.
1382 pick_v6_prefix(struct reply_state
*reply
) {
1383 struct ipv6_pool
*p
= NULL
;
1384 struct ipv6_pond
*pond
;
1386 isc_result_t result
;
1389 * Do a quick walk through of the ponds and pools
1390 * to see if we have any prefix pools
1392 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1393 if (pond
->ipv6_pools
== NULL
)
1396 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1397 if (p
->pool_type
== D6O_IA_PD
)
1404 /* If we get here and p is NULL we have no useful pools */
1406 log_debug("Unable to pick client prefix: "
1407 "no IPv6 pools on this shared network");
1408 return ISC_R_NORESOURCES
;
1411 if (reply
->preflen
<= 0) {
1412 /* If we didn't get a plen (-1) or client plen is 0, then just
1413 * select first available (same as PLM_INGORE) */
1414 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1416 switch (prefix_length_mode
) {
1418 /* First we look for an exact match, if not found
1419 * then first available */
1420 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1421 if (result
!= ISC_R_SUCCESS
) {
1422 result
= pick_v6_prefix_helper(reply
,
1428 /* Match exactly or fail */
1429 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1434 /* First we look for an exact match, if not found
1435 * then first available by mode */
1436 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1437 if (result
!= ISC_R_SUCCESS
) {
1438 result
= pick_v6_prefix_helper(reply
,
1439 prefix_length_mode
);
1444 /* First available */
1445 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1450 if (result
== ISC_R_SUCCESS
) {
1451 char tmp_buf
[INET6_ADDRSTRLEN
];
1453 log_debug("Picking pool prefix %s/%u",
1454 inet_ntop(AF_INET6
, &(reply
->lease
->addr
),
1455 tmp_buf
, sizeof(tmp_buf
)),
1456 (unsigned)(reply
->lease
->plen
));
1457 return (ISC_R_SUCCESS
);
1461 * If we failed to pick an IPv6 prefix
1462 * Presumably that means we have no prefixes for the client.
1464 log_debug("Unable to pick client prefix: no prefixes available");
1465 return ISC_R_NORESOURCES
;
1470 * \brief Get an IPv6 prefix for the client based upon selection mode.
1472 * We walk through the ponds checking for permit and deny. If a pond is
1473 * permissable to use, loop through its PD pools checking prefix lengths
1474 * against the client plen based on the prefix length mode, looking for
1475 * available prefixes.
1477 * \param reply = the state structure for the current work on this request
1478 * if we create a lease we return it using reply->lease
1479 * \prefix_mode = selection mode to use
1482 * ISC_R_SUCCESS = we were able to find a prefix and are returning a
1483 * pointer to the lease
1484 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1485 * is probabalistic. We don't exhaustively try the
1486 * address range, instead we hash the duid and if
1487 * the address derived from the hash is in use we
1488 * hash the address. After a number of failures we
1489 * conclude the pool is basically full.
1492 pick_v6_prefix_helper(struct reply_state
*reply
, int prefix_mode
) {
1493 struct ipv6_pool
*p
= NULL
;
1494 struct ipv6_pond
*pond
;
1496 unsigned int attempts
;
1497 struct iasubopt
**pref
= &reply
->lease
;
1499 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1500 if (((pond
->prohibit_list
!= NULL
) &&
1501 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1502 ((pond
->permit_list
!= NULL
) &&
1503 (!permitted(reply
->packet
, pond
->permit_list
))))
1506 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1507 if ((p
->pool_type
== D6O_IA_PD
) &&
1508 (eval_prefix_mode(p
->units
, reply
->preflen
,
1509 prefix_mode
) == 1) &&
1510 (create_prefix6(p
, pref
, &attempts
,
1511 &reply
->ia
->iaid_duid
,
1512 cur_time
+ 120) == ISC_R_SUCCESS
)) {
1513 return (ISC_R_SUCCESS
);
1518 return ISC_R_NORESOURCES
;
1523 * \brief Test a prefix length against another based on prefix length mode
1525 * \param len - prefix length to test
1526 * \param preflen - preferred prefix length against which to test
1527 * \param prefix_mode - prefix selection mode with which to test
1529 * Note that the case of preferred length of 0 is not short-cut here as it
1530 * is assumed to be done at a higher level.
1532 * \return 1 if the given length is usable based upon mode and a preferred
1536 eval_prefix_mode(int len
, int preflen
, int prefix_mode
) {
1538 switch (prefix_mode
) {
1540 use_it
= (len
== preflen
);
1543 /* they asked for a prefix length no "shorter" than preflen */
1544 use_it
= (len
>= preflen
);
1547 /* they asked for a prefix length no "longer" than preflen */
1548 use_it
= (len
<= preflen
);
1551 /* otherwise use it */
1556 log_debug("eval_prefix_mode: "
1557 "len %d, preflen %d, mode %s, use_it %d",
1559 prefix_length_modes
.values
[prefix_mode
].name
, use_it
);
1566 *! \file server/dhcpv6.c
1568 * \brief construct a reply containing information about a client's lease
1570 * lease_to_client() is called from several messages to construct a
1571 * reply that contains all that we know about the client's correct lease
1572 * (or projected lease).
1574 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1575 * send what we "may" give them on a request.
1577 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1578 * the client should really use).
1580 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1581 * Rebind out any "wrong" addresses the client sends. This means we send
1582 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1583 * possibly send the address with zeroed lifetimes.
1585 * Information-Request - No binding.
1587 * The basic structure is to traverse the client-supplied data first, and
1588 * validate and echo back any contents that can be. If the client-supplied
1589 * data does not error out (on renew/rebind as above), but we did not send
1590 * any addresses, attempt to allocate one.
1592 * At the end of the this function we call commit_leases_timed() to
1593 * fsync and rotate the file as necessary. commit_leases_timed() will
1594 * check that we have written at least one lease to the file and that
1595 * some time has passed before doing any fsync or file rewrite so we
1596 * don't bother tracking if we did a write_ia during this function.
1598 /* TODO: look at client hints for lease times */
1601 lease_to_client(struct data_string
*reply_ret
,
1602 struct packet
*packet
,
1603 const struct data_string
*client_id
,
1604 const struct data_string
*server_id
)
1606 static struct reply_state reply
;
1607 struct option_cache
*oc
;
1608 struct data_string packet_oro
;
1611 memset(&packet_oro
, 0, sizeof(packet_oro
));
1613 /* Locate the client. */
1614 if (shared_network_from_packet6(&reply
.shared
,
1615 packet
) != ISC_R_SUCCESS
)
1619 * Initialize the reply.
1621 packet_reference(&reply
.packet
, packet
, MDL
);
1622 data_string_copy(&reply
.client_id
, client_id
, MDL
);
1624 if (!start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
1628 /* Set the write cursor to just past the reply header. */
1629 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1632 * Get the ORO from the packet, if any.
1634 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ORO
);
1636 if (!evaluate_option_cache(&packet_oro
, packet
,
1638 packet
->options
, NULL
,
1639 &global_scope
, oc
, MDL
)) {
1640 log_error("lease_to_client: error evaluating ORO.");
1646 * Find a host record that matches from the packet, if any, and is
1647 * valid for the shared network the client is on.
1649 if (find_hosts_by_uid(&reply
.host
, client_id
->data
, client_id
->len
,
1652 seek_shared_host(&reply
.host
, reply
.shared
);
1655 if ((reply
.host
== NULL
) &&
1656 find_hosts_by_option(&reply
.host
, packet
, packet
->options
, MDL
)) {
1658 seek_shared_host(&reply
.host
, reply
.shared
);
1662 * Check for 'hardware' matches last, as some of the synthesis methods
1663 * are not considered to be as reliable.
1665 if ((reply
.host
== NULL
) &&
1666 find_hosts_by_duid_chaddr(&reply
.host
, client_id
)) {
1668 seek_shared_host(&reply
.host
, reply
.shared
);
1671 /* Process the client supplied IA's onto the reply buffer. */
1673 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
1675 for (; oc
!= NULL
; oc
= oc
->next
) {
1676 isc_result_t status
;
1678 /* Start counting resources (addresses) offered. */
1679 reply
.client_resources
= 0;
1680 reply
.resources_included
= ISC_FALSE
;
1682 status
= reply_process_ia_na(&reply
, oc
);
1685 * We continue to try other IA's whether we can address
1686 * this one or not. Any other result is an immediate fail.
1688 if ((status
!= ISC_R_SUCCESS
) &&
1689 (status
!= ISC_R_NORESOURCES
))
1692 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
1693 for (; oc
!= NULL
; oc
= oc
->next
) {
1694 isc_result_t status
;
1696 /* Start counting resources (addresses) offered. */
1697 reply
.client_resources
= 0;
1698 reply
.resources_included
= ISC_FALSE
;
1700 status
= reply_process_ia_ta(&reply
, oc
);
1703 * We continue to try other IA's whether we can address
1704 * this one or not. Any other result is an immediate fail.
1706 if ((status
!= ISC_R_SUCCESS
) &&
1707 (status
!= ISC_R_NORESOURCES
))
1711 /* Same for IA_PD's. */
1713 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
1714 for (; oc
!= NULL
; oc
= oc
->next
) {
1715 isc_result_t status
;
1717 /* Start counting resources (prefixes) offered. */
1718 reply
.client_resources
= 0;
1719 reply
.resources_included
= ISC_FALSE
;
1721 status
= reply_process_ia_pd(&reply
, oc
);
1724 * We continue to try other IA_PD's whether we can address
1725 * this one or not. Any other result is an immediate fail.
1727 if ((status
!= ISC_R_SUCCESS
) &&
1728 (status
!= ISC_R_NORESOURCES
))
1733 * Make no reply if we gave no resources and is not
1734 * for Information-Request.
1736 if ((reply
.ia_count
== 0) && (reply
.pd_count
== 0)) {
1737 if (reply
.packet
->dhcpv6_msg_type
!=
1738 DHCPV6_INFORMATION_REQUEST
)
1742 * Because we only execute statements on a per-IA basis,
1743 * we need to execute statements in any non-IA reply to
1744 * source configuration.
1746 execute_statements_in_scope(NULL
, reply
.packet
, NULL
, NULL
,
1747 reply
.packet
->options
,
1748 reply
.opt_state
, &global_scope
,
1749 reply
.shared
->group
, root_group
,
1752 /* Execute statements from class scopes. */
1753 for (i
= reply
.packet
->class_count
; i
> 0; i
--) {
1754 execute_statements_in_scope(NULL
, reply
.packet
,
1756 reply
.packet
->options
,
1759 reply
.packet
->classes
[i
- 1]->group
,
1760 reply
.shared
->group
, NULL
);
1763 /* Bring in any configuration from a host record. */
1764 if (reply
.host
!= NULL
)
1765 execute_statements_in_scope(NULL
, reply
.packet
,
1767 reply
.packet
->options
,
1771 reply
.shared
->group
, NULL
);
1775 * RFC3315 section 17.2.2 (Solicit):
1777 * If the server will not assign any addresses to any IAs in a
1778 * subsequent Request from the client, the server MUST send an
1779 * Advertise message to the client that includes only a Status
1780 * Code option with code NoAddrsAvail and a status message for
1781 * the user, a Server Identifier option with the server's DUID,
1782 * and a Client Identifier option with the client's DUID.
1784 * This has been updated by an errata such that the server
1785 * can always send an IA.
1787 * Section 18.2.1 (Request):
1789 * If the server cannot assign any addresses to an IA in the
1790 * message from the client, the server MUST include the IA in
1791 * the Reply message with no addresses in the IA and a Status
1792 * Code option in the IA containing status code NoAddrsAvail.
1794 * Section 18.1.8 (Client Behavior):
1796 * Leave unchanged any information about addresses the client has
1797 * recorded in the IA but that were not included in the IA from
1799 * Sends a Renew/Rebind if the IA is not in the Reply message.
1803 * Having stored the client's IA's, store any options that
1804 * will fit in the remaining space.
1806 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+ reply
.cursor
,
1807 sizeof(reply
.buf
) - reply
.cursor
,
1808 reply
.opt_state
, reply
.packet
,
1809 required_opts_solicit
,
1812 /* Return our reply to the caller. */
1813 reply_ret
->len
= reply
.cursor
;
1814 reply_ret
->buffer
= NULL
;
1815 if (!buffer_allocate(&reply_ret
->buffer
, reply
.cursor
, MDL
)) {
1816 log_fatal("No memory to store Reply.");
1818 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
, reply
.cursor
);
1819 reply_ret
->data
= reply_ret
->buffer
->data
;
1821 /* If appropriate commit and rotate the lease file */
1822 (void) commit_leases_timed();
1826 if (reply
.shared
!= NULL
)
1827 shared_network_dereference(&reply
.shared
, MDL
);
1828 if (reply
.host
!= NULL
)
1829 host_dereference(&reply
.host
, MDL
);
1830 if (reply
.opt_state
!= NULL
)
1831 option_state_dereference(&reply
.opt_state
, MDL
);
1832 if (reply
.packet
!= NULL
)
1833 packet_dereference(&reply
.packet
, MDL
);
1834 if (reply
.client_id
.data
!= NULL
)
1835 data_string_forget(&reply
.client_id
, MDL
);
1836 if (packet_oro
.buffer
!= NULL
)
1837 data_string_forget(&packet_oro
, MDL
);
1838 reply
.renew
= reply
.rebind
= reply
.prefer
= reply
.valid
= 0;
1842 /* Process a client-supplied IA_NA. This may append options to the tail of
1843 * the reply packet being built in the reply_state structure.
1846 reply_process_ia_na(struct reply_state
*reply
, struct option_cache
*ia
) {
1847 isc_result_t status
= ISC_R_SUCCESS
;
1850 struct option_state
*packet_ia
;
1851 struct option_cache
*oc
;
1852 struct data_string ia_data
, data
;
1854 /* Initialize values that will get cleaned up on return. */
1856 memset(&ia_data
, 0, sizeof(ia_data
));
1857 memset(&data
, 0, sizeof(data
));
1859 * Note that find_client_address() may set reply->lease.
1862 /* Make sure there is at least room for the header. */
1863 if ((reply
->cursor
+ IA_NA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
1864 log_error("reply_process_ia_na: Reply too long for IA.");
1865 return ISC_R_NOSPACE
;
1869 /* Fetch the IA_NA contents. */
1870 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
1871 ia
, IA_NA_OFFSET
)) {
1872 log_error("reply_process_ia_na: error evaluating ia");
1873 status
= ISC_R_FAILURE
;
1877 /* Extract IA_NA header contents. */
1878 iaid
= getULong(ia_data
.data
);
1879 reply
->renew
= getULong(ia_data
.data
+ 4);
1880 reply
->rebind
= getULong(ia_data
.data
+ 8);
1882 /* Create an IA_NA structure. */
1883 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
1884 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
1885 log_error("reply_process_ia_na: no memory for ia.");
1886 status
= ISC_R_NOMEMORY
;
1889 reply
->ia
->ia_type
= D6O_IA_NA
;
1891 /* Cache pre-existing IA, if any. */
1892 ia_hash_lookup(&reply
->old_ia
, ia_na_active
,
1893 (unsigned char *)reply
->ia
->iaid_duid
.data
,
1894 reply
->ia
->iaid_duid
.len
, MDL
);
1897 * Create an option cache to carry the IA_NA option contents, and
1898 * execute any user-supplied values into it.
1900 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
1901 status
= ISC_R_NOMEMORY
;
1905 /* Check & cache the fixed host record. */
1906 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_addr
!= NULL
)) {
1907 struct iaddr tmp_addr
;
1909 if (!evaluate_option_cache(&reply
->fixed
, NULL
, NULL
, NULL
,
1910 NULL
, NULL
, &global_scope
,
1911 reply
->host
->fixed_addr
, MDL
)) {
1912 log_error("reply_process_ia_na: unable to evaluate "
1914 status
= ISC_R_FAILURE
;
1918 if (reply
->fixed
.len
< 16) {
1919 log_error("reply_process_ia_na: invalid fixed address.");
1920 status
= DHCP_R_INVALIDARG
;
1924 /* Find the static lease's subnet. */
1926 memcpy(tmp_addr
.iabuf
, reply
->fixed
.data
, 16);
1928 if (find_grouped_subnet(&reply
->subnet
, reply
->shared
,
1929 tmp_addr
, MDL
) == 0)
1930 log_fatal("Impossible condition at %s:%d.", MDL
);
1932 reply
->static_lease
= ISC_TRUE
;
1934 reply
->static_lease
= ISC_FALSE
;
1937 * Save the cursor position at the start of the IA, so we can
1938 * set length and adjust t1/t2 values later. We write a temporary
1939 * header out now just in case we decide to adjust the packet
1940 * within sub-process functions.
1942 ia_cursor
= reply
->cursor
;
1944 /* Initialize the IA_NA header. First the code. */
1945 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_NA
);
1948 /* Then option length. */
1949 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
1952 /* Then IA_NA header contents; IAID. */
1953 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
1956 /* We store the client's t1 for now, and may over-ride it later. */
1957 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
1960 /* We store the client's t2 for now, and may over-ride it later. */
1961 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
1965 * For each address in this IA_NA, decide what to do about it.
1969 * The client leaves unchanged any information about addresses
1970 * it has recorded but are not included ("cancel/break" below).
1971 * A not included IA ("cleanup" below) could give a Renew/Rebind.
1973 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
1974 reply
->valid
= reply
->prefer
= 0xffffffff;
1975 reply
->client_valid
= reply
->client_prefer
= 0;
1976 for (; oc
!= NULL
; oc
= oc
->next
) {
1977 status
= reply_process_addr(reply
, oc
);
1980 * Canceled means we did not allocate addresses to the
1981 * client, but we're "done" with this IA - we set a status
1982 * code. So transmit this reply, e.g., move on to the next
1985 if (status
== ISC_R_CANCELED
)
1988 if ((status
!= ISC_R_SUCCESS
) &&
1989 (status
!= ISC_R_ADDRINUSE
) &&
1990 (status
!= ISC_R_ADDRNOTAVAIL
))
1997 * If we fell through the above and never gave the client
1998 * an address, give it one now.
2000 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
2001 status
= find_client_address(reply
);
2003 if (status
== ISC_R_NORESOURCES
) {
2004 switch (reply
->packet
->dhcpv6_msg_type
) {
2005 case DHCPV6_SOLICIT
:
2007 * No address for any IA is handled
2012 case DHCPV6_REQUEST
:
2013 /* Section 18.2.1 (Request):
2015 * If the server cannot assign any addresses to
2016 * an IA in the message from the client, the
2017 * server MUST include the IA in the Reply
2018 * message with no addresses in the IA and a
2019 * Status Code option in the IA containing
2020 * status code NoAddrsAvail.
2022 option_state_dereference(&reply
->reply_ia
, MDL
);
2023 if (!option_state_allocate(&reply
->reply_ia
,
2026 log_error("reply_process_ia_na: No "
2027 "memory for option state "
2029 status
= ISC_R_NOMEMORY
;
2033 if (!set_status_code(STATUS_NoAddrsAvail
,
2034 "No addresses available "
2035 "for this interface.",
2037 log_error("reply_process_ia_na: Unable "
2038 "to set NoAddrsAvail status "
2040 status
= ISC_R_FAILURE
;
2044 status
= ISC_R_SUCCESS
;
2049 * RFC 3315 does not tell us to emit a status
2050 * code in this condition, or anything else.
2052 * If we included non-allocated addresses
2053 * (zeroed lifetimes) in an IA, then the client
2054 * will deconfigure them.
2056 * So we want to include the IA even if we
2057 * can't give it a new address if it includes
2058 * zeroed lifetime addresses.
2060 * We don't want to include the IA if we
2061 * provide zero addresses including zeroed
2064 if (reply
->resources_included
)
2065 status
= ISC_R_SUCCESS
;
2072 if (status
!= ISC_R_SUCCESS
)
2076 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2077 sizeof(reply
->buf
) - reply
->cursor
,
2078 reply
->reply_ia
, reply
->packet
,
2079 required_opts_IA
, NULL
);
2081 /* Reset the length of this IA to match what was just written. */
2082 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2083 reply
->cursor
- (ia_cursor
+ 4));
2086 * T1/T2 time selection is kind of weird. We actually use DHCP
2087 * (v4) scoped options as handy existing places where these might
2088 * be configured by an administrator. A value of zero tells the
2089 * client it may choose its own renewal time.
2092 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
2093 DHO_DHCP_RENEWAL_TIME
);
2095 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
2096 reply
->packet
->options
,
2097 reply
->opt_state
, &global_scope
,
2100 log_error("Invalid renewal time.");
2102 reply
->renew
= getULong(data
.data
);
2105 if (data
.data
!= NULL
)
2106 data_string_forget(&data
, MDL
);
2108 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
2112 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
2113 DHO_DHCP_REBINDING_TIME
);
2115 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
2116 reply
->packet
->options
,
2117 reply
->opt_state
, &global_scope
,
2120 log_error("Invalid rebinding time.");
2122 reply
->rebind
= getULong(data
.data
);
2125 if (data
.data
!= NULL
)
2126 data_string_forget(&data
, MDL
);
2128 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
2131 * yes, goto's aren't the best but we also want to avoid extra
2134 if (status
== ISC_R_CANCELED
)
2138 * Handle static leases, we always log stuff and if it's
2139 * a hard binding we run any commit statements that we have
2141 if (reply
->static_lease
) {
2142 char tmp_addr
[INET6_ADDRSTRLEN
];
2143 log_info("%s NA: address %s to client with duid %s iaid = %d "
2145 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2146 inet_ntop(AF_INET6
, reply
->fixed
.data
, tmp_addr
,
2148 print_hex_1(reply
->client_id
.len
,
2149 reply
->client_id
.data
, 60),
2152 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
2153 (reply
->on_star
.on_commit
!= NULL
)) {
2154 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
2155 reply
->packet
->options
,
2156 reply
->opt_state
, NULL
,
2157 reply
->on_star
.on_commit
, NULL
);
2158 executable_statement_dereference
2159 (&reply
->on_star
.on_commit
, MDL
);
2165 * If we have any addresses log what we are doing.
2167 if (reply
->ia
->num_iasubopt
!= 0) {
2168 struct iasubopt
*tmp
;
2170 char tmp_addr
[INET6_ADDRSTRLEN
];
2172 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2173 tmp
= reply
->ia
->iasubopt
[i
];
2175 log_info("%s NA: address %s to client with duid %s "
2176 "iaid = %d valid for %u seconds",
2177 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2178 inet_ntop(AF_INET6
, &tmp
->addr
,
2179 tmp_addr
, sizeof(tmp_addr
)),
2180 print_hex_1(reply
->client_id
.len
,
2181 reply
->client_id
.data
, 60),
2187 * If this is not a 'soft' binding, consume the new changes into
2188 * the database (if any have been attached to the ia_na).
2190 * Loop through the assigned dynamic addresses, referencing the
2191 * leases onto this IA_NA rather than any old ones, and updating
2192 * pool timers for each (if any).
2195 if ((reply
->ia
->num_iasubopt
!= 0) &&
2196 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
2197 struct iasubopt
*tmp
;
2198 struct data_string
*ia_id
;
2201 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2202 tmp
= reply
->ia
->iasubopt
[i
];
2204 if (tmp
->ia
!= NULL
)
2205 ia_dereference(&tmp
->ia
, MDL
);
2206 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2208 /* Commit 'hard' bindings. */
2209 renew_lease6(tmp
->ipv6_pool
, tmp
);
2210 schedule_lease_timeout(tmp
->ipv6_pool
);
2212 /* If we have anything to do on commit do it now */
2213 if (tmp
->on_star
.on_commit
!= NULL
) {
2214 execute_statements(NULL
, reply
->packet
,
2216 reply
->packet
->options
,
2219 tmp
->on_star
.on_commit
,
2221 executable_statement_dereference
2222 (&tmp
->on_star
.on_commit
, MDL
);
2225 #if defined (NSUPDATE)
2227 * Perform ddns updates.
2229 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2232 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2234 reply
->packet
->options
,
2238 ddns_updates(reply
->packet
, NULL
, NULL
,
2239 tmp
, NULL
, reply
->opt_state
);
2242 /* Do our threshold check. */
2243 check_pool6_threshold(reply
, tmp
);
2246 /* Remove any old ia from the hash. */
2247 if (reply
->old_ia
!= NULL
) {
2248 ia_id
= &reply
->old_ia
->iaid_duid
;
2249 ia_hash_delete(ia_na_active
,
2250 (unsigned char *)ia_id
->data
,
2252 ia_dereference(&reply
->old_ia
, MDL
);
2255 /* Put new ia into the hash. */
2256 reply
->ia
->cltt
= cur_time
;
2257 ia_id
= &reply
->ia
->iaid_duid
;
2258 ia_hash_add(ia_na_active
, (unsigned char *)ia_id
->data
,
2259 ia_id
->len
, reply
->ia
, MDL
);
2261 write_ia(reply
->ia
);
2263 schedule_lease_timeout_reply(reply
);
2267 if (packet_ia
!= NULL
)
2268 option_state_dereference(&packet_ia
, MDL
);
2269 if (reply
->reply_ia
!= NULL
)
2270 option_state_dereference(&reply
->reply_ia
, MDL
);
2271 if (ia_data
.data
!= NULL
)
2272 data_string_forget(&ia_data
, MDL
);
2273 if (data
.data
!= NULL
)
2274 data_string_forget(&data
, MDL
);
2275 if (reply
->ia
!= NULL
)
2276 ia_dereference(&reply
->ia
, MDL
);
2277 if (reply
->old_ia
!= NULL
)
2278 ia_dereference(&reply
->old_ia
, MDL
);
2279 if (reply
->lease
!= NULL
)
2280 iasubopt_dereference(&reply
->lease
, MDL
);
2281 if (reply
->fixed
.data
!= NULL
)
2282 data_string_forget(&reply
->fixed
, MDL
);
2283 if (reply
->subnet
!= NULL
)
2284 subnet_dereference(&reply
->subnet
, MDL
);
2285 if (reply
->on_star
.on_expiry
!= NULL
)
2286 executable_statement_dereference
2287 (&reply
->on_star
.on_expiry
, MDL
);
2288 if (reply
->on_star
.on_release
!= NULL
)
2289 executable_statement_dereference
2290 (&reply
->on_star
.on_release
, MDL
);
2293 * ISC_R_CANCELED is a status code used by the addr processing to
2294 * indicate we're replying with a status code. This is still a
2295 * success at higher layers.
2297 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2301 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
2302 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
2303 * in the event we are replying with a status code and do not wish to process
2304 * more IAADDRs within this IA.
2307 reply_process_addr(struct reply_state
*reply
, struct option_cache
*addr
) {
2308 u_int32_t pref_life
, valid_life
;
2309 struct binding_scope
**scope
;
2310 struct group
*group
;
2311 struct subnet
*subnet
;
2312 struct iaddr tmp_addr
;
2313 struct option_cache
*oc
;
2314 struct data_string iaaddr
, data
;
2315 isc_result_t status
= ISC_R_SUCCESS
;
2317 /* Initializes values that will be cleaned up. */
2318 memset(&iaaddr
, 0, sizeof(iaaddr
));
2319 memset(&data
, 0, sizeof(data
));
2320 /* Note that reply->lease may be set by address_is_owned() */
2323 * There is no point trying to process an incoming address if there
2324 * is no room for an outgoing address.
2326 if ((reply
->cursor
+ 28) > sizeof(reply
->buf
)) {
2327 log_error("reply_process_addr: Out of room for address.");
2328 return ISC_R_NOSPACE
;
2331 /* Extract this IAADDR option. */
2332 if (!evaluate_option_cache(&iaaddr
, reply
->packet
, NULL
, NULL
,
2333 reply
->packet
->options
, NULL
, &global_scope
,
2335 (iaaddr
.len
< IAADDR_OFFSET
)) {
2336 log_error("reply_process_addr: error evaluating IAADDR.");
2337 status
= ISC_R_FAILURE
;
2341 /* The first 16 bytes are the IPv6 address. */
2342 pref_life
= getULong(iaaddr
.data
+ 16);
2343 valid_life
= getULong(iaaddr
.data
+ 20);
2345 if ((reply
->client_valid
== 0) ||
2346 (reply
->client_valid
> valid_life
))
2347 reply
->client_valid
= valid_life
;
2349 if ((reply
->client_prefer
== 0) ||
2350 (reply
->client_prefer
> pref_life
))
2351 reply
->client_prefer
= pref_life
;
2354 * Clients may choose to send :: as an address, with the idea to give
2355 * hints about preferred-lifetime or valid-lifetime.
2358 memset(tmp_addr
.iabuf
, 0, 16);
2359 if (!memcmp(iaaddr
.data
, tmp_addr
.iabuf
, 16)) {
2360 /* Status remains success; we just ignore this one. */
2364 /* tmp_addr len remains 16 */
2365 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2368 * Verify that this address is on the client's network.
2370 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
2371 subnet
= subnet
->next_sibling
) {
2372 if (addr_eq(subnet_number(tmp_addr
, subnet
->netmask
),
2377 /* Address not found on shared network. */
2378 if (subnet
== NULL
) {
2379 /* Ignore this address on 'soft' bindings. */
2380 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
2381 /* disable rapid commit */
2382 reply
->buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
2383 delete_option(&dhcpv6_universe
,
2386 /* status remains success */
2391 * RFC3315 section 18.2.1:
2393 * If the server finds that the prefix on one or more IP
2394 * addresses in any IA in the message from the client is not
2395 * appropriate for the link to which the client is connected,
2396 * the server MUST return the IA to the client with a Status
2397 * Code option with the value NotOnLink.
2399 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) {
2400 /* Rewind the IA_NA to empty. */
2401 option_state_dereference(&reply
->reply_ia
, MDL
);
2402 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2403 log_error("reply_process_addr: No memory for "
2404 "option state wipe.");
2405 status
= ISC_R_NOMEMORY
;
2409 /* Append a NotOnLink status code. */
2410 if (!set_status_code(STATUS_NotOnLink
,
2411 "Address not for use on this "
2412 "link.", reply
->reply_ia
)) {
2413 log_error("reply_process_addr: Failure "
2414 "setting status code.");
2415 status
= ISC_R_FAILURE
;
2419 /* Fin (no more IAADDRs). */
2420 status
= ISC_R_CANCELED
;
2425 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2427 * If the server finds that any of the addresses are not
2428 * appropriate for the link to which the client is attached,
2429 * the server returns the address to the client with lifetimes
2432 if ((reply
->packet
->dhcpv6_msg_type
!= DHCPV6_RENEW
) &&
2433 (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
2434 log_error("It is impossible to lease a client that is "
2435 "not sending a solicit, request, renew, or "
2437 status
= ISC_R_FAILURE
;
2441 reply
->send_prefer
= reply
->send_valid
= 0;
2445 /* Verify the address belongs to the client. */
2446 if (!address_is_owned(reply
, &tmp_addr
)) {
2448 * For solicit and request, any addresses included are
2449 * 'requested' addresses. For rebind, we actually have
2450 * no direction on what to do from 3315 section 18.2.4!
2451 * So I think the best bet is to try and give it out, and if
2452 * we can't, zero lifetimes.
2454 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
2455 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
2456 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
2457 status
= reply_process_try_addr(reply
, &tmp_addr
);
2460 * If the address is in use, or isn't in any dynamic
2461 * range, continue as normal. If any other error was
2464 if ((status
!= ISC_R_SUCCESS
) &&
2465 (status
!= ISC_R_ADDRINUSE
) &&
2466 (status
!= ISC_R_ADDRNOTAVAIL
))
2470 * If we didn't honor this lease, for solicit and
2471 * request we simply omit it from our answer. For
2472 * rebind, we send it with zeroed lifetimes.
2474 if (reply
->lease
== NULL
) {
2475 if (reply
->packet
->dhcpv6_msg_type
==
2477 reply
->send_prefer
= 0;
2478 reply
->send_valid
= 0;
2482 /* status remains success - ignore */
2486 * RFC3315 section 18.2.3:
2488 * If the server cannot find a client entry for the IA the
2489 * server returns the IA containing no addresses with a Status
2490 * Code option set to NoBinding in the Reply message.
2492 * On mismatch we (ab)use this pretending we have not the IA
2493 * as soon as we have not an address.
2495 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
2496 /* Rewind the IA_NA to empty. */
2497 option_state_dereference(&reply
->reply_ia
, MDL
);
2498 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2499 log_error("reply_process_addr: No memory for "
2500 "option state wipe.");
2501 status
= ISC_R_NOMEMORY
;
2505 /* Append a NoBinding status code. */
2506 if (!set_status_code(STATUS_NoBinding
,
2507 "Address not bound to this "
2508 "interface.", reply
->reply_ia
)) {
2509 log_error("reply_process_addr: Unable to "
2510 "attach status code.");
2511 status
= ISC_R_FAILURE
;
2515 /* Fin (no more IAADDRs). */
2516 status
= ISC_R_CANCELED
;
2519 log_error("It is impossible to lease a client that is "
2520 "not sending a solicit, request, renew, or "
2522 status
= ISC_R_FAILURE
;
2527 if (reply
->static_lease
) {
2528 if (reply
->host
== NULL
)
2529 log_fatal("Impossible condition at %s:%d.", MDL
);
2531 scope
= &global_scope
;
2532 group
= reply
->subnet
->group
;
2534 if (reply
->lease
== NULL
)
2535 log_fatal("Impossible condition at %s:%d.", MDL
);
2537 scope
= &reply
->lease
->scope
;
2538 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
2542 * If client_resources is nonzero, then the reply_process_is_addressed
2543 * function has executed configuration state into the reply option
2544 * cache. We will use that valid cache to derive configuration for
2545 * whether or not to engage in additional addresses, and similar.
2547 if (reply
->client_resources
!= 0) {
2551 * Does this client have "enough" addresses already? Default
2552 * to one. Everybody gets one, and one should be enough for
2555 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2556 SV_LIMIT_ADDRS_PER_IA
);
2558 if (!evaluate_option_cache(&data
, reply
->packet
,
2560 reply
->packet
->options
,
2564 log_error("reply_process_addr: unable to "
2565 "evaluate addrs-per-ia value.");
2566 status
= ISC_R_FAILURE
;
2570 limit
= getULong(data
.data
);
2571 data_string_forget(&data
, MDL
);
2575 * If we wish to limit the client to a certain number of
2576 * addresses, then omit the address from the reply.
2578 if (reply
->client_resources
>= limit
)
2582 status
= reply_process_is_addressed(reply
, scope
, group
);
2583 if (status
!= ISC_R_SUCCESS
)
2587 status
= reply_process_send_addr(reply
, &tmp_addr
);
2590 if (iaaddr
.data
!= NULL
)
2591 data_string_forget(&iaaddr
, MDL
);
2592 if (data
.data
!= NULL
)
2593 data_string_forget(&data
, MDL
);
2594 if (reply
->lease
!= NULL
)
2595 iasubopt_dereference(&reply
->lease
, MDL
);
2601 * Verify the address belongs to the client. If we've got a host
2602 * record with a fixed address, it has to be the assigned address
2603 * (fault out all else). Otherwise it's a dynamic address, so lookup
2604 * that address and make sure it belongs to this DUID:IAID pair.
2606 static isc_boolean_t
2607 address_is_owned(struct reply_state
*reply
, struct iaddr
*addr
) {
2609 struct ipv6_pond
*pond
;
2612 * This faults out addresses that don't match fixed addresses.
2614 if (reply
->static_lease
) {
2615 if (reply
->fixed
.data
== NULL
)
2616 log_fatal("Impossible condition at %s:%d.", MDL
);
2618 if (memcmp(addr
->iabuf
, reply
->fixed
.data
, 16) == 0)
2624 if ((reply
->old_ia
== NULL
) || (reply
->old_ia
->num_iasubopt
== 0))
2627 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2628 struct iasubopt
*tmp
;
2630 tmp
= reply
->old_ia
->iasubopt
[i
];
2632 if (memcmp(addr
->iabuf
, &tmp
->addr
, 16) == 0) {
2633 if (lease6_usable(tmp
) == ISC_FALSE
) {
2637 pond
= tmp
->ipv6_pool
->ipv6_pond
;
2638 if (((pond
->prohibit_list
!= NULL
) &&
2639 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
2640 ((pond
->permit_list
!= NULL
) &&
2641 (!permitted(reply
->packet
, pond
->permit_list
))))
2644 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
2653 /* Process a client-supplied IA_TA. This may append options to the tail of
2654 * the reply packet being built in the reply_state structure.
2657 reply_process_ia_ta(struct reply_state
*reply
, struct option_cache
*ia
) {
2658 isc_result_t status
= ISC_R_SUCCESS
;
2661 struct option_state
*packet_ia
;
2662 struct option_cache
*oc
;
2663 struct data_string ia_data
, data
;
2664 struct data_string iaaddr
;
2665 u_int32_t pref_life
, valid_life
;
2666 struct iaddr tmp_addr
;
2668 /* Initialize values that will get cleaned up on return. */
2670 memset(&ia_data
, 0, sizeof(ia_data
));
2671 memset(&data
, 0, sizeof(data
));
2672 memset(&iaaddr
, 0, sizeof(iaaddr
));
2674 /* Make sure there is at least room for the header. */
2675 if ((reply
->cursor
+ IA_TA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2676 log_error("reply_process_ia_ta: Reply too long for IA.");
2677 return ISC_R_NOSPACE
;
2681 /* Fetch the IA_TA contents. */
2682 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2683 ia
, IA_TA_OFFSET
)) {
2684 log_error("reply_process_ia_ta: error evaluating ia");
2685 status
= ISC_R_FAILURE
;
2689 /* Extract IA_TA header contents. */
2690 iaid
= getULong(ia_data
.data
);
2692 /* Create an IA_TA structure. */
2693 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2694 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2695 log_error("reply_process_ia_ta: no memory for ia.");
2696 status
= ISC_R_NOMEMORY
;
2699 reply
->ia
->ia_type
= D6O_IA_TA
;
2701 /* Cache pre-existing IA, if any. */
2702 ia_hash_lookup(&reply
->old_ia
, ia_ta_active
,
2703 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2704 reply
->ia
->iaid_duid
.len
, MDL
);
2707 * Create an option cache to carry the IA_TA option contents, and
2708 * execute any user-supplied values into it.
2710 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2711 status
= ISC_R_NOMEMORY
;
2716 * Temporary leases are dynamic by definition.
2718 reply
->static_lease
= ISC_FALSE
;
2721 * Save the cursor position at the start of the IA, so we can
2722 * set length later. We write a temporary
2723 * header out now just in case we decide to adjust the packet
2724 * within sub-process functions.
2726 ia_cursor
= reply
->cursor
;
2728 /* Initialize the IA_TA header. First the code. */
2729 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_TA
);
2732 /* Then option length. */
2733 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x04u
);
2736 /* Then IA_TA header contents; IAID. */
2737 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2741 * Deal with an IAADDR for lifetimes.
2742 * For all or none, process IAADDRs as hints.
2744 reply
->valid
= reply
->prefer
= 0xffffffff;
2745 reply
->client_valid
= reply
->client_prefer
= 0;
2746 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2747 for (; oc
!= NULL
; oc
= oc
->next
) {
2748 memset(&iaaddr
, 0, sizeof(iaaddr
));
2749 if (!evaluate_option_cache(&iaaddr
, reply
->packet
,
2751 reply
->packet
->options
, NULL
,
2752 &global_scope
, oc
, MDL
) ||
2753 (iaaddr
.len
< IAADDR_OFFSET
)) {
2754 log_error("reply_process_ia_ta: error "
2755 "evaluating IAADDR.");
2756 status
= ISC_R_FAILURE
;
2759 /* The first 16 bytes are the IPv6 address. */
2760 pref_life
= getULong(iaaddr
.data
+ 16);
2761 valid_life
= getULong(iaaddr
.data
+ 20);
2763 if ((reply
->client_valid
== 0) ||
2764 (reply
->client_valid
> valid_life
))
2765 reply
->client_valid
= valid_life
;
2767 if ((reply
->client_prefer
== 0) ||
2768 (reply
->client_prefer
> pref_life
))
2769 reply
->client_prefer
= pref_life
;
2771 /* Nothing more if something has failed. */
2772 if (status
== ISC_R_CANCELED
)
2776 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2777 if (!temporary_is_available(reply
, &tmp_addr
))
2779 status
= reply_process_is_addressed(reply
,
2780 &reply
->lease
->scope
,
2781 reply
->lease
->ipv6_pool
->ipv6_pond
->group
);
2782 if (status
!= ISC_R_SUCCESS
)
2784 status
= reply_process_send_addr(reply
, &tmp_addr
);
2785 if (status
!= ISC_R_SUCCESS
)
2787 if (reply
->lease
!= NULL
)
2788 iasubopt_dereference(&reply
->lease
, MDL
);
2792 /* Rewind the IA_TA to empty. */
2793 option_state_dereference(&reply
->reply_ia
, MDL
);
2794 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2795 status
= ISC_R_NOMEMORY
;
2798 status
= ISC_R_CANCELED
;
2799 reply
->client_resources
= 0;
2800 reply
->resources_included
= ISC_FALSE
;
2801 if (reply
->lease
!= NULL
)
2802 iasubopt_dereference(&reply
->lease
, MDL
);
2807 * Give the client temporary addresses.
2809 if (reply
->client_resources
!= 0)
2811 status
= find_client_temporaries(reply
);
2812 if (status
== ISC_R_NORESOURCES
) {
2813 switch (reply
->packet
->dhcpv6_msg_type
) {
2814 case DHCPV6_SOLICIT
:
2816 * No address for any IA is handled
2821 case DHCPV6_REQUEST
:
2822 /* Section 18.2.1 (Request):
2824 * If the server cannot assign any addresses to
2825 * an IA in the message from the client, the
2826 * server MUST include the IA in the Reply
2827 * message with no addresses in the IA and a
2828 * Status Code option in the IA containing
2829 * status code NoAddrsAvail.
2831 option_state_dereference(&reply
->reply_ia
, MDL
);
2832 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2833 log_error("reply_process_ia_ta: No "
2834 "memory for option state wipe.");
2835 status
= ISC_R_NOMEMORY
;
2839 if (!set_status_code(STATUS_NoAddrsAvail
,
2840 "No addresses available "
2841 "for this interface.",
2843 log_error("reply_process_ia_ta: Unable "
2844 "to set NoAddrsAvail status code.");
2845 status
= ISC_R_FAILURE
;
2849 status
= ISC_R_SUCCESS
;
2854 * We don't want to include the IA if we
2855 * provide zero addresses including zeroed
2858 if (reply
->resources_included
)
2859 status
= ISC_R_SUCCESS
;
2864 } else if (status
!= ISC_R_SUCCESS
)
2868 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2869 sizeof(reply
->buf
) - reply
->cursor
,
2870 reply
->reply_ia
, reply
->packet
,
2871 required_opts_IA
, NULL
);
2873 /* Reset the length of this IA to match what was just written. */
2874 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2875 reply
->cursor
- (ia_cursor
+ 4));
2878 * yes, goto's aren't the best but we also want to avoid extra
2881 if (status
== ISC_R_CANCELED
)
2885 * If we have any addresses log what we are doing.
2887 if (reply
->ia
->num_iasubopt
!= 0) {
2888 struct iasubopt
*tmp
;
2890 char tmp_addr
[INET6_ADDRSTRLEN
];
2892 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2893 tmp
= reply
->ia
->iasubopt
[i
];
2895 log_info("%s TA: address %s to client with duid %s "
2896 "iaid = %d valid for %u seconds",
2897 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2898 inet_ntop(AF_INET6
, &tmp
->addr
,
2899 tmp_addr
, sizeof(tmp_addr
)),
2900 print_hex_1(reply
->client_id
.len
,
2901 reply
->client_id
.data
, 60),
2908 * For hard bindings we consume the new changes into
2909 * the database (if any have been attached to the ia_ta).
2911 * Loop through the assigned dynamic addresses, referencing the
2912 * leases onto this IA_TA rather than any old ones, and updating
2913 * pool timers for each (if any).
2915 if ((reply
->ia
->num_iasubopt
!= 0) &&
2916 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
2917 struct iasubopt
*tmp
;
2918 struct data_string
*ia_id
;
2921 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2922 tmp
= reply
->ia
->iasubopt
[i
];
2924 if (tmp
->ia
!= NULL
)
2925 ia_dereference(&tmp
->ia
, MDL
);
2926 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2928 /* Commit 'hard' bindings. */
2929 renew_lease6(tmp
->ipv6_pool
, tmp
);
2930 schedule_lease_timeout(tmp
->ipv6_pool
);
2932 /* If we have anything to do on commit do it now */
2933 if (tmp
->on_star
.on_commit
!= NULL
) {
2934 execute_statements(NULL
, reply
->packet
,
2936 reply
->packet
->options
,
2939 tmp
->on_star
.on_commit
,
2941 executable_statement_dereference
2942 (&tmp
->on_star
.on_commit
, MDL
);
2945 #if defined (NSUPDATE)
2947 * Perform ddns updates.
2949 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2952 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2954 reply
->packet
->options
,
2958 ddns_updates(reply
->packet
, NULL
, NULL
,
2959 tmp
, NULL
, reply
->opt_state
);
2962 /* Do our threshold check. */
2963 check_pool6_threshold(reply
, tmp
);
2966 /* Remove any old ia from the hash. */
2967 if (reply
->old_ia
!= NULL
) {
2968 ia_id
= &reply
->old_ia
->iaid_duid
;
2969 ia_hash_delete(ia_ta_active
,
2970 (unsigned char *)ia_id
->data
,
2972 ia_dereference(&reply
->old_ia
, MDL
);
2975 /* Put new ia into the hash. */
2976 reply
->ia
->cltt
= cur_time
;
2977 ia_id
= &reply
->ia
->iaid_duid
;
2978 ia_hash_add(ia_ta_active
, (unsigned char *)ia_id
->data
,
2979 ia_id
->len
, reply
->ia
, MDL
);
2981 write_ia(reply
->ia
);
2983 schedule_lease_timeout_reply(reply
);
2987 if (packet_ia
!= NULL
)
2988 option_state_dereference(&packet_ia
, MDL
);
2989 if (iaaddr
.data
!= NULL
)
2990 data_string_forget(&iaaddr
, MDL
);
2991 if (reply
->reply_ia
!= NULL
)
2992 option_state_dereference(&reply
->reply_ia
, MDL
);
2993 if (ia_data
.data
!= NULL
)
2994 data_string_forget(&ia_data
, MDL
);
2995 if (data
.data
!= NULL
)
2996 data_string_forget(&data
, MDL
);
2997 if (reply
->ia
!= NULL
)
2998 ia_dereference(&reply
->ia
, MDL
);
2999 if (reply
->old_ia
!= NULL
)
3000 ia_dereference(&reply
->old_ia
, MDL
);
3001 if (reply
->lease
!= NULL
)
3002 iasubopt_dereference(&reply
->lease
, MDL
);
3005 * ISC_R_CANCELED is a status code used by the addr processing to
3006 * indicate we're replying with other addresses. This is still a
3007 * success at higher layers.
3009 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
3013 * Verify the temporary address is available.
3015 static isc_boolean_t
3016 temporary_is_available(struct reply_state
*reply
, struct iaddr
*addr
) {
3017 struct in6_addr tmp_addr
;
3018 struct subnet
*subnet
;
3019 struct ipv6_pool
*pool
= NULL
;
3020 struct ipv6_pond
*pond
= NULL
;
3023 memcpy(&tmp_addr
, addr
->iabuf
, sizeof(tmp_addr
));
3025 * Clients may choose to send :: as an address, with the idea to give
3026 * hints about preferred-lifetime or valid-lifetime.
3027 * So this is not a request for this address.
3029 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
))
3033 * Verify that this address is on the client's network.
3035 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
3036 subnet
= subnet
->next_sibling
) {
3037 if (addr_eq(subnet_number(*addr
, subnet
->netmask
),
3042 /* Address not found on shared network. */
3047 * Check if this address is owned (must be before next step).
3049 if (address_is_owned(reply
, addr
))
3053 * Verify that this address is in a temporary pool and try to get it.
3055 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3056 if (((pond
->prohibit_list
!= NULL
) &&
3057 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3058 ((pond
->permit_list
!= NULL
) &&
3059 (!permitted(reply
->packet
, pond
->permit_list
))))
3062 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3063 if (pool
->pool_type
!= D6O_IA_TA
)
3066 if (ipv6_in_pool(&tmp_addr
, pool
))
3076 if (lease6_exists(pool
, &tmp_addr
))
3078 if (iasubopt_allocate(&reply
->lease
, MDL
) != ISC_R_SUCCESS
)
3080 reply
->lease
->addr
= tmp_addr
;
3081 reply
->lease
->plen
= 0;
3082 /* Default is soft binding for 2 minutes. */
3083 if (add_lease6(pool
, reply
->lease
, cur_time
+ 120) != ISC_R_SUCCESS
)
3090 * Get a temporary address per prefix.
3093 find_client_temporaries(struct reply_state
*reply
) {
3095 struct ipv6_pool
*p
= NULL
;
3096 struct ipv6_pond
*pond
;
3097 isc_result_t status
= ISC_R_NORESOURCES
;;
3098 unsigned int attempts
;
3099 struct iaddr send_addr
;
3102 * Do a quick walk through of the ponds and pools
3103 * to see if we have any prefix pools
3105 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3106 if (pond
->ipv6_pools
== NULL
)
3109 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3110 if (p
->pool_type
== D6O_IA_TA
)
3117 /* If we get here and p is NULL we have no useful pools */
3119 log_debug("Unable to get client addresses: "
3120 "no IPv6 pools on this shared network");
3121 return ISC_R_NORESOURCES
;
3125 * We have at least one pool that could provide an address
3126 * Now we walk through the ponds and pools again and check
3127 * to see if the client is permitted and if an address is
3131 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3132 if (((pond
->prohibit_list
!= NULL
) &&
3133 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3134 ((pond
->permit_list
!= NULL
) &&
3135 (!permitted(reply
->packet
, pond
->permit_list
))))
3138 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3139 if (p
->pool_type
!= D6O_IA_TA
) {
3144 * Get an address in this temporary pool.
3146 status
= create_lease6(p
, &reply
->lease
, &attempts
,
3147 &reply
->client_id
, cur_time
+ 120);
3148 if (status
!= ISC_R_SUCCESS
) {
3149 log_debug("Unable to get a temporary address.");
3153 status
= reply_process_is_addressed(reply
,
3154 &reply
->lease
->scope
,
3156 if (status
!= ISC_R_SUCCESS
) {
3160 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3161 status
= reply_process_send_addr(reply
, &send_addr
);
3162 if (status
!= ISC_R_SUCCESS
) {
3166 * reply->lease can't be null as we use it above
3167 * add check if that changes
3169 iasubopt_dereference(&reply
->lease
, MDL
);
3174 if (reply
->lease
!= NULL
) {
3175 iasubopt_dereference(&reply
->lease
, MDL
);
3181 * This function only returns failure on 'hard' failures. If it succeeds,
3182 * it will leave a lease structure behind.
3185 reply_process_try_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3186 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
3187 struct ipv6_pool
*pool
= NULL
;
3188 struct ipv6_pond
*pond
= NULL
;
3190 struct data_string data_addr
;
3192 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
3193 (addr
== NULL
) || (reply
->lease
!= NULL
))
3194 return (DHCP_R_INVALIDARG
);
3197 * Do a quick walk through of the ponds and pools
3198 * to see if we have any NA address pools
3200 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3201 if (pond
->ipv6_pools
== NULL
)
3204 for (i
= 0; ; i
++) {
3205 pool
= pond
->ipv6_pools
[i
];
3206 if ((pool
== NULL
) ||
3207 (pool
->pool_type
== D6O_IA_NA
))
3214 /* If we get here and p is NULL we have no useful pools */
3216 return (ISC_R_ADDRNOTAVAIL
);
3219 memset(&data_addr
, 0, sizeof(data_addr
));
3220 data_addr
.len
= addr
->len
;
3221 data_addr
.data
= addr
->iabuf
;
3224 * We have at least one pool that could provide an address
3225 * Now we walk through the ponds and pools again and check
3226 * to see if the client is permitted and if an address is
3229 * Within a given pond we start looking at the last pool we
3230 * allocated from, unless it had a collision trying to allocate
3231 * an address. This will tend to move us into less-filled pools.
3234 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3235 if (((pond
->prohibit_list
!= NULL
) &&
3236 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3237 ((pond
->permit_list
!= NULL
) &&
3238 (!permitted(reply
->packet
, pond
->permit_list
))))
3241 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3242 if (pool
->pool_type
!= D6O_IA_NA
)
3245 status
= try_client_v6_address(&reply
->lease
, pool
,
3247 if (status
== ISC_R_SUCCESS
)
3251 if (status
== ISC_R_SUCCESS
)
3255 /* Note that this is just pedantry. There is no allocation to free. */
3256 data_string_forget(&data_addr
, MDL
);
3257 /* Return just the most recent status... */
3261 /* Look around for an address to give the client. First, look through the
3262 * old IA for addresses we can extend. Second, try to allocate a new address.
3263 * Finally, actually add that address into the current reply IA.
3266 find_client_address(struct reply_state
*reply
) {
3267 struct iaddr send_addr
;
3268 isc_result_t status
= ISC_R_NORESOURCES
;
3269 struct iasubopt
*lease
, *best_lease
= NULL
;
3270 struct binding_scope
**scope
;
3271 struct group
*group
;
3274 if (reply
->static_lease
) {
3275 if (reply
->host
== NULL
)
3276 return DHCP_R_INVALIDARG
;
3279 memcpy(send_addr
.iabuf
, reply
->fixed
.data
, 16);
3281 scope
= &global_scope
;
3282 group
= reply
->subnet
->group
;
3286 if (reply
->old_ia
!= NULL
) {
3287 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3288 struct shared_network
*candidate_shared
;
3289 struct ipv6_pond
*pond
;
3291 lease
= reply
->old_ia
->iasubopt
[i
];
3292 candidate_shared
= lease
->ipv6_pool
->shared_network
;
3293 pond
= lease
->ipv6_pool
->ipv6_pond
;
3296 * Look for the best lease on the client's shared
3297 * network, that is still permitted
3300 if ((candidate_shared
!= reply
->shared
) ||
3301 (lease6_usable(lease
) != ISC_TRUE
))
3304 if (((pond
->prohibit_list
!= NULL
) &&
3305 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3306 ((pond
->permit_list
!= NULL
) &&
3307 (!permitted(reply
->packet
, pond
->permit_list
))))
3310 best_lease
= lease_compare(lease
, best_lease
);
3314 /* Try to pick a new address if we didn't find one, or if we found an
3317 if ((best_lease
== NULL
) || (best_lease
->state
== FTS_ABANDONED
)) {
3318 status
= pick_v6_address(reply
);
3319 } else if (best_lease
!= NULL
) {
3320 iasubopt_reference(&reply
->lease
, best_lease
, MDL
);
3321 status
= ISC_R_SUCCESS
;
3324 /* Pick the abandoned lease as a last resort. */
3325 if ((status
== ISC_R_NORESOURCES
) && (best_lease
!= NULL
)) {
3326 /* I don't see how this is supposed to be done right now. */
3327 log_error("Best match for DUID %s is an abandoned address,"
3328 " This may be a result of multiple clients attempting"
3329 " to use this DUID",
3330 print_hex_1(reply
->client_id
.len
,
3331 reply
->client_id
.data
, 60));
3332 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
3335 /* Give up now if we didn't find a lease. */
3336 if (status
!= ISC_R_SUCCESS
)
3339 if (reply
->lease
== NULL
)
3340 log_fatal("Impossible condition at %s:%d.", MDL
);
3342 /* Draw binding scopes from the lease's binding scope, and config
3343 * from the lease's containing subnet and higher. Note that it may
3344 * be desirable to place the group attachment directly in the pool.
3346 scope
= &reply
->lease
->scope
;
3347 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
3350 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3353 status
= reply_process_is_addressed(reply
, scope
, group
);
3354 if (status
!= ISC_R_SUCCESS
)
3357 status
= reply_process_send_addr(reply
, &send_addr
);
3361 /* Once an address is found for a client, perform several common functions;
3362 * Calculate and store valid and preferred lease times, draw client options
3363 * into the option state.
3366 reply_process_is_addressed(struct reply_state
*reply
,
3367 struct binding_scope
**scope
, struct group
*group
)
3369 isc_result_t status
= ISC_R_SUCCESS
;
3370 struct data_string data
;
3371 struct option_cache
*oc
;
3372 struct option_state
*tmp_options
= NULL
;
3373 struct on_star
*on_star
;
3376 /* Initialize values we will cleanup. */
3377 memset(&data
, 0, sizeof(data
));
3380 * Find the proper on_star block to use. We use the
3381 * one in the lease if we have a lease or the one in
3382 * the reply if we don't have a lease because this is
3386 on_star
= &reply
->lease
->on_star
;
3388 on_star
= &reply
->on_star
;
3392 * Bring in the root configuration. We only do this to bring
3393 * in the on * statements, as we didn't have the lease available
3394 * we did it the first time.
3396 option_state_allocate(&tmp_options
, MDL
);
3397 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3398 reply
->packet
->options
, tmp_options
,
3399 &global_scope
, root_group
, NULL
,
3401 if (tmp_options
!= NULL
) {
3402 option_state_dereference(&tmp_options
, MDL
);
3406 * Bring configured options into the root packet level cache - start
3407 * with the lease's closest enclosing group (passed in by the caller
3410 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3411 reply
->packet
->options
, reply
->opt_state
,
3412 scope
, group
, root_group
, on_star
);
3414 /* Execute statements from class scopes. */
3415 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3416 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3417 reply
->packet
->options
,
3418 reply
->opt_state
, scope
,
3419 reply
->packet
->classes
[i
- 1]->group
,
3424 * If there is a host record, over-ride with values configured there,
3425 * without re-evaluating configuration from the previously executed
3426 * group or its common enclosers.
3428 if (reply
->host
!= NULL
)
3429 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3430 reply
->packet
->options
,
3431 reply
->opt_state
, scope
,
3432 reply
->host
->group
, group
,
3435 /* Determine valid lifetime. */
3436 if (reply
->client_valid
== 0)
3437 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
3439 reply
->send_valid
= reply
->client_valid
;
3441 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3442 SV_DEFAULT_LEASE_TIME
);
3444 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3445 reply
->packet
->options
,
3449 log_error("reply_process_is_addressed: unable to "
3450 "evaluate default lease time");
3451 status
= ISC_R_FAILURE
;
3455 reply
->send_valid
= getULong(data
.data
);
3456 data_string_forget(&data
, MDL
);
3459 /* Check to see if the lease time would cause us to wrap
3460 * in which case we make it infinite.
3461 * The following doesn't work on at least some systems:
3462 * (cur_time + reply->send_valid < cur_time)
3464 if (reply
->send_valid
!= 0xFFFFFFFF) {
3465 time_t test_time
= cur_time
+ reply
->send_valid
;
3466 if (test_time
< cur_time
)
3467 reply
->send_valid
= 0xFFFFFFFF;
3470 if (reply
->client_prefer
== 0)
3471 reply
->send_prefer
= reply
->send_valid
;
3473 reply
->send_prefer
= reply
->client_prefer
;
3475 if ((reply
->send_prefer
>= reply
->send_valid
) &&
3476 (reply
->send_valid
!= 0xFFFFFFFF))
3477 reply
->send_prefer
= (reply
->send_valid
/ 2) +
3478 (reply
->send_valid
/ 8);
3480 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3481 SV_PREFER_LIFETIME
);
3483 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3484 reply
->packet
->options
,
3488 log_error("reply_process_is_addressed: unable to "
3489 "evaluate preferred lease time");
3490 status
= ISC_R_FAILURE
;
3494 reply
->send_prefer
= getULong(data
.data
);
3495 data_string_forget(&data
, MDL
);
3498 /* Note lowest values for later calculation of renew/rebind times. */
3499 if (reply
->prefer
> reply
->send_prefer
)
3500 reply
->prefer
= reply
->send_prefer
;
3502 if (reply
->valid
> reply
->send_valid
)
3503 reply
->valid
= reply
->send_valid
;
3507 * XXX: Old 4.0.0 alpha code would change the host {} record
3508 * XXX: uid upon lease assignment. This was intended to cover the
3509 * XXX: case where a client first identifies itself using vendor
3510 * XXX: options in a solicit, or request, but later neglects to include
3511 * XXX: these options in a Renew or Rebind. It is not clear that this
3512 * XXX: is required, and has some startling ramifications (such as
3513 * XXX: how to recover this dynamic host {} state across restarts).
3515 if (reply
->host
!= NULL
)
3516 change_host_uid(host
, reply
->client_id
->data
,
3517 reply
->client_id
->len
);
3520 /* Perform dynamic lease related update work. */
3521 if (reply
->lease
!= NULL
) {
3522 /* Cached lifetimes */
3523 reply
->lease
->prefer
= reply
->send_prefer
;
3524 reply
->lease
->valid
= reply
->send_valid
;
3526 /* Advance (or rewind) the valid lifetime.
3527 * In the protocol 0xFFFFFFFF is infinite
3528 * when connecting to the lease file MAX_TIME is
3530 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
3531 if (reply
->send_valid
== 0xFFFFFFFF) {
3532 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
3534 reply
->lease
->soft_lifetime_end_time
=
3535 cur_time
+ reply
->send_valid
;
3537 /* Wait before renew! */
3540 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
3541 if (status
!= ISC_R_SUCCESS
) {
3542 log_fatal("reply_process_is_addressed: Unable to "
3543 "attach lease to new IA: %s",
3544 isc_result_totext(status
));
3548 * If this is a new lease, make sure it is attached somewhere.
3550 if (reply
->lease
->ia
== NULL
) {
3551 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
3555 /* Bring a copy of the relevant options into the IA scope. */
3556 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3557 reply
->packet
->options
, reply
->reply_ia
,
3558 scope
, group
, root_group
, NULL
);
3560 /* Execute statements from class scopes. */
3561 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3562 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3563 reply
->packet
->options
,
3564 reply
->reply_ia
, scope
,
3565 reply
->packet
->classes
[i
- 1]->group
,
3570 * And bring in host record configuration, if any, but not to overlap
3571 * the previous group or its common enclosers.
3573 if (reply
->host
!= NULL
)
3574 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3575 reply
->packet
->options
,
3576 reply
->reply_ia
, scope
,
3577 reply
->host
->group
, group
, NULL
);
3580 if (data
.data
!= NULL
)
3581 data_string_forget(&data
, MDL
);
3583 if (status
== ISC_R_SUCCESS
)
3584 reply
->client_resources
++;
3589 /* Simply send an IAADDR within the IA scope as described. */
3591 reply_process_send_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3592 isc_result_t status
= ISC_R_SUCCESS
;
3593 struct data_string data
;
3595 memset(&data
, 0, sizeof(data
));
3597 /* Now append the lease. */
3598 data
.len
= IAADDR_OFFSET
;
3599 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
3600 log_error("reply_process_send_addr: out of memory"
3601 "allocating new IAADDR buffer.");
3602 status
= ISC_R_NOMEMORY
;
3605 data
.data
= data
.buffer
->data
;
3607 memcpy(data
.buffer
->data
, addr
->iabuf
, 16);
3608 putULong(data
.buffer
->data
+ 16, reply
->send_prefer
);
3609 putULong(data
.buffer
->data
+ 20, reply
->send_valid
);
3611 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
3612 data
.buffer
, data
.buffer
->data
,
3613 data
.len
, D6O_IAADDR
, 0)) {
3614 log_error("reply_process_send_addr: unable "
3615 "to save IAADDR option");
3616 status
= ISC_R_FAILURE
;
3620 reply
->resources_included
= ISC_TRUE
;
3623 if (data
.data
!= NULL
)
3624 data_string_forget(&data
, MDL
);
3629 /* Choose the better of two leases. */
3630 static struct iasubopt
*
3631 lease_compare(struct iasubopt
*alpha
, struct iasubopt
*beta
) {
3637 switch(alpha
->state
) {
3639 switch(beta
->state
) {
3641 /* Choose the lease with the longest lifetime (most
3642 * likely the most recently allocated).
3644 if (alpha
->hard_lifetime_end_time
<
3645 beta
->hard_lifetime_end_time
)
3655 log_fatal("Impossible condition at %s:%d.", MDL
);
3660 switch (beta
->state
) {
3665 /* Choose the most recently expired lease. */
3666 if (alpha
->hard_lifetime_end_time
<
3667 beta
->hard_lifetime_end_time
)
3669 else if ((alpha
->hard_lifetime_end_time
==
3670 beta
->hard_lifetime_end_time
) &&
3671 (alpha
->soft_lifetime_end_time
<
3672 beta
->soft_lifetime_end_time
))
3681 log_fatal("Impossible condition at %s:%d.", MDL
);
3686 switch (beta
->state
) {
3692 /* Choose the lease that was abandoned longest ago. */
3693 if (alpha
->hard_lifetime_end_time
<
3694 beta
->hard_lifetime_end_time
)
3700 log_fatal("Impossible condition at %s:%d.", MDL
);
3705 log_fatal("Impossible condition at %s:%d.", MDL
);
3708 log_fatal("Triple impossible condition at %s:%d.", MDL
);
3712 /* Process a client-supplied IA_PD. This may append options to the tail of
3713 * the reply packet being built in the reply_state structure.
3716 reply_process_ia_pd(struct reply_state
*reply
, struct option_cache
*ia
) {
3717 isc_result_t status
= ISC_R_SUCCESS
;
3720 struct option_state
*packet_ia
;
3721 struct option_cache
*oc
;
3722 struct data_string ia_data
, data
;
3724 /* Initialize values that will get cleaned up on return. */
3726 memset(&ia_data
, 0, sizeof(ia_data
));
3727 memset(&data
, 0, sizeof(data
));
3729 * Note that find_client_prefix() may set reply->lease.
3732 /* Make sure there is at least room for the header. */
3733 if ((reply
->cursor
+ IA_PD_OFFSET
+ 4) > sizeof(reply
->buf
)) {
3734 log_error("reply_process_ia_pd: Reply too long for IA.");
3735 return ISC_R_NOSPACE
;
3739 /* Fetch the IA_PD contents. */
3740 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
3741 ia
, IA_PD_OFFSET
)) {
3742 log_error("reply_process_ia_pd: error evaluating ia");
3743 status
= ISC_R_FAILURE
;
3747 /* Extract IA_PD header contents. */
3748 iaid
= getULong(ia_data
.data
);
3749 reply
->renew
= getULong(ia_data
.data
+ 4);
3750 reply
->rebind
= getULong(ia_data
.data
+ 8);
3752 /* Create an IA_PD structure. */
3753 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
3754 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
3755 log_error("reply_process_ia_pd: no memory for ia.");
3756 status
= ISC_R_NOMEMORY
;
3759 reply
->ia
->ia_type
= D6O_IA_PD
;
3761 /* Cache pre-existing IA_PD, if any. */
3762 ia_hash_lookup(&reply
->old_ia
, ia_pd_active
,
3763 (unsigned char *)reply
->ia
->iaid_duid
.data
,
3764 reply
->ia
->iaid_duid
.len
, MDL
);
3767 * Create an option cache to carry the IA_PD option contents, and
3768 * execute any user-supplied values into it.
3770 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
3771 status
= ISC_R_NOMEMORY
;
3775 /* Check & count the fixed prefix host records. */
3776 reply
->static_prefixes
= 0;
3777 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_prefix
!= NULL
)) {
3778 struct iaddrcidrnetlist
*fp
;
3780 for (fp
= reply
->host
->fixed_prefix
; fp
!= NULL
;
3782 reply
->static_prefixes
+= 1;
3787 * Save the cursor position at the start of the IA_PD, so we can
3788 * set length and adjust t1/t2 values later. We write a temporary
3789 * header out now just in case we decide to adjust the packet
3790 * within sub-process functions.
3792 ia_cursor
= reply
->cursor
;
3794 /* Initialize the IA_PD header. First the code. */
3795 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_PD
);
3798 /* Then option length. */
3799 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
3802 /* Then IA_PD header contents; IAID. */
3803 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
3806 /* We store the client's t1 for now, and may over-ride it later. */
3807 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
3810 /* We store the client's t2 for now, and may over-ride it later. */
3811 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
3815 * For each prefix in this IA_PD, decide what to do about it.
3817 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAPREFIX
);
3818 reply
->valid
= reply
->prefer
= 0xffffffff;
3819 reply
->client_valid
= reply
->client_prefer
= 0;
3820 reply
->preflen
= -1;
3821 for (; oc
!= NULL
; oc
= oc
->next
) {
3822 status
= reply_process_prefix(reply
, oc
);
3825 * Canceled means we did not allocate prefixes to the
3826 * client, but we're "done" with this IA - we set a status
3827 * code. So transmit this reply, e.g., move on to the next
3830 if (status
== ISC_R_CANCELED
)
3833 if ((status
!= ISC_R_SUCCESS
) &&
3834 (status
!= ISC_R_ADDRINUSE
) &&
3835 (status
!= ISC_R_ADDRNOTAVAIL
))
3842 * If we fell through the above and never gave the client
3843 * a prefix, give it one now.
3845 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
3846 status
= find_client_prefix(reply
);
3848 if (status
== ISC_R_NORESOURCES
) {
3849 switch (reply
->packet
->dhcpv6_msg_type
) {
3850 case DHCPV6_SOLICIT
:
3852 * No prefix for any IA is handled
3857 case DHCPV6_REQUEST
:
3858 /* Same than for addresses. */
3859 option_state_dereference(&reply
->reply_ia
, MDL
);
3860 if (!option_state_allocate(&reply
->reply_ia
,
3863 log_error("reply_process_ia_pd: No "
3864 "memory for option state "
3866 status
= ISC_R_NOMEMORY
;
3870 if (!set_status_code(STATUS_NoPrefixAvail
,
3871 "No prefixes available "
3872 "for this interface.",
3874 log_error("reply_process_ia_pd: "
3876 "NoPrefixAvail status "
3878 status
= ISC_R_FAILURE
;
3882 status
= ISC_R_SUCCESS
;
3886 if (reply
->resources_included
)
3887 status
= ISC_R_SUCCESS
;
3894 if (status
!= ISC_R_SUCCESS
)
3898 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
3899 sizeof(reply
->buf
) - reply
->cursor
,
3900 reply
->reply_ia
, reply
->packet
,
3901 required_opts_IA_PD
, NULL
);
3903 /* Reset the length of this IA_PD to match what was just written. */
3904 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
3905 reply
->cursor
- (ia_cursor
+ 4));
3908 * T1/T2 time selection is kind of weird. We actually use DHCP
3909 * (v4) scoped options as handy existing places where these might
3910 * be configured by an administrator. A value of zero tells the
3911 * client it may choose its own renewal time.
3914 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
3915 DHO_DHCP_RENEWAL_TIME
);
3917 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3918 reply
->packet
->options
,
3919 reply
->opt_state
, &global_scope
,
3922 log_error("Invalid renewal time.");
3924 reply
->renew
= getULong(data
.data
);
3927 if (data
.data
!= NULL
)
3928 data_string_forget(&data
, MDL
);
3930 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
3934 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
3935 DHO_DHCP_REBINDING_TIME
);
3937 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3938 reply
->packet
->options
,
3939 reply
->opt_state
, &global_scope
,
3942 log_error("Invalid rebinding time.");
3944 reply
->rebind
= getULong(data
.data
);
3947 if (data
.data
!= NULL
)
3948 data_string_forget(&data
, MDL
);
3950 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
3953 * yes, goto's aren't the best but we also want to avoid extra
3956 if (status
== ISC_R_CANCELED
)
3960 * Handle static prefixes, we always log stuff and if it's
3961 * a hard binding we run any commit statements that we have
3963 if (reply
->static_prefixes
!= 0) {
3964 char tmp_addr
[INET6_ADDRSTRLEN
];
3965 log_info("%s PD: address %s/%d to client with duid %s "
3967 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
3968 inet_ntop(AF_INET6
, reply
->fixed_pref
.lo_addr
.iabuf
,
3969 tmp_addr
, sizeof(tmp_addr
)),
3970 reply
->fixed_pref
.bits
,
3971 print_hex_1(reply
->client_id
.len
,
3972 reply
->client_id
.data
, 60),
3974 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
3975 (reply
->on_star
.on_commit
!= NULL
)) {
3976 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
3977 reply
->packet
->options
,
3979 NULL
, reply
->on_star
.on_commit
,
3981 executable_statement_dereference
3982 (&reply
->on_star
.on_commit
, MDL
);
3988 * If we have any addresses log what we are doing.
3990 if (reply
->ia
->num_iasubopt
!= 0) {
3991 struct iasubopt
*tmp
;
3993 char tmp_addr
[INET6_ADDRSTRLEN
];
3995 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3996 tmp
= reply
->ia
->iasubopt
[i
];
3998 log_info("%s PD: address %s/%d to client with duid %s"
3999 " iaid = %d valid for %u seconds",
4000 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
4001 inet_ntop(AF_INET6
, &tmp
->addr
,
4002 tmp_addr
, sizeof(tmp_addr
)),
4004 print_hex_1(reply
->client_id
.len
,
4005 reply
->client_id
.data
, 60),
4011 * If this is not a 'soft' binding, consume the new changes into
4012 * the database (if any have been attached to the ia_pd).
4014 * Loop through the assigned dynamic prefixes, referencing the
4015 * prefixes onto this IA_PD rather than any old ones, and updating
4016 * prefix pool timers for each (if any).
4018 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
4019 (reply
->ia
->num_iasubopt
!= 0)) {
4020 struct iasubopt
*tmp
;
4021 struct data_string
*ia_id
;
4024 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
4025 tmp
= reply
->ia
->iasubopt
[i
];
4027 if (tmp
->ia
!= NULL
)
4028 ia_dereference(&tmp
->ia
, MDL
);
4029 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
4031 /* Commit 'hard' bindings. */
4032 renew_lease6(tmp
->ipv6_pool
, tmp
);
4033 schedule_lease_timeout(tmp
->ipv6_pool
);
4035 /* If we have anything to do on commit do it now */
4036 if (tmp
->on_star
.on_commit
!= NULL
) {
4037 execute_statements(NULL
, reply
->packet
,
4039 reply
->packet
->options
,
4042 tmp
->on_star
.on_commit
,
4044 executable_statement_dereference
4045 (&tmp
->on_star
.on_commit
, MDL
);
4048 /* Do our threshold check. */
4049 check_pool6_threshold(reply
, tmp
);
4052 /* Remove any old ia from the hash. */
4053 if (reply
->old_ia
!= NULL
) {
4054 ia_id
= &reply
->old_ia
->iaid_duid
;
4055 ia_hash_delete(ia_pd_active
,
4056 (unsigned char *)ia_id
->data
,
4058 ia_dereference(&reply
->old_ia
, MDL
);
4061 /* Put new ia into the hash. */
4062 reply
->ia
->cltt
= cur_time
;
4063 ia_id
= &reply
->ia
->iaid_duid
;
4064 ia_hash_add(ia_pd_active
, (unsigned char *)ia_id
->data
,
4065 ia_id
->len
, reply
->ia
, MDL
);
4067 write_ia(reply
->ia
);
4069 schedule_lease_timeout_reply(reply
);
4073 if (packet_ia
!= NULL
)
4074 option_state_dereference(&packet_ia
, MDL
);
4075 if (reply
->reply_ia
!= NULL
)
4076 option_state_dereference(&reply
->reply_ia
, MDL
);
4077 if (ia_data
.data
!= NULL
)
4078 data_string_forget(&ia_data
, MDL
);
4079 if (data
.data
!= NULL
)
4080 data_string_forget(&data
, MDL
);
4081 if (reply
->ia
!= NULL
)
4082 ia_dereference(&reply
->ia
, MDL
);
4083 if (reply
->old_ia
!= NULL
)
4084 ia_dereference(&reply
->old_ia
, MDL
);
4085 if (reply
->lease
!= NULL
)
4086 iasubopt_dereference(&reply
->lease
, MDL
);
4087 if (reply
->on_star
.on_expiry
!= NULL
)
4088 executable_statement_dereference
4089 (&reply
->on_star
.on_expiry
, MDL
);
4090 if (reply
->on_star
.on_release
!= NULL
)
4091 executable_statement_dereference
4092 (&reply
->on_star
.on_release
, MDL
);
4095 * ISC_R_CANCELED is a status code used by the prefix processing to
4096 * indicate we're replying with a status code. This is still a
4097 * success at higher layers.
4099 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
4104 * \brief Find the proper scoping group for use with a v6 static prefix.
4106 * We start by trying to find a subnet based on the given prefix and
4107 * the shared network. If we don't find one then the prefix has been
4108 * declared outside of any subnets. If there is a static address
4109 * associated with the host we use it to try and find a subnet (this
4110 * should succeed). If there isn't a static address we fall back
4111 * to the shared subnet itself.
4112 * Once we have a subnet we extract the group from it and return it.
4114 * \param reply - the reply structure we use to collect information
4115 * we will use the fields shared, fixed_pref and host
4116 * from the structure
4118 * \return a pointer to the group structure to use for scoping
4121 static struct group
*
4122 find_group_by_prefix(struct reply_state
*reply
) {
4123 /* default group if we don't find anything better */
4124 struct group
*group
= reply
->shared
->group
;
4125 struct subnet
*subnet
= NULL
;
4126 struct iaddr tmp_addr
;
4127 struct data_string fixed_addr
;
4129 /* Try with the prefix first */
4130 if (find_grouped_subnet(&subnet
, reply
->shared
,
4131 reply
->fixed_pref
.lo_addr
, MDL
) != 0) {
4132 group
= subnet
->group
;
4133 subnet_dereference(&subnet
, MDL
);
4137 /* Didn't find a subnet via prefix, what about fixed address */
4138 /* The caller has already tested reply->host != NULL */
4140 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
4142 if ((reply
->host
->fixed_addr
!= NULL
) &&
4143 (evaluate_option_cache(&fixed_addr
, NULL
, NULL
, NULL
,
4144 NULL
, NULL
, &global_scope
,
4145 reply
->host
->fixed_addr
, MDL
))) {
4146 if (fixed_addr
.len
>= 16) {
4148 memcpy(tmp_addr
.iabuf
, fixed_addr
.data
, 16);
4149 if (find_grouped_subnet(&subnet
, reply
->shared
,
4150 tmp_addr
, MDL
) != 0) {
4151 group
= subnet
->group
;
4152 subnet_dereference(&subnet
, MDL
);
4155 data_string_forget(&fixed_addr
, MDL
);
4158 /* return whatever we got */
4163 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
4164 * contents into the reply's current ia_pd-scoped option cache. Returns
4165 * ISC_R_CANCELED in the event we are replying with a status code and do
4166 * not wish to process more IAPREFIXes within this IA_PD.
4169 reply_process_prefix(struct reply_state
*reply
, struct option_cache
*pref
) {
4170 u_int32_t pref_life
, valid_life
;
4171 struct binding_scope
**scope
;
4172 struct iaddrcidrnet tmp_pref
;
4173 struct option_cache
*oc
;
4174 struct data_string iapref
, data
;
4175 isc_result_t status
= ISC_R_SUCCESS
;
4176 struct group
*group
;
4178 /* Initializes values that will be cleaned up. */
4179 memset(&iapref
, 0, sizeof(iapref
));
4180 memset(&data
, 0, sizeof(data
));
4181 /* Note that reply->lease may be set by prefix_is_owned() */
4184 * There is no point trying to process an incoming prefix if there
4185 * is no room for an outgoing prefix.
4187 if ((reply
->cursor
+ 29) > sizeof(reply
->buf
)) {
4188 log_error("reply_process_prefix: Out of room for prefix.");
4189 return ISC_R_NOSPACE
;
4192 /* Extract this IAPREFIX option. */
4193 if (!evaluate_option_cache(&iapref
, reply
->packet
, NULL
, NULL
,
4194 reply
->packet
->options
, NULL
, &global_scope
,
4196 (iapref
.len
< IAPREFIX_OFFSET
)) {
4197 log_error("reply_process_prefix: error evaluating IAPREFIX.");
4198 status
= ISC_R_FAILURE
;
4203 * Layout: preferred and valid lifetimes followed by the prefix
4204 * length and the IPv6 address.
4206 pref_life
= getULong(iapref
.data
);
4207 valid_life
= getULong(iapref
.data
+ 4);
4209 if ((reply
->client_valid
== 0) ||
4210 (reply
->client_valid
> valid_life
))
4211 reply
->client_valid
= valid_life
;
4213 if ((reply
->client_prefer
== 0) ||
4214 (reply
->client_prefer
> pref_life
))
4215 reply
->client_prefer
= pref_life
;
4218 * Clients may choose to send ::/0 as a prefix, with the idea to give
4219 * hints about preferred-lifetime or valid-lifetime.
4221 tmp_pref
.lo_addr
.len
= 16;
4222 memset(tmp_pref
.lo_addr
.iabuf
, 0, 16);
4223 if ((iapref
.data
[8] == 0) &&
4224 (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0)) {
4225 /* Status remains success; we just ignore this one. */
4230 * Clients may choose to send ::/X as a prefix to specify a
4231 * preferred/requested prefix length. Note X is never zero here.
4233 tmp_pref
.bits
= (int) iapref
.data
[8];
4234 if (reply
->preflen
< 0) {
4235 /* Cache the first preferred prefix length. */
4236 reply
->preflen
= tmp_pref
.bits
;
4238 if (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0) {
4242 memcpy(tmp_pref
.lo_addr
.iabuf
, iapref
.data
+ 9, 16);
4244 /* Verify the prefix belongs to the client. */
4245 if (!prefix_is_owned(reply
, &tmp_pref
)) {
4246 /* Same than for addresses. */
4247 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
4248 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
4249 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
4250 status
= reply_process_try_prefix(reply
, &tmp_pref
);
4252 /* Either error out or skip this prefix. */
4253 if ((status
!= ISC_R_SUCCESS
) &&
4254 (status
!= ISC_R_ADDRINUSE
) &&
4255 (status
!= ISC_R_ADDRNOTAVAIL
))
4258 if (reply
->lease
== NULL
) {
4259 if (reply
->packet
->dhcpv6_msg_type
==
4261 reply
->send_prefer
= 0;
4262 reply
->send_valid
= 0;
4266 /* status remains success - ignore */
4270 * RFC3633 section 18.2.3:
4272 * If the delegating router cannot find a binding
4273 * for the requesting router's IA_PD the delegating
4274 * router returns the IA_PD containing no prefixes
4275 * with a Status Code option set to NoBinding in the
4278 * On mismatch we (ab)use this pretending we have not the IA
4279 * as soon as we have not a prefix.
4281 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
4282 /* Rewind the IA_PD to empty. */
4283 option_state_dereference(&reply
->reply_ia
, MDL
);
4284 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
4285 log_error("reply_process_prefix: No memory "
4286 "for option state wipe.");
4287 status
= ISC_R_NOMEMORY
;
4291 /* Append a NoBinding status code. */
4292 if (!set_status_code(STATUS_NoBinding
,
4293 "Prefix not bound to this "
4294 "interface.", reply
->reply_ia
)) {
4295 log_error("reply_process_prefix: Unable to "
4296 "attach status code.");
4297 status
= ISC_R_FAILURE
;
4301 /* Fin (no more IAPREFIXes). */
4302 status
= ISC_R_CANCELED
;
4305 log_error("It is impossible to lease a client that is "
4306 "not sending a solicit, request, renew, or "
4308 status
= ISC_R_FAILURE
;
4313 if (reply
->static_prefixes
> 0) {
4314 if (reply
->host
== NULL
)
4315 log_fatal("Impossible condition at %s:%d.", MDL
);
4317 scope
= &global_scope
;
4319 /* Copy the static prefix for logging and finding the group */
4320 memcpy(&reply
->fixed_pref
, &tmp_pref
, sizeof(tmp_pref
));
4322 /* Try to find a group for the static prefix */
4323 group
= find_group_by_prefix(reply
);
4325 if (reply
->lease
== NULL
)
4326 log_fatal("Impossible condition at %s:%d.", MDL
);
4328 scope
= &reply
->lease
->scope
;
4329 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4333 * If client_resources is nonzero, then the reply_process_is_prefixed
4334 * function has executed configuration state into the reply option
4335 * cache. We will use that valid cache to derive configuration for
4336 * whether or not to engage in additional prefixes, and similar.
4338 if (reply
->client_resources
!= 0) {
4342 * Does this client have "enough" prefixes already? Default
4343 * to one. Everybody gets one, and one should be enough for
4346 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4347 SV_LIMIT_PREFS_PER_IA
);
4349 if (!evaluate_option_cache(&data
, reply
->packet
,
4351 reply
->packet
->options
,
4355 log_error("reply_process_prefix: unable to "
4356 "evaluate prefs-per-ia value.");
4357 status
= ISC_R_FAILURE
;
4361 limit
= getULong(data
.data
);
4362 data_string_forget(&data
, MDL
);
4366 * If we wish to limit the client to a certain number of
4367 * prefixes, then omit the prefix from the reply.
4369 if (reply
->client_resources
>= limit
)
4373 status
= reply_process_is_prefixed(reply
, scope
, group
);
4374 if (status
!= ISC_R_SUCCESS
)
4378 status
= reply_process_send_prefix(reply
, &tmp_pref
);
4381 if (iapref
.data
!= NULL
)
4382 data_string_forget(&iapref
, MDL
);
4383 if (data
.data
!= NULL
)
4384 data_string_forget(&data
, MDL
);
4385 if (reply
->lease
!= NULL
)
4386 iasubopt_dereference(&reply
->lease
, MDL
);
4392 * Verify the prefix belongs to the client. If we've got a host
4393 * record with fixed prefixes, it has to be an assigned prefix
4394 * (fault out all else). Otherwise it's a dynamic prefix, so lookup
4395 * that prefix and make sure it belongs to this DUID:IAID pair.
4397 static isc_boolean_t
4398 prefix_is_owned(struct reply_state
*reply
, struct iaddrcidrnet
*pref
) {
4399 struct iaddrcidrnetlist
*l
;
4401 struct ipv6_pond
*pond
;
4404 * This faults out prefixes that don't match fixed prefixes.
4406 if (reply
->static_prefixes
> 0) {
4407 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4408 if ((pref
->bits
== l
->cidrnet
.bits
) &&
4409 (memcmp(pref
->lo_addr
.iabuf
,
4410 l
->cidrnet
.lo_addr
.iabuf
, 16) == 0))
4416 if ((reply
->old_ia
== NULL
) ||
4417 (reply
->old_ia
->num_iasubopt
== 0))
4420 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4421 struct iasubopt
*tmp
;
4423 tmp
= reply
->old_ia
->iasubopt
[i
];
4425 if ((pref
->bits
== (int) tmp
->plen
) &&
4426 (memcmp(pref
->lo_addr
.iabuf
, &tmp
->addr
, 16) == 0)) {
4427 if (lease6_usable(tmp
) == ISC_FALSE
) {
4431 pond
= tmp
->ipv6_pool
->ipv6_pond
;
4432 if (((pond
->prohibit_list
!= NULL
) &&
4433 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4434 ((pond
->permit_list
!= NULL
) &&
4435 (!permitted(reply
->packet
, pond
->permit_list
))))
4438 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
4447 * This function only returns failure on 'hard' failures. If it succeeds,
4448 * it will leave a prefix structure behind.
4451 reply_process_try_prefix(struct reply_state
*reply
,
4452 struct iaddrcidrnet
*pref
) {
4453 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
4454 struct ipv6_pool
*pool
= NULL
;
4455 struct ipv6_pond
*pond
= NULL
;
4457 struct data_string data_pref
;
4459 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
4460 (pref
== NULL
) || (reply
->lease
!= NULL
))
4461 return (DHCP_R_INVALIDARG
);
4464 * Do a quick walk through of the ponds and pools
4465 * to see if we have any prefix pools
4467 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4468 if (pond
->ipv6_pools
== NULL
)
4471 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4472 if (pool
->pool_type
== D6O_IA_PD
)
4479 /* If we get here and p is NULL we have no useful pools */
4481 return (ISC_R_ADDRNOTAVAIL
);
4484 memset(&data_pref
, 0, sizeof(data_pref
));
4486 if (!buffer_allocate(&data_pref
.buffer
, data_pref
.len
, MDL
)) {
4487 log_error("reply_process_try_prefix: out of memory.");
4488 return (ISC_R_NOMEMORY
);
4490 data_pref
.data
= data_pref
.buffer
->data
;
4491 data_pref
.buffer
->data
[0] = (u_int8_t
) pref
->bits
;
4492 memcpy(data_pref
.buffer
->data
+ 1, pref
->lo_addr
.iabuf
, 16);
4495 * We have at least one pool that could provide a prefix
4496 * Now we walk through the ponds and pools again and check
4497 * to see if the client is permitted and if an prefix is
4502 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4503 if (((pond
->prohibit_list
!= NULL
) &&
4504 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4505 ((pond
->permit_list
!= NULL
) &&
4506 (!permitted(reply
->packet
, pond
->permit_list
))))
4509 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4510 if (pool
->pool_type
!= D6O_IA_PD
) {
4514 status
= try_client_v6_prefix(&reply
->lease
, pool
,
4516 /* If we found it in this pool (either in use or available),
4517 there is no need to look further. */
4518 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4521 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4525 data_string_forget(&data_pref
, MDL
);
4526 /* Return just the most recent status... */
4530 /* Look around for a prefix to give the client. First, look through the old
4531 * IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
4532 * Finally, actually add that prefix into the current reply IA_PD.
4535 find_client_prefix(struct reply_state
*reply
) {
4536 struct iaddrcidrnet send_pref
;
4537 isc_result_t status
= ISC_R_NORESOURCES
;
4538 struct iasubopt
*prefix
, *best_prefix
= NULL
;
4539 struct binding_scope
**scope
;
4541 struct group
*group
;
4543 if (reply
->static_prefixes
> 0) {
4544 struct iaddrcidrnetlist
*l
;
4546 if (reply
->host
== NULL
)
4547 return DHCP_R_INVALIDARG
;
4549 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4550 if (l
->cidrnet
.bits
== reply
->preflen
)
4555 * If no fixed prefix has the preferred length,
4556 * get the first one.
4558 l
= reply
->host
->fixed_prefix
;
4560 memcpy(&send_pref
, &l
->cidrnet
, sizeof(send_pref
));
4562 scope
= &global_scope
;
4564 /* Copy the prefix for logging purposes */
4565 memcpy(&reply
->fixed_pref
, &l
->cidrnet
, sizeof(send_pref
));
4567 /* Try to find a group for the static prefix */
4568 group
= find_group_by_prefix(reply
);
4573 if (reply
->old_ia
!= NULL
) {
4574 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4575 struct shared_network
*candidate_shared
;
4576 struct ipv6_pond
*pond
;
4578 prefix
= reply
->old_ia
->iasubopt
[i
];
4579 candidate_shared
= prefix
->ipv6_pool
->shared_network
;
4580 pond
= prefix
->ipv6_pool
->ipv6_pond
;
4583 * Consider this prefix if it is in a global pool or
4584 * if it is scoped in a pool under the client's shared
4587 if (((candidate_shared
!= NULL
) &&
4588 (candidate_shared
!= reply
->shared
)) ||
4589 (lease6_usable(prefix
) != ISC_TRUE
))
4593 * And check if the prefix is still permitted
4596 if (((pond
->prohibit_list
!= NULL
) &&
4597 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4598 ((pond
->permit_list
!= NULL
) &&
4599 (!permitted(reply
->packet
, pond
->permit_list
))))
4602 best_prefix
= prefix_compare(reply
, prefix
,
4607 /* Try to pick a new prefix if we didn't find one, or if we found an
4610 if ((best_prefix
== NULL
) || (best_prefix
->state
== FTS_ABANDONED
)) {
4611 status
= pick_v6_prefix(reply
);
4612 } else if (best_prefix
!= NULL
) {
4613 iasubopt_reference(&reply
->lease
, best_prefix
, MDL
);
4614 status
= ISC_R_SUCCESS
;
4617 /* Pick the abandoned prefix as a last resort. */
4618 if ((status
== ISC_R_NORESOURCES
) && (best_prefix
!= NULL
)) {
4619 /* I don't see how this is supposed to be done right now. */
4620 log_error("Reclaiming abandoned prefixes is not yet "
4621 "supported. Treating this as an out of space "
4623 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
4626 /* Give up now if we didn't find a prefix. */
4627 if (status
!= ISC_R_SUCCESS
)
4630 if (reply
->lease
== NULL
)
4631 log_fatal("Impossible condition at %s:%d.", MDL
);
4633 scope
= &reply
->lease
->scope
;
4634 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4636 send_pref
.lo_addr
.len
= 16;
4637 memcpy(send_pref
.lo_addr
.iabuf
, &reply
->lease
->addr
, 16);
4638 send_pref
.bits
= (int) reply
->lease
->plen
;
4641 status
= reply_process_is_prefixed(reply
, scope
, group
);
4642 if (status
!= ISC_R_SUCCESS
)
4645 status
= reply_process_send_prefix(reply
, &send_pref
);
4649 /* Once a prefix is found for a client, perform several common functions;
4650 * Calculate and store valid and preferred prefix times, draw client options
4651 * into the option state.
4654 reply_process_is_prefixed(struct reply_state
*reply
,
4655 struct binding_scope
**scope
, struct group
*group
)
4657 isc_result_t status
= ISC_R_SUCCESS
;
4658 struct data_string data
;
4659 struct option_cache
*oc
;
4660 struct option_state
*tmp_options
= NULL
;
4661 struct on_star
*on_star
;
4664 /* Initialize values we will cleanup. */
4665 memset(&data
, 0, sizeof(data
));
4668 * Find the proper on_star block to use. We use the
4669 * one in the lease if we have a lease or the one in
4670 * the reply if we don't have a lease because this is
4674 on_star
= &reply
->lease
->on_star
;
4676 on_star
= &reply
->on_star
;
4680 * Bring in the root configuration. We only do this to bring
4681 * in the on * statements, as we didn't have the lease available
4682 * we we did it the first time.
4684 option_state_allocate(&tmp_options
, MDL
);
4685 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4686 reply
->packet
->options
, tmp_options
,
4687 &global_scope
, root_group
, NULL
,
4689 if (tmp_options
!= NULL
) {
4690 option_state_dereference(&tmp_options
, MDL
);
4694 * Bring configured options into the root packet level cache - start
4695 * with the lease's closest enclosing group (passed in by the caller
4698 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4699 reply
->packet
->options
, reply
->opt_state
,
4700 scope
, group
, root_group
, on_star
);
4702 /* Execute statements from class scopes. */
4703 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
4704 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4705 reply
->packet
->options
,
4706 reply
->opt_state
, scope
,
4707 reply
->packet
->classes
[i
- 1]->group
,
4712 * If there is a host record, over-ride with values configured there,
4713 * without re-evaluating configuration from the previously executed
4714 * group or its common enclosers.
4716 if (reply
->host
!= NULL
)
4717 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4718 reply
->packet
->options
,
4719 reply
->opt_state
, scope
,
4720 reply
->host
->group
, group
,
4723 /* Determine valid lifetime. */
4724 if (reply
->client_valid
== 0)
4725 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
4727 reply
->send_valid
= reply
->client_valid
;
4729 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4730 SV_DEFAULT_LEASE_TIME
);
4732 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4733 reply
->packet
->options
,
4737 log_error("reply_process_is_prefixed: unable to "
4738 "evaluate default prefix time");
4739 status
= ISC_R_FAILURE
;
4743 reply
->send_valid
= getULong(data
.data
);
4744 data_string_forget(&data
, MDL
);
4747 /* Check to see if the lease time would cause us to wrap
4748 * in which case we make it infinite.
4749 * The following doesn't work on at least some systems:
4750 * (cur_time + reply->send_valid < cur_time)
4752 if (reply
->send_valid
!= 0xFFFFFFFF) {
4753 time_t test_time
= cur_time
+ reply
->send_valid
;
4754 if (test_time
< cur_time
)
4755 reply
->send_valid
= 0xFFFFFFFF;
4758 if (reply
->client_prefer
== 0)
4759 reply
->send_prefer
= reply
->send_valid
;
4761 reply
->send_prefer
= reply
->client_prefer
;
4763 if ((reply
->send_prefer
>= reply
->send_valid
) &&
4764 (reply
->send_valid
!= 0xFFFFFFFF))
4765 reply
->send_prefer
= (reply
->send_valid
/ 2) +
4766 (reply
->send_valid
/ 8);
4768 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4769 SV_PREFER_LIFETIME
);
4771 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4772 reply
->packet
->options
,
4776 log_error("reply_process_is_prefixed: unable to "
4777 "evaluate preferred prefix time");
4778 status
= ISC_R_FAILURE
;
4782 reply
->send_prefer
= getULong(data
.data
);
4783 data_string_forget(&data
, MDL
);
4786 /* Note lowest values for later calculation of renew/rebind times. */
4787 if (reply
->prefer
> reply
->send_prefer
)
4788 reply
->prefer
= reply
->send_prefer
;
4790 if (reply
->valid
> reply
->send_valid
)
4791 reply
->valid
= reply
->send_valid
;
4793 /* Perform dynamic prefix related update work. */
4794 if (reply
->lease
!= NULL
) {
4795 /* Cached lifetimes */
4796 reply
->lease
->prefer
= reply
->send_prefer
;
4797 reply
->lease
->valid
= reply
->send_valid
;
4799 /* Advance (or rewind) the valid lifetime.
4800 * In the protocol 0xFFFFFFFF is infinite
4801 * when connecting to the lease file MAX_TIME is
4803 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
4804 if (reply
->send_valid
== 0xFFFFFFFF) {
4805 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
4807 reply
->lease
->soft_lifetime_end_time
=
4808 cur_time
+ reply
->send_valid
;
4810 /* Wait before renew! */
4813 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
4814 if (status
!= ISC_R_SUCCESS
) {
4815 log_fatal("reply_process_is_prefixed: Unable to "
4816 "attach prefix to new IA_PD: %s",
4817 isc_result_totext(status
));
4821 * If this is a new prefix, make sure it is attached somewhere.
4823 if (reply
->lease
->ia
== NULL
) {
4824 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
4828 /* Bring a copy of the relevant options into the IA_PD scope. */
4829 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4830 reply
->packet
->options
, reply
->reply_ia
,
4831 scope
, group
, root_group
, NULL
);
4833 /* Execute statements from class scopes. */
4834 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
4835 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4836 reply
->packet
->options
,
4837 reply
->reply_ia
, scope
,
4838 reply
->packet
->classes
[i
- 1]->group
,
4843 * And bring in host record configuration, if any, but not to overlap
4844 * the previous group or its common enclosers.
4846 if (reply
->host
!= NULL
)
4847 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4848 reply
->packet
->options
,
4849 reply
->reply_ia
, scope
,
4850 reply
->host
->group
, group
, NULL
);
4853 if (data
.data
!= NULL
)
4854 data_string_forget(&data
, MDL
);
4856 if (status
== ISC_R_SUCCESS
)
4857 reply
->client_resources
++;
4862 /* Simply send an IAPREFIX within the IA_PD scope as described. */
4864 reply_process_send_prefix(struct reply_state
*reply
,
4865 struct iaddrcidrnet
*pref
) {
4866 isc_result_t status
= ISC_R_SUCCESS
;
4867 struct data_string data
;
4869 memset(&data
, 0, sizeof(data
));
4871 /* Now append the prefix. */
4872 data
.len
= IAPREFIX_OFFSET
;
4873 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
4874 log_error("reply_process_send_prefix: out of memory"
4875 "allocating new IAPREFIX buffer.");
4876 status
= ISC_R_NOMEMORY
;
4879 data
.data
= data
.buffer
->data
;
4881 putULong(data
.buffer
->data
, reply
->send_prefer
);
4882 putULong(data
.buffer
->data
+ 4, reply
->send_valid
);
4883 data
.buffer
->data
[8] = pref
->bits
;
4884 memcpy(data
.buffer
->data
+ 9, pref
->lo_addr
.iabuf
, 16);
4886 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
4887 data
.buffer
, data
.buffer
->data
,
4888 data
.len
, D6O_IAPREFIX
, 0)) {
4889 log_error("reply_process_send_prefix: unable "
4890 "to save IAPREFIX option");
4891 status
= ISC_R_FAILURE
;
4895 reply
->resources_included
= ISC_TRUE
;
4898 if (data
.data
!= NULL
)
4899 data_string_forget(&data
, MDL
);
4904 /* Choose the better of two prefixes. */
4905 static struct iasubopt
*
4906 prefix_compare(struct reply_state
*reply
,
4907 struct iasubopt
*alpha
, struct iasubopt
*beta
) {
4913 if (reply
->preflen
>= 0) {
4914 if ((alpha
->plen
== reply
->preflen
) &&
4915 (beta
->plen
!= reply
->preflen
))
4917 if ((beta
->plen
== reply
->preflen
) &&
4918 (alpha
->plen
!= reply
->preflen
))
4922 switch(alpha
->state
) {
4924 switch(beta
->state
) {
4926 /* Choose the prefix with the longest lifetime (most
4927 * likely the most recently allocated).
4929 if (alpha
->hard_lifetime_end_time
<
4930 beta
->hard_lifetime_end_time
)
4940 log_fatal("Impossible condition at %s:%d.", MDL
);
4945 switch (beta
->state
) {
4950 /* Choose the most recently expired prefix. */
4951 if (alpha
->hard_lifetime_end_time
<
4952 beta
->hard_lifetime_end_time
)
4954 else if ((alpha
->hard_lifetime_end_time
==
4955 beta
->hard_lifetime_end_time
) &&
4956 (alpha
->soft_lifetime_end_time
<
4957 beta
->soft_lifetime_end_time
))
4966 log_fatal("Impossible condition at %s:%d.", MDL
);
4971 switch (beta
->state
) {
4977 /* Choose the prefix that was abandoned longest ago. */
4978 if (alpha
->hard_lifetime_end_time
<
4979 beta
->hard_lifetime_end_time
)
4985 log_fatal("Impossible condition at %s:%d.", MDL
);
4990 log_fatal("Impossible condition at %s:%d.", MDL
);
4993 log_fatal("Triple impossible condition at %s:%d.", MDL
);
4998 * Solicit is how a client starts requesting addresses.
5000 * If the client asks for rapid commit, and we support it, we will
5001 * allocate the addresses and reply.
5003 * Otherwise we will send an advertise message.
5007 dhcpv6_solicit(struct data_string
*reply_ret
, struct packet
*packet
) {
5008 struct data_string client_id
;
5011 * Validate our input.
5013 if (!valid_client_msg(packet
, &client_id
)) {
5017 lease_to_client(reply_ret
, packet
, &client_id
, NULL
);
5022 data_string_forget(&client_id
, MDL
);
5026 * Request is how a client actually requests addresses.
5028 * Very similar to Solicit handling, except the server DUID is required.
5032 dhcpv6_request(struct data_string
*reply_ret
, struct packet
*packet
) {
5033 struct data_string client_id
;
5034 struct data_string server_id
;
5037 * Validate our input.
5039 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5043 /* If the REQUEST arrived via unicast and unicast option isn't set,
5044 * reject it per RFC 3315, Sec 18.2.1 */
5045 if (packet
->unicast
== ISC_TRUE
&&
5046 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5047 unicast_reject(reply_ret
, packet
, &client_id
, &server_id
);
5052 lease_to_client(reply_ret
, packet
, &client_id
, &server_id
);
5058 data_string_forget(&client_id
, MDL
);
5059 data_string_forget(&server_id
, MDL
);
5062 /* Find a DHCPv6 packet's shared network from hints in the packet.
5065 shared_network_from_packet6(struct shared_network
**shared
,
5066 struct packet
*packet
)
5068 const struct packet
*chk_packet
;
5069 const struct in6_addr
*link_addr
, *first_link_addr
;
5070 struct iaddr tmp_addr
;
5071 struct subnet
*subnet
;
5072 isc_result_t status
;
5074 if ((shared
== NULL
) || (*shared
!= NULL
) || (packet
== NULL
))
5075 return DHCP_R_INVALIDARG
;
5078 * First, find the link address where the packet from the client
5079 * first appeared (if this packet was relayed).
5081 first_link_addr
= NULL
;
5082 chk_packet
= packet
->dhcpv6_container_packet
;
5083 while (chk_packet
!= NULL
) {
5084 link_addr
= &chk_packet
->dhcpv6_link_address
;
5085 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
5086 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
5087 first_link_addr
= link_addr
;
5090 chk_packet
= chk_packet
->dhcpv6_container_packet
;
5094 * If there is a relayed link address, find the subnet associated
5095 * with that, and use that to get the appropriate
5098 if (first_link_addr
!= NULL
) {
5099 tmp_addr
.len
= sizeof(*first_link_addr
);
5100 memcpy(tmp_addr
.iabuf
,
5101 first_link_addr
, sizeof(*first_link_addr
));
5103 if (!find_subnet(&subnet
, tmp_addr
, MDL
)) {
5104 log_debug("No subnet found for link-address %s.",
5106 return ISC_R_NOTFOUND
;
5108 status
= shared_network_reference(shared
,
5109 subnet
->shared_network
, MDL
);
5110 subnet_dereference(&subnet
, MDL
);
5113 * If there is no link address, we will use the interface
5114 * that this packet came in on to pick the shared_network.
5116 } else if (packet
->interface
!= NULL
) {
5117 status
= shared_network_reference(shared
,
5118 packet
->interface
->shared_network
,
5120 if (packet
->dhcpv6_container_packet
!= NULL
) {
5121 log_info("[L2 Relay] No link address in relay packet "
5122 "assuming L2 relay and using receiving "
5128 * We shouldn't be able to get here but if there is no link
5129 * address and no interface we don't know where to get the
5130 * pool from log an error and return an error.
5132 log_error("No interface and no link address "
5133 "can't determine pool");
5134 status
= DHCP_R_INVALIDARG
;
5141 * When a client thinks it might be on a new link, it sends a
5144 * From RFC3315 section 18.2.2:
5146 * When the server receives a Confirm message, the server determines
5147 * whether the addresses in the Confirm message are appropriate for the
5148 * link to which the client is attached. If all of the addresses in the
5149 * Confirm message pass this test, the server returns a status of
5150 * Success. If any of the addresses do not pass this test, the server
5151 * returns a status of NotOnLink. If the server is unable to perform
5152 * this test (for example, the server does not have information about
5153 * prefixes on the link to which the client is connected), or there were
5154 * no addresses in any of the IAs sent by the client, the server MUST
5155 * NOT send a reply to the client.
5159 dhcpv6_confirm(struct data_string
*reply_ret
, struct packet
*packet
) {
5160 struct shared_network
*shared
;
5161 struct subnet
*subnet
;
5162 struct option_cache
*ia
, *ta
, *oc
;
5163 struct data_string cli_enc_opt_data
, iaaddr
, client_id
, packet_oro
;
5164 struct option_state
*cli_enc_opt_state
, *opt_state
;
5165 struct iaddr cli_addr
;
5167 isc_boolean_t inappropriate
, has_addrs
;
5168 char reply_data
[65536];
5169 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5170 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5173 * Basic client message validation.
5175 memset(&client_id
, 0, sizeof(client_id
));
5176 if (!valid_client_msg(packet
, &client_id
)) {
5181 * Do not process Confirms that do not have IA's we do not recognize.
5183 ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5184 ta
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
5185 if ((ia
== NULL
) && (ta
== NULL
))
5189 * IA_PD's are simply ignored.
5191 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5194 * Bit of variable initialization.
5196 opt_state
= cli_enc_opt_state
= NULL
;
5197 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5198 memset(&iaaddr
, 0, sizeof(iaaddr
));
5199 memset(&packet_oro
, 0, sizeof(packet_oro
));
5201 /* Determine what shared network the client is connected to. We
5202 * must not respond if we don't have any information about the
5203 * network the client is on.
5206 if ((shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
) ||
5210 /* If there are no recorded subnets, then we have no
5211 * information about this subnet - ignore Confirms.
5213 subnet
= shared
->subnets
;
5217 /* Are the addresses in all the IA's appropriate for that link? */
5218 has_addrs
= inappropriate
= ISC_FALSE
;
5220 while(!inappropriate
) {
5221 /* If we've reached the end of the IA_NA pass, move to the
5224 if ((pass
== D6O_IA_NA
) && (ia
== NULL
)) {
5229 /* If we've reached the end of all passes, we're done. */
5233 if (((pass
== D6O_IA_NA
) &&
5234 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5236 packet
, ia
, IA_NA_OFFSET
)) ||
5237 ((pass
== D6O_IA_TA
) &&
5238 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5240 packet
, ia
, IA_TA_OFFSET
))) {
5244 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5247 for ( ; oc
!= NULL
; oc
= oc
->next
) {
5248 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5249 packet
->options
, NULL
,
5250 &global_scope
, oc
, MDL
) ||
5251 (iaaddr
.len
< IAADDR_OFFSET
)) {
5252 log_error("dhcpv6_confirm: "
5253 "error evaluating IAADDR.");
5257 /* Copy out the IPv6 address for processing. */
5259 memcpy(cli_addr
.iabuf
, iaaddr
.data
, 16);
5261 data_string_forget(&iaaddr
, MDL
);
5263 /* Record that we've processed at least one address. */
5264 has_addrs
= ISC_TRUE
;
5266 /* Find out if any subnets cover this address. */
5267 for (subnet
= shared
->subnets
; subnet
!= NULL
;
5268 subnet
= subnet
->next_sibling
) {
5269 if (addr_eq(subnet_number(cli_addr
,
5275 /* If we reach the end of the subnet list, and no
5276 * subnet matches the client address, then it must
5277 * be inappropriate to the link (so far as our
5278 * configuration says). Once we've found one
5279 * inappropriate address, there is no reason to
5280 * continue searching.
5282 if (subnet
== NULL
) {
5283 inappropriate
= ISC_TRUE
;
5288 option_state_dereference(&cli_enc_opt_state
, MDL
);
5289 data_string_forget(&cli_enc_opt_data
, MDL
);
5291 /* Advance to the next IA_*. */
5295 /* If the client supplied no addresses, do not reply. */
5302 if (!start_reply(packet
, &client_id
, NULL
, &opt_state
, reply
)) {
5309 if (inappropriate
) {
5310 if (!set_status_code(STATUS_NotOnLink
,
5311 "Some of the addresses are not on link.",
5316 if (!set_status_code(STATUS_Success
,
5317 "All addresses still on link.",
5324 * Only one option: add it.
5326 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5327 sizeof(reply_data
)-reply_ofs
,
5329 required_opts
, &packet_oro
);
5332 * Return our reply to the caller.
5334 reply_ret
->len
= reply_ofs
;
5335 reply_ret
->buffer
= NULL
;
5336 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5337 log_fatal("No memory to store reply.");
5339 reply_ret
->data
= reply_ret
->buffer
->data
;
5340 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5343 /* Cleanup any stale data strings. */
5344 if (cli_enc_opt_data
.buffer
!= NULL
)
5345 data_string_forget(&cli_enc_opt_data
, MDL
);
5346 if (iaaddr
.buffer
!= NULL
)
5347 data_string_forget(&iaaddr
, MDL
);
5348 if (client_id
.buffer
!= NULL
)
5349 data_string_forget(&client_id
, MDL
);
5350 if (packet_oro
.buffer
!= NULL
)
5351 data_string_forget(&packet_oro
, MDL
);
5353 /* Release any stale option states. */
5354 if (cli_enc_opt_state
!= NULL
)
5355 option_state_dereference(&cli_enc_opt_state
, MDL
);
5356 if (opt_state
!= NULL
)
5357 option_state_dereference(&opt_state
, MDL
);
5361 * Renew is when a client wants to extend its lease/prefix, at time T1.
5363 * We handle this the same as if the client wants a new lease/prefix,
5364 * except for the error code of when addresses don't match.
5368 dhcpv6_renew(struct data_string
*reply
, struct packet
*packet
) {
5369 struct data_string client_id
;
5370 struct data_string server_id
;
5373 * Validate the request.
5375 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5379 /* If the RENEW arrived via unicast and unicast option isn't set,
5380 * reject it per RFC 3315, Sec 18.2.3 */
5381 if (packet
->unicast
== ISC_TRUE
&&
5382 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5383 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5388 lease_to_client(reply
, packet
, &client_id
, &server_id
);
5394 data_string_forget(&server_id
, MDL
);
5395 data_string_forget(&client_id
, MDL
);
5399 * Rebind is when a client wants to extend its lease, at time T2.
5401 * We handle this the same as if the client wants a new lease, except
5402 * for the error code of when addresses don't match.
5406 dhcpv6_rebind(struct data_string
*reply
, struct packet
*packet
) {
5407 struct data_string client_id
;
5409 if (!valid_client_msg(packet
, &client_id
)) {
5413 lease_to_client(reply
, packet
, &client_id
, NULL
);
5415 data_string_forget(&client_id
, MDL
);
5419 ia_na_match_decline(const struct data_string
*client_id
,
5420 const struct data_string
*iaaddr
,
5421 struct iasubopt
*lease
)
5423 char tmp_addr
[INET6_ADDRSTRLEN
];
5425 log_error("Client %s reports address %s is "
5426 "already in use by another host!",
5427 print_hex_1(client_id
->len
, client_id
->data
, 60),
5428 inet_ntop(AF_INET6
, iaaddr
->data
,
5429 tmp_addr
, sizeof(tmp_addr
)));
5430 if (lease
!= NULL
) {
5431 decline_lease6(lease
->ipv6_pool
, lease
);
5432 lease
->ia
->cltt
= cur_time
;
5433 write_ia(lease
->ia
);
5438 ia_na_nomatch_decline(const struct data_string
*client_id
,
5439 const struct data_string
*iaaddr
,
5440 u_int32_t
*ia_na_id
,
5441 struct packet
*packet
,
5446 char tmp_addr
[INET6_ADDRSTRLEN
];
5447 struct option_state
*host_opt_state
;
5450 log_info("Client %s declines address %s, which is not offered to it.",
5451 print_hex_1(client_id
->len
, client_id
->data
, 60),
5452 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5455 * Create state for this IA_NA.
5457 host_opt_state
= NULL
;
5458 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5459 log_error("ia_na_nomatch_decline: out of memory "
5460 "allocating option_state.");
5464 if (!set_status_code(STATUS_NoBinding
, "Decline for unknown address.",
5470 * Insure we have enough space
5472 if (reply_len
< (*reply_ofs
+ 16)) {
5473 log_error("ia_na_nomatch_decline: "
5474 "out of space for reply packet.");
5479 * Put our status code into the reply packet.
5481 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5482 reply_len
-(*reply_ofs
)-16,
5483 host_opt_state
, packet
,
5484 required_opts_STATUS_CODE
, NULL
);
5487 * Store the non-encapsulated option data for this
5488 * IA_NA into our reply packet. Defined in RFC 3315,
5492 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5494 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5495 /* IA_NA, copied from the client */
5496 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5497 /* t1 and t2, odd that we need them, but here it is */
5498 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5499 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5502 * Get ready for next IA_NA.
5504 *reply_ofs
+= (len
+ 16);
5507 option_state_dereference(&host_opt_state
, MDL
);
5511 iterate_over_ia_na(struct data_string
*reply_ret
,
5512 struct packet
*packet
,
5513 const struct data_string
*client_id
,
5514 const struct data_string
*server_id
,
5515 const char *packet_type
,
5516 void (*ia_na_match
)(),
5517 void (*ia_na_nomatch
)())
5519 struct option_state
*opt_state
;
5520 struct host_decl
*packet_host
;
5521 struct option_cache
*ia
;
5522 struct option_cache
*oc
;
5523 /* cli_enc_... variables come from the IA_NA/IA_TA options */
5524 struct data_string cli_enc_opt_data
;
5525 struct option_state
*cli_enc_opt_state
;
5526 struct host_decl
*host
;
5527 struct option_state
*host_opt_state
;
5528 struct data_string iaaddr
;
5529 struct data_string fixed_addr
;
5530 char reply_data
[65536];
5531 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5532 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5533 char status_msg
[32];
5534 struct iasubopt
*lease
;
5535 struct ia_xx
*existing_ia_na
;
5537 struct data_string key
;
5541 * Initialize to empty values, in case we have to exit early.
5544 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5545 cli_enc_opt_state
= NULL
;
5546 memset(&iaaddr
, 0, sizeof(iaaddr
));
5547 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
5548 host_opt_state
= NULL
;
5552 * Find the host record that matches from the packet, if any.
5555 if (!find_hosts_by_uid(&packet_host
,
5556 client_id
->data
, client_id
->len
, MDL
)) {
5559 * Note: In general, we don't expect a client to provide
5560 * enough information to match by option for these
5561 * types of messages, but if we don't have a UID
5562 * match we can check anyway.
5564 if (!find_hosts_by_option(&packet_host
,
5565 packet
, packet
->options
, MDL
)) {
5568 if (!find_hosts_by_duid_chaddr(&packet_host
,
5575 * Set our reply information.
5577 reply
->msg_type
= DHCPV6_REPLY
;
5578 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
5579 sizeof(reply
->transaction_id
));
5582 * Build our option state for reply.
5585 if (!option_state_allocate(&opt_state
, MDL
)) {
5586 log_error("iterate_over_ia_na: no memory for option_state.");
5589 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5590 packet
->options
, opt_state
,
5591 &global_scope
, root_group
, NULL
, NULL
);
5594 * RFC 3315, section 18.2.7 tells us which options to include.
5596 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
5598 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5599 (unsigned char *)server_duid
.data
,
5600 server_duid
.len
, D6O_SERVERID
, 0)) {
5601 log_error("iterate_over_ia_na: "
5602 "error saving server identifier.");
5607 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
5609 (unsigned char *)client_id
->data
,
5612 log_error("iterate_over_ia_na: "
5613 "error saving client identifier.");
5617 snprintf(status_msg
, sizeof(status_msg
), "%s received.", packet_type
);
5618 if (!set_status_code(STATUS_Success
, status_msg
, opt_state
)) {
5623 * Add our options that are not associated with any IA_NA or IA_TA.
5625 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5626 sizeof(reply_data
)-reply_ofs
,
5628 required_opts
, NULL
);
5631 * Loop through the IA_NA reported by the client, and deal with
5632 * addresses reported as already in use.
5634 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5635 ia
!= NULL
; ia
= ia
->next
) {
5637 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
5639 packet
, ia
, IA_NA_OFFSET
)) {
5643 iaid
= getULong(cli_enc_opt_data
.data
);
5646 * XXX: It is possible that we can get multiple addresses
5647 * sent by the client. We don't send multiple
5648 * addresses, so this indicates a client error.
5649 * We should check for multiple IAADDR options, log
5650 * if found, and set as an error.
5652 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5655 /* no address given for this IA, ignore */
5656 option_state_dereference(&cli_enc_opt_state
, MDL
);
5657 data_string_forget(&cli_enc_opt_data
, MDL
);
5661 memset(&iaaddr
, 0, sizeof(iaaddr
));
5662 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5663 packet
->options
, NULL
,
5664 &global_scope
, oc
, MDL
)) {
5665 log_error("iterate_over_ia_na: "
5666 "error evaluating IAADDR.");
5671 * Now we need to figure out which host record matches
5672 * this IA_NA and IAADDR (encapsulated option contents
5673 * matching a host record by option).
5675 * XXX: We don't currently track IA_NA separately, but
5676 * we will need to do this!
5679 if (!find_hosts_by_option(&host
, packet
,
5680 cli_enc_opt_state
, MDL
)) {
5681 if (packet_host
!= NULL
) {
5687 while (host
!= NULL
) {
5688 if (host
->fixed_addr
!= NULL
) {
5689 if (!evaluate_option_cache(&fixed_addr
, NULL
,
5691 NULL
, &global_scope
,
5694 log_error("iterate_over_ia_na: error "
5695 "evaluating host address.");
5698 if ((iaaddr
.len
>= 16) &&
5699 !memcmp(fixed_addr
.data
, iaaddr
.data
, 16)) {
5700 data_string_forget(&fixed_addr
, MDL
);
5703 data_string_forget(&fixed_addr
, MDL
);
5705 host
= host
->n_ipaddr
;
5708 if ((host
== NULL
) && (iaaddr
.len
>= IAADDR_OFFSET
)) {
5710 * Find existing IA_NA.
5712 if (ia_make_key(&key
, iaid
,
5713 (char *)client_id
->data
,
5715 MDL
) != ISC_R_SUCCESS
) {
5716 log_fatal("iterate_over_ia_na: no memory for "
5720 existing_ia_na
= NULL
;
5721 if (ia_hash_lookup(&existing_ia_na
, ia_na_active
,
5722 (unsigned char *)key
.data
,
5725 * Make sure this address is in the IA_NA.
5727 for (i
=0; i
<existing_ia_na
->num_iasubopt
; i
++) {
5728 struct iasubopt
*tmp
;
5729 struct in6_addr
*in6_addr
;
5731 tmp
= existing_ia_na
->iasubopt
[i
];
5732 in6_addr
= &tmp
->addr
;
5733 if (memcmp(in6_addr
,
5734 iaaddr
.data
, 16) == 0) {
5735 iasubopt_reference(&lease
,
5742 data_string_forget(&key
, MDL
);
5745 if ((host
!= NULL
) || (lease
!= NULL
)) {
5746 ia_na_match(client_id
, &iaaddr
, lease
);
5748 ia_na_nomatch(client_id
, &iaaddr
,
5749 (u_int32_t
*)cli_enc_opt_data
.data
,
5750 packet
, reply_data
, &reply_ofs
,
5751 sizeof(reply_data
));
5754 if (lease
!= NULL
) {
5755 iasubopt_dereference(&lease
, MDL
);
5758 data_string_forget(&iaaddr
, MDL
);
5759 option_state_dereference(&cli_enc_opt_state
, MDL
);
5760 data_string_forget(&cli_enc_opt_data
, MDL
);
5764 * Return our reply to the caller.
5766 reply_ret
->len
= reply_ofs
;
5767 reply_ret
->buffer
= NULL
;
5768 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5769 log_fatal("No memory to store reply.");
5771 reply_ret
->data
= reply_ret
->buffer
->data
;
5772 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5775 if (lease
!= NULL
) {
5776 iasubopt_dereference(&lease
, MDL
);
5778 if (host_opt_state
!= NULL
) {
5779 option_state_dereference(&host_opt_state
, MDL
);
5781 if (fixed_addr
.buffer
!= NULL
) {
5782 data_string_forget(&fixed_addr
, MDL
);
5784 if (iaaddr
.buffer
!= NULL
) {
5785 data_string_forget(&iaaddr
, MDL
);
5787 if (cli_enc_opt_state
!= NULL
) {
5788 option_state_dereference(&cli_enc_opt_state
, MDL
);
5790 if (cli_enc_opt_data
.buffer
!= NULL
) {
5791 data_string_forget(&cli_enc_opt_data
, MDL
);
5793 if (opt_state
!= NULL
) {
5794 option_state_dereference(&opt_state
, MDL
);
5799 * Decline means a client has detected that something else is using an
5800 * address we gave it.
5802 * Since we're only dealing with fixed leases for now, there's not
5803 * much we can do, other that log the occurrence.
5805 * When we start issuing addresses from pools, then we will have to
5806 * record our declined addresses and issue another. In general with
5807 * IPv6 there is no worry about DoS by clients exhausting space, but
5808 * we still need to be aware of this possibility.
5813 dhcpv6_decline(struct data_string
*reply
, struct packet
*packet
) {
5814 struct data_string client_id
;
5815 struct data_string server_id
;
5818 * Validate our input.
5820 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5824 /* If the DECLINE arrived via unicast and unicast option isn't set,
5825 * reject it per RFC 3315, Sec 18.2.7 */
5826 if (packet
->unicast
== ISC_TRUE
&&
5827 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5828 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5831 * Undefined for IA_PD.
5833 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5836 * And operate on each IA_NA in this packet.
5838 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
5839 "Decline", ia_na_match_decline
,
5840 ia_na_nomatch_decline
);
5844 data_string_forget(&server_id
, MDL
);
5845 data_string_forget(&client_id
, MDL
);
5849 ia_na_match_release(const struct data_string
*client_id
,
5850 const struct data_string
*iaaddr
,
5851 struct iasubopt
*lease
)
5853 char tmp_addr
[INET6_ADDRSTRLEN
];
5855 log_info("Client %s releases address %s",
5856 print_hex_1(client_id
->len
, client_id
->data
, 60),
5857 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5858 if (lease
!= NULL
) {
5859 release_lease6(lease
->ipv6_pool
, lease
);
5860 lease
->ia
->cltt
= cur_time
;
5861 write_ia(lease
->ia
);
5866 ia_na_nomatch_release(const struct data_string
*client_id
,
5867 const struct data_string
*iaaddr
,
5868 u_int32_t
*ia_na_id
,
5869 struct packet
*packet
,
5874 char tmp_addr
[INET6_ADDRSTRLEN
];
5875 struct option_state
*host_opt_state
;
5878 log_info("Client %s releases address %s, which is not leased to it.",
5879 print_hex_1(client_id
->len
, client_id
->data
, 60),
5880 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5883 * Create state for this IA_NA.
5885 host_opt_state
= NULL
;
5886 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5887 log_error("ia_na_nomatch_release: out of memory "
5888 "allocating option_state.");
5892 if (!set_status_code(STATUS_NoBinding
,
5893 "Release for non-leased address.",
5899 * Insure we have enough space
5901 if (reply_len
< (*reply_ofs
+ 16)) {
5902 log_error("ia_na_nomatch_release: "
5903 "out of space for reply packet.");
5908 * Put our status code into the reply packet.
5910 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5911 reply_len
-(*reply_ofs
)-16,
5912 host_opt_state
, packet
,
5913 required_opts_STATUS_CODE
, NULL
);
5916 * Store the non-encapsulated option data for this
5917 * IA_NA into our reply packet. Defined in RFC 3315,
5921 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5923 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5924 /* IA_NA, copied from the client */
5925 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5926 /* t1 and t2, odd that we need them, but here it is */
5927 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5928 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5931 * Get ready for next IA_NA.
5933 *reply_ofs
+= (len
+ 16);
5936 option_state_dereference(&host_opt_state
, MDL
);
5940 ia_pd_match_release(const struct data_string
*client_id
,
5941 const struct data_string
*iapref
,
5942 struct iasubopt
*prefix
)
5944 char tmp_addr
[INET6_ADDRSTRLEN
];
5946 log_info("Client %s releases prefix %s/%u",
5947 print_hex_1(client_id
->len
, client_id
->data
, 60),
5948 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5949 tmp_addr
, sizeof(tmp_addr
)),
5950 (unsigned) getUChar(iapref
->data
+ 8));
5951 if (prefix
!= NULL
) {
5952 release_lease6(prefix
->ipv6_pool
, prefix
);
5953 prefix
->ia
->cltt
= cur_time
;
5954 write_ia(prefix
->ia
);
5959 ia_pd_nomatch_release(const struct data_string
*client_id
,
5960 const struct data_string
*iapref
,
5961 u_int32_t
*ia_pd_id
,
5962 struct packet
*packet
,
5967 char tmp_addr
[INET6_ADDRSTRLEN
];
5968 struct option_state
*host_opt_state
;
5971 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
5972 print_hex_1(client_id
->len
, client_id
->data
, 60),
5973 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5974 tmp_addr
, sizeof(tmp_addr
)),
5975 (unsigned) getUChar(iapref
->data
+ 8));
5978 * Create state for this IA_PD.
5980 host_opt_state
= NULL
;
5981 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5982 log_error("ia_pd_nomatch_release: out of memory "
5983 "allocating option_state.");
5987 if (!set_status_code(STATUS_NoBinding
,
5988 "Release for non-leased prefix.",
5994 * Insure we have enough space
5996 if (reply_len
< (*reply_ofs
+ 16)) {
5997 log_error("ia_pd_nomatch_release: "
5998 "out of space for reply packet.");
6003 * Put our status code into the reply packet.
6005 len
= store_options6(reply_data
+(*reply_ofs
)+16,
6006 reply_len
-(*reply_ofs
)-16,
6007 host_opt_state
, packet
,
6008 required_opts_STATUS_CODE
, NULL
);
6011 * Store the non-encapsulated option data for this
6012 * IA_PD into our reply packet. Defined in RFC 3315,
6016 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_PD
);
6018 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
6019 /* IA_PD, copied from the client */
6020 memcpy(reply_data
+(*reply_ofs
)+4, ia_pd_id
, 4);
6021 /* t1 and t2, odd that we need them, but here it is */
6022 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
6023 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
6026 * Get ready for next IA_PD.
6028 *reply_ofs
+= (len
+ 16);
6031 option_state_dereference(&host_opt_state
, MDL
);
6035 iterate_over_ia_pd(struct data_string
*reply_ret
,
6036 struct packet
*packet
,
6037 const struct data_string
*client_id
,
6038 const struct data_string
*server_id
,
6039 const char *packet_type
,
6040 void (*ia_pd_match
)(),
6041 void (*ia_pd_nomatch
)())
6043 struct data_string reply_new
;
6045 struct option_state
*opt_state
;
6046 struct host_decl
*packet_host
;
6047 struct option_cache
*ia
;
6048 struct option_cache
*oc
;
6049 /* cli_enc_... variables come from the IA_PD options */
6050 struct data_string cli_enc_opt_data
;
6051 struct option_state
*cli_enc_opt_state
;
6052 struct host_decl
*host
;
6053 struct option_state
*host_opt_state
;
6054 struct data_string iaprefix
;
6055 char reply_data
[65536];
6057 struct iasubopt
*prefix
;
6058 struct ia_xx
*existing_ia_pd
;
6060 struct data_string key
;
6064 * Initialize to empty values, in case we have to exit early.
6066 memset(&reply_new
, 0, sizeof(reply_new
));
6068 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
6069 cli_enc_opt_state
= NULL
;
6070 memset(&iaprefix
, 0, sizeof(iaprefix
));
6071 host_opt_state
= NULL
;
6075 * Compute the available length for the reply.
6077 reply_len
= sizeof(reply_data
) - reply_ret
->len
;
6081 * Find the host record that matches from the packet, if any.
6084 if (!find_hosts_by_uid(&packet_host
,
6085 client_id
->data
, client_id
->len
, MDL
)) {
6088 * Note: In general, we don't expect a client to provide
6089 * enough information to match by option for these
6090 * types of messages, but if we don't have a UID
6091 * match we can check anyway.
6093 if (!find_hosts_by_option(&packet_host
,
6094 packet
, packet
->options
, MDL
)) {
6097 if (!find_hosts_by_duid_chaddr(&packet_host
,
6104 * Build our option state for reply.
6107 if (!option_state_allocate(&opt_state
, MDL
)) {
6108 log_error("iterate_over_ia_pd: no memory for option_state.");
6111 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
6112 packet
->options
, opt_state
,
6113 &global_scope
, root_group
, NULL
, NULL
);
6116 * Loop through the IA_PD reported by the client, and deal with
6117 * prefixes reported as already in use.
6119 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
6120 ia
!= NULL
; ia
= ia
->next
) {
6122 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
6124 packet
, ia
, IA_PD_OFFSET
)) {
6128 iaid
= getULong(cli_enc_opt_data
.data
);
6130 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
6133 /* no prefix given for this IA_PD, ignore */
6134 option_state_dereference(&cli_enc_opt_state
, MDL
);
6135 data_string_forget(&cli_enc_opt_data
, MDL
);
6139 for (; oc
!= NULL
; oc
= oc
->next
) {
6140 memset(&iaprefix
, 0, sizeof(iaprefix
));
6141 if (!evaluate_option_cache(&iaprefix
, packet
, NULL
, NULL
,
6142 packet
->options
, NULL
,
6143 &global_scope
, oc
, MDL
)) {
6144 log_error("iterate_over_ia_pd: "
6145 "error evaluating IAPREFIX.");
6150 * Now we need to figure out which host record matches
6151 * this IA_PD and IAPREFIX (encapsulated option contents
6152 * matching a host record by option).
6154 * XXX: We don't currently track IA_PD separately, but
6155 * we will need to do this!
6158 if (!find_hosts_by_option(&host
, packet
,
6159 cli_enc_opt_state
, MDL
)) {
6160 if (packet_host
!= NULL
) {
6166 while (host
!= NULL
) {
6167 if (host
->fixed_prefix
!= NULL
) {
6168 struct iaddrcidrnetlist
*l
;
6169 int plen
= (int) getUChar(iaprefix
.data
+ 8);
6171 for (l
= host
->fixed_prefix
; l
!= NULL
;
6173 if (plen
!= l
->cidrnet
.bits
)
6175 if (memcmp(iaprefix
.data
+ 9,
6176 l
->cidrnet
.lo_addr
.iabuf
,
6180 if ((l
!= NULL
) && (iaprefix
.len
>= 17))
6183 host
= host
->n_ipaddr
;
6186 if ((host
== NULL
) && (iaprefix
.len
>= IAPREFIX_OFFSET
)) {
6188 * Find existing IA_PD.
6190 if (ia_make_key(&key
, iaid
,
6191 (char *)client_id
->data
,
6193 MDL
) != ISC_R_SUCCESS
) {
6194 log_fatal("iterate_over_ia_pd: no memory for "
6198 existing_ia_pd
= NULL
;
6199 if (ia_hash_lookup(&existing_ia_pd
, ia_pd_active
,
6200 (unsigned char *)key
.data
,
6203 * Make sure this prefix is in the IA_PD.
6206 i
< existing_ia_pd
->num_iasubopt
;
6208 struct iasubopt
*tmp
;
6211 plen
= getUChar(iaprefix
.data
+ 8);
6212 tmp
= existing_ia_pd
->iasubopt
[i
];
6213 if ((tmp
->plen
== plen
) &&
6217 iasubopt_reference(&prefix
,
6224 data_string_forget(&key
, MDL
);
6227 if ((host
!= NULL
) || (prefix
!= NULL
)) {
6228 ia_pd_match(client_id
, &iaprefix
, prefix
);
6230 ia_pd_nomatch(client_id
, &iaprefix
,
6231 (u_int32_t
*)cli_enc_opt_data
.data
,
6232 packet
, reply_data
, &reply_ofs
,
6233 reply_len
- reply_ofs
);
6236 if (prefix
!= NULL
) {
6237 iasubopt_dereference(&prefix
, MDL
);
6240 data_string_forget(&iaprefix
, MDL
);
6243 option_state_dereference(&cli_enc_opt_state
, MDL
);
6244 data_string_forget(&cli_enc_opt_data
, MDL
);
6248 * Return our reply to the caller.
6249 * The IA_NA routine has already filled at least the header.
6251 reply_new
.len
= reply_ret
->len
+ reply_ofs
;
6252 if (!buffer_allocate(&reply_new
.buffer
, reply_new
.len
, MDL
)) {
6253 log_fatal("No memory to store reply.");
6255 reply_new
.data
= reply_new
.buffer
->data
;
6256 memcpy(reply_new
.buffer
->data
,
6257 reply_ret
->buffer
->data
, reply_ret
->len
);
6258 memcpy(reply_new
.buffer
->data
+ reply_ret
->len
,
6259 reply_data
, reply_ofs
);
6260 data_string_forget(reply_ret
, MDL
);
6261 data_string_copy(reply_ret
, &reply_new
, MDL
);
6262 data_string_forget(&reply_new
, MDL
);
6265 if (prefix
!= NULL
) {
6266 iasubopt_dereference(&prefix
, MDL
);
6268 if (host_opt_state
!= NULL
) {
6269 option_state_dereference(&host_opt_state
, MDL
);
6271 if (iaprefix
.buffer
!= NULL
) {
6272 data_string_forget(&iaprefix
, MDL
);
6274 if (cli_enc_opt_state
!= NULL
) {
6275 option_state_dereference(&cli_enc_opt_state
, MDL
);
6277 if (cli_enc_opt_data
.buffer
!= NULL
) {
6278 data_string_forget(&cli_enc_opt_data
, MDL
);
6280 if (opt_state
!= NULL
) {
6281 option_state_dereference(&opt_state
, MDL
);
6286 * Release means a client is done with the leases.
6290 dhcpv6_release(struct data_string
*reply
, struct packet
*packet
) {
6291 struct data_string client_id
;
6292 struct data_string server_id
;
6295 * Validate our input.
6297 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
6301 /* If the RELEASE arrived via unicast and unicast option isn't set,
6302 * reject it per RFC 3315, Sec 18.2.6 */
6303 if (packet
->unicast
== ISC_TRUE
&&
6304 is_unicast_option_defined(packet
) == ISC_FALSE
) {
6305 unicast_reject(reply
, packet
, &client_id
, &server_id
);
6308 * And operate on each IA_NA in this packet.
6310 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
6311 "Release", ia_na_match_release
,
6312 ia_na_nomatch_release
);
6315 * And operate on each IA_PD in this packet.
6317 iterate_over_ia_pd(reply
, packet
, &client_id
, &server_id
,
6318 "Release", ia_pd_match_release
,
6319 ia_pd_nomatch_release
);
6322 data_string_forget(&server_id
, MDL
);
6323 data_string_forget(&client_id
, MDL
);
6327 * Information-Request is used by clients who have obtained an address
6328 * from other means, but want configuration information from the server.
6332 dhcpv6_information_request(struct data_string
*reply
, struct packet
*packet
) {
6333 struct data_string client_id
;
6334 struct data_string server_id
;
6337 * Validate our input.
6339 if (!valid_client_info_req(packet
, &server_id
)) {
6344 * Get our client ID, if there is one.
6346 memset(&client_id
, 0, sizeof(client_id
));
6347 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
) {
6348 data_string_forget(&client_id
, MDL
);
6352 * Use the lease_to_client() function. This will work fine,
6353 * because the valid_client_info_req() insures that we
6354 * don't have any IA that would cause us to allocate
6355 * resources to the client.
6357 lease_to_client(reply
, packet
, &client_id
,
6358 server_id
.data
!= NULL
? &server_id
: NULL
);
6363 if (client_id
.data
!= NULL
) {
6364 data_string_forget(&client_id
, MDL
);
6366 data_string_forget(&server_id
, MDL
);
6370 * The Relay-forw message is sent by relays. It typically contains a
6371 * single option, which encapsulates an entire packet.
6373 * We need to build an encapsulated reply.
6376 /* XXX: this is very, very similar to do_packet6(), and should probably
6377 be combined in a clever way */
6379 dhcpv6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
6380 struct option_cache
*oc
;
6381 struct data_string enc_opt_data
;
6382 struct packet
*enc_packet
;
6383 unsigned char msg_type
;
6384 const struct dhcpv6_packet
*msg
;
6385 const struct dhcpv6_relay_packet
*relay
;
6386 struct data_string enc_reply
;
6387 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6388 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6389 struct data_string a_opt
, packet_ero
;
6390 struct option_state
*opt_state
;
6391 static char reply_data
[65536];
6392 struct dhcpv6_relay_packet
*reply
;
6396 * Initialize variables for early exit.
6399 memset(&a_opt
, 0, sizeof(a_opt
));
6400 memset(&packet_ero
, 0, sizeof(packet_ero
));
6401 memset(&enc_reply
, 0, sizeof(enc_reply
));
6402 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6406 * Get our encapsulated relay message.
6408 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
6410 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
6411 link_addr
, sizeof(link_addr
));
6412 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
6413 peer_addr
, sizeof(peer_addr
));
6414 log_info("Relay-forward from %s with link address=%s and "
6415 "peer address=%s missing Relay Message option.",
6416 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
6420 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
6421 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
6422 log_error("dhcpv6_forw_relay: error evaluating "
6423 "relayed message.");
6427 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
6428 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
6433 * Build a packet structure from this encapsulated packet.
6436 if (!packet_allocate(&enc_packet
, MDL
)) {
6437 log_error("dhcpv6_forw_relay: "
6438 "no memory for encapsulated packet.");
6442 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
6443 log_error("dhcpv6_forw_relay: "
6444 "no memory for encapsulated packet's options.");
6448 enc_packet
->client_port
= packet
->client_port
;
6449 enc_packet
->client_addr
= packet
->client_addr
;
6450 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
6451 enc_packet
->dhcpv6_container_packet
= packet
;
6453 msg_type
= enc_opt_data
.data
[0];
6454 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
6455 (msg_type
== DHCPV6_RELAY_REPL
)) {
6456 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6457 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
6458 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
6460 /* relay-specific data */
6461 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
6462 memcpy(&enc_packet
->dhcpv6_link_address
,
6463 relay
->link_address
, sizeof(relay
->link_address
));
6464 memcpy(&enc_packet
->dhcpv6_peer_address
,
6465 relay
->peer_address
, sizeof(relay
->peer_address
));
6467 if (!parse_option_buffer(enc_packet
->options
,
6469 enc_opt_data
.len
- relaylen
,
6470 &dhcpv6_universe
)) {
6471 /* no logging here, as parse_option_buffer() logs all
6472 cases where it fails */
6476 int msglen
= (int)(offsetof(struct dhcpv6_packet
, options
));
6477 msg
= (struct dhcpv6_packet
*)enc_opt_data
.data
;
6478 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
6480 /* message-specific data */
6481 memcpy(enc_packet
->dhcpv6_transaction_id
,
6482 msg
->transaction_id
,
6483 sizeof(enc_packet
->dhcpv6_transaction_id
));
6485 if (!parse_option_buffer(enc_packet
->options
,
6487 enc_opt_data
.len
- msglen
,
6488 &dhcpv6_universe
)) {
6489 /* no logging here, as parse_option_buffer() logs all
6490 cases where it fails */
6496 * This is recursive. It is possible to exceed maximum packet size.
6497 * XXX: This will cause the packet send to fail.
6499 build_dhcpv6_reply(&enc_reply
, enc_packet
);
6502 * If we got no encapsulated data, then it is discarded, and
6503 * our reply-forw is also discarded.
6505 if (enc_reply
.data
== NULL
) {
6510 * Now we can use the reply_data buffer.
6511 * Packet header stuff all comes from the forward message.
6513 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
6514 reply
->msg_type
= DHCPV6_RELAY_REPL
;
6515 reply
->hop_count
= packet
->dhcpv6_hop_count
;
6516 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
6517 sizeof(reply
->link_address
));
6518 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
6519 sizeof(reply
->peer_address
));
6520 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6523 * Get the reply option state.
6526 if (!option_state_allocate(&opt_state
, MDL
)) {
6527 log_error("dhcpv6_relay_forw: no memory for option state.");
6532 * Append the interface-id if present.
6534 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6537 if (!evaluate_option_cache(&a_opt
, packet
,
6539 packet
->options
, NULL
,
6540 &global_scope
, oc
, MDL
)) {
6541 log_error("dhcpv6_relay_forw: error evaluating "
6545 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6546 (unsigned char *)a_opt
.data
,
6548 D6O_INTERFACE_ID
, 0)) {
6549 log_error("dhcpv6_relay_forw: error saving "
6553 data_string_forget(&a_opt
, MDL
);
6557 * Append our encapsulated stuff for caller.
6559 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6560 (unsigned char *)enc_reply
.data
,
6562 D6O_RELAY_MSG
, 0)) {
6563 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
6568 * Get the ERO if any.
6570 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
6575 if (!evaluate_option_cache(&packet_ero
, packet
,
6577 packet
->options
, NULL
,
6578 &global_scope
, oc
, MDL
) ||
6579 (packet_ero
.len
& 1)) {
6580 log_error("dhcpv6_relay_forw: error evaluating ERO.");
6584 /* Decode and apply the ERO. */
6585 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
6586 req
= getUShort(packet_ero
.data
+ i
);
6587 /* Already in the reply? */
6588 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
6591 /* Get it from the packet if present. */
6592 oc
= lookup_option(&dhcpv6_universe
,
6597 if (!evaluate_option_cache(&a_opt
, packet
,
6599 packet
->options
, NULL
,
6600 &global_scope
, oc
, MDL
)) {
6601 log_error("dhcpv6_relay_forw: error "
6602 "evaluating option %u.", req
);
6605 if (!save_option_buffer(&dhcpv6_universe
,
6608 (unsigned char *)a_opt
.data
,
6612 log_error("dhcpv6_relay_forw: error saving "
6616 data_string_forget(&a_opt
, MDL
);
6620 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
6621 sizeof(reply_data
) - reply_ofs
,
6623 required_opts_agent
, &packet_ero
);
6626 * Return our reply to the caller.
6628 reply_ret
->len
= reply_ofs
;
6629 reply_ret
->buffer
= NULL
;
6630 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
6631 log_fatal("No memory to store reply.");
6633 reply_ret
->data
= reply_ret
->buffer
->data
;
6634 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
6637 if (opt_state
!= NULL
)
6638 option_state_dereference(&opt_state
, MDL
);
6639 if (a_opt
.data
!= NULL
) {
6640 data_string_forget(&a_opt
, MDL
);
6642 if (packet_ero
.data
!= NULL
) {
6643 data_string_forget(&packet_ero
, MDL
);
6645 if (enc_reply
.data
!= NULL
) {
6646 data_string_forget(&enc_reply
, MDL
);
6648 if (enc_opt_data
.data
!= NULL
) {
6649 data_string_forget(&enc_opt_data
, MDL
);
6651 if (enc_packet
!= NULL
) {
6652 packet_dereference(&enc_packet
, MDL
);
6657 dhcpv6_discard(struct packet
*packet
) {
6658 /* INSIST(packet->msg_type > 0); */
6659 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
6661 log_debug("Discarding %s from %s; message type not handled by server",
6662 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
6663 piaddr(packet
->client_addr
));
6667 build_dhcpv6_reply(struct data_string
*reply
, struct packet
*packet
) {
6668 memset(reply
, 0, sizeof(*reply
));
6670 /* I would like to classify the client once here, but
6671 * as I don't want to classify all of the incoming packets
6672 * I need to do it before handling specific types.
6673 * We don't need to classify if we are tossing the packet
6674 * or if it is a relay - the classification step will get
6675 * done when we process the inner client packet.
6678 switch (packet
->dhcpv6_msg_type
) {
6679 case DHCPV6_SOLICIT
:
6680 classify_client(packet
);
6681 dhcpv6_solicit(reply
, packet
);
6683 case DHCPV6_ADVERTISE
:
6684 dhcpv6_discard(packet
);
6686 case DHCPV6_REQUEST
:
6687 classify_client(packet
);
6688 dhcpv6_request(reply
, packet
);
6690 case DHCPV6_CONFIRM
:
6691 classify_client(packet
);
6692 dhcpv6_confirm(reply
, packet
);
6695 classify_client(packet
);
6696 dhcpv6_renew(reply
, packet
);
6699 classify_client(packet
);
6700 dhcpv6_rebind(reply
, packet
);
6703 dhcpv6_discard(packet
);
6705 case DHCPV6_RELEASE
:
6706 classify_client(packet
);
6707 dhcpv6_release(reply
, packet
);
6709 case DHCPV6_DECLINE
:
6710 classify_client(packet
);
6711 dhcpv6_decline(reply
, packet
);
6713 case DHCPV6_RECONFIGURE
:
6714 dhcpv6_discard(packet
);
6716 case DHCPV6_INFORMATION_REQUEST
:
6717 classify_client(packet
);
6718 dhcpv6_information_request(reply
, packet
);
6720 case DHCPV6_RELAY_FORW
:
6721 dhcpv6_relay_forw(reply
, packet
);
6723 case DHCPV6_RELAY_REPL
:
6724 dhcpv6_discard(packet
);
6726 case DHCPV6_LEASEQUERY
:
6727 classify_client(packet
);
6728 dhcpv6_leasequery(reply
, packet
);
6730 case DHCPV6_LEASEQUERY_REPLY
:
6731 dhcpv6_discard(packet
);
6734 /* XXX: would be nice if we had "notice" level,
6735 as syslog, for this */
6736 log_info("Discarding unknown DHCPv6 message type %d "
6737 "from %s", packet
->dhcpv6_msg_type
,
6738 piaddr(packet
->client_addr
));
6743 log_packet_in(const struct packet
*packet
) {
6744 struct data_string s
;
6746 char tmp_addr
[INET6_ADDRSTRLEN
];
6749 memset(&s
, 0, sizeof(s
));
6751 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
6752 data_string_sprintfa(&s
, "%s message from %s port %d",
6753 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
6754 piaddr(packet
->client_addr
),
6755 ntohs(packet
->client_port
));
6757 data_string_sprintfa(&s
,
6758 "Unknown message type %d from %s port %d",
6759 packet
->dhcpv6_msg_type
,
6760 piaddr(packet
->client_addr
),
6761 ntohs(packet
->client_port
));
6763 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
6764 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
6765 addr
= &packet
->dhcpv6_link_address
;
6766 data_string_sprintfa(&s
, ", link address %s",
6767 inet_ntop(AF_INET6
, addr
,
6768 tmp_addr
, sizeof(tmp_addr
)));
6769 addr
= &packet
->dhcpv6_peer_address
;
6770 data_string_sprintfa(&s
, ", peer address %s",
6771 inet_ntop(AF_INET6
, addr
,
6772 tmp_addr
, sizeof(tmp_addr
)));
6775 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
6776 data_string_sprintfa(&s
, ", transaction ID 0x%06X", tid
);
6779 oc = lookup_option(&dhcpv6_universe, packet->options,
6782 memset(&tmp_ds, 0, sizeof(tmp_ds_));
6783 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
6784 packet->options, NULL,
6785 &global_scope, oc, MDL)) {
6786 log_error("Error evaluating Client Identifier");
6788 data_strint_sprintf(&s, ", client ID %s",
6790 data_string_forget(&tmp_ds, MDL);
6796 log_info("%s", s
.data
);
6798 data_string_forget(&s
, MDL
);
6802 dhcpv6(struct packet
*packet
) {
6803 struct data_string reply
;
6804 struct sockaddr_in6 to_addr
;
6808 * Log a message that we received this packet.
6810 log_packet_in(packet
);
6813 * Build our reply packet.
6815 build_dhcpv6_reply(&reply
, packet
);
6817 if (reply
.data
!= NULL
) {
6819 * Send our reply, if we have one.
6821 memset(&to_addr
, 0, sizeof(to_addr
));
6822 to_addr
.sin6_family
= AF_INET6
;
6823 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
6824 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
6825 to_addr
.sin6_port
= local_port
;
6827 to_addr
.sin6_port
= remote_port
;
6830 #if defined (REPLY_TO_SOURCE_PORT)
6832 * This appears to have been included for testing so we would
6833 * not need a root client, but was accidently left in the
6834 * final code. We continue to include it in case
6835 * some users have come to rely upon it, but leave
6836 * it off by default as it's a bad idea.
6838 to_addr
.sin6_port
= packet
->client_port
;
6841 memcpy(&to_addr
.sin6_addr
, packet
->client_addr
.iabuf
,
6842 sizeof(to_addr
.sin6_addr
));
6844 log_info("Sending %s to %s port %d",
6845 dhcpv6_type_names
[reply
.data
[0]],
6846 piaddr(packet
->client_addr
),
6847 ntohs(to_addr
.sin6_port
));
6849 send_ret
= send_packet6(packet
->interface
,
6850 reply
.data
, reply
.len
, &to_addr
);
6851 if (send_ret
!= reply
.len
) {
6852 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
6853 send_ret
, reply
.len
);
6855 data_string_forget(&reply
, MDL
);
6860 seek_shared_host(struct host_decl
**hp
, struct shared_network
*shared
) {
6861 struct host_decl
*nofixed
= NULL
;
6862 struct host_decl
*seek
, *hold
= NULL
;
6865 * Seek forward through fixed addresses for the right link.
6867 * Note: how to do this for fixed prefixes???
6869 host_reference(&hold
, *hp
, MDL
);
6870 host_dereference(hp
, MDL
);
6872 while (seek
!= NULL
) {
6873 if (seek
->fixed_addr
== NULL
)
6875 else if (fixed_matches_shared(seek
, shared
))
6878 seek
= seek
->n_ipaddr
;
6881 if ((seek
== NULL
) && (nofixed
!= NULL
))
6885 host_reference(hp
, seek
, MDL
);
6888 static isc_boolean_t
6889 fixed_matches_shared(struct host_decl
*host
, struct shared_network
*shared
) {
6890 struct subnet
*subnet
;
6891 struct data_string addr
;
6892 isc_boolean_t matched
;
6895 if (host
->fixed_addr
== NULL
)
6898 memset(&addr
, 0, sizeof(addr
));
6899 if (!evaluate_option_cache(&addr
, NULL
, NULL
, NULL
, NULL
, NULL
,
6900 &global_scope
, host
->fixed_addr
, MDL
))
6903 if (addr
.len
< 16) {
6904 data_string_forget(&addr
, MDL
);
6909 memcpy(fixed
.iabuf
, addr
.data
, 16);
6911 matched
= ISC_FALSE
;
6912 for (subnet
= shared
->subnets
; subnet
!= NULL
;
6913 subnet
= subnet
->next_sibling
) {
6914 if (addr_eq(subnet_number(fixed
, subnet
->netmask
),
6921 data_string_forget(&addr
, MDL
);
6926 * find_host_by_duid_chaddr() synthesizes a DHCPv4-like 'hardware'
6927 * parameter from a DHCPv6 supplied DUID (client-identifier option),
6928 * and may seek to use client or relay supplied hardware addresses.
6931 find_hosts_by_duid_chaddr(struct host_decl
**host
,
6932 const struct data_string
*client_id
) {
6933 static int once_htype
;
6935 const unsigned char *chaddr
;
6938 * The DUID-LL and DUID-LLT must have a 2-byte DUID type and 2-byte
6941 if (client_id
->len
< 4)
6945 * The third and fourth octets of the DUID-LL and DUID-LLT
6946 * is the hardware type, but in 16 bits.
6948 htype
= getUShort(client_id
->data
+ 2);
6952 /* The first two octets of the DUID identify the type. */
6953 switch(getUShort(client_id
->data
)) {
6955 if (client_id
->len
> 8) {
6956 hlen
= client_id
->len
- 8;
6957 chaddr
= client_id
->data
+ 8;
6963 * Note that client_id->len must be greater than or equal
6964 * to four to get to this point in the function.
6966 hlen
= client_id
->len
- 4;
6967 chaddr
= client_id
->data
+ 4;
6974 if ((hlen
== 0) || (hlen
> HARDWARE_ADDR_LEN
))
6978 * XXX: DHCPv6 gives a 16-bit field for the htype. DHCPv4 gives an
6979 * 8-bit field. To change the semantics of the generic 'hardware'
6980 * structure, we would have to adjust many DHCPv4 sources (from
6981 * interface to DHCPv4 lease code), and we would have to update the
6982 * 'hardware' config directive (probably being reverse compatible and
6983 * providing a new upgrade/replacement primitive). This is a little
6984 * too much to change for now. Hopefully we will revisit this before
6985 * hardware types exceeding 8 bits are assigned.
6987 if ((htype
& 0xFF00) && !once_htype
) {
6989 log_error("Attention: At least one client advertises a "
6990 "hardware type of %d, which exceeds the software "
6991 "limitation of 255.", htype
);
6994 return find_hosts_by_haddr(host
, htype
, chaddr
, hlen
, MDL
);
7000 * \brief Constructs a REPLY with status of UseMulticast to a given packet
7002 * Per RFC 3315 Secs 18.2.1,3,6 & 7, when a server rejects a client's
7003 * unicast-sent packet, the response must only contain the client id,
7004 * server id, and a status code option of 5 (UseMulticast). This function
7005 * constructs such a packet and returns it as a data_string.
7007 * \param reply_ret = data_string which will receive the newly constructed
7009 * \param packet = client request which is being rejected
7010 * \param client_id = data_string which contains the client id
7011 * \param server_id = data_string which which contains the server id
7015 unicast_reject(struct data_string
*reply_ret
,
7016 struct packet
*packet
,
7017 const struct data_string
*client_id
,
7018 const struct data_string
*server_id
)
7020 struct reply_state reply
;
7021 memset(&reply
, 0x0, sizeof(struct reply_state
));
7023 /* Locate the client. */
7024 if (shared_network_from_packet6(&reply
.shared
, packet
)
7026 log_error("unicast_reject: could not locate client.");
7030 /* Initialize the reply. */
7031 packet_reference(&reply
.packet
, packet
, MDL
);
7032 data_string_copy(&reply
.client_id
, client_id
, MDL
);
7034 if (start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
7035 &reply
.buf
.reply
)) {
7036 /* Set the UseMulticast status code. */
7037 if (!set_status_code(STATUS_UseMulticast
,
7038 "Unicast not allowed by server.",
7040 log_error("unicast_reject: Unable to set status code.");
7042 /* Set write cursor to just past the reply header. */
7043 reply
.cursor
= REPLY_OPTIONS_INDEX
;
7044 reply
.cursor
+= store_options6(((char *)reply
.buf
.data
7050 unicast_reject_opts
,
7053 /* Return our reply to the caller. */
7054 reply_ret
->len
= reply
.cursor
;
7055 reply_ret
->buffer
= NULL
;
7056 if (!buffer_allocate(&reply_ret
->buffer
,
7057 reply
.cursor
, MDL
)) {
7058 log_fatal("unicast_reject:"
7059 "No memory to store Reply.");
7062 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
,
7064 reply_ret
->data
= reply_ret
->buffer
->data
;
7070 if (reply
.shared
!= NULL
)
7071 shared_network_dereference(&reply
.shared
, MDL
);
7072 if (reply
.opt_state
!= NULL
)
7073 option_state_dereference(&reply
.opt_state
, MDL
);
7074 if (reply
.packet
!= NULL
)
7075 packet_dereference(&reply
.packet
, MDL
);
7076 if (reply
.client_id
.data
!= NULL
)
7077 data_string_forget(&reply
.client_id
, MDL
);
7082 * \brief Checks if the dhcp6.unicast option has been defined
7084 * Scans the option space for the presence of the dhcp6.unicast option. The
7085 * function attempts to map the inbound packet to a shared network first
7086 * by an ip address specified via an D6O_IA_XX option and if that fails then
7087 * by the packet's source information (e.g. relay link, link, or interace).
7088 * Once the packet is mapped to a shared network, the function executes all
7089 * statements from the network's group outward into a local option cache.
7090 * The option cache is then scanned for the presence of unicast option. If
7091 * the packet cannot be mapped to a shared network, the function returns
7093 * \param packet inbound packet from the client
7095 * \return ISC_TRUE if the dhcp6.unicast option is defined, false otherwise.
7099 is_unicast_option_defined(struct packet
*packet
) {
7100 isc_boolean_t is_defined
= ISC_FALSE
;
7101 struct option_state
*opt_state
= NULL
;
7102 struct option_cache
*oc
= NULL
;
7103 struct shared_network
*shared
= NULL
;
7105 if (!option_state_allocate(&opt_state
, MDL
)) {
7106 log_fatal("is_unicast_option_defined:"
7107 "No memory for option state.");
7110 /* We try to map the packet to a network first by an IA_XX value.
7111 * If that fails, we try by packet source. */
7112 if (((shared_network_from_requested_addr(&shared
, packet
)
7113 != ISC_R_SUCCESS
) &&
7114 (shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
))
7115 || (shared
== NULL
)) {
7116 /* @todo what would this really mean? I think wrong network
7117 * logic will catch it */
7118 log_error("is_unicast_option_defined:"
7119 "cannot attribute packet to a network.");
7123 /* Now that we've mapped it to a network, execute statments to that
7124 * scope, looking for the unicast option. We don't care about the
7125 * value of the option, only whether or not it is defined. */
7126 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
, opt_state
,
7127 &global_scope
, shared
->group
, NULL
, NULL
);
7129 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_UNICAST
);
7130 is_defined
= (oc
!= NULL
? ISC_TRUE
: ISC_FALSE
);
7131 log_debug("is_unicast_option_defined: option found : %d", is_defined
);
7133 if (shared
!= NULL
) {
7134 shared_network_dereference(&shared
, MDL
);
7137 if (opt_state
!= NULL
) {
7138 option_state_dereference(&opt_state
, MDL
);
7141 return (is_defined
);
7146 * \brief Maps a packet to a shared network based on the requested IP address
7148 * The function attempts to find a subnet that matches the first requested IP
7149 * address contained within the given packet. Note that it looks first for
7150 * D6O_IA_NAs, then D6O_IA_PDs and lastly D6O_IA_TAs. If a matching network is
7151 * found, a reference to it is returned in the parameter, shared.
7153 * \param shared shared_network pointer which will receive the matching network
7154 * \param packet inbound packet from the client
7156 * \return ISC_R_SUCCESS if the packet can be mapped to a shared_network.
7160 shared_network_from_requested_addr (struct shared_network
**shared
,
7161 struct packet
* packet
) {
7163 struct subnet
* subnet
= NULL
;
7164 isc_result_t status
= ISC_R_FAILURE
;
7166 /* Try to match first IA_ address or prefix we find to a subnet. In
7167 * theory all IA_ values in a given request are supposed to be in the
7168 * same subnet so we only need to try one right? */
7169 if ((get_first_ia_addr_val(packet
, D6O_IA_NA
, &iaddr
) != ISC_R_SUCCESS
)
7170 && (get_first_ia_addr_val(packet
, D6O_IA_PD
, &iaddr
)
7172 && (get_first_ia_addr_val(packet
, D6O_IA_TA
, &iaddr
)
7173 != ISC_R_SUCCESS
)) {
7174 /* we found nothing to match against */
7175 log_debug("share_network_from_request_addr: nothing to match");
7176 return (ISC_R_FAILURE
);
7179 if (!find_subnet(&subnet
, iaddr
, MDL
)) {
7180 log_debug("shared_network_from_requested_addr:"
7181 "No subnet found for addr %s.", piaddr(iaddr
));
7183 status
= shared_network_reference(shared
,
7184 subnet
->shared_network
, MDL
);
7185 subnet_dereference(&subnet
, MDL
);
7186 log_debug("shared_network_from_requested_addr:"
7187 " found shared network %s for address %s.",
7188 ((*shared
)->name
? (*shared
)->name
: "unnamed"),
7193 return (ISC_R_FAILURE
);
7198 * \brief Retrieves the first IP address from a given packet of a given type
7200 * Search a packet for options of a given type (D6O_IA_AN, D6O_IA_PD, or
7201 * D6O_IA_TA) for the first non-blank IA_XX value and return its IP address
7204 * \param packet packet received from the client
7205 * \param addr_type the address option type (D6O_IA_NA , D6O_IA_PD, or
7206 * D6O_IP_TA) to look for within the packet.
7207 * \param iaddr pointer to the iaddr structure which will receive the extracted
7210 * \return ISC_R_SUCCESS if an address was succesfully extracted, ISC_R_FALURE
7215 get_first_ia_addr_val (struct packet
* packet
, int addr_type
,
7216 struct iaddr
* iaddr
) {
7217 struct option_cache
*ia
;
7218 struct option_cache
*oc
= NULL
;
7219 struct data_string cli_enc_opt_data
;
7220 struct option_state
*cli_enc_opt_state
;
7221 int addr_opt_offset
;
7223 int addr_opt_data_len
;
7226 isc_result_t status
= ISC_R_FAILURE
;
7227 memset(iaddr
, 0, sizeof(struct iaddr
));
7229 /* Set up address type specifics */
7230 switch (addr_type
) {
7232 addr_opt_offset
= IA_NA_OFFSET
;
7233 addr_opt
= D6O_IAADDR
;
7234 addr_opt_data_len
= 24;
7238 addr_opt_offset
= IA_TA_OFFSET
;
7239 addr_opt
= D6O_IAADDR
;
7240 addr_opt_data_len
= 24;
7244 addr_opt_offset
= IA_PD_OFFSET
;
7245 addr_opt
= D6O_IAPREFIX
;
7246 addr_opt_data_len
= 25;
7250 /* shouldn't be here */
7251 log_error ("get_first_ia_addr_val: invalid opt type %d",
7253 return (ISC_R_FAILURE
);
7256 /* Find the first, non-blank IA_XX value within an D6O_IA_XX option. */
7257 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, addr_type
);
7258 ia
!= NULL
&& oc
== NULL
; ia
= ia
->next
) {
7259 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
7261 packet
, ia
, addr_opt_offset
)) {
7262 log_debug ("get_first_ia_addr_val:"
7263 " couldn't unroll enclosing option");
7264 return (ISC_R_FAILURE
);
7267 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
7270 /* no address given for this IA, ignore */
7271 option_state_dereference(&cli_enc_opt_state
, MDL
);
7272 data_string_forget(&cli_enc_opt_data
, MDL
);
7276 /* If we found a non-blank IA_XX then extract its ip address. */
7278 struct data_string iaddr_str
;
7280 memset(&iaddr_str
, 0, sizeof(iaddr_str
));
7281 if (!evaluate_option_cache(&iaddr_str
, packet
, NULL
, NULL
,
7282 packet
->options
, NULL
, &global_scope
,
7284 log_error("get_first_ia_addr_val: "
7285 "error evaluating IA_XX option.");
7287 if (iaddr_str
.len
!= addr_opt_data_len
) {
7288 log_error("shared_network_from_requested_addr:"
7289 " invalid length %d, expected %d",
7290 iaddr_str
.len
, addr_opt_data_len
);
7293 memcpy (iaddr
->iabuf
,
7294 iaddr_str
.data
+ ip_addr_offset
, 16);
7295 status
= ISC_R_SUCCESS
;
7297 data_string_forget(&iaddr_str
, MDL
);
7300 option_state_dereference(&cli_enc_opt_state
, MDL
);
7301 data_string_forget(&cli_enc_opt_data
, MDL
);