2 * Copyright (C) 2006-2015 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 %d 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 %d 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 if (reply
->client_prefer
== 0)
3460 reply
->send_prefer
= reply
->send_valid
;
3462 reply
->send_prefer
= reply
->client_prefer
;
3464 if (reply
->send_prefer
>= reply
->send_valid
)
3465 reply
->send_prefer
= (reply
->send_valid
/ 2) +
3466 (reply
->send_valid
/ 8);
3468 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3469 SV_PREFER_LIFETIME
);
3471 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3472 reply
->packet
->options
,
3476 log_error("reply_process_is_addressed: unable to "
3477 "evaluate preferred lease time");
3478 status
= ISC_R_FAILURE
;
3482 reply
->send_prefer
= getULong(data
.data
);
3483 data_string_forget(&data
, MDL
);
3486 /* Note lowest values for later calculation of renew/rebind times. */
3487 if (reply
->prefer
> reply
->send_prefer
)
3488 reply
->prefer
= reply
->send_prefer
;
3490 if (reply
->valid
> reply
->send_valid
)
3491 reply
->valid
= reply
->send_valid
;
3495 * XXX: Old 4.0.0 alpha code would change the host {} record
3496 * XXX: uid upon lease assignment. This was intended to cover the
3497 * XXX: case where a client first identifies itself using vendor
3498 * XXX: options in a solicit, or request, but later neglects to include
3499 * XXX: these options in a Renew or Rebind. It is not clear that this
3500 * XXX: is required, and has some startling ramifications (such as
3501 * XXX: how to recover this dynamic host {} state across restarts).
3503 if (reply
->host
!= NULL
)
3504 change_host_uid(host
, reply
->client_id
->data
,
3505 reply
->client_id
->len
);
3508 /* Perform dynamic lease related update work. */
3509 if (reply
->lease
!= NULL
) {
3510 /* Cached lifetimes */
3511 reply
->lease
->prefer
= reply
->send_prefer
;
3512 reply
->lease
->valid
= reply
->send_valid
;
3514 /* Advance (or rewind) the valid lifetime. */
3515 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
3516 reply
->lease
->soft_lifetime_end_time
=
3517 cur_time
+ reply
->send_valid
;
3518 /* Wait before renew! */
3521 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
3522 if (status
!= ISC_R_SUCCESS
) {
3523 log_fatal("reply_process_is_addressed: Unable to "
3524 "attach lease to new IA: %s",
3525 isc_result_totext(status
));
3529 * If this is a new lease, make sure it is attached somewhere.
3531 if (reply
->lease
->ia
== NULL
) {
3532 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
3536 /* Bring a copy of the relevant options into the IA scope. */
3537 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3538 reply
->packet
->options
, reply
->reply_ia
,
3539 scope
, group
, root_group
, NULL
);
3541 /* Execute statements from class scopes. */
3542 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3543 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3544 reply
->packet
->options
,
3545 reply
->reply_ia
, scope
,
3546 reply
->packet
->classes
[i
- 1]->group
,
3551 * And bring in host record configuration, if any, but not to overlap
3552 * the previous group or its common enclosers.
3554 if (reply
->host
!= NULL
)
3555 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3556 reply
->packet
->options
,
3557 reply
->reply_ia
, scope
,
3558 reply
->host
->group
, group
, NULL
);
3561 if (data
.data
!= NULL
)
3562 data_string_forget(&data
, MDL
);
3564 if (status
== ISC_R_SUCCESS
)
3565 reply
->client_resources
++;
3570 /* Simply send an IAADDR within the IA scope as described. */
3572 reply_process_send_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3573 isc_result_t status
= ISC_R_SUCCESS
;
3574 struct data_string data
;
3576 memset(&data
, 0, sizeof(data
));
3578 /* Now append the lease. */
3579 data
.len
= IAADDR_OFFSET
;
3580 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
3581 log_error("reply_process_send_addr: out of memory"
3582 "allocating new IAADDR buffer.");
3583 status
= ISC_R_NOMEMORY
;
3586 data
.data
= data
.buffer
->data
;
3588 memcpy(data
.buffer
->data
, addr
->iabuf
, 16);
3589 putULong(data
.buffer
->data
+ 16, reply
->send_prefer
);
3590 putULong(data
.buffer
->data
+ 20, reply
->send_valid
);
3592 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
3593 data
.buffer
, data
.buffer
->data
,
3594 data
.len
, D6O_IAADDR
, 0)) {
3595 log_error("reply_process_send_addr: unable "
3596 "to save IAADDR option");
3597 status
= ISC_R_FAILURE
;
3601 reply
->resources_included
= ISC_TRUE
;
3604 if (data
.data
!= NULL
)
3605 data_string_forget(&data
, MDL
);
3610 /* Choose the better of two leases. */
3611 static struct iasubopt
*
3612 lease_compare(struct iasubopt
*alpha
, struct iasubopt
*beta
) {
3618 switch(alpha
->state
) {
3620 switch(beta
->state
) {
3622 /* Choose the lease with the longest lifetime (most
3623 * likely the most recently allocated).
3625 if (alpha
->hard_lifetime_end_time
<
3626 beta
->hard_lifetime_end_time
)
3636 log_fatal("Impossible condition at %s:%d.", MDL
);
3641 switch (beta
->state
) {
3646 /* Choose the most recently expired lease. */
3647 if (alpha
->hard_lifetime_end_time
<
3648 beta
->hard_lifetime_end_time
)
3650 else if ((alpha
->hard_lifetime_end_time
==
3651 beta
->hard_lifetime_end_time
) &&
3652 (alpha
->soft_lifetime_end_time
<
3653 beta
->soft_lifetime_end_time
))
3662 log_fatal("Impossible condition at %s:%d.", MDL
);
3667 switch (beta
->state
) {
3673 /* Choose the lease that was abandoned longest ago. */
3674 if (alpha
->hard_lifetime_end_time
<
3675 beta
->hard_lifetime_end_time
)
3681 log_fatal("Impossible condition at %s:%d.", MDL
);
3686 log_fatal("Impossible condition at %s:%d.", MDL
);
3689 log_fatal("Triple impossible condition at %s:%d.", MDL
);
3693 /* Process a client-supplied IA_PD. This may append options to the tail of
3694 * the reply packet being built in the reply_state structure.
3697 reply_process_ia_pd(struct reply_state
*reply
, struct option_cache
*ia
) {
3698 isc_result_t status
= ISC_R_SUCCESS
;
3701 struct option_state
*packet_ia
;
3702 struct option_cache
*oc
;
3703 struct data_string ia_data
, data
;
3705 /* Initialize values that will get cleaned up on return. */
3707 memset(&ia_data
, 0, sizeof(ia_data
));
3708 memset(&data
, 0, sizeof(data
));
3710 * Note that find_client_prefix() may set reply->lease.
3713 /* Make sure there is at least room for the header. */
3714 if ((reply
->cursor
+ IA_PD_OFFSET
+ 4) > sizeof(reply
->buf
)) {
3715 log_error("reply_process_ia_pd: Reply too long for IA.");
3716 return ISC_R_NOSPACE
;
3720 /* Fetch the IA_PD contents. */
3721 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
3722 ia
, IA_PD_OFFSET
)) {
3723 log_error("reply_process_ia_pd: error evaluating ia");
3724 status
= ISC_R_FAILURE
;
3728 /* Extract IA_PD header contents. */
3729 iaid
= getULong(ia_data
.data
);
3730 reply
->renew
= getULong(ia_data
.data
+ 4);
3731 reply
->rebind
= getULong(ia_data
.data
+ 8);
3733 /* Create an IA_PD structure. */
3734 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
3735 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
3736 log_error("reply_process_ia_pd: no memory for ia.");
3737 status
= ISC_R_NOMEMORY
;
3740 reply
->ia
->ia_type
= D6O_IA_PD
;
3742 /* Cache pre-existing IA_PD, if any. */
3743 ia_hash_lookup(&reply
->old_ia
, ia_pd_active
,
3744 (unsigned char *)reply
->ia
->iaid_duid
.data
,
3745 reply
->ia
->iaid_duid
.len
, MDL
);
3748 * Create an option cache to carry the IA_PD option contents, and
3749 * execute any user-supplied values into it.
3751 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
3752 status
= ISC_R_NOMEMORY
;
3756 /* Check & count the fixed prefix host records. */
3757 reply
->static_prefixes
= 0;
3758 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_prefix
!= NULL
)) {
3759 struct iaddrcidrnetlist
*fp
;
3761 for (fp
= reply
->host
->fixed_prefix
; fp
!= NULL
;
3763 reply
->static_prefixes
+= 1;
3768 * Save the cursor position at the start of the IA_PD, so we can
3769 * set length and adjust t1/t2 values later. We write a temporary
3770 * header out now just in case we decide to adjust the packet
3771 * within sub-process functions.
3773 ia_cursor
= reply
->cursor
;
3775 /* Initialize the IA_PD header. First the code. */
3776 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_PD
);
3779 /* Then option length. */
3780 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
3783 /* Then IA_PD header contents; IAID. */
3784 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
3787 /* We store the client's t1 for now, and may over-ride it later. */
3788 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
3791 /* We store the client's t2 for now, and may over-ride it later. */
3792 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
3796 * For each prefix in this IA_PD, decide what to do about it.
3798 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAPREFIX
);
3799 reply
->valid
= reply
->prefer
= 0xffffffff;
3800 reply
->client_valid
= reply
->client_prefer
= 0;
3801 reply
->preflen
= -1;
3802 for (; oc
!= NULL
; oc
= oc
->next
) {
3803 status
= reply_process_prefix(reply
, oc
);
3806 * Canceled means we did not allocate prefixes to the
3807 * client, but we're "done" with this IA - we set a status
3808 * code. So transmit this reply, e.g., move on to the next
3811 if (status
== ISC_R_CANCELED
)
3814 if ((status
!= ISC_R_SUCCESS
) &&
3815 (status
!= ISC_R_ADDRINUSE
) &&
3816 (status
!= ISC_R_ADDRNOTAVAIL
))
3823 * If we fell through the above and never gave the client
3824 * a prefix, give it one now.
3826 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
3827 status
= find_client_prefix(reply
);
3829 if (status
== ISC_R_NORESOURCES
) {
3830 switch (reply
->packet
->dhcpv6_msg_type
) {
3831 case DHCPV6_SOLICIT
:
3833 * No prefix for any IA is handled
3838 case DHCPV6_REQUEST
:
3839 /* Same than for addresses. */
3840 option_state_dereference(&reply
->reply_ia
, MDL
);
3841 if (!option_state_allocate(&reply
->reply_ia
,
3844 log_error("reply_process_ia_pd: No "
3845 "memory for option state "
3847 status
= ISC_R_NOMEMORY
;
3851 if (!set_status_code(STATUS_NoPrefixAvail
,
3852 "No prefixes available "
3853 "for this interface.",
3855 log_error("reply_process_ia_pd: "
3857 "NoPrefixAvail status "
3859 status
= ISC_R_FAILURE
;
3863 status
= ISC_R_SUCCESS
;
3867 if (reply
->resources_included
)
3868 status
= ISC_R_SUCCESS
;
3875 if (status
!= ISC_R_SUCCESS
)
3879 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
3880 sizeof(reply
->buf
) - reply
->cursor
,
3881 reply
->reply_ia
, reply
->packet
,
3882 required_opts_IA_PD
, NULL
);
3884 /* Reset the length of this IA_PD to match what was just written. */
3885 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
3886 reply
->cursor
- (ia_cursor
+ 4));
3889 * T1/T2 time selection is kind of weird. We actually use DHCP
3890 * (v4) scoped options as handy existing places where these might
3891 * be configured by an administrator. A value of zero tells the
3892 * client it may choose its own renewal time.
3895 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
3896 DHO_DHCP_RENEWAL_TIME
);
3898 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3899 reply
->packet
->options
,
3900 reply
->opt_state
, &global_scope
,
3903 log_error("Invalid renewal time.");
3905 reply
->renew
= getULong(data
.data
);
3908 if (data
.data
!= NULL
)
3909 data_string_forget(&data
, MDL
);
3911 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
3915 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
3916 DHO_DHCP_REBINDING_TIME
);
3918 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3919 reply
->packet
->options
,
3920 reply
->opt_state
, &global_scope
,
3923 log_error("Invalid rebinding time.");
3925 reply
->rebind
= getULong(data
.data
);
3928 if (data
.data
!= NULL
)
3929 data_string_forget(&data
, MDL
);
3931 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
3934 * yes, goto's aren't the best but we also want to avoid extra
3937 if (status
== ISC_R_CANCELED
)
3941 * Handle static prefixes, we always log stuff and if it's
3942 * a hard binding we run any commit statements that we have
3944 if (reply
->static_prefixes
!= 0) {
3945 char tmp_addr
[INET6_ADDRSTRLEN
];
3946 log_info("%s PD: address %s/%d to client with duid %s "
3948 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
3949 inet_ntop(AF_INET6
, reply
->fixed_pref
.lo_addr
.iabuf
,
3950 tmp_addr
, sizeof(tmp_addr
)),
3951 reply
->fixed_pref
.bits
,
3952 print_hex_1(reply
->client_id
.len
,
3953 reply
->client_id
.data
, 60),
3955 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
3956 (reply
->on_star
.on_commit
!= NULL
)) {
3957 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
3958 reply
->packet
->options
,
3960 NULL
, reply
->on_star
.on_commit
,
3962 executable_statement_dereference
3963 (&reply
->on_star
.on_commit
, MDL
);
3969 * If we have any addresses log what we are doing.
3971 if (reply
->ia
->num_iasubopt
!= 0) {
3972 struct iasubopt
*tmp
;
3974 char tmp_addr
[INET6_ADDRSTRLEN
];
3976 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3977 tmp
= reply
->ia
->iasubopt
[i
];
3979 log_info("%s PD: address %s/%d to client with duid %s"
3980 " iaid = %d valid for %d seconds",
3981 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
3982 inet_ntop(AF_INET6
, &tmp
->addr
,
3983 tmp_addr
, sizeof(tmp_addr
)),
3985 print_hex_1(reply
->client_id
.len
,
3986 reply
->client_id
.data
, 60),
3992 * If this is not a 'soft' binding, consume the new changes into
3993 * the database (if any have been attached to the ia_pd).
3995 * Loop through the assigned dynamic prefixes, referencing the
3996 * prefixes onto this IA_PD rather than any old ones, and updating
3997 * prefix pool timers for each (if any).
3999 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
4000 (reply
->ia
->num_iasubopt
!= 0)) {
4001 struct iasubopt
*tmp
;
4002 struct data_string
*ia_id
;
4005 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
4006 tmp
= reply
->ia
->iasubopt
[i
];
4008 if (tmp
->ia
!= NULL
)
4009 ia_dereference(&tmp
->ia
, MDL
);
4010 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
4012 /* Commit 'hard' bindings. */
4013 renew_lease6(tmp
->ipv6_pool
, tmp
);
4014 schedule_lease_timeout(tmp
->ipv6_pool
);
4016 /* If we have anything to do on commit do it now */
4017 if (tmp
->on_star
.on_commit
!= NULL
) {
4018 execute_statements(NULL
, reply
->packet
,
4020 reply
->packet
->options
,
4023 tmp
->on_star
.on_commit
,
4025 executable_statement_dereference
4026 (&tmp
->on_star
.on_commit
, MDL
);
4029 /* Do our threshold check. */
4030 check_pool6_threshold(reply
, tmp
);
4033 /* Remove any old ia from the hash. */
4034 if (reply
->old_ia
!= NULL
) {
4035 ia_id
= &reply
->old_ia
->iaid_duid
;
4036 ia_hash_delete(ia_pd_active
,
4037 (unsigned char *)ia_id
->data
,
4039 ia_dereference(&reply
->old_ia
, MDL
);
4042 /* Put new ia into the hash. */
4043 reply
->ia
->cltt
= cur_time
;
4044 ia_id
= &reply
->ia
->iaid_duid
;
4045 ia_hash_add(ia_pd_active
, (unsigned char *)ia_id
->data
,
4046 ia_id
->len
, reply
->ia
, MDL
);
4048 write_ia(reply
->ia
);
4050 schedule_lease_timeout_reply(reply
);
4054 if (packet_ia
!= NULL
)
4055 option_state_dereference(&packet_ia
, MDL
);
4056 if (reply
->reply_ia
!= NULL
)
4057 option_state_dereference(&reply
->reply_ia
, MDL
);
4058 if (ia_data
.data
!= NULL
)
4059 data_string_forget(&ia_data
, MDL
);
4060 if (data
.data
!= NULL
)
4061 data_string_forget(&data
, MDL
);
4062 if (reply
->ia
!= NULL
)
4063 ia_dereference(&reply
->ia
, MDL
);
4064 if (reply
->old_ia
!= NULL
)
4065 ia_dereference(&reply
->old_ia
, MDL
);
4066 if (reply
->lease
!= NULL
)
4067 iasubopt_dereference(&reply
->lease
, MDL
);
4068 if (reply
->on_star
.on_expiry
!= NULL
)
4069 executable_statement_dereference
4070 (&reply
->on_star
.on_expiry
, MDL
);
4071 if (reply
->on_star
.on_release
!= NULL
)
4072 executable_statement_dereference
4073 (&reply
->on_star
.on_release
, MDL
);
4076 * ISC_R_CANCELED is a status code used by the prefix processing to
4077 * indicate we're replying with a status code. This is still a
4078 * success at higher layers.
4080 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
4085 * \brief Find the proper scoping group for use with a v6 static prefix.
4087 * We start by trying to find a subnet based on the given prefix and
4088 * the shared network. If we don't find one then the prefix has been
4089 * declared outside of any subnets. If there is a static address
4090 * associated with the host we use it to try and find a subnet (this
4091 * should succeed). If there isn't a static address we fall back
4092 * to the shared subnet itself.
4093 * Once we have a subnet we extract the group from it and return it.
4095 * \param reply - the reply structure we use to collect information
4096 * we will use the fields shared, fixed_pref and host
4097 * from the structure
4099 * \return a pointer to the group structure to use for scoping
4102 static struct group
*
4103 find_group_by_prefix(struct reply_state
*reply
) {
4104 /* default group if we don't find anything better */
4105 struct group
*group
= reply
->shared
->group
;
4106 struct subnet
*subnet
= NULL
;
4107 struct iaddr tmp_addr
;
4108 struct data_string fixed_addr
;
4110 /* Try with the prefix first */
4111 if (find_grouped_subnet(&subnet
, reply
->shared
,
4112 reply
->fixed_pref
.lo_addr
, MDL
) != 0) {
4113 group
= subnet
->group
;
4114 subnet_dereference(&subnet
, MDL
);
4118 /* Didn't find a subnet via prefix, what about fixed address */
4119 /* The caller has already tested reply->host != NULL */
4121 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
4123 if ((reply
->host
->fixed_addr
!= NULL
) &&
4124 (evaluate_option_cache(&fixed_addr
, NULL
, NULL
, NULL
,
4125 NULL
, NULL
, &global_scope
,
4126 reply
->host
->fixed_addr
, MDL
))) {
4127 if (fixed_addr
.len
>= 16) {
4129 memcpy(tmp_addr
.iabuf
, fixed_addr
.data
, 16);
4130 if (find_grouped_subnet(&subnet
, reply
->shared
,
4131 tmp_addr
, MDL
) != 0) {
4132 group
= subnet
->group
;
4133 subnet_dereference(&subnet
, MDL
);
4136 data_string_forget(&fixed_addr
, MDL
);
4139 /* return whatever we got */
4144 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
4145 * contents into the reply's current ia_pd-scoped option cache. Returns
4146 * ISC_R_CANCELED in the event we are replying with a status code and do
4147 * not wish to process more IAPREFIXes within this IA_PD.
4150 reply_process_prefix(struct reply_state
*reply
, struct option_cache
*pref
) {
4151 u_int32_t pref_life
, valid_life
;
4152 struct binding_scope
**scope
;
4153 struct iaddrcidrnet tmp_pref
;
4154 struct option_cache
*oc
;
4155 struct data_string iapref
, data
;
4156 isc_result_t status
= ISC_R_SUCCESS
;
4157 struct group
*group
;
4159 /* Initializes values that will be cleaned up. */
4160 memset(&iapref
, 0, sizeof(iapref
));
4161 memset(&data
, 0, sizeof(data
));
4162 /* Note that reply->lease may be set by prefix_is_owned() */
4165 * There is no point trying to process an incoming prefix if there
4166 * is no room for an outgoing prefix.
4168 if ((reply
->cursor
+ 29) > sizeof(reply
->buf
)) {
4169 log_error("reply_process_prefix: Out of room for prefix.");
4170 return ISC_R_NOSPACE
;
4173 /* Extract this IAPREFIX option. */
4174 if (!evaluate_option_cache(&iapref
, reply
->packet
, NULL
, NULL
,
4175 reply
->packet
->options
, NULL
, &global_scope
,
4177 (iapref
.len
< IAPREFIX_OFFSET
)) {
4178 log_error("reply_process_prefix: error evaluating IAPREFIX.");
4179 status
= ISC_R_FAILURE
;
4184 * Layout: preferred and valid lifetimes followed by the prefix
4185 * length and the IPv6 address.
4187 pref_life
= getULong(iapref
.data
);
4188 valid_life
= getULong(iapref
.data
+ 4);
4190 if ((reply
->client_valid
== 0) ||
4191 (reply
->client_valid
> valid_life
))
4192 reply
->client_valid
= valid_life
;
4194 if ((reply
->client_prefer
== 0) ||
4195 (reply
->client_prefer
> pref_life
))
4196 reply
->client_prefer
= pref_life
;
4199 * Clients may choose to send ::/0 as a prefix, with the idea to give
4200 * hints about preferred-lifetime or valid-lifetime.
4202 tmp_pref
.lo_addr
.len
= 16;
4203 memset(tmp_pref
.lo_addr
.iabuf
, 0, 16);
4204 if ((iapref
.data
[8] == 0) &&
4205 (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0)) {
4206 /* Status remains success; we just ignore this one. */
4211 * Clients may choose to send ::/X as a prefix to specify a
4212 * preferred/requested prefix length. Note X is never zero here.
4214 tmp_pref
.bits
= (int) iapref
.data
[8];
4215 if (reply
->preflen
< 0) {
4216 /* Cache the first preferred prefix length. */
4217 reply
->preflen
= tmp_pref
.bits
;
4219 if (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0) {
4223 memcpy(tmp_pref
.lo_addr
.iabuf
, iapref
.data
+ 9, 16);
4225 /* Verify the prefix belongs to the client. */
4226 if (!prefix_is_owned(reply
, &tmp_pref
)) {
4227 /* Same than for addresses. */
4228 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
4229 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
4230 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
4231 status
= reply_process_try_prefix(reply
, &tmp_pref
);
4233 /* Either error out or skip this prefix. */
4234 if ((status
!= ISC_R_SUCCESS
) &&
4235 (status
!= ISC_R_ADDRINUSE
) &&
4236 (status
!= ISC_R_ADDRNOTAVAIL
))
4239 if (reply
->lease
== NULL
) {
4240 if (reply
->packet
->dhcpv6_msg_type
==
4242 reply
->send_prefer
= 0;
4243 reply
->send_valid
= 0;
4247 /* status remains success - ignore */
4251 * RFC3633 section 18.2.3:
4253 * If the delegating router cannot find a binding
4254 * for the requesting router's IA_PD the delegating
4255 * router returns the IA_PD containing no prefixes
4256 * with a Status Code option set to NoBinding in the
4259 * On mismatch we (ab)use this pretending we have not the IA
4260 * as soon as we have not a prefix.
4262 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
4263 /* Rewind the IA_PD to empty. */
4264 option_state_dereference(&reply
->reply_ia
, MDL
);
4265 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
4266 log_error("reply_process_prefix: No memory "
4267 "for option state wipe.");
4268 status
= ISC_R_NOMEMORY
;
4272 /* Append a NoBinding status code. */
4273 if (!set_status_code(STATUS_NoBinding
,
4274 "Prefix not bound to this "
4275 "interface.", reply
->reply_ia
)) {
4276 log_error("reply_process_prefix: Unable to "
4277 "attach status code.");
4278 status
= ISC_R_FAILURE
;
4282 /* Fin (no more IAPREFIXes). */
4283 status
= ISC_R_CANCELED
;
4286 log_error("It is impossible to lease a client that is "
4287 "not sending a solicit, request, renew, or "
4289 status
= ISC_R_FAILURE
;
4294 if (reply
->static_prefixes
> 0) {
4295 if (reply
->host
== NULL
)
4296 log_fatal("Impossible condition at %s:%d.", MDL
);
4298 scope
= &global_scope
;
4300 /* Copy the static prefix for logging and finding the group */
4301 memcpy(&reply
->fixed_pref
, &tmp_pref
, sizeof(tmp_pref
));
4303 /* Try to find a group for the static prefix */
4304 group
= find_group_by_prefix(reply
);
4306 if (reply
->lease
== NULL
)
4307 log_fatal("Impossible condition at %s:%d.", MDL
);
4309 scope
= &reply
->lease
->scope
;
4310 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4314 * If client_resources is nonzero, then the reply_process_is_prefixed
4315 * function has executed configuration state into the reply option
4316 * cache. We will use that valid cache to derive configuration for
4317 * whether or not to engage in additional prefixes, and similar.
4319 if (reply
->client_resources
!= 0) {
4323 * Does this client have "enough" prefixes already? Default
4324 * to one. Everybody gets one, and one should be enough for
4327 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4328 SV_LIMIT_PREFS_PER_IA
);
4330 if (!evaluate_option_cache(&data
, reply
->packet
,
4332 reply
->packet
->options
,
4336 log_error("reply_process_prefix: unable to "
4337 "evaluate prefs-per-ia value.");
4338 status
= ISC_R_FAILURE
;
4342 limit
= getULong(data
.data
);
4343 data_string_forget(&data
, MDL
);
4347 * If we wish to limit the client to a certain number of
4348 * prefixes, then omit the prefix from the reply.
4350 if (reply
->client_resources
>= limit
)
4354 status
= reply_process_is_prefixed(reply
, scope
, group
);
4355 if (status
!= ISC_R_SUCCESS
)
4359 status
= reply_process_send_prefix(reply
, &tmp_pref
);
4362 if (iapref
.data
!= NULL
)
4363 data_string_forget(&iapref
, MDL
);
4364 if (data
.data
!= NULL
)
4365 data_string_forget(&data
, MDL
);
4366 if (reply
->lease
!= NULL
)
4367 iasubopt_dereference(&reply
->lease
, MDL
);
4373 * Verify the prefix belongs to the client. If we've got a host
4374 * record with fixed prefixes, it has to be an assigned prefix
4375 * (fault out all else). Otherwise it's a dynamic prefix, so lookup
4376 * that prefix and make sure it belongs to this DUID:IAID pair.
4378 static isc_boolean_t
4379 prefix_is_owned(struct reply_state
*reply
, struct iaddrcidrnet
*pref
) {
4380 struct iaddrcidrnetlist
*l
;
4382 struct ipv6_pond
*pond
;
4385 * This faults out prefixes that don't match fixed prefixes.
4387 if (reply
->static_prefixes
> 0) {
4388 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4389 if ((pref
->bits
== l
->cidrnet
.bits
) &&
4390 (memcmp(pref
->lo_addr
.iabuf
,
4391 l
->cidrnet
.lo_addr
.iabuf
, 16) == 0))
4397 if ((reply
->old_ia
== NULL
) ||
4398 (reply
->old_ia
->num_iasubopt
== 0))
4401 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4402 struct iasubopt
*tmp
;
4404 tmp
= reply
->old_ia
->iasubopt
[i
];
4406 if ((pref
->bits
== (int) tmp
->plen
) &&
4407 (memcmp(pref
->lo_addr
.iabuf
, &tmp
->addr
, 16) == 0)) {
4408 if (lease6_usable(tmp
) == ISC_FALSE
) {
4412 pond
= tmp
->ipv6_pool
->ipv6_pond
;
4413 if (((pond
->prohibit_list
!= NULL
) &&
4414 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4415 ((pond
->permit_list
!= NULL
) &&
4416 (!permitted(reply
->packet
, pond
->permit_list
))))
4419 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
4428 * This function only returns failure on 'hard' failures. If it succeeds,
4429 * it will leave a prefix structure behind.
4432 reply_process_try_prefix(struct reply_state
*reply
,
4433 struct iaddrcidrnet
*pref
) {
4434 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
4435 struct ipv6_pool
*pool
= NULL
;
4436 struct ipv6_pond
*pond
= NULL
;
4438 struct data_string data_pref
;
4440 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
4441 (pref
== NULL
) || (reply
->lease
!= NULL
))
4442 return (DHCP_R_INVALIDARG
);
4445 * Do a quick walk through of the ponds and pools
4446 * to see if we have any prefix pools
4448 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4449 if (pond
->ipv6_pools
== NULL
)
4452 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4453 if (pool
->pool_type
== D6O_IA_PD
)
4460 /* If we get here and p is NULL we have no useful pools */
4462 return (ISC_R_ADDRNOTAVAIL
);
4465 memset(&data_pref
, 0, sizeof(data_pref
));
4467 if (!buffer_allocate(&data_pref
.buffer
, data_pref
.len
, MDL
)) {
4468 log_error("reply_process_try_prefix: out of memory.");
4469 return (ISC_R_NOMEMORY
);
4471 data_pref
.data
= data_pref
.buffer
->data
;
4472 data_pref
.buffer
->data
[0] = (u_int8_t
) pref
->bits
;
4473 memcpy(data_pref
.buffer
->data
+ 1, pref
->lo_addr
.iabuf
, 16);
4476 * We have at least one pool that could provide a prefix
4477 * Now we walk through the ponds and pools again and check
4478 * to see if the client is permitted and if an prefix is
4483 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4484 if (((pond
->prohibit_list
!= NULL
) &&
4485 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4486 ((pond
->permit_list
!= NULL
) &&
4487 (!permitted(reply
->packet
, pond
->permit_list
))))
4490 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4491 if (pool
->pool_type
!= D6O_IA_PD
) {
4495 status
= try_client_v6_prefix(&reply
->lease
, pool
,
4497 /* If we found it in this pool (either in use or available),
4498 there is no need to look further. */
4499 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4502 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4506 data_string_forget(&data_pref
, MDL
);
4507 /* Return just the most recent status... */
4511 /* Look around for a prefix to give the client. First, look through the old
4512 * IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
4513 * Finally, actually add that prefix into the current reply IA_PD.
4516 find_client_prefix(struct reply_state
*reply
) {
4517 struct iaddrcidrnet send_pref
;
4518 isc_result_t status
= ISC_R_NORESOURCES
;
4519 struct iasubopt
*prefix
, *best_prefix
= NULL
;
4520 struct binding_scope
**scope
;
4522 struct group
*group
;
4524 if (reply
->static_prefixes
> 0) {
4525 struct iaddrcidrnetlist
*l
;
4527 if (reply
->host
== NULL
)
4528 return DHCP_R_INVALIDARG
;
4530 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4531 if (l
->cidrnet
.bits
== reply
->preflen
)
4536 * If no fixed prefix has the preferred length,
4537 * get the first one.
4539 l
= reply
->host
->fixed_prefix
;
4541 memcpy(&send_pref
, &l
->cidrnet
, sizeof(send_pref
));
4543 scope
= &global_scope
;
4545 /* Copy the prefix for logging purposes */
4546 memcpy(&reply
->fixed_pref
, &l
->cidrnet
, sizeof(send_pref
));
4548 /* Try to find a group for the static prefix */
4549 group
= find_group_by_prefix(reply
);
4554 if (reply
->old_ia
!= NULL
) {
4555 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4556 struct shared_network
*candidate_shared
;
4557 struct ipv6_pond
*pond
;
4559 prefix
= reply
->old_ia
->iasubopt
[i
];
4560 candidate_shared
= prefix
->ipv6_pool
->shared_network
;
4561 pond
= prefix
->ipv6_pool
->ipv6_pond
;
4564 * Consider this prefix if it is in a global pool or
4565 * if it is scoped in a pool under the client's shared
4568 if (((candidate_shared
!= NULL
) &&
4569 (candidate_shared
!= reply
->shared
)) ||
4570 (lease6_usable(prefix
) != ISC_TRUE
))
4574 * And check if the prefix is still permitted
4577 if (((pond
->prohibit_list
!= NULL
) &&
4578 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4579 ((pond
->permit_list
!= NULL
) &&
4580 (!permitted(reply
->packet
, pond
->permit_list
))))
4583 best_prefix
= prefix_compare(reply
, prefix
,
4588 /* Try to pick a new prefix if we didn't find one, or if we found an
4591 if ((best_prefix
== NULL
) || (best_prefix
->state
== FTS_ABANDONED
)) {
4592 status
= pick_v6_prefix(reply
);
4593 } else if (best_prefix
!= NULL
) {
4594 iasubopt_reference(&reply
->lease
, best_prefix
, MDL
);
4595 status
= ISC_R_SUCCESS
;
4598 /* Pick the abandoned prefix as a last resort. */
4599 if ((status
== ISC_R_NORESOURCES
) && (best_prefix
!= NULL
)) {
4600 /* I don't see how this is supposed to be done right now. */
4601 log_error("Reclaiming abandoned prefixes is not yet "
4602 "supported. Treating this as an out of space "
4604 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
4607 /* Give up now if we didn't find a prefix. */
4608 if (status
!= ISC_R_SUCCESS
)
4611 if (reply
->lease
== NULL
)
4612 log_fatal("Impossible condition at %s:%d.", MDL
);
4614 scope
= &reply
->lease
->scope
;
4615 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4617 send_pref
.lo_addr
.len
= 16;
4618 memcpy(send_pref
.lo_addr
.iabuf
, &reply
->lease
->addr
, 16);
4619 send_pref
.bits
= (int) reply
->lease
->plen
;
4622 status
= reply_process_is_prefixed(reply
, scope
, group
);
4623 if (status
!= ISC_R_SUCCESS
)
4626 status
= reply_process_send_prefix(reply
, &send_pref
);
4630 /* Once a prefix is found for a client, perform several common functions;
4631 * Calculate and store valid and preferred prefix times, draw client options
4632 * into the option state.
4635 reply_process_is_prefixed(struct reply_state
*reply
,
4636 struct binding_scope
**scope
, struct group
*group
)
4638 isc_result_t status
= ISC_R_SUCCESS
;
4639 struct data_string data
;
4640 struct option_cache
*oc
;
4641 struct option_state
*tmp_options
= NULL
;
4642 struct on_star
*on_star
;
4645 /* Initialize values we will cleanup. */
4646 memset(&data
, 0, sizeof(data
));
4649 * Find the proper on_star block to use. We use the
4650 * one in the lease if we have a lease or the one in
4651 * the reply if we don't have a lease because this is
4655 on_star
= &reply
->lease
->on_star
;
4657 on_star
= &reply
->on_star
;
4661 * Bring in the root configuration. We only do this to bring
4662 * in the on * statements, as we didn't have the lease available
4663 * we we did it the first time.
4665 option_state_allocate(&tmp_options
, MDL
);
4666 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4667 reply
->packet
->options
, tmp_options
,
4668 &global_scope
, root_group
, NULL
,
4670 if (tmp_options
!= NULL
) {
4671 option_state_dereference(&tmp_options
, MDL
);
4675 * Bring configured options into the root packet level cache - start
4676 * with the lease's closest enclosing group (passed in by the caller
4679 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4680 reply
->packet
->options
, reply
->opt_state
,
4681 scope
, group
, root_group
, on_star
);
4683 /* Execute statements from class scopes. */
4684 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
4685 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4686 reply
->packet
->options
,
4687 reply
->opt_state
, scope
,
4688 reply
->packet
->classes
[i
- 1]->group
,
4693 * If there is a host record, over-ride with values configured there,
4694 * without re-evaluating configuration from the previously executed
4695 * group or its common enclosers.
4697 if (reply
->host
!= NULL
)
4698 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4699 reply
->packet
->options
,
4700 reply
->opt_state
, scope
,
4701 reply
->host
->group
, group
,
4704 /* Determine valid lifetime. */
4705 if (reply
->client_valid
== 0)
4706 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
4708 reply
->send_valid
= reply
->client_valid
;
4710 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4711 SV_DEFAULT_LEASE_TIME
);
4713 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4714 reply
->packet
->options
,
4718 log_error("reply_process_is_prefixed: unable to "
4719 "evaluate default prefix time");
4720 status
= ISC_R_FAILURE
;
4724 reply
->send_valid
= getULong(data
.data
);
4725 data_string_forget(&data
, MDL
);
4728 if (reply
->client_prefer
== 0)
4729 reply
->send_prefer
= reply
->send_valid
;
4731 reply
->send_prefer
= reply
->client_prefer
;
4733 if (reply
->send_prefer
>= reply
->send_valid
)
4734 reply
->send_prefer
= (reply
->send_valid
/ 2) +
4735 (reply
->send_valid
/ 8);
4737 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4738 SV_PREFER_LIFETIME
);
4740 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4741 reply
->packet
->options
,
4745 log_error("reply_process_is_prefixed: unable to "
4746 "evaluate preferred prefix time");
4747 status
= ISC_R_FAILURE
;
4751 reply
->send_prefer
= getULong(data
.data
);
4752 data_string_forget(&data
, MDL
);
4755 /* Note lowest values for later calculation of renew/rebind times. */
4756 if (reply
->prefer
> reply
->send_prefer
)
4757 reply
->prefer
= reply
->send_prefer
;
4759 if (reply
->valid
> reply
->send_valid
)
4760 reply
->valid
= reply
->send_valid
;
4762 /* Perform dynamic prefix related update work. */
4763 if (reply
->lease
!= NULL
) {
4764 /* Cached lifetimes */
4765 reply
->lease
->prefer
= reply
->send_prefer
;
4766 reply
->lease
->valid
= reply
->send_valid
;
4768 /* Advance (or rewind) the valid lifetime. */
4769 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
4770 reply
->lease
->soft_lifetime_end_time
=
4771 cur_time
+ reply
->send_valid
;
4772 /* Wait before renew! */
4775 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
4776 if (status
!= ISC_R_SUCCESS
) {
4777 log_fatal("reply_process_is_prefixed: Unable to "
4778 "attach prefix to new IA_PD: %s",
4779 isc_result_totext(status
));
4783 * If this is a new prefix, make sure it is attached somewhere.
4785 if (reply
->lease
->ia
== NULL
) {
4786 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
4790 /* Bring a copy of the relevant options into the IA_PD scope. */
4791 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4792 reply
->packet
->options
, reply
->reply_ia
,
4793 scope
, group
, root_group
, NULL
);
4795 /* Execute statements from class scopes. */
4796 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
4797 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4798 reply
->packet
->options
,
4799 reply
->reply_ia
, scope
,
4800 reply
->packet
->classes
[i
- 1]->group
,
4805 * And bring in host record configuration, if any, but not to overlap
4806 * the previous group or its common enclosers.
4808 if (reply
->host
!= NULL
)
4809 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4810 reply
->packet
->options
,
4811 reply
->reply_ia
, scope
,
4812 reply
->host
->group
, group
, NULL
);
4815 if (data
.data
!= NULL
)
4816 data_string_forget(&data
, MDL
);
4818 if (status
== ISC_R_SUCCESS
)
4819 reply
->client_resources
++;
4824 /* Simply send an IAPREFIX within the IA_PD scope as described. */
4826 reply_process_send_prefix(struct reply_state
*reply
,
4827 struct iaddrcidrnet
*pref
) {
4828 isc_result_t status
= ISC_R_SUCCESS
;
4829 struct data_string data
;
4831 memset(&data
, 0, sizeof(data
));
4833 /* Now append the prefix. */
4834 data
.len
= IAPREFIX_OFFSET
;
4835 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
4836 log_error("reply_process_send_prefix: out of memory"
4837 "allocating new IAPREFIX buffer.");
4838 status
= ISC_R_NOMEMORY
;
4841 data
.data
= data
.buffer
->data
;
4843 putULong(data
.buffer
->data
, reply
->send_prefer
);
4844 putULong(data
.buffer
->data
+ 4, reply
->send_valid
);
4845 data
.buffer
->data
[8] = pref
->bits
;
4846 memcpy(data
.buffer
->data
+ 9, pref
->lo_addr
.iabuf
, 16);
4848 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
4849 data
.buffer
, data
.buffer
->data
,
4850 data
.len
, D6O_IAPREFIX
, 0)) {
4851 log_error("reply_process_send_prefix: unable "
4852 "to save IAPREFIX option");
4853 status
= ISC_R_FAILURE
;
4857 reply
->resources_included
= ISC_TRUE
;
4860 if (data
.data
!= NULL
)
4861 data_string_forget(&data
, MDL
);
4866 /* Choose the better of two prefixes. */
4867 static struct iasubopt
*
4868 prefix_compare(struct reply_state
*reply
,
4869 struct iasubopt
*alpha
, struct iasubopt
*beta
) {
4875 if (reply
->preflen
>= 0) {
4876 if ((alpha
->plen
== reply
->preflen
) &&
4877 (beta
->plen
!= reply
->preflen
))
4879 if ((beta
->plen
== reply
->preflen
) &&
4880 (alpha
->plen
!= reply
->preflen
))
4884 switch(alpha
->state
) {
4886 switch(beta
->state
) {
4888 /* Choose the prefix with the longest lifetime (most
4889 * likely the most recently allocated).
4891 if (alpha
->hard_lifetime_end_time
<
4892 beta
->hard_lifetime_end_time
)
4902 log_fatal("Impossible condition at %s:%d.", MDL
);
4907 switch (beta
->state
) {
4912 /* Choose the most recently expired prefix. */
4913 if (alpha
->hard_lifetime_end_time
<
4914 beta
->hard_lifetime_end_time
)
4916 else if ((alpha
->hard_lifetime_end_time
==
4917 beta
->hard_lifetime_end_time
) &&
4918 (alpha
->soft_lifetime_end_time
<
4919 beta
->soft_lifetime_end_time
))
4928 log_fatal("Impossible condition at %s:%d.", MDL
);
4933 switch (beta
->state
) {
4939 /* Choose the prefix that was abandoned longest ago. */
4940 if (alpha
->hard_lifetime_end_time
<
4941 beta
->hard_lifetime_end_time
)
4947 log_fatal("Impossible condition at %s:%d.", MDL
);
4952 log_fatal("Impossible condition at %s:%d.", MDL
);
4955 log_fatal("Triple impossible condition at %s:%d.", MDL
);
4960 * Solicit is how a client starts requesting addresses.
4962 * If the client asks for rapid commit, and we support it, we will
4963 * allocate the addresses and reply.
4965 * Otherwise we will send an advertise message.
4969 dhcpv6_solicit(struct data_string
*reply_ret
, struct packet
*packet
) {
4970 struct data_string client_id
;
4973 * Validate our input.
4975 if (!valid_client_msg(packet
, &client_id
)) {
4979 lease_to_client(reply_ret
, packet
, &client_id
, NULL
);
4984 data_string_forget(&client_id
, MDL
);
4988 * Request is how a client actually requests addresses.
4990 * Very similar to Solicit handling, except the server DUID is required.
4994 dhcpv6_request(struct data_string
*reply_ret
, struct packet
*packet
) {
4995 struct data_string client_id
;
4996 struct data_string server_id
;
4999 * Validate our input.
5001 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5005 /* If the REQUEST arrived via unicast and unicast option isn't set,
5006 * reject it per RFC 3315, Sec 18.2.1 */
5007 if (packet
->unicast
== ISC_TRUE
&&
5008 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5009 unicast_reject(reply_ret
, packet
, &client_id
, &server_id
);
5014 lease_to_client(reply_ret
, packet
, &client_id
, &server_id
);
5020 data_string_forget(&client_id
, MDL
);
5021 data_string_forget(&server_id
, MDL
);
5024 /* Find a DHCPv6 packet's shared network from hints in the packet.
5027 shared_network_from_packet6(struct shared_network
**shared
,
5028 struct packet
*packet
)
5030 const struct packet
*chk_packet
;
5031 const struct in6_addr
*link_addr
, *first_link_addr
;
5032 struct iaddr tmp_addr
;
5033 struct subnet
*subnet
;
5034 isc_result_t status
;
5036 if ((shared
== NULL
) || (*shared
!= NULL
) || (packet
== NULL
))
5037 return DHCP_R_INVALIDARG
;
5040 * First, find the link address where the packet from the client
5041 * first appeared (if this packet was relayed).
5043 first_link_addr
= NULL
;
5044 chk_packet
= packet
->dhcpv6_container_packet
;
5045 while (chk_packet
!= NULL
) {
5046 link_addr
= &chk_packet
->dhcpv6_link_address
;
5047 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
5048 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
5049 first_link_addr
= link_addr
;
5052 chk_packet
= chk_packet
->dhcpv6_container_packet
;
5056 * If there is a relayed link address, find the subnet associated
5057 * with that, and use that to get the appropriate
5060 if (first_link_addr
!= NULL
) {
5061 tmp_addr
.len
= sizeof(*first_link_addr
);
5062 memcpy(tmp_addr
.iabuf
,
5063 first_link_addr
, sizeof(*first_link_addr
));
5065 if (!find_subnet(&subnet
, tmp_addr
, MDL
)) {
5066 log_debug("No subnet found for link-address %s.",
5068 return ISC_R_NOTFOUND
;
5070 status
= shared_network_reference(shared
,
5071 subnet
->shared_network
, MDL
);
5072 subnet_dereference(&subnet
, MDL
);
5075 * If there is no link address, we will use the interface
5076 * that this packet came in on to pick the shared_network.
5078 } else if (packet
->interface
!= NULL
) {
5079 status
= shared_network_reference(shared
,
5080 packet
->interface
->shared_network
,
5082 if (packet
->dhcpv6_container_packet
!= NULL
) {
5083 log_info("[L2 Relay] No link address in relay packet "
5084 "assuming L2 relay and using receiving "
5090 * We shouldn't be able to get here but if there is no link
5091 * address and no interface we don't know where to get the
5092 * pool from log an error and return an error.
5094 log_error("No interface and no link address "
5095 "can't determine pool");
5096 status
= DHCP_R_INVALIDARG
;
5103 * When a client thinks it might be on a new link, it sends a
5106 * From RFC3315 section 18.2.2:
5108 * When the server receives a Confirm message, the server determines
5109 * whether the addresses in the Confirm message are appropriate for the
5110 * link to which the client is attached. If all of the addresses in the
5111 * Confirm message pass this test, the server returns a status of
5112 * Success. If any of the addresses do not pass this test, the server
5113 * returns a status of NotOnLink. If the server is unable to perform
5114 * this test (for example, the server does not have information about
5115 * prefixes on the link to which the client is connected), or there were
5116 * no addresses in any of the IAs sent by the client, the server MUST
5117 * NOT send a reply to the client.
5121 dhcpv6_confirm(struct data_string
*reply_ret
, struct packet
*packet
) {
5122 struct shared_network
*shared
;
5123 struct subnet
*subnet
;
5124 struct option_cache
*ia
, *ta
, *oc
;
5125 struct data_string cli_enc_opt_data
, iaaddr
, client_id
, packet_oro
;
5126 struct option_state
*cli_enc_opt_state
, *opt_state
;
5127 struct iaddr cli_addr
;
5129 isc_boolean_t inappropriate
, has_addrs
;
5130 char reply_data
[65536];
5131 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5132 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5135 * Basic client message validation.
5137 memset(&client_id
, 0, sizeof(client_id
));
5138 if (!valid_client_msg(packet
, &client_id
)) {
5143 * Do not process Confirms that do not have IA's we do not recognize.
5145 ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5146 ta
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
5147 if ((ia
== NULL
) && (ta
== NULL
))
5151 * IA_PD's are simply ignored.
5153 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5156 * Bit of variable initialization.
5158 opt_state
= cli_enc_opt_state
= NULL
;
5159 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5160 memset(&iaaddr
, 0, sizeof(iaaddr
));
5161 memset(&packet_oro
, 0, sizeof(packet_oro
));
5163 /* Determine what shared network the client is connected to. We
5164 * must not respond if we don't have any information about the
5165 * network the client is on.
5168 if ((shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
) ||
5172 /* If there are no recorded subnets, then we have no
5173 * information about this subnet - ignore Confirms.
5175 subnet
= shared
->subnets
;
5179 /* Are the addresses in all the IA's appropriate for that link? */
5180 has_addrs
= inappropriate
= ISC_FALSE
;
5182 while(!inappropriate
) {
5183 /* If we've reached the end of the IA_NA pass, move to the
5186 if ((pass
== D6O_IA_NA
) && (ia
== NULL
)) {
5191 /* If we've reached the end of all passes, we're done. */
5195 if (((pass
== D6O_IA_NA
) &&
5196 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5198 packet
, ia
, IA_NA_OFFSET
)) ||
5199 ((pass
== D6O_IA_TA
) &&
5200 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5202 packet
, ia
, IA_TA_OFFSET
))) {
5206 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5209 for ( ; oc
!= NULL
; oc
= oc
->next
) {
5210 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5211 packet
->options
, NULL
,
5212 &global_scope
, oc
, MDL
) ||
5213 (iaaddr
.len
< IAADDR_OFFSET
)) {
5214 log_error("dhcpv6_confirm: "
5215 "error evaluating IAADDR.");
5219 /* Copy out the IPv6 address for processing. */
5221 memcpy(cli_addr
.iabuf
, iaaddr
.data
, 16);
5223 data_string_forget(&iaaddr
, MDL
);
5225 /* Record that we've processed at least one address. */
5226 has_addrs
= ISC_TRUE
;
5228 /* Find out if any subnets cover this address. */
5229 for (subnet
= shared
->subnets
; subnet
!= NULL
;
5230 subnet
= subnet
->next_sibling
) {
5231 if (addr_eq(subnet_number(cli_addr
,
5237 /* If we reach the end of the subnet list, and no
5238 * subnet matches the client address, then it must
5239 * be inappropriate to the link (so far as our
5240 * configuration says). Once we've found one
5241 * inappropriate address, there is no reason to
5242 * continue searching.
5244 if (subnet
== NULL
) {
5245 inappropriate
= ISC_TRUE
;
5250 option_state_dereference(&cli_enc_opt_state
, MDL
);
5251 data_string_forget(&cli_enc_opt_data
, MDL
);
5253 /* Advance to the next IA_*. */
5257 /* If the client supplied no addresses, do not reply. */
5264 if (!start_reply(packet
, &client_id
, NULL
, &opt_state
, reply
)) {
5271 if (inappropriate
) {
5272 if (!set_status_code(STATUS_NotOnLink
,
5273 "Some of the addresses are not on link.",
5278 if (!set_status_code(STATUS_Success
,
5279 "All addresses still on link.",
5286 * Only one option: add it.
5288 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5289 sizeof(reply_data
)-reply_ofs
,
5291 required_opts
, &packet_oro
);
5294 * Return our reply to the caller.
5296 reply_ret
->len
= reply_ofs
;
5297 reply_ret
->buffer
= NULL
;
5298 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5299 log_fatal("No memory to store reply.");
5301 reply_ret
->data
= reply_ret
->buffer
->data
;
5302 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5305 /* Cleanup any stale data strings. */
5306 if (cli_enc_opt_data
.buffer
!= NULL
)
5307 data_string_forget(&cli_enc_opt_data
, MDL
);
5308 if (iaaddr
.buffer
!= NULL
)
5309 data_string_forget(&iaaddr
, MDL
);
5310 if (client_id
.buffer
!= NULL
)
5311 data_string_forget(&client_id
, MDL
);
5312 if (packet_oro
.buffer
!= NULL
)
5313 data_string_forget(&packet_oro
, MDL
);
5315 /* Release any stale option states. */
5316 if (cli_enc_opt_state
!= NULL
)
5317 option_state_dereference(&cli_enc_opt_state
, MDL
);
5318 if (opt_state
!= NULL
)
5319 option_state_dereference(&opt_state
, MDL
);
5323 * Renew is when a client wants to extend its lease/prefix, at time T1.
5325 * We handle this the same as if the client wants a new lease/prefix,
5326 * except for the error code of when addresses don't match.
5330 dhcpv6_renew(struct data_string
*reply
, struct packet
*packet
) {
5331 struct data_string client_id
;
5332 struct data_string server_id
;
5335 * Validate the request.
5337 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5341 /* If the RENEW arrived via unicast and unicast option isn't set,
5342 * reject it per RFC 3315, Sec 18.2.3 */
5343 if (packet
->unicast
== ISC_TRUE
&&
5344 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5345 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5350 lease_to_client(reply
, packet
, &client_id
, &server_id
);
5356 data_string_forget(&server_id
, MDL
);
5357 data_string_forget(&client_id
, MDL
);
5361 * Rebind is when a client wants to extend its lease, at time T2.
5363 * We handle this the same as if the client wants a new lease, except
5364 * for the error code of when addresses don't match.
5368 dhcpv6_rebind(struct data_string
*reply
, struct packet
*packet
) {
5369 struct data_string client_id
;
5371 if (!valid_client_msg(packet
, &client_id
)) {
5375 lease_to_client(reply
, packet
, &client_id
, NULL
);
5377 data_string_forget(&client_id
, MDL
);
5381 ia_na_match_decline(const struct data_string
*client_id
,
5382 const struct data_string
*iaaddr
,
5383 struct iasubopt
*lease
)
5385 char tmp_addr
[INET6_ADDRSTRLEN
];
5387 log_error("Client %s reports address %s is "
5388 "already in use by another host!",
5389 print_hex_1(client_id
->len
, client_id
->data
, 60),
5390 inet_ntop(AF_INET6
, iaaddr
->data
,
5391 tmp_addr
, sizeof(tmp_addr
)));
5392 if (lease
!= NULL
) {
5393 decline_lease6(lease
->ipv6_pool
, lease
);
5394 lease
->ia
->cltt
= cur_time
;
5395 write_ia(lease
->ia
);
5400 ia_na_nomatch_decline(const struct data_string
*client_id
,
5401 const struct data_string
*iaaddr
,
5402 u_int32_t
*ia_na_id
,
5403 struct packet
*packet
,
5408 char tmp_addr
[INET6_ADDRSTRLEN
];
5409 struct option_state
*host_opt_state
;
5412 log_info("Client %s declines address %s, which is not offered to it.",
5413 print_hex_1(client_id
->len
, client_id
->data
, 60),
5414 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5417 * Create state for this IA_NA.
5419 host_opt_state
= NULL
;
5420 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5421 log_error("ia_na_nomatch_decline: out of memory "
5422 "allocating option_state.");
5426 if (!set_status_code(STATUS_NoBinding
, "Decline for unknown address.",
5432 * Insure we have enough space
5434 if (reply_len
< (*reply_ofs
+ 16)) {
5435 log_error("ia_na_nomatch_decline: "
5436 "out of space for reply packet.");
5441 * Put our status code into the reply packet.
5443 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5444 reply_len
-(*reply_ofs
)-16,
5445 host_opt_state
, packet
,
5446 required_opts_STATUS_CODE
, NULL
);
5449 * Store the non-encapsulated option data for this
5450 * IA_NA into our reply packet. Defined in RFC 3315,
5454 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5456 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5457 /* IA_NA, copied from the client */
5458 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5459 /* t1 and t2, odd that we need them, but here it is */
5460 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5461 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5464 * Get ready for next IA_NA.
5466 *reply_ofs
+= (len
+ 16);
5469 option_state_dereference(&host_opt_state
, MDL
);
5473 iterate_over_ia_na(struct data_string
*reply_ret
,
5474 struct packet
*packet
,
5475 const struct data_string
*client_id
,
5476 const struct data_string
*server_id
,
5477 const char *packet_type
,
5478 void (*ia_na_match
)(),
5479 void (*ia_na_nomatch
)())
5481 struct option_state
*opt_state
;
5482 struct host_decl
*packet_host
;
5483 struct option_cache
*ia
;
5484 struct option_cache
*oc
;
5485 /* cli_enc_... variables come from the IA_NA/IA_TA options */
5486 struct data_string cli_enc_opt_data
;
5487 struct option_state
*cli_enc_opt_state
;
5488 struct host_decl
*host
;
5489 struct option_state
*host_opt_state
;
5490 struct data_string iaaddr
;
5491 struct data_string fixed_addr
;
5492 char reply_data
[65536];
5493 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5494 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5495 char status_msg
[32];
5496 struct iasubopt
*lease
;
5497 struct ia_xx
*existing_ia_na
;
5499 struct data_string key
;
5503 * Initialize to empty values, in case we have to exit early.
5506 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5507 cli_enc_opt_state
= NULL
;
5508 memset(&iaaddr
, 0, sizeof(iaaddr
));
5509 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
5510 host_opt_state
= NULL
;
5514 * Find the host record that matches from the packet, if any.
5517 if (!find_hosts_by_uid(&packet_host
,
5518 client_id
->data
, client_id
->len
, MDL
)) {
5521 * Note: In general, we don't expect a client to provide
5522 * enough information to match by option for these
5523 * types of messages, but if we don't have a UID
5524 * match we can check anyway.
5526 if (!find_hosts_by_option(&packet_host
,
5527 packet
, packet
->options
, MDL
)) {
5530 if (!find_hosts_by_duid_chaddr(&packet_host
,
5537 * Set our reply information.
5539 reply
->msg_type
= DHCPV6_REPLY
;
5540 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
5541 sizeof(reply
->transaction_id
));
5544 * Build our option state for reply.
5547 if (!option_state_allocate(&opt_state
, MDL
)) {
5548 log_error("iterate_over_ia_na: no memory for option_state.");
5551 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5552 packet
->options
, opt_state
,
5553 &global_scope
, root_group
, NULL
, NULL
);
5556 * RFC 3315, section 18.2.7 tells us which options to include.
5558 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
5560 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5561 (unsigned char *)server_duid
.data
,
5562 server_duid
.len
, D6O_SERVERID
, 0)) {
5563 log_error("iterate_over_ia_na: "
5564 "error saving server identifier.");
5569 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
5571 (unsigned char *)client_id
->data
,
5574 log_error("iterate_over_ia_na: "
5575 "error saving client identifier.");
5579 snprintf(status_msg
, sizeof(status_msg
), "%s received.", packet_type
);
5580 if (!set_status_code(STATUS_Success
, status_msg
, opt_state
)) {
5585 * Add our options that are not associated with any IA_NA or IA_TA.
5587 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5588 sizeof(reply_data
)-reply_ofs
,
5590 required_opts
, NULL
);
5593 * Loop through the IA_NA reported by the client, and deal with
5594 * addresses reported as already in use.
5596 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5597 ia
!= NULL
; ia
= ia
->next
) {
5599 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
5601 packet
, ia
, IA_NA_OFFSET
)) {
5605 iaid
= getULong(cli_enc_opt_data
.data
);
5608 * XXX: It is possible that we can get multiple addresses
5609 * sent by the client. We don't send multiple
5610 * addresses, so this indicates a client error.
5611 * We should check for multiple IAADDR options, log
5612 * if found, and set as an error.
5614 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5617 /* no address given for this IA, ignore */
5618 option_state_dereference(&cli_enc_opt_state
, MDL
);
5619 data_string_forget(&cli_enc_opt_data
, MDL
);
5623 memset(&iaaddr
, 0, sizeof(iaaddr
));
5624 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5625 packet
->options
, NULL
,
5626 &global_scope
, oc
, MDL
)) {
5627 log_error("iterate_over_ia_na: "
5628 "error evaluating IAADDR.");
5633 * Now we need to figure out which host record matches
5634 * this IA_NA and IAADDR (encapsulated option contents
5635 * matching a host record by option).
5637 * XXX: We don't currently track IA_NA separately, but
5638 * we will need to do this!
5641 if (!find_hosts_by_option(&host
, packet
,
5642 cli_enc_opt_state
, MDL
)) {
5643 if (packet_host
!= NULL
) {
5649 while (host
!= NULL
) {
5650 if (host
->fixed_addr
!= NULL
) {
5651 if (!evaluate_option_cache(&fixed_addr
, NULL
,
5653 NULL
, &global_scope
,
5656 log_error("iterate_over_ia_na: error "
5657 "evaluating host address.");
5660 if ((iaaddr
.len
>= 16) &&
5661 !memcmp(fixed_addr
.data
, iaaddr
.data
, 16)) {
5662 data_string_forget(&fixed_addr
, MDL
);
5665 data_string_forget(&fixed_addr
, MDL
);
5667 host
= host
->n_ipaddr
;
5670 if ((host
== NULL
) && (iaaddr
.len
>= IAADDR_OFFSET
)) {
5672 * Find existing IA_NA.
5674 if (ia_make_key(&key
, iaid
,
5675 (char *)client_id
->data
,
5677 MDL
) != ISC_R_SUCCESS
) {
5678 log_fatal("iterate_over_ia_na: no memory for "
5682 existing_ia_na
= NULL
;
5683 if (ia_hash_lookup(&existing_ia_na
, ia_na_active
,
5684 (unsigned char *)key
.data
,
5687 * Make sure this address is in the IA_NA.
5689 for (i
=0; i
<existing_ia_na
->num_iasubopt
; i
++) {
5690 struct iasubopt
*tmp
;
5691 struct in6_addr
*in6_addr
;
5693 tmp
= existing_ia_na
->iasubopt
[i
];
5694 in6_addr
= &tmp
->addr
;
5695 if (memcmp(in6_addr
,
5696 iaaddr
.data
, 16) == 0) {
5697 iasubopt_reference(&lease
,
5704 data_string_forget(&key
, MDL
);
5707 if ((host
!= NULL
) || (lease
!= NULL
)) {
5708 ia_na_match(client_id
, &iaaddr
, lease
);
5710 ia_na_nomatch(client_id
, &iaaddr
,
5711 (u_int32_t
*)cli_enc_opt_data
.data
,
5712 packet
, reply_data
, &reply_ofs
,
5713 sizeof(reply_data
));
5716 if (lease
!= NULL
) {
5717 iasubopt_dereference(&lease
, MDL
);
5720 data_string_forget(&iaaddr
, MDL
);
5721 option_state_dereference(&cli_enc_opt_state
, MDL
);
5722 data_string_forget(&cli_enc_opt_data
, MDL
);
5726 * Return our reply to the caller.
5728 reply_ret
->len
= reply_ofs
;
5729 reply_ret
->buffer
= NULL
;
5730 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5731 log_fatal("No memory to store reply.");
5733 reply_ret
->data
= reply_ret
->buffer
->data
;
5734 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5737 if (lease
!= NULL
) {
5738 iasubopt_dereference(&lease
, MDL
);
5740 if (host_opt_state
!= NULL
) {
5741 option_state_dereference(&host_opt_state
, MDL
);
5743 if (fixed_addr
.buffer
!= NULL
) {
5744 data_string_forget(&fixed_addr
, MDL
);
5746 if (iaaddr
.buffer
!= NULL
) {
5747 data_string_forget(&iaaddr
, MDL
);
5749 if (cli_enc_opt_state
!= NULL
) {
5750 option_state_dereference(&cli_enc_opt_state
, MDL
);
5752 if (cli_enc_opt_data
.buffer
!= NULL
) {
5753 data_string_forget(&cli_enc_opt_data
, MDL
);
5755 if (opt_state
!= NULL
) {
5756 option_state_dereference(&opt_state
, MDL
);
5761 * Decline means a client has detected that something else is using an
5762 * address we gave it.
5764 * Since we're only dealing with fixed leases for now, there's not
5765 * much we can do, other that log the occurrence.
5767 * When we start issuing addresses from pools, then we will have to
5768 * record our declined addresses and issue another. In general with
5769 * IPv6 there is no worry about DoS by clients exhausting space, but
5770 * we still need to be aware of this possibility.
5775 dhcpv6_decline(struct data_string
*reply
, struct packet
*packet
) {
5776 struct data_string client_id
;
5777 struct data_string server_id
;
5780 * Validate our input.
5782 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5786 /* If the DECLINE arrived via unicast and unicast option isn't set,
5787 * reject it per RFC 3315, Sec 18.2.7 */
5788 if (packet
->unicast
== ISC_TRUE
&&
5789 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5790 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5793 * Undefined for IA_PD.
5795 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5798 * And operate on each IA_NA in this packet.
5800 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
5801 "Decline", ia_na_match_decline
,
5802 ia_na_nomatch_decline
);
5806 data_string_forget(&server_id
, MDL
);
5807 data_string_forget(&client_id
, MDL
);
5811 ia_na_match_release(const struct data_string
*client_id
,
5812 const struct data_string
*iaaddr
,
5813 struct iasubopt
*lease
)
5815 char tmp_addr
[INET6_ADDRSTRLEN
];
5817 log_info("Client %s releases address %s",
5818 print_hex_1(client_id
->len
, client_id
->data
, 60),
5819 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5820 if (lease
!= NULL
) {
5821 release_lease6(lease
->ipv6_pool
, lease
);
5822 lease
->ia
->cltt
= cur_time
;
5823 write_ia(lease
->ia
);
5828 ia_na_nomatch_release(const struct data_string
*client_id
,
5829 const struct data_string
*iaaddr
,
5830 u_int32_t
*ia_na_id
,
5831 struct packet
*packet
,
5836 char tmp_addr
[INET6_ADDRSTRLEN
];
5837 struct option_state
*host_opt_state
;
5840 log_info("Client %s releases address %s, which is not leased to it.",
5841 print_hex_1(client_id
->len
, client_id
->data
, 60),
5842 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5845 * Create state for this IA_NA.
5847 host_opt_state
= NULL
;
5848 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5849 log_error("ia_na_nomatch_release: out of memory "
5850 "allocating option_state.");
5854 if (!set_status_code(STATUS_NoBinding
,
5855 "Release for non-leased address.",
5861 * Insure we have enough space
5863 if (reply_len
< (*reply_ofs
+ 16)) {
5864 log_error("ia_na_nomatch_release: "
5865 "out of space for reply packet.");
5870 * Put our status code into the reply packet.
5872 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5873 reply_len
-(*reply_ofs
)-16,
5874 host_opt_state
, packet
,
5875 required_opts_STATUS_CODE
, NULL
);
5878 * Store the non-encapsulated option data for this
5879 * IA_NA into our reply packet. Defined in RFC 3315,
5883 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5885 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5886 /* IA_NA, copied from the client */
5887 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5888 /* t1 and t2, odd that we need them, but here it is */
5889 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5890 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5893 * Get ready for next IA_NA.
5895 *reply_ofs
+= (len
+ 16);
5898 option_state_dereference(&host_opt_state
, MDL
);
5902 ia_pd_match_release(const struct data_string
*client_id
,
5903 const struct data_string
*iapref
,
5904 struct iasubopt
*prefix
)
5906 char tmp_addr
[INET6_ADDRSTRLEN
];
5908 log_info("Client %s releases prefix %s/%u",
5909 print_hex_1(client_id
->len
, client_id
->data
, 60),
5910 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5911 tmp_addr
, sizeof(tmp_addr
)),
5912 (unsigned) getUChar(iapref
->data
+ 8));
5913 if (prefix
!= NULL
) {
5914 release_lease6(prefix
->ipv6_pool
, prefix
);
5915 prefix
->ia
->cltt
= cur_time
;
5916 write_ia(prefix
->ia
);
5921 ia_pd_nomatch_release(const struct data_string
*client_id
,
5922 const struct data_string
*iapref
,
5923 u_int32_t
*ia_pd_id
,
5924 struct packet
*packet
,
5929 char tmp_addr
[INET6_ADDRSTRLEN
];
5930 struct option_state
*host_opt_state
;
5933 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
5934 print_hex_1(client_id
->len
, client_id
->data
, 60),
5935 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5936 tmp_addr
, sizeof(tmp_addr
)),
5937 (unsigned) getUChar(iapref
->data
+ 8));
5940 * Create state for this IA_PD.
5942 host_opt_state
= NULL
;
5943 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5944 log_error("ia_pd_nomatch_release: out of memory "
5945 "allocating option_state.");
5949 if (!set_status_code(STATUS_NoBinding
,
5950 "Release for non-leased prefix.",
5956 * Insure we have enough space
5958 if (reply_len
< (*reply_ofs
+ 16)) {
5959 log_error("ia_pd_nomatch_release: "
5960 "out of space for reply packet.");
5965 * Put our status code into the reply packet.
5967 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5968 reply_len
-(*reply_ofs
)-16,
5969 host_opt_state
, packet
,
5970 required_opts_STATUS_CODE
, NULL
);
5973 * Store the non-encapsulated option data for this
5974 * IA_PD into our reply packet. Defined in RFC 3315,
5978 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_PD
);
5980 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5981 /* IA_PD, copied from the client */
5982 memcpy(reply_data
+(*reply_ofs
)+4, ia_pd_id
, 4);
5983 /* t1 and t2, odd that we need them, but here it is */
5984 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5985 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5988 * Get ready for next IA_PD.
5990 *reply_ofs
+= (len
+ 16);
5993 option_state_dereference(&host_opt_state
, MDL
);
5997 iterate_over_ia_pd(struct data_string
*reply_ret
,
5998 struct packet
*packet
,
5999 const struct data_string
*client_id
,
6000 const struct data_string
*server_id
,
6001 const char *packet_type
,
6002 void (*ia_pd_match
)(),
6003 void (*ia_pd_nomatch
)())
6005 struct data_string reply_new
;
6007 struct option_state
*opt_state
;
6008 struct host_decl
*packet_host
;
6009 struct option_cache
*ia
;
6010 struct option_cache
*oc
;
6011 /* cli_enc_... variables come from the IA_PD options */
6012 struct data_string cli_enc_opt_data
;
6013 struct option_state
*cli_enc_opt_state
;
6014 struct host_decl
*host
;
6015 struct option_state
*host_opt_state
;
6016 struct data_string iaprefix
;
6017 char reply_data
[65536];
6019 struct iasubopt
*prefix
;
6020 struct ia_xx
*existing_ia_pd
;
6022 struct data_string key
;
6026 * Initialize to empty values, in case we have to exit early.
6028 memset(&reply_new
, 0, sizeof(reply_new
));
6030 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
6031 cli_enc_opt_state
= NULL
;
6032 memset(&iaprefix
, 0, sizeof(iaprefix
));
6033 host_opt_state
= NULL
;
6037 * Compute the available length for the reply.
6039 reply_len
= sizeof(reply_data
) - reply_ret
->len
;
6043 * Find the host record that matches from the packet, if any.
6046 if (!find_hosts_by_uid(&packet_host
,
6047 client_id
->data
, client_id
->len
, MDL
)) {
6050 * Note: In general, we don't expect a client to provide
6051 * enough information to match by option for these
6052 * types of messages, but if we don't have a UID
6053 * match we can check anyway.
6055 if (!find_hosts_by_option(&packet_host
,
6056 packet
, packet
->options
, MDL
)) {
6059 if (!find_hosts_by_duid_chaddr(&packet_host
,
6066 * Build our option state for reply.
6069 if (!option_state_allocate(&opt_state
, MDL
)) {
6070 log_error("iterate_over_ia_pd: no memory for option_state.");
6073 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
6074 packet
->options
, opt_state
,
6075 &global_scope
, root_group
, NULL
, NULL
);
6078 * Loop through the IA_PD reported by the client, and deal with
6079 * prefixes reported as already in use.
6081 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
6082 ia
!= NULL
; ia
= ia
->next
) {
6084 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
6086 packet
, ia
, IA_PD_OFFSET
)) {
6090 iaid
= getULong(cli_enc_opt_data
.data
);
6092 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
6095 /* no prefix given for this IA_PD, ignore */
6096 option_state_dereference(&cli_enc_opt_state
, MDL
);
6097 data_string_forget(&cli_enc_opt_data
, MDL
);
6101 for (; oc
!= NULL
; oc
= oc
->next
) {
6102 memset(&iaprefix
, 0, sizeof(iaprefix
));
6103 if (!evaluate_option_cache(&iaprefix
, packet
, NULL
, NULL
,
6104 packet
->options
, NULL
,
6105 &global_scope
, oc
, MDL
)) {
6106 log_error("iterate_over_ia_pd: "
6107 "error evaluating IAPREFIX.");
6112 * Now we need to figure out which host record matches
6113 * this IA_PD and IAPREFIX (encapsulated option contents
6114 * matching a host record by option).
6116 * XXX: We don't currently track IA_PD separately, but
6117 * we will need to do this!
6120 if (!find_hosts_by_option(&host
, packet
,
6121 cli_enc_opt_state
, MDL
)) {
6122 if (packet_host
!= NULL
) {
6128 while (host
!= NULL
) {
6129 if (host
->fixed_prefix
!= NULL
) {
6130 struct iaddrcidrnetlist
*l
;
6131 int plen
= (int) getUChar(iaprefix
.data
+ 8);
6133 for (l
= host
->fixed_prefix
; l
!= NULL
;
6135 if (plen
!= l
->cidrnet
.bits
)
6137 if (memcmp(iaprefix
.data
+ 9,
6138 l
->cidrnet
.lo_addr
.iabuf
,
6142 if ((l
!= NULL
) && (iaprefix
.len
>= 17))
6145 host
= host
->n_ipaddr
;
6148 if ((host
== NULL
) && (iaprefix
.len
>= IAPREFIX_OFFSET
)) {
6150 * Find existing IA_PD.
6152 if (ia_make_key(&key
, iaid
,
6153 (char *)client_id
->data
,
6155 MDL
) != ISC_R_SUCCESS
) {
6156 log_fatal("iterate_over_ia_pd: no memory for "
6160 existing_ia_pd
= NULL
;
6161 if (ia_hash_lookup(&existing_ia_pd
, ia_pd_active
,
6162 (unsigned char *)key
.data
,
6165 * Make sure this prefix is in the IA_PD.
6168 i
< existing_ia_pd
->num_iasubopt
;
6170 struct iasubopt
*tmp
;
6173 plen
= getUChar(iaprefix
.data
+ 8);
6174 tmp
= existing_ia_pd
->iasubopt
[i
];
6175 if ((tmp
->plen
== plen
) &&
6179 iasubopt_reference(&prefix
,
6186 data_string_forget(&key
, MDL
);
6189 if ((host
!= NULL
) || (prefix
!= NULL
)) {
6190 ia_pd_match(client_id
, &iaprefix
, prefix
);
6192 ia_pd_nomatch(client_id
, &iaprefix
,
6193 (u_int32_t
*)cli_enc_opt_data
.data
,
6194 packet
, reply_data
, &reply_ofs
,
6195 reply_len
- reply_ofs
);
6198 if (prefix
!= NULL
) {
6199 iasubopt_dereference(&prefix
, MDL
);
6202 data_string_forget(&iaprefix
, MDL
);
6205 option_state_dereference(&cli_enc_opt_state
, MDL
);
6206 data_string_forget(&cli_enc_opt_data
, MDL
);
6210 * Return our reply to the caller.
6211 * The IA_NA routine has already filled at least the header.
6213 reply_new
.len
= reply_ret
->len
+ reply_ofs
;
6214 if (!buffer_allocate(&reply_new
.buffer
, reply_new
.len
, MDL
)) {
6215 log_fatal("No memory to store reply.");
6217 reply_new
.data
= reply_new
.buffer
->data
;
6218 memcpy(reply_new
.buffer
->data
,
6219 reply_ret
->buffer
->data
, reply_ret
->len
);
6220 memcpy(reply_new
.buffer
->data
+ reply_ret
->len
,
6221 reply_data
, reply_ofs
);
6222 data_string_forget(reply_ret
, MDL
);
6223 data_string_copy(reply_ret
, &reply_new
, MDL
);
6224 data_string_forget(&reply_new
, MDL
);
6227 if (prefix
!= NULL
) {
6228 iasubopt_dereference(&prefix
, MDL
);
6230 if (host_opt_state
!= NULL
) {
6231 option_state_dereference(&host_opt_state
, MDL
);
6233 if (iaprefix
.buffer
!= NULL
) {
6234 data_string_forget(&iaprefix
, MDL
);
6236 if (cli_enc_opt_state
!= NULL
) {
6237 option_state_dereference(&cli_enc_opt_state
, MDL
);
6239 if (cli_enc_opt_data
.buffer
!= NULL
) {
6240 data_string_forget(&cli_enc_opt_data
, MDL
);
6242 if (opt_state
!= NULL
) {
6243 option_state_dereference(&opt_state
, MDL
);
6248 * Release means a client is done with the leases.
6252 dhcpv6_release(struct data_string
*reply
, struct packet
*packet
) {
6253 struct data_string client_id
;
6254 struct data_string server_id
;
6257 * Validate our input.
6259 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
6263 /* If the RELEASE arrived via unicast and unicast option isn't set,
6264 * reject it per RFC 3315, Sec 18.2.6 */
6265 if (packet
->unicast
== ISC_TRUE
&&
6266 is_unicast_option_defined(packet
) == ISC_FALSE
) {
6267 unicast_reject(reply
, packet
, &client_id
, &server_id
);
6270 * And operate on each IA_NA in this packet.
6272 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
6273 "Release", ia_na_match_release
,
6274 ia_na_nomatch_release
);
6277 * And operate on each IA_PD in this packet.
6279 iterate_over_ia_pd(reply
, packet
, &client_id
, &server_id
,
6280 "Release", ia_pd_match_release
,
6281 ia_pd_nomatch_release
);
6284 data_string_forget(&server_id
, MDL
);
6285 data_string_forget(&client_id
, MDL
);
6289 * Information-Request is used by clients who have obtained an address
6290 * from other means, but want configuration information from the server.
6294 dhcpv6_information_request(struct data_string
*reply
, struct packet
*packet
) {
6295 struct data_string client_id
;
6296 struct data_string server_id
;
6299 * Validate our input.
6301 if (!valid_client_info_req(packet
, &server_id
)) {
6306 * Get our client ID, if there is one.
6308 memset(&client_id
, 0, sizeof(client_id
));
6309 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
) {
6310 data_string_forget(&client_id
, MDL
);
6314 * Use the lease_to_client() function. This will work fine,
6315 * because the valid_client_info_req() insures that we
6316 * don't have any IA that would cause us to allocate
6317 * resources to the client.
6319 lease_to_client(reply
, packet
, &client_id
,
6320 server_id
.data
!= NULL
? &server_id
: NULL
);
6325 if (client_id
.data
!= NULL
) {
6326 data_string_forget(&client_id
, MDL
);
6328 data_string_forget(&server_id
, MDL
);
6332 * The Relay-forw message is sent by relays. It typically contains a
6333 * single option, which encapsulates an entire packet.
6335 * We need to build an encapsulated reply.
6338 /* XXX: this is very, very similar to do_packet6(), and should probably
6339 be combined in a clever way */
6341 dhcpv6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
6342 struct option_cache
*oc
;
6343 struct data_string enc_opt_data
;
6344 struct packet
*enc_packet
;
6345 unsigned char msg_type
;
6346 const struct dhcpv6_packet
*msg
;
6347 const struct dhcpv6_relay_packet
*relay
;
6348 struct data_string enc_reply
;
6349 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6350 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6351 struct data_string a_opt
, packet_ero
;
6352 struct option_state
*opt_state
;
6353 static char reply_data
[65536];
6354 struct dhcpv6_relay_packet
*reply
;
6358 * Initialize variables for early exit.
6361 memset(&a_opt
, 0, sizeof(a_opt
));
6362 memset(&packet_ero
, 0, sizeof(packet_ero
));
6363 memset(&enc_reply
, 0, sizeof(enc_reply
));
6364 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6368 * Get our encapsulated relay message.
6370 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
6372 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
6373 link_addr
, sizeof(link_addr
));
6374 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
6375 peer_addr
, sizeof(peer_addr
));
6376 log_info("Relay-forward from %s with link address=%s and "
6377 "peer address=%s missing Relay Message option.",
6378 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
6382 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
6383 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
6384 log_error("dhcpv6_forw_relay: error evaluating "
6385 "relayed message.");
6389 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
6390 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
6395 * Build a packet structure from this encapsulated packet.
6398 if (!packet_allocate(&enc_packet
, MDL
)) {
6399 log_error("dhcpv6_forw_relay: "
6400 "no memory for encapsulated packet.");
6404 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
6405 log_error("dhcpv6_forw_relay: "
6406 "no memory for encapsulated packet's options.");
6410 enc_packet
->client_port
= packet
->client_port
;
6411 enc_packet
->client_addr
= packet
->client_addr
;
6412 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
6413 enc_packet
->dhcpv6_container_packet
= packet
;
6415 msg_type
= enc_opt_data
.data
[0];
6416 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
6417 (msg_type
== DHCPV6_RELAY_REPL
)) {
6418 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6419 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
6420 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
6422 /* relay-specific data */
6423 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
6424 memcpy(&enc_packet
->dhcpv6_link_address
,
6425 relay
->link_address
, sizeof(relay
->link_address
));
6426 memcpy(&enc_packet
->dhcpv6_peer_address
,
6427 relay
->peer_address
, sizeof(relay
->peer_address
));
6429 if (!parse_option_buffer(enc_packet
->options
,
6431 enc_opt_data
.len
- relaylen
,
6432 &dhcpv6_universe
)) {
6433 /* no logging here, as parse_option_buffer() logs all
6434 cases where it fails */
6438 int msglen
= (int)(offsetof(struct dhcpv6_packet
, options
));
6439 msg
= (struct dhcpv6_packet
*)enc_opt_data
.data
;
6440 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
6442 /* message-specific data */
6443 memcpy(enc_packet
->dhcpv6_transaction_id
,
6444 msg
->transaction_id
,
6445 sizeof(enc_packet
->dhcpv6_transaction_id
));
6447 if (!parse_option_buffer(enc_packet
->options
,
6449 enc_opt_data
.len
- msglen
,
6450 &dhcpv6_universe
)) {
6451 /* no logging here, as parse_option_buffer() logs all
6452 cases where it fails */
6458 * This is recursive. It is possible to exceed maximum packet size.
6459 * XXX: This will cause the packet send to fail.
6461 build_dhcpv6_reply(&enc_reply
, enc_packet
);
6464 * If we got no encapsulated data, then it is discarded, and
6465 * our reply-forw is also discarded.
6467 if (enc_reply
.data
== NULL
) {
6472 * Now we can use the reply_data buffer.
6473 * Packet header stuff all comes from the forward message.
6475 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
6476 reply
->msg_type
= DHCPV6_RELAY_REPL
;
6477 reply
->hop_count
= packet
->dhcpv6_hop_count
;
6478 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
6479 sizeof(reply
->link_address
));
6480 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
6481 sizeof(reply
->peer_address
));
6482 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6485 * Get the reply option state.
6488 if (!option_state_allocate(&opt_state
, MDL
)) {
6489 log_error("dhcpv6_relay_forw: no memory for option state.");
6494 * Append the interface-id if present.
6496 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6499 if (!evaluate_option_cache(&a_opt
, packet
,
6501 packet
->options
, NULL
,
6502 &global_scope
, oc
, MDL
)) {
6503 log_error("dhcpv6_relay_forw: error evaluating "
6507 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6508 (unsigned char *)a_opt
.data
,
6510 D6O_INTERFACE_ID
, 0)) {
6511 log_error("dhcpv6_relay_forw: error saving "
6515 data_string_forget(&a_opt
, MDL
);
6519 * Append our encapsulated stuff for caller.
6521 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6522 (unsigned char *)enc_reply
.data
,
6524 D6O_RELAY_MSG
, 0)) {
6525 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
6530 * Get the ERO if any.
6532 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
6537 if (!evaluate_option_cache(&packet_ero
, packet
,
6539 packet
->options
, NULL
,
6540 &global_scope
, oc
, MDL
) ||
6541 (packet_ero
.len
& 1)) {
6542 log_error("dhcpv6_relay_forw: error evaluating ERO.");
6546 /* Decode and apply the ERO. */
6547 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
6548 req
= getUShort(packet_ero
.data
+ i
);
6549 /* Already in the reply? */
6550 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
6553 /* Get it from the packet if present. */
6554 oc
= lookup_option(&dhcpv6_universe
,
6559 if (!evaluate_option_cache(&a_opt
, packet
,
6561 packet
->options
, NULL
,
6562 &global_scope
, oc
, MDL
)) {
6563 log_error("dhcpv6_relay_forw: error "
6564 "evaluating option %u.", req
);
6567 if (!save_option_buffer(&dhcpv6_universe
,
6570 (unsigned char *)a_opt
.data
,
6574 log_error("dhcpv6_relay_forw: error saving "
6578 data_string_forget(&a_opt
, MDL
);
6582 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
6583 sizeof(reply_data
) - reply_ofs
,
6585 required_opts_agent
, &packet_ero
);
6588 * Return our reply to the caller.
6590 reply_ret
->len
= reply_ofs
;
6591 reply_ret
->buffer
= NULL
;
6592 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
6593 log_fatal("No memory to store reply.");
6595 reply_ret
->data
= reply_ret
->buffer
->data
;
6596 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
6599 if (opt_state
!= NULL
)
6600 option_state_dereference(&opt_state
, MDL
);
6601 if (a_opt
.data
!= NULL
) {
6602 data_string_forget(&a_opt
, MDL
);
6604 if (packet_ero
.data
!= NULL
) {
6605 data_string_forget(&packet_ero
, MDL
);
6607 if (enc_reply
.data
!= NULL
) {
6608 data_string_forget(&enc_reply
, MDL
);
6610 if (enc_opt_data
.data
!= NULL
) {
6611 data_string_forget(&enc_opt_data
, MDL
);
6613 if (enc_packet
!= NULL
) {
6614 packet_dereference(&enc_packet
, MDL
);
6619 dhcpv6_discard(struct packet
*packet
) {
6620 /* INSIST(packet->msg_type > 0); */
6621 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
6623 log_debug("Discarding %s from %s; message type not handled by server",
6624 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
6625 piaddr(packet
->client_addr
));
6629 build_dhcpv6_reply(struct data_string
*reply
, struct packet
*packet
) {
6630 memset(reply
, 0, sizeof(*reply
));
6632 /* I would like to classify the client once here, but
6633 * as I don't want to classify all of the incoming packets
6634 * I need to do it before handling specific types.
6635 * We don't need to classify if we are tossing the packet
6636 * or if it is a relay - the classification step will get
6637 * done when we process the inner client packet.
6640 switch (packet
->dhcpv6_msg_type
) {
6641 case DHCPV6_SOLICIT
:
6642 classify_client(packet
);
6643 dhcpv6_solicit(reply
, packet
);
6645 case DHCPV6_ADVERTISE
:
6646 dhcpv6_discard(packet
);
6648 case DHCPV6_REQUEST
:
6649 classify_client(packet
);
6650 dhcpv6_request(reply
, packet
);
6652 case DHCPV6_CONFIRM
:
6653 classify_client(packet
);
6654 dhcpv6_confirm(reply
, packet
);
6657 classify_client(packet
);
6658 dhcpv6_renew(reply
, packet
);
6661 classify_client(packet
);
6662 dhcpv6_rebind(reply
, packet
);
6665 dhcpv6_discard(packet
);
6667 case DHCPV6_RELEASE
:
6668 classify_client(packet
);
6669 dhcpv6_release(reply
, packet
);
6671 case DHCPV6_DECLINE
:
6672 classify_client(packet
);
6673 dhcpv6_decline(reply
, packet
);
6675 case DHCPV6_RECONFIGURE
:
6676 dhcpv6_discard(packet
);
6678 case DHCPV6_INFORMATION_REQUEST
:
6679 classify_client(packet
);
6680 dhcpv6_information_request(reply
, packet
);
6682 case DHCPV6_RELAY_FORW
:
6683 dhcpv6_relay_forw(reply
, packet
);
6685 case DHCPV6_RELAY_REPL
:
6686 dhcpv6_discard(packet
);
6688 case DHCPV6_LEASEQUERY
:
6689 classify_client(packet
);
6690 dhcpv6_leasequery(reply
, packet
);
6692 case DHCPV6_LEASEQUERY_REPLY
:
6693 dhcpv6_discard(packet
);
6696 /* XXX: would be nice if we had "notice" level,
6697 as syslog, for this */
6698 log_info("Discarding unknown DHCPv6 message type %d "
6699 "from %s", packet
->dhcpv6_msg_type
,
6700 piaddr(packet
->client_addr
));
6705 log_packet_in(const struct packet
*packet
) {
6706 struct data_string s
;
6708 char tmp_addr
[INET6_ADDRSTRLEN
];
6711 memset(&s
, 0, sizeof(s
));
6713 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
6714 data_string_sprintfa(&s
, "%s message from %s port %d",
6715 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
6716 piaddr(packet
->client_addr
),
6717 ntohs(packet
->client_port
));
6719 data_string_sprintfa(&s
,
6720 "Unknown message type %d from %s port %d",
6721 packet
->dhcpv6_msg_type
,
6722 piaddr(packet
->client_addr
),
6723 ntohs(packet
->client_port
));
6725 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
6726 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
6727 addr
= &packet
->dhcpv6_link_address
;
6728 data_string_sprintfa(&s
, ", link address %s",
6729 inet_ntop(AF_INET6
, addr
,
6730 tmp_addr
, sizeof(tmp_addr
)));
6731 addr
= &packet
->dhcpv6_peer_address
;
6732 data_string_sprintfa(&s
, ", peer address %s",
6733 inet_ntop(AF_INET6
, addr
,
6734 tmp_addr
, sizeof(tmp_addr
)));
6737 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
6738 data_string_sprintfa(&s
, ", transaction ID 0x%06X", tid
);
6741 oc = lookup_option(&dhcpv6_universe, packet->options,
6744 memset(&tmp_ds, 0, sizeof(tmp_ds_));
6745 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
6746 packet->options, NULL,
6747 &global_scope, oc, MDL)) {
6748 log_error("Error evaluating Client Identifier");
6750 data_strint_sprintf(&s, ", client ID %s",
6752 data_string_forget(&tmp_ds, MDL);
6758 log_info("%s", s
.data
);
6760 data_string_forget(&s
, MDL
);
6764 dhcpv6(struct packet
*packet
) {
6765 struct data_string reply
;
6766 struct sockaddr_in6 to_addr
;
6770 * Log a message that we received this packet.
6772 log_packet_in(packet
);
6775 * Build our reply packet.
6777 build_dhcpv6_reply(&reply
, packet
);
6779 if (reply
.data
!= NULL
) {
6781 * Send our reply, if we have one.
6783 memset(&to_addr
, 0, sizeof(to_addr
));
6784 to_addr
.sin6_family
= AF_INET6
;
6785 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
6786 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
6787 to_addr
.sin6_port
= local_port
;
6789 to_addr
.sin6_port
= remote_port
;
6792 #if defined (REPLY_TO_SOURCE_PORT)
6794 * This appears to have been included for testing so we would
6795 * not need a root client, but was accidently left in the
6796 * final code. We continue to include it in case
6797 * some users have come to rely upon it, but leave
6798 * it off by default as it's a bad idea.
6800 to_addr
.sin6_port
= packet
->client_port
;
6803 memcpy(&to_addr
.sin6_addr
, packet
->client_addr
.iabuf
,
6804 sizeof(to_addr
.sin6_addr
));
6806 log_info("Sending %s to %s port %d",
6807 dhcpv6_type_names
[reply
.data
[0]],
6808 piaddr(packet
->client_addr
),
6809 ntohs(to_addr
.sin6_port
));
6811 send_ret
= send_packet6(packet
->interface
,
6812 reply
.data
, reply
.len
, &to_addr
);
6813 if (send_ret
!= reply
.len
) {
6814 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
6815 send_ret
, reply
.len
);
6817 data_string_forget(&reply
, MDL
);
6822 seek_shared_host(struct host_decl
**hp
, struct shared_network
*shared
) {
6823 struct host_decl
*nofixed
= NULL
;
6824 struct host_decl
*seek
, *hold
= NULL
;
6827 * Seek forward through fixed addresses for the right link.
6829 * Note: how to do this for fixed prefixes???
6831 host_reference(&hold
, *hp
, MDL
);
6832 host_dereference(hp
, MDL
);
6834 while (seek
!= NULL
) {
6835 if (seek
->fixed_addr
== NULL
)
6837 else if (fixed_matches_shared(seek
, shared
))
6840 seek
= seek
->n_ipaddr
;
6843 if ((seek
== NULL
) && (nofixed
!= NULL
))
6847 host_reference(hp
, seek
, MDL
);
6850 static isc_boolean_t
6851 fixed_matches_shared(struct host_decl
*host
, struct shared_network
*shared
) {
6852 struct subnet
*subnet
;
6853 struct data_string addr
;
6854 isc_boolean_t matched
;
6857 if (host
->fixed_addr
== NULL
)
6860 memset(&addr
, 0, sizeof(addr
));
6861 if (!evaluate_option_cache(&addr
, NULL
, NULL
, NULL
, NULL
, NULL
,
6862 &global_scope
, host
->fixed_addr
, MDL
))
6865 if (addr
.len
< 16) {
6866 data_string_forget(&addr
, MDL
);
6871 memcpy(fixed
.iabuf
, addr
.data
, 16);
6873 matched
= ISC_FALSE
;
6874 for (subnet
= shared
->subnets
; subnet
!= NULL
;
6875 subnet
= subnet
->next_sibling
) {
6876 if (addr_eq(subnet_number(fixed
, subnet
->netmask
),
6883 data_string_forget(&addr
, MDL
);
6888 * find_host_by_duid_chaddr() synthesizes a DHCPv4-like 'hardware'
6889 * parameter from a DHCPv6 supplied DUID (client-identifier option),
6890 * and may seek to use client or relay supplied hardware addresses.
6893 find_hosts_by_duid_chaddr(struct host_decl
**host
,
6894 const struct data_string
*client_id
) {
6895 static int once_htype
;
6897 const unsigned char *chaddr
;
6900 * The DUID-LL and DUID-LLT must have a 2-byte DUID type and 2-byte
6903 if (client_id
->len
< 4)
6907 * The third and fourth octets of the DUID-LL and DUID-LLT
6908 * is the hardware type, but in 16 bits.
6910 htype
= getUShort(client_id
->data
+ 2);
6914 /* The first two octets of the DUID identify the type. */
6915 switch(getUShort(client_id
->data
)) {
6917 if (client_id
->len
> 8) {
6918 hlen
= client_id
->len
- 8;
6919 chaddr
= client_id
->data
+ 8;
6925 * Note that client_id->len must be greater than or equal
6926 * to four to get to this point in the function.
6928 hlen
= client_id
->len
- 4;
6929 chaddr
= client_id
->data
+ 4;
6936 if ((hlen
== 0) || (hlen
> HARDWARE_ADDR_LEN
))
6940 * XXX: DHCPv6 gives a 16-bit field for the htype. DHCPv4 gives an
6941 * 8-bit field. To change the semantics of the generic 'hardware'
6942 * structure, we would have to adjust many DHCPv4 sources (from
6943 * interface to DHCPv4 lease code), and we would have to update the
6944 * 'hardware' config directive (probably being reverse compatible and
6945 * providing a new upgrade/replacement primitive). This is a little
6946 * too much to change for now. Hopefully we will revisit this before
6947 * hardware types exceeding 8 bits are assigned.
6949 if ((htype
& 0xFF00) && !once_htype
) {
6951 log_error("Attention: At least one client advertises a "
6952 "hardware type of %d, which exceeds the software "
6953 "limitation of 255.", htype
);
6956 return find_hosts_by_haddr(host
, htype
, chaddr
, hlen
, MDL
);
6962 * \brief Constructs a REPLY with status of UseMulticast to a given packet
6964 * Per RFC 3315 Secs 18.2.1,3,6 & 7, when a server rejects a client's
6965 * unicast-sent packet, the response must only contain the client id,
6966 * server id, and a status code option of 5 (UseMulticast). This function
6967 * constructs such a packet and returns it as a data_string.
6969 * \param reply_ret = data_string which will receive the newly constructed
6971 * \param packet = client request which is being rejected
6972 * \param client_id = data_string which contains the client id
6973 * \param server_id = data_string which which contains the server id
6977 unicast_reject(struct data_string
*reply_ret
,
6978 struct packet
*packet
,
6979 const struct data_string
*client_id
,
6980 const struct data_string
*server_id
)
6982 struct reply_state reply
;
6983 memset(&reply
, 0x0, sizeof(struct reply_state
));
6985 /* Locate the client. */
6986 if (shared_network_from_packet6(&reply
.shared
, packet
)
6988 log_error("unicast_reject: could not locate client.");
6992 /* Initialize the reply. */
6993 packet_reference(&reply
.packet
, packet
, MDL
);
6994 data_string_copy(&reply
.client_id
, client_id
, MDL
);
6996 if (start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
6997 &reply
.buf
.reply
)) {
6998 /* Set the UseMulticast status code. */
6999 if (!set_status_code(STATUS_UseMulticast
,
7000 "Unicast not allowed by server.",
7002 log_error("unicast_reject: Unable to set status code.");
7004 /* Set write cursor to just past the reply header. */
7005 reply
.cursor
= REPLY_OPTIONS_INDEX
;
7006 reply
.cursor
+= store_options6(((char *)reply
.buf
.data
7012 unicast_reject_opts
,
7015 /* Return our reply to the caller. */
7016 reply_ret
->len
= reply
.cursor
;
7017 reply_ret
->buffer
= NULL
;
7018 if (!buffer_allocate(&reply_ret
->buffer
,
7019 reply
.cursor
, MDL
)) {
7020 log_fatal("unicast_reject:"
7021 "No memory to store Reply.");
7024 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
,
7026 reply_ret
->data
= reply_ret
->buffer
->data
;
7032 if (reply
.shared
!= NULL
)
7033 shared_network_dereference(&reply
.shared
, MDL
);
7034 if (reply
.opt_state
!= NULL
)
7035 option_state_dereference(&reply
.opt_state
, MDL
);
7036 if (reply
.packet
!= NULL
)
7037 packet_dereference(&reply
.packet
, MDL
);
7038 if (reply
.client_id
.data
!= NULL
)
7039 data_string_forget(&reply
.client_id
, MDL
);
7044 * \brief Checks if the dhcp6.unicast option has been defined
7046 * Scans the option space for the presence of the dhcp6.unicast option. The
7047 * function attempts to map the inbound packet to a shared network first
7048 * by an ip address specified via an D6O_IA_XX option and if that fails then
7049 * by the packet's source information (e.g. relay link, link, or interace).
7050 * Once the packet is mapped to a shared network, the function executes all
7051 * statements from the network's group outward into a local option cache.
7052 * The option cache is then scanned for the presence of unicast option. If
7053 * the packet cannot be mapped to a shared network, the function returns
7055 * \param packet inbound packet from the client
7057 * \return ISC_TRUE if the dhcp6.unicast option is defined, false otherwise.
7061 is_unicast_option_defined(struct packet
*packet
) {
7062 isc_boolean_t is_defined
= ISC_FALSE
;
7063 struct option_state
*opt_state
= NULL
;
7064 struct option_cache
*oc
= NULL
;
7065 struct shared_network
*shared
= NULL
;
7067 if (!option_state_allocate(&opt_state
, MDL
)) {
7068 log_fatal("is_unicast_option_defined:"
7069 "No memory for option state.");
7072 /* We try to map the packet to a network first by an IA_XX value.
7073 * If that fails, we try by packet source. */
7074 if (((shared_network_from_requested_addr(&shared
, packet
)
7075 != ISC_R_SUCCESS
) &&
7076 (shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
))
7077 || (shared
== NULL
)) {
7078 /* @todo what would this really mean? I think wrong network
7079 * logic will catch it */
7080 log_error("is_unicast_option_defined:"
7081 "cannot attribute packet to a network.");
7085 /* Now that we've mapped it to a network, execute statments to that
7086 * scope, looking for the unicast option. We don't care about the
7087 * value of the option, only whether or not it is defined. */
7088 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
, opt_state
,
7089 &global_scope
, shared
->group
, NULL
, NULL
);
7091 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_UNICAST
);
7092 is_defined
= (oc
!= NULL
? ISC_TRUE
: ISC_FALSE
);
7093 log_debug("is_unicast_option_defined: option found : %d", is_defined
);
7095 if (shared
!= NULL
) {
7096 shared_network_dereference(&shared
, MDL
);
7099 if (opt_state
!= NULL
) {
7100 option_state_dereference(&opt_state
, MDL
);
7103 return (is_defined
);
7108 * \brief Maps a packet to a shared network based on the requested IP address
7110 * The function attempts to find a subnet that matches the first requested IP
7111 * address contained within the given packet. Note that it looks first for
7112 * D6O_IA_NAs, then D6O_IA_PDs and lastly D6O_IA_TAs. If a matching network is
7113 * found, a reference to it is returned in the parameter, shared.
7115 * \param shared shared_network pointer which will receive the matching network
7116 * \param packet inbound packet from the client
7118 * \return ISC_R_SUCCESS if the packet can be mapped to a shared_network.
7122 shared_network_from_requested_addr (struct shared_network
**shared
,
7123 struct packet
* packet
) {
7125 struct subnet
* subnet
= NULL
;
7126 isc_result_t status
= ISC_R_FAILURE
;
7128 /* Try to match first IA_ address or prefix we find to a subnet. In
7129 * theory all IA_ values in a given request are supposed to be in the
7130 * same subnet so we only need to try one right? */
7131 if ((get_first_ia_addr_val(packet
, D6O_IA_NA
, &iaddr
) != ISC_R_SUCCESS
)
7132 && (get_first_ia_addr_val(packet
, D6O_IA_PD
, &iaddr
)
7134 && (get_first_ia_addr_val(packet
, D6O_IA_TA
, &iaddr
)
7135 != ISC_R_SUCCESS
)) {
7136 /* we found nothing to match against */
7137 log_debug("share_network_from_request_addr: nothing to match");
7138 return (ISC_R_FAILURE
);
7141 if (!find_subnet(&subnet
, iaddr
, MDL
)) {
7142 log_debug("shared_network_from_requested_addr:"
7143 "No subnet found for addr %s.", piaddr(iaddr
));
7145 status
= shared_network_reference(shared
,
7146 subnet
->shared_network
, MDL
);
7147 subnet_dereference(&subnet
, MDL
);
7148 log_debug("shared_network_from_requested_addr:"
7149 " found shared network %s for address %s.",
7150 ((*shared
)->name
? (*shared
)->name
: "unnamed"),
7155 return (ISC_R_FAILURE
);
7160 * \brief Retrieves the first IP address from a given packet of a given type
7162 * Search a packet for options of a given type (D6O_IA_AN, D6O_IA_PD, or
7163 * D6O_IA_TA) for the first non-blank IA_XX value and return its IP address
7166 * \param packet packet received from the client
7167 * \param addr_type the address option type (D6O_IA_NA , D6O_IA_PD, or
7168 * D6O_IP_TA) to look for within the packet.
7169 * \param iaddr pointer to the iaddr structure which will receive the extracted
7172 * \return ISC_R_SUCCESS if an address was succesfully extracted, ISC_R_FALURE
7177 get_first_ia_addr_val (struct packet
* packet
, int addr_type
,
7178 struct iaddr
* iaddr
) {
7179 struct option_cache
*ia
;
7180 struct option_cache
*oc
= NULL
;
7181 struct data_string cli_enc_opt_data
;
7182 struct option_state
*cli_enc_opt_state
;
7183 int addr_opt_offset
;
7185 int addr_opt_data_len
;
7188 isc_result_t status
= ISC_R_FAILURE
;
7189 memset(iaddr
, 0, sizeof(struct iaddr
));
7191 /* Set up address type specifics */
7192 switch (addr_type
) {
7194 addr_opt_offset
= IA_NA_OFFSET
;
7195 addr_opt
= D6O_IAADDR
;
7196 addr_opt_data_len
= 24;
7200 addr_opt_offset
= IA_TA_OFFSET
;
7201 addr_opt
= D6O_IAADDR
;
7202 addr_opt_data_len
= 24;
7206 addr_opt_offset
= IA_PD_OFFSET
;
7207 addr_opt
= D6O_IAPREFIX
;
7208 addr_opt_data_len
= 25;
7212 /* shouldn't be here */
7213 log_error ("get_first_ia_addr_val: invalid opt type %d",
7215 return (ISC_R_FAILURE
);
7218 /* Find the first, non-blank IA_XX value within an D6O_IA_XX option. */
7219 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, addr_type
);
7220 ia
!= NULL
&& oc
== NULL
; ia
= ia
->next
) {
7221 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
7223 packet
, ia
, addr_opt_offset
)) {
7224 log_debug ("get_first_ia_addr_val:"
7225 " couldn't unroll enclosing option");
7226 return (ISC_R_FAILURE
);
7229 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
7232 /* no address given for this IA, ignore */
7233 option_state_dereference(&cli_enc_opt_state
, MDL
);
7234 data_string_forget(&cli_enc_opt_data
, MDL
);
7238 /* If we found a non-blank IA_XX then extract its ip address. */
7240 struct data_string iaddr_str
;
7242 memset(&iaddr_str
, 0, sizeof(iaddr_str
));
7243 if (!evaluate_option_cache(&iaddr_str
, packet
, NULL
, NULL
,
7244 packet
->options
, NULL
, &global_scope
,
7246 log_error("get_first_ia_addr_val: "
7247 "error evaluating IA_XX option.");
7249 if (iaddr_str
.len
!= addr_opt_data_len
) {
7250 log_error("shared_network_from_requested_addr:"
7251 " invalid length %d, expected %d",
7252 iaddr_str
.len
, addr_opt_data_len
);
7255 memcpy (iaddr
->iabuf
,
7256 iaddr_str
.data
+ ip_addr_offset
, 16);
7257 status
= ISC_R_SUCCESS
;
7259 data_string_forget(&iaddr_str
, MDL
);
7262 option_state_dereference(&cli_enc_opt_state
, MDL
);
7263 data_string_forget(&cli_enc_opt_data
, MDL
);