2 * Copyright (C) 2006-2016 by Internet Systems Consortium, Inc. ("ISC")
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
17 /*! \file server/dhcpv6.c */
24 * We use print_hex_1() to output DUID values. We could actually output
25 * the DUID with more information... MAC address if using type 1 or 3,
26 * and so on. However, RFC 3315 contains Grave Warnings against actually
27 * attempting to understand a DUID.
31 * TODO: gettext() or other method of localization for the messages
32 * for status codes (and probably for log formats eventually)
33 * TODO: refactoring (simplify, simplify, simplify)
34 * TODO: support multiple shared_networks on each interface (this
35 * will allow the server to issue multiple IPv6 addresses to
40 * DHCPv6 Reply workflow assist. A Reply packet is built by various
41 * different functions; this gives us one location where we keep state
45 /* root level persistent state */
46 struct shared_network
*shared
;
47 struct host_decl
*host
;
48 struct subnet
*subnet
; /* Used to match fixed-addrs to subnet scopes. */
49 struct option_state
*opt_state
;
50 struct packet
*packet
;
51 struct data_string client_id
;
53 /* IA level persistent state */
56 unsigned client_resources
;
57 isc_boolean_t resources_included
;
58 isc_boolean_t static_lease
;
59 unsigned static_prefixes
;
62 struct option_state
*reply_ia
;
63 struct data_string fixed
;
64 struct iaddrcidrnet fixed_pref
; /* static prefix for logging */
66 /* IAADDR/PREFIX level persistent state */
67 struct iasubopt
*lease
;
70 * "t1", "t2", preferred, and valid lifetimes records for calculating
71 * t1 and t2 (min/max).
73 u_int32_t renew
, rebind
, prefer
, valid
;
75 /* Client-requested valid and preferred lifetimes. */
76 u_int32_t client_valid
, client_prefer
;
78 /* Chosen values to transmit for valid and preferred lifetimes. */
79 u_int32_t send_valid
, send_prefer
;
81 /* Preferred prefix length (-1 is any). */
84 /* Index into the data field that has been consumed. */
87 /* Space for the on commit statements for a fixed host */
88 struct on_star on_star
;
91 unsigned char data
[65536];
92 struct dhcpv6_packet reply
;
97 * Prototypes local to this file.
99 static int get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
100 struct data_string
*enc_opt_data
,
101 struct packet
*packet
,
102 struct option_cache
*oc
,
104 static void build_dhcpv6_reply(struct data_string
*, struct packet
*);
105 static isc_result_t
shared_network_from_packet6(struct shared_network
**shared
,
106 struct packet
*packet
);
107 static void seek_shared_host(struct host_decl
**hp
,
108 struct shared_network
*shared
);
109 static isc_boolean_t
fixed_matches_shared(struct host_decl
*host
,
110 struct shared_network
*shared
);
111 static isc_result_t
reply_process_ia_na(struct reply_state
*reply
,
112 struct option_cache
*ia
);
113 static isc_result_t
reply_process_ia_ta(struct reply_state
*reply
,
114 struct option_cache
*ia
);
115 static isc_result_t
reply_process_addr(struct reply_state
*reply
,
116 struct option_cache
*addr
);
117 static isc_boolean_t
address_is_owned(struct reply_state
*reply
,
119 static isc_boolean_t
temporary_is_available(struct reply_state
*reply
,
121 static isc_result_t
find_client_temporaries(struct reply_state
*reply
);
122 static isc_result_t
reply_process_try_addr(struct reply_state
*reply
,
124 static isc_result_t
find_client_address(struct reply_state
*reply
);
125 static isc_result_t
reply_process_is_addressed(struct reply_state
*reply
,
126 struct binding_scope
**scope
,
127 struct group
*group
);
128 static isc_result_t
reply_process_send_addr(struct reply_state
*reply
,
130 static struct iasubopt
*lease_compare(struct iasubopt
*alpha
,
131 struct iasubopt
*beta
);
132 static isc_result_t
reply_process_ia_pd(struct reply_state
*reply
,
133 struct option_cache
*ia_pd
);
134 static struct group
*find_group_by_prefix(struct reply_state
*reply
);
135 static isc_result_t
reply_process_prefix(struct reply_state
*reply
,
136 struct option_cache
*pref
);
137 static isc_boolean_t
prefix_is_owned(struct reply_state
*reply
,
138 struct iaddrcidrnet
*pref
);
139 static isc_result_t
find_client_prefix(struct reply_state
*reply
);
140 static isc_result_t
reply_process_try_prefix(struct reply_state
*reply
,
141 struct iaddrcidrnet
*pref
);
142 static isc_result_t
reply_process_is_prefixed(struct reply_state
*reply
,
143 struct binding_scope
**scope
,
144 struct group
*group
);
145 static isc_result_t
reply_process_send_prefix(struct reply_state
*reply
,
146 struct iaddrcidrnet
*pref
);
147 static struct iasubopt
*prefix_compare(struct reply_state
*reply
,
148 struct iasubopt
*alpha
,
149 struct iasubopt
*beta
);
150 static void schedule_lease_timeout_reply(struct reply_state
*reply
);
152 static int eval_prefix_mode(int thislen
, int preflen
, int prefix_mode
);
153 static isc_result_t
pick_v6_prefix_helper(struct reply_state
*reply
,
156 static void unicast_reject(struct data_string
*reply_ret
, struct packet
*packet
,
157 const struct data_string
*client_id
,
158 const struct data_string
*server_id
);
160 static isc_boolean_t
is_unicast_option_defined(struct packet
*packet
);
161 static isc_result_t
shared_network_from_requested_addr (struct shared_network
163 struct packet
* packet
);
164 static isc_result_t
get_first_ia_addr_val (struct packet
* packet
, int addr_type
,
165 struct iaddr
* iaddr
);
168 * Schedule lease timeouts for all of the iasubopts in the reply.
169 * This is currently used to schedule timeouts for soft leases.
173 schedule_lease_timeout_reply(struct reply_state
*reply
) {
174 struct iasubopt
*tmp
;
177 /* sanity check the reply */
178 if ((reply
== NULL
) || (reply
->ia
== NULL
) || (reply
->ia
->iasubopt
== NULL
))
181 /* walk through the list, scheduling as we go */
182 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
183 tmp
= reply
->ia
->iasubopt
[i
];
184 schedule_lease_timeout(tmp
->ipv6_pool
);
189 * This function returns the time since DUID time start for the
190 * given time_t value.
193 duid_time(time_t when
) {
195 * This time is modulo 2^32.
197 while ((when
- DUID_TIME_EPOCH
) > 4294967295u) {
198 /* use 2^31 to avoid spurious compiler warnings */
203 return when
- DUID_TIME_EPOCH
;
210 * This must remain the same for the lifetime of this server, because
211 * clients return the server DUID that we sent them in Request packets.
213 * We pick the server DUID like this:
215 * 1. Check dhcpd.conf - any value the administrator has configured
216 * overrides any possible values.
217 * 2. Check the leases.txt - we want to use the previous value if
219 * 3. Check if dhcpd.conf specifies a type of server DUID to use,
220 * and generate that type.
221 * 4. Generate a type 1 (time + hardware address) DUID.
223 static struct data_string server_duid
;
226 * Check if the server_duid has been set.
229 server_duid_isset(void) {
230 return (server_duid
.data
!= NULL
);
234 * Return the server_duid.
237 copy_server_duid(struct data_string
*ds
, const char *file
, int line
) {
238 data_string_copy(ds
, &server_duid
, file
, line
);
242 * Set the server DUID to a specified value. This is used when
243 * the server DUID is stored in persistent memory (basically the
247 set_server_duid(struct data_string
*new_duid
) {
248 /* INSIST(new_duid != NULL); */
249 /* INSIST(new_duid->data != NULL); */
251 if (server_duid_isset()) {
252 data_string_forget(&server_duid
, MDL
);
254 data_string_copy(&server_duid
, new_duid
, MDL
);
259 * Set the server DUID based on the D6O_SERVERID option. This handles
260 * the case where the administrator explicitly put it in the dhcpd.conf
264 set_server_duid_from_option(void) {
265 struct option_state
*opt_state
;
266 struct option_cache
*oc
;
267 struct data_string option_duid
;
268 isc_result_t ret_val
;
271 if (!option_state_allocate(&opt_state
, MDL
)) {
272 log_fatal("No memory for server DUID.");
275 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
,
276 opt_state
, &global_scope
, root_group
,
279 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
281 ret_val
= ISC_R_NOTFOUND
;
283 memset(&option_duid
, 0, sizeof(option_duid
));
284 if (!evaluate_option_cache(&option_duid
, NULL
, NULL
, NULL
,
285 opt_state
, NULL
, &global_scope
,
287 ret_val
= ISC_R_UNEXPECTED
;
289 set_server_duid(&option_duid
);
290 data_string_forget(&option_duid
, MDL
);
291 ret_val
= ISC_R_SUCCESS
;
295 option_state_dereference(&opt_state
, MDL
);
301 * DUID layout, as defined in RFC 3315, section 9.
303 * We support type 1 (hardware address plus time) and type 3 (hardware
306 * We can support type 2 for specific vendors in the future, if they
307 * publish the specification. And of course there may be additional
310 static int server_duid_type
= DUID_LLT
;
316 set_server_duid_type(int type
) {
317 server_duid_type
= type
;
321 * Generate a new server DUID. This is done if there was no DUID in
322 * the leases.txt or in the dhcpd.conf file.
325 generate_new_server_duid(void) {
326 struct interface_info
*p
;
328 struct data_string generated_duid
;
331 * Verify we have a type that we support.
333 if ((server_duid_type
!= DUID_LL
) && (server_duid_type
!= DUID_LLT
)) {
334 log_error("Invalid DUID type %d specified, "
335 "only LL and LLT types supported", server_duid_type
);
336 return DHCP_R_INVALIDARG
;
340 * Find an interface with a hardware address.
343 for (p
= interfaces
; p
!= NULL
; p
= p
->next
) {
344 if (p
->hw_address
.hlen
> 0) {
349 return ISC_R_UNEXPECTED
;
355 memset(&generated_duid
, 0, sizeof(generated_duid
));
356 if (server_duid_type
== DUID_LLT
) {
357 time_val
= duid_time(time(NULL
));
358 generated_duid
.len
= 8 + p
->hw_address
.hlen
- 1;
359 if (!buffer_allocate(&generated_duid
.buffer
,
360 generated_duid
.len
, MDL
)) {
361 log_fatal("No memory for server DUID.");
363 generated_duid
.data
= generated_duid
.buffer
->data
;
364 putUShort(generated_duid
.buffer
->data
, DUID_LLT
);
365 putUShort(generated_duid
.buffer
->data
+ 2,
366 p
->hw_address
.hbuf
[0]);
367 putULong(generated_duid
.buffer
->data
+ 4, time_val
);
368 memcpy(generated_duid
.buffer
->data
+ 8,
369 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
370 } else if (server_duid_type
== DUID_LL
) {
371 generated_duid
.len
= 4 + p
->hw_address
.hlen
- 1;
372 if (!buffer_allocate(&generated_duid
.buffer
,
373 generated_duid
.len
, MDL
)) {
374 log_fatal("No memory for server DUID.");
376 generated_duid
.data
= generated_duid
.buffer
->data
;
377 putUShort(generated_duid
.buffer
->data
, DUID_LL
);
378 putUShort(generated_duid
.buffer
->data
+ 2,
379 p
->hw_address
.hbuf
[0]);
380 memcpy(generated_duid
.buffer
->data
+ 4,
381 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
383 log_fatal("Unsupported server DUID type %d.", server_duid_type
);
386 set_server_duid(&generated_duid
);
387 data_string_forget(&generated_duid
, MDL
);
389 return ISC_R_SUCCESS
;
393 * Get the client identifier from the packet.
396 get_client_id(struct packet
*packet
, struct data_string
*client_id
) {
397 struct option_cache
*oc
;
400 * Verify our client_id structure is empty.
402 if ((client_id
->data
!= NULL
) || (client_id
->len
!= 0)) {
403 return DHCP_R_INVALIDARG
;
406 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_CLIENTID
);
408 return ISC_R_NOTFOUND
;
411 if (!evaluate_option_cache(client_id
, packet
, NULL
, NULL
,
412 packet
->options
, NULL
,
413 &global_scope
, oc
, MDL
)) {
414 return ISC_R_FAILURE
;
417 return ISC_R_SUCCESS
;
421 * Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
423 * Servers MUST discard any Solicit messages that do not include a
424 * Client Identifier option or that do include a Server Identifier
428 valid_client_msg(struct packet
*packet
, struct data_string
*client_id
) {
430 struct option_cache
*oc
;
431 struct data_string data
;
434 memset(client_id
, 0, sizeof(*client_id
));
435 memset(&data
, 0, sizeof(data
));
437 switch (get_client_id(packet
, client_id
)) {
441 log_debug("Discarding %s from %s; "
442 "client identifier missing",
443 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
444 piaddr(packet
->client_addr
));
447 log_error("Error processing %s from %s; "
448 "unable to evaluate Client Identifier",
449 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
450 piaddr(packet
->client_addr
));
455 * Required by RFC 3315, section 15.
457 if (packet
->unicast
) {
458 log_debug("Discarding %s from %s; packet sent unicast "
460 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
461 piaddr(packet
->client_addr
),
462 print_hex_1(client_id
->len
, client_id
->data
, 60));
467 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
469 if (evaluate_option_cache(&data
, packet
, NULL
, NULL
,
470 packet
->options
, NULL
,
471 &global_scope
, oc
, MDL
)) {
472 log_debug("Discarding %s from %s; "
473 "server identifier found "
474 "(CLIENTID %s, SERVERID %s)",
475 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
476 piaddr(packet
->client_addr
),
477 print_hex_1(client_id
->len
,
478 client_id
->data
, 60),
479 print_hex_2(data
.len
,
482 log_debug("Discarding %s from %s; "
483 "server identifier found "
485 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
486 print_hex_1(client_id
->len
,
487 client_id
->data
, 60),
488 piaddr(packet
->client_addr
));
498 data_string_forget(&data
, MDL
);
501 if (client_id
->len
> 0) {
502 data_string_forget(client_id
, MDL
);
509 * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
510 * 15.9 (slightly different wording, but same meaning):
512 * Servers MUST discard any received Request message that meet any of
513 * the following conditions:
515 * - the message does not include a Server Identifier option.
516 * - the contents of the Server Identifier option do not match the
518 * - the message does not include a Client Identifier option.
521 valid_client_resp(struct packet
*packet
,
522 struct data_string
*client_id
,
523 struct data_string
*server_id
)
526 struct option_cache
*oc
;
528 /* INSIST((duid.data != NULL) && (duid.len > 0)); */
531 memset(client_id
, 0, sizeof(*client_id
));
532 memset(server_id
, 0, sizeof(*server_id
));
534 switch (get_client_id(packet
, client_id
)) {
538 log_debug("Discarding %s from %s; "
539 "client identifier missing",
540 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
541 piaddr(packet
->client_addr
));
544 log_error("Error processing %s from %s; "
545 "unable to evaluate Client Identifier",
546 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
547 piaddr(packet
->client_addr
));
551 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
553 log_debug("Discarding %s from %s: "
554 "server identifier missing (CLIENTID %s)",
555 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
556 piaddr(packet
->client_addr
),
557 print_hex_1(client_id
->len
, client_id
->data
, 60));
560 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
561 packet
->options
, NULL
,
562 &global_scope
, oc
, MDL
)) {
563 log_error("Error processing %s from %s; "
564 "unable to evaluate Server Identifier (CLIENTID %s)",
565 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
566 piaddr(packet
->client_addr
),
567 print_hex_1(client_id
->len
, client_id
->data
, 60));
570 if ((server_duid
.len
!= server_id
->len
) ||
571 (memcmp(server_duid
.data
, server_id
->data
, server_duid
.len
) != 0)) {
572 log_debug("Discarding %s from %s; "
573 "not our server identifier "
574 "(CLIENTID %s, SERVERID %s, server DUID %s)",
575 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
576 piaddr(packet
->client_addr
),
577 print_hex_1(client_id
->len
, client_id
->data
, 60),
578 print_hex_2(server_id
->len
, server_id
->data
, 60),
579 print_hex_3(server_duid
.len
, server_duid
.data
, 60));
588 if (server_id
->len
> 0) {
589 data_string_forget(server_id
, MDL
);
591 if (client_id
->len
> 0) {
592 data_string_forget(client_id
, MDL
);
599 * Information request validation, defined in RFC 3315, section 15.12:
601 * Servers MUST discard any received Information-request message that
602 * meets any of the following conditions:
604 * - The message includes a Server Identifier option and the DUID in
605 * the option does not match the server's DUID.
607 * - The message includes an IA option.
610 valid_client_info_req(struct packet
*packet
, struct data_string
*server_id
) {
612 struct option_cache
*oc
;
613 struct data_string client_id
;
614 char client_id_str
[80]; /* print_hex_1() uses maximum 60 characters,
615 plus a few more for extra information */
618 memset(server_id
, 0, sizeof(*server_id
));
619 memset(&client_id
, 0, sizeof(client_id
));
622 * Make a string that we can print out to give more
623 * information about the client if we need to.
625 * By RFC 3315, Section 18.1.5 clients SHOULD have a
626 * client-id on an Information-request packet, but it
627 * is not strictly necessary.
629 if (get_client_id(packet
, &client_id
) == ISC_R_SUCCESS
) {
630 snprintf(client_id_str
, sizeof(client_id_str
), " (CLIENTID %s)",
631 print_hex_1(client_id
.len
, client_id
.data
, 60));
632 data_string_forget(&client_id
, MDL
);
634 client_id_str
[0] = '\0';
638 * Required by RFC 3315, section 15.
640 if (packet
->unicast
) {
641 log_debug("Discarding %s from %s; packet sent unicast%s",
642 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
643 piaddr(packet
->client_addr
), client_id_str
);
647 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
649 log_debug("Discarding %s from %s; "
650 "IA_NA option present%s",
651 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
652 piaddr(packet
->client_addr
), client_id_str
);
655 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
657 log_debug("Discarding %s from %s; "
658 "IA_TA option present%s",
659 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
660 piaddr(packet
->client_addr
), client_id_str
);
663 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
665 log_debug("Discarding %s from %s; "
666 "IA_PD option present%s",
667 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
668 piaddr(packet
->client_addr
), client_id_str
);
672 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
674 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
675 packet
->options
, NULL
,
676 &global_scope
, oc
, MDL
)) {
677 log_error("Error processing %s from %s; "
678 "unable to evaluate Server Identifier%s",
679 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
680 piaddr(packet
->client_addr
), client_id_str
);
683 if ((server_duid
.len
!= server_id
->len
) ||
684 (memcmp(server_duid
.data
, server_id
->data
,
685 server_duid
.len
) != 0)) {
686 log_debug("Discarding %s from %s; "
687 "not our server identifier "
688 "(SERVERID %s, server DUID %s)%s",
689 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
690 piaddr(packet
->client_addr
),
691 print_hex_1(server_id
->len
,
692 server_id
->data
, 60),
693 print_hex_2(server_duid
.len
,
694 server_duid
.data
, 60),
705 if (server_id
->len
> 0) {
706 data_string_forget(server_id
, MDL
);
713 * Options that we want to send, in addition to what was requested
716 static const int required_opts
[] = {
723 static const int required_opts_solicit
[] = {
735 static const int required_opts_agent
[] = {
740 static const int required_opts_IA
[] = {
745 static const int required_opts_IA_PD
[] = {
750 static const int required_opts_STATUS_CODE
[] = {
755 static const int unicast_reject_opts
[] = {
764 * Extracts from packet contents an IA_* option, storing the IA structure
765 * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
766 * in enc_opt_state for later lookup and evaluation. The 'offset' indicates
767 * where in the IA_* the DHCPv6 options commence.
770 get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
771 struct data_string
*enc_opt_data
,
772 struct packet
*packet
,
773 struct option_cache
*oc
,
777 * Get the raw data for the encapsulated options.
779 memset(enc_opt_data
, 0, sizeof(*enc_opt_data
));
780 if (!evaluate_option_cache(enc_opt_data
, packet
,
781 NULL
, NULL
, packet
->options
, NULL
,
782 &global_scope
, oc
, MDL
)) {
783 log_error("get_encapsulated_IA_state: "
784 "error evaluating raw option.");
787 if (enc_opt_data
->len
< offset
) {
788 log_error("get_encapsulated_IA_state: raw option too small.");
789 data_string_forget(enc_opt_data
, MDL
);
794 * Now create the option state structure, and pass it to the
795 * function that parses options.
797 *enc_opt_state
= NULL
;
798 if (!option_state_allocate(enc_opt_state
, MDL
)) {
799 log_error("get_encapsulated_IA_state: no memory for options.");
800 data_string_forget(enc_opt_data
, MDL
);
803 if (!parse_option_buffer(*enc_opt_state
,
804 enc_opt_data
->data
+ offset
,
805 enc_opt_data
->len
- offset
,
807 log_error("get_encapsulated_IA_state: error parsing options.");
808 option_state_dereference(enc_opt_state
, MDL
);
809 data_string_forget(enc_opt_data
, MDL
);
817 set_status_code(u_int16_t status_code
, const char *status_message
,
818 struct option_state
*opt_state
)
820 struct data_string d
;
823 memset(&d
, 0, sizeof(d
));
824 d
.len
= sizeof(status_code
) + strlen(status_message
);
825 if (!buffer_allocate(&d
.buffer
, d
.len
, MDL
)) {
826 log_fatal("set_status_code: no memory for status code.");
828 d
.data
= d
.buffer
->data
;
829 putUShort(d
.buffer
->data
, status_code
);
830 memcpy(d
.buffer
->data
+ sizeof(status_code
),
831 status_message
, d
.len
- sizeof(status_code
));
832 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
833 d
.buffer
, (unsigned char *)d
.data
, d
.len
,
834 D6O_STATUS_CODE
, 0)) {
835 log_error("set_status_code: error saving status code.");
840 data_string_forget(&d
, MDL
);
844 void check_pool6_threshold(struct reply_state
*reply
,
845 struct iasubopt
*lease
)
847 struct ipv6_pond
*pond
;
848 isc_uint64_t used
, count
, high_threshold
;
849 int poolhigh
= 0, poollow
= 0;
850 char *shared_name
= "no name";
851 char tmp_addr
[INET6_ADDRSTRLEN
];
853 if ((lease
->ipv6_pool
== NULL
) || (lease
->ipv6_pool
->ipv6_pond
== NULL
))
855 pond
= lease
->ipv6_pool
->ipv6_pond
;
857 /* If the address range is too large to track, just skip all this. */
858 if (pond
->jumbo_range
== 1) {
862 count
= pond
->num_total
;
863 used
= pond
->num_active
;
865 /* get network name for logging */
866 if ((pond
->shared_network
!= NULL
) &&
867 (pond
->shared_network
->name
!= NULL
)) {
868 shared_name
= pond
->shared_network
->name
;
871 /* The logged flag indicates if we have already crossed the high
872 * threshold and emitted a log message. If it is set we check to
873 * see if we have re-crossed the low threshold and need to reset
874 * things. When we cross the high threshold we determine what
875 * the low threshold is and save it into the low_threshold value.
876 * When we cross that threshold we reset the logged flag and
877 * the low_threshold to 0 which allows the high threshold message
878 * to be emitted once again.
879 * if we haven't recrossed the boundry we don't need to do anything.
881 if (pond
->logged
!=0) {
882 if (used
<= pond
->low_threshold
) {
883 pond
->low_threshold
= 0;
885 log_error("Pool threshold reset - shared subnet: %s; "
886 "address: %s; low threshold %llu/%llu.",
888 inet_ntop(AF_INET6
, &lease
->addr
,
889 tmp_addr
, sizeof(tmp_addr
)),
895 /* find the high threshold */
896 if (get_option_int(&poolhigh
, &server_universe
, reply
->packet
, NULL
,
897 NULL
, reply
->packet
->options
, reply
->opt_state
,
898 reply
->opt_state
, &lease
->scope
,
899 SV_LOG_THRESHOLD_HIGH
, MDL
) == 0) {
900 /* no threshold bail out */
904 /* We do have a threshold for this pool, see if its valid */
905 if ((poolhigh
<= 0) || (poolhigh
> 100)) {
910 /* we have a valid value, have we exceeded it */
911 high_threshold
= FIND_POND6_PERCENT(count
, poolhigh
);
912 if (used
< high_threshold
) {
913 /* nope, no more to do */
917 /* we've exceeded it, output a message */
918 log_error("Pool threshold exceeded - shared subnet: %s; "
919 "address: %s; high threshold %d%% %llu/%llu.",
921 inet_ntop(AF_INET6
, &lease
->addr
, tmp_addr
, sizeof(tmp_addr
)),
922 poolhigh
, used
, count
);
924 /* handle the low threshold now, if we don't
925 * have one we default to 0. */
926 if ((get_option_int(&poollow
, &server_universe
, reply
->packet
, NULL
,
927 NULL
, reply
->packet
->options
, reply
->opt_state
,
928 reply
->opt_state
, &lease
->scope
,
929 SV_LOG_THRESHOLD_LOW
, MDL
) == 0) ||
935 * If the low theshold is higher than the high threshold we continue to log
936 * If it isn't then we set the flag saying we already logged and determine
937 * what the reset threshold is.
939 if (poollow
< poolhigh
) {
941 pond
->low_threshold
= FIND_POND6_PERCENT(count
, poollow
);
946 * We have a set of operations we do to set up the reply packet, which
947 * is the same for many message types.
950 start_reply(struct packet
*packet
,
951 const struct data_string
*client_id
,
952 const struct data_string
*server_id
,
953 struct option_state
**opt_state
,
954 struct dhcpv6_packet
*reply
)
956 struct option_cache
*oc
;
957 const unsigned char *server_id_data
;
961 * Build our option state for reply.
964 if (!option_state_allocate(opt_state
, MDL
)) {
965 log_error("start_reply: no memory for option_state.");
968 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
969 packet
->options
, *opt_state
,
970 &global_scope
, root_group
, NULL
, NULL
);
973 * A small bit of special handling for Solicit messages.
975 * We could move the logic into a flag, but for now just check
978 if (packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
979 reply
->msg_type
= DHCPV6_ADVERTISE
;
983 * - this message type supports rapid commit (Solicit), and
984 * - the server is configured to supply a rapid commit, and
985 * - the client requests a rapid commit,
986 * Then we add a rapid commit option, and send Reply (instead
989 oc
= lookup_option(&dhcpv6_universe
,
990 *opt_state
, D6O_RAPID_COMMIT
);
992 oc
= lookup_option(&dhcpv6_universe
,
993 packet
->options
, D6O_RAPID_COMMIT
);
995 /* Rapid-commit in action. */
996 reply
->msg_type
= DHCPV6_REPLY
;
998 /* Don't want a rapid-commit in advertise. */
999 delete_option(&dhcpv6_universe
,
1000 *opt_state
, D6O_RAPID_COMMIT
);
1004 reply
->msg_type
= DHCPV6_REPLY
;
1005 /* Delete the rapid-commit from the sent options. */
1006 oc
= lookup_option(&dhcpv6_universe
,
1007 *opt_state
, D6O_RAPID_COMMIT
);
1009 delete_option(&dhcpv6_universe
,
1010 *opt_state
, D6O_RAPID_COMMIT
);
1015 * Use the client's transaction identifier for the reply.
1017 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
1018 sizeof(reply
->transaction_id
));
1021 * RFC 3315, section 18.2 says we need server identifier and
1022 * client identifier.
1024 * If the server ID is defined via the configuration file, then
1025 * it will already be present in the option state at this point,
1026 * so we don't need to set it.
1028 * If we have a server ID passed in from the caller,
1029 * use that, otherwise use the global DUID.
1031 oc
= lookup_option(&dhcpv6_universe
, *opt_state
, D6O_SERVERID
);
1033 if (server_id
== NULL
) {
1034 server_id_data
= server_duid
.data
;
1035 server_id_len
= server_duid
.len
;
1037 server_id_data
= server_id
->data
;
1038 server_id_len
= server_id
->len
;
1040 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1041 NULL
, (unsigned char *)server_id_data
,
1042 server_id_len
, D6O_SERVERID
, 0)) {
1043 log_error("start_reply: "
1044 "error saving server identifier.");
1049 if (client_id
->buffer
!= NULL
) {
1050 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1052 (unsigned char *)client_id
->data
,
1055 log_error("start_reply: error saving "
1056 "client identifier.");
1062 * If the client accepts reconfiguration, let it know that we
1065 * Note: we don't actually do this yet, but DOCSIS requires we
1068 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
1071 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1072 NULL
, (unsigned char *)"", 0,
1073 D6O_RECONF_ACCEPT
, 0)) {
1074 log_error("start_reply: "
1075 "error saving RECONF_ACCEPT option.");
1076 option_state_dereference(opt_state
, MDL
);
1085 * Try to get the IPv6 address the client asked for from the
1088 * addr is the result (should be a pointer to NULL on entry)
1089 * pool is the pool to search in
1090 * requested_addr is the address the client wants
1093 try_client_v6_address(struct iasubopt
**addr
,
1094 struct ipv6_pool
*pool
,
1095 const struct data_string
*requested_addr
)
1097 struct in6_addr tmp_addr
;
1098 isc_result_t result
;
1100 if (requested_addr
->len
< sizeof(tmp_addr
)) {
1101 return DHCP_R_INVALIDARG
;
1103 memcpy(&tmp_addr
, requested_addr
->data
, sizeof(tmp_addr
));
1104 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
)) {
1105 return ISC_R_FAILURE
;
1109 * The address is not covered by this (or possibly any) dynamic
1112 if (!ipv6_in_pool(&tmp_addr
, pool
)) {
1113 return ISC_R_ADDRNOTAVAIL
;
1116 if (lease6_exists(pool
, &tmp_addr
)) {
1117 return ISC_R_ADDRINUSE
;
1120 result
= iasubopt_allocate(addr
, MDL
);
1121 if (result
!= ISC_R_SUCCESS
) {
1124 (*addr
)->addr
= tmp_addr
;
1127 /* Default is soft binding for 2 minutes. */
1128 result
= add_lease6(pool
, *addr
, cur_time
+ 120);
1129 if (result
!= ISC_R_SUCCESS
) {
1130 iasubopt_dereference(addr
, MDL
);
1138 * \brief Get an IPv6 address for the client.
1140 * Attempt to find a usable address for the client. We walk through
1141 * the ponds checking for permit and deny then through the pools
1142 * seeing if they have an available address.
1144 * \param reply = the state structure for the current work on this request
1145 * if we create a lease we return it using reply->lease
1148 * ISC_R_SUCCESS = we were able to find an address and are returning a
1149 * pointer to the lease
1150 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1151 * is probabalistic. We don't exhaustively try the
1152 * address range, instead we hash the duid and if
1153 * the address derived from the hash is in use we
1154 * hash the address. After a number of failures we
1155 * conclude the pool is basically full.
1158 pick_v6_address(struct reply_state
*reply
)
1160 struct ipv6_pool
*p
= NULL
;
1161 struct ipv6_pond
*pond
;
1164 unsigned int attempts
;
1165 char tmp_buf
[INET6_ADDRSTRLEN
];
1166 struct iasubopt
**addr
= &reply
->lease
;
1167 isc_uint64_t total
= 0;
1168 isc_uint64_t active
= 0;
1169 isc_uint64_t abandoned
= 0;
1170 int jumbo_range
= 0;
1171 char *shared_name
= (reply
->shared
->name
?
1172 reply
->shared
->name
: "(no name)");
1175 * Do a quick walk through of the ponds and pools
1176 * to see if we have any NA address pools
1178 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1179 if (pond
->ipv6_pools
== NULL
)
1182 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1183 if (p
->pool_type
== D6O_IA_NA
)
1190 /* If we get here and p is NULL we have no useful pools */
1192 log_debug("Unable to pick client address: "
1193 "no IPv6 pools on this shared network");
1194 return ISC_R_NORESOURCES
;
1198 * We have at least one pool that could provide an address
1199 * Now we walk through the ponds and pools again and check
1200 * to see if the client is permitted and if an address is
1203 * Within a given pond we start looking at the last pool we
1204 * allocated from, unless it had a collision trying to allocate
1205 * an address. This will tend to move us into less-filled pools.
1208 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1209 isc_result_t result
= ISC_R_FAILURE
;
1211 if (((pond
->prohibit_list
!= NULL
) &&
1212 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1213 ((pond
->permit_list
!= NULL
) &&
1214 (!permitted(reply
->packet
, pond
->permit_list
))))
1217 start_pool
= pond
->last_ipv6_pool
;
1220 p
= pond
->ipv6_pools
[i
];
1221 if (p
->pool_type
== D6O_IA_NA
) {
1222 result
= create_lease6(p
, addr
, &attempts
,
1223 &reply
->ia
->iaid_duid
,
1225 if (result
== ISC_R_SUCCESS
) {
1227 * Record the pool used (or next one if
1228 * there was a collision).
1232 if (pond
->ipv6_pools
[i
]
1238 pond
->last_ipv6_pool
= i
;
1240 log_debug("Picking pool address %s",
1243 tmp_buf
, sizeof(tmp_buf
)));
1244 return (ISC_R_SUCCESS
);
1249 if (pond
->ipv6_pools
[i
] == NULL
) {
1252 } while (i
!= start_pool
);
1254 if (result
== ISC_R_NORESOURCES
) {
1255 jumbo_range
+= pond
->jumbo_range
;
1256 total
+= pond
->num_total
;
1257 active
+= pond
->num_active
;
1258 abandoned
+= pond
->num_abandoned
;
1263 * If we failed to pick an IPv6 address from any of the subnets.
1264 * Presumably that means we have no addresses for the client.
1266 if (jumbo_range
!= 0) {
1267 log_debug("Unable to pick client address: "
1268 "no addresses available - shared network %s: "
1269 " 2^64-1 < total, %llu active, %llu abandoned",
1270 shared_name
, active
- abandoned
, abandoned
);
1272 log_debug("Unable to pick client address: "
1273 "no addresses available - shared network %s: "
1274 "%llu total, %llu active, %llu abandoned",
1275 shared_name
, total
, active
- abandoned
, abandoned
);
1278 return ISC_R_NORESOURCES
;
1282 * Try to get the IPv6 prefix the client asked for from the
1285 * pref is the result (should be a pointer to NULL on entry)
1286 * pool is the prefix pool to search in
1287 * requested_pref is the address the client wants
1290 try_client_v6_prefix(struct iasubopt
**pref
,
1291 struct ipv6_pool
*pool
,
1292 const struct data_string
*requested_pref
)
1295 struct in6_addr tmp_pref
;
1297 isc_result_t result
;
1299 if (requested_pref
->len
< sizeof(tmp_plen
) + sizeof(tmp_pref
)) {
1300 return DHCP_R_INVALIDARG
;
1302 tmp_plen
= (int) requested_pref
->data
[0];
1303 if ((tmp_plen
< 3) || (tmp_plen
> 128) ||
1304 ((int)tmp_plen
!= pool
->units
)) {
1305 return ISC_R_FAILURE
;
1307 memcpy(&tmp_pref
, requested_pref
->data
+ 1, sizeof(tmp_pref
));
1308 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref
)) {
1309 return ISC_R_FAILURE
;
1312 memcpy(&ia
.iabuf
, &tmp_pref
, 16);
1313 if (!is_cidr_mask_valid(&ia
, (int) tmp_plen
)) {
1314 return ISC_R_FAILURE
;
1317 if (!ipv6_in_pool(&tmp_pref
, pool
)) {
1318 return ISC_R_ADDRNOTAVAIL
;
1321 if (prefix6_exists(pool
, &tmp_pref
, tmp_plen
)) {
1322 return ISC_R_ADDRINUSE
;
1325 result
= iasubopt_allocate(pref
, MDL
);
1326 if (result
!= ISC_R_SUCCESS
) {
1329 (*pref
)->addr
= tmp_pref
;
1330 (*pref
)->plen
= tmp_plen
;
1332 /* Default is soft binding for 2 minutes. */
1333 result
= add_lease6(pool
, *pref
, cur_time
+ 120);
1334 if (result
!= ISC_R_SUCCESS
) {
1335 iasubopt_dereference(pref
, MDL
);
1342 * \brief Get an IPv6 prefix for the client.
1344 * Attempt to find a usable prefix for the client. Based upon the prefix
1345 * length mode and the plen supplied by the client (if one), we make one
1346 * or more calls to pick_v6_prefix_helper() to find a prefix as follows:
1348 * PLM_IGNORE or client specifies a plen of zero, use the first available
1349 * prefix regardless of it's length.
1351 * PLM_PREFER – look for an exact match to client's plen first, if none
1352 * found, use the first available prefix of any length
1354 * PLM_EXACT – look for an exact match first, if none found then fail. This
1355 * is the default behavior.
1357 * PLM_MAXIMUM - look for an exact match first, then the first available whose
1358 * prefix length is less than client's plen, otherwise fail.
1360 * PLM_MINIMUM - look for an exact match first, then the first available whose
1361 * prefix length is greater than client's plen, otherwise fail.
1363 * Note that the selection mode is configurable at the global scope only via
1366 * \param reply = the state structure for the current work on this request
1367 * if we create a lease we return it using reply->lease
1370 * ISC_R_SUCCESS = we were able to find an prefix and are returning a
1371 * pointer to the lease
1372 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1373 * is probabalistic. We don't exhaustively try the
1374 * address range, instead we hash the duid and if
1375 * the address derived from the hash is in use we
1376 * hash the address. After a number of failures we
1377 * conclude the pool is basically full.
1380 pick_v6_prefix(struct reply_state
*reply
) {
1381 struct ipv6_pool
*p
= NULL
;
1382 struct ipv6_pond
*pond
;
1384 isc_result_t result
;
1387 * Do a quick walk through of the ponds and pools
1388 * to see if we have any prefix pools
1390 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1391 if (pond
->ipv6_pools
== NULL
)
1394 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1395 if (p
->pool_type
== D6O_IA_PD
)
1402 /* If we get here and p is NULL we have no useful pools */
1404 log_debug("Unable to pick client prefix: "
1405 "no IPv6 pools on this shared network");
1406 return ISC_R_NORESOURCES
;
1409 if (reply
->preflen
<= 0) {
1410 /* If we didn't get a plen (-1) or client plen is 0, then just
1411 * select first available (same as PLM_INGORE) */
1412 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1414 switch (prefix_length_mode
) {
1416 /* First we look for an exact match, if not found
1417 * then first available */
1418 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1419 if (result
!= ISC_R_SUCCESS
) {
1420 result
= pick_v6_prefix_helper(reply
,
1426 /* Match exactly or fail */
1427 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1432 /* First we look for an exact match, if not found
1433 * then first available by mode */
1434 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1435 if (result
!= ISC_R_SUCCESS
) {
1436 result
= pick_v6_prefix_helper(reply
,
1437 prefix_length_mode
);
1442 /* First available */
1443 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1448 if (result
== ISC_R_SUCCESS
) {
1449 char tmp_buf
[INET6_ADDRSTRLEN
];
1451 log_debug("Picking pool prefix %s/%u",
1452 inet_ntop(AF_INET6
, &(reply
->lease
->addr
),
1453 tmp_buf
, sizeof(tmp_buf
)),
1454 (unsigned)(reply
->lease
->plen
));
1455 return (ISC_R_SUCCESS
);
1459 * If we failed to pick an IPv6 prefix
1460 * Presumably that means we have no prefixes for the client.
1462 log_debug("Unable to pick client prefix: no prefixes available");
1463 return ISC_R_NORESOURCES
;
1468 * \brief Get an IPv6 prefix for the client based upon selection mode.
1470 * We walk through the ponds checking for permit and deny. If a pond is
1471 * permissable to use, loop through its PD pools checking prefix lengths
1472 * against the client plen based on the prefix length mode, looking for
1473 * available prefixes.
1475 * \param reply = the state structure for the current work on this request
1476 * if we create a lease we return it using reply->lease
1477 * \prefix_mode = selection mode to use
1480 * ISC_R_SUCCESS = we were able to find a prefix and are returning a
1481 * pointer to the lease
1482 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1483 * is probabalistic. We don't exhaustively try the
1484 * address range, instead we hash the duid and if
1485 * the address derived from the hash is in use we
1486 * hash the address. After a number of failures we
1487 * conclude the pool is basically full.
1490 pick_v6_prefix_helper(struct reply_state
*reply
, int prefix_mode
) {
1491 struct ipv6_pool
*p
= NULL
;
1492 struct ipv6_pond
*pond
;
1494 unsigned int attempts
;
1495 struct iasubopt
**pref
= &reply
->lease
;
1497 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1498 if (((pond
->prohibit_list
!= NULL
) &&
1499 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1500 ((pond
->permit_list
!= NULL
) &&
1501 (!permitted(reply
->packet
, pond
->permit_list
))))
1504 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1505 if ((p
->pool_type
== D6O_IA_PD
) &&
1506 (eval_prefix_mode(p
->units
, reply
->preflen
,
1507 prefix_mode
) == 1) &&
1508 (create_prefix6(p
, pref
, &attempts
,
1509 &reply
->ia
->iaid_duid
,
1510 cur_time
+ 120) == ISC_R_SUCCESS
)) {
1511 return (ISC_R_SUCCESS
);
1516 return ISC_R_NORESOURCES
;
1521 * \brief Test a prefix length against another based on prefix length mode
1523 * \param len - prefix length to test
1524 * \param preflen - preferred prefix length against which to test
1525 * \param prefix_mode - prefix selection mode with which to test
1527 * Note that the case of preferred length of 0 is not short-cut here as it
1528 * is assumed to be done at a higher level.
1530 * \return 1 if the given length is usable based upon mode and a preferred
1534 eval_prefix_mode(int len
, int preflen
, int prefix_mode
) {
1536 switch (prefix_mode
) {
1538 use_it
= (len
== preflen
);
1541 /* they asked for a prefix length no "shorter" than preflen */
1542 use_it
= (len
>= preflen
);
1545 /* they asked for a prefix length no "longer" than preflen */
1546 use_it
= (len
<= preflen
);
1549 /* otherwise use it */
1554 log_debug("eval_prefix_mode: "
1555 "len %d, preflen %d, mode %s, use_it %d",
1557 prefix_length_modes
.values
[prefix_mode
].name
, use_it
);
1564 *! \file server/dhcpv6.c
1566 * \brief construct a reply containing information about a client's lease
1568 * lease_to_client() is called from several messages to construct a
1569 * reply that contains all that we know about the client's correct lease
1570 * (or projected lease).
1572 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1573 * send what we "may" give them on a request.
1575 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1576 * the client should really use).
1578 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1579 * Rebind out any "wrong" addresses the client sends. This means we send
1580 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1581 * possibly send the address with zeroed lifetimes.
1583 * Information-Request - No binding.
1585 * The basic structure is to traverse the client-supplied data first, and
1586 * validate and echo back any contents that can be. If the client-supplied
1587 * data does not error out (on renew/rebind as above), but we did not send
1588 * any addresses, attempt to allocate one.
1590 * At the end of the this function we call commit_leases_timed() to
1591 * fsync and rotate the file as necessary. commit_leases_timed() will
1592 * check that we have written at least one lease to the file and that
1593 * some time has passed before doing any fsync or file rewrite so we
1594 * don't bother tracking if we did a write_ia during this function.
1596 /* TODO: look at client hints for lease times */
1599 lease_to_client(struct data_string
*reply_ret
,
1600 struct packet
*packet
,
1601 const struct data_string
*client_id
,
1602 const struct data_string
*server_id
)
1604 static struct reply_state reply
;
1605 struct option_cache
*oc
;
1606 struct data_string packet_oro
;
1609 memset(&packet_oro
, 0, sizeof(packet_oro
));
1611 /* Locate the client. */
1612 if (shared_network_from_packet6(&reply
.shared
,
1613 packet
) != ISC_R_SUCCESS
)
1617 * Initialize the reply.
1619 packet_reference(&reply
.packet
, packet
, MDL
);
1620 data_string_copy(&reply
.client_id
, client_id
, MDL
);
1622 if (!start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
1626 /* Set the write cursor to just past the reply header. */
1627 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1630 * Get the ORO from the packet, if any.
1632 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ORO
);
1634 if (!evaluate_option_cache(&packet_oro
, packet
,
1636 packet
->options
, NULL
,
1637 &global_scope
, oc
, MDL
)) {
1638 log_error("lease_to_client: error evaluating ORO.");
1644 * Find a host record that matches the packet, if any, and is
1645 * valid for the shared network the client is on.
1647 if (find_hosts6(&reply
.host
, packet
, client_id
, MDL
)) {
1649 seek_shared_host(&reply
.host
, reply
.shared
);
1652 /* Process the client supplied IA's onto the reply buffer. */
1654 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
1656 for (; oc
!= NULL
; oc
= oc
->next
) {
1657 isc_result_t status
;
1659 /* Start counting resources (addresses) offered. */
1660 reply
.client_resources
= 0;
1661 reply
.resources_included
= ISC_FALSE
;
1663 status
= reply_process_ia_na(&reply
, oc
);
1666 * We continue to try other IA's whether we can address
1667 * this one or not. Any other result is an immediate fail.
1669 if ((status
!= ISC_R_SUCCESS
) &&
1670 (status
!= ISC_R_NORESOURCES
))
1673 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
1674 for (; oc
!= NULL
; oc
= oc
->next
) {
1675 isc_result_t status
;
1677 /* Start counting resources (addresses) offered. */
1678 reply
.client_resources
= 0;
1679 reply
.resources_included
= ISC_FALSE
;
1681 status
= reply_process_ia_ta(&reply
, oc
);
1684 * We continue to try other IA's whether we can address
1685 * this one or not. Any other result is an immediate fail.
1687 if ((status
!= ISC_R_SUCCESS
) &&
1688 (status
!= ISC_R_NORESOURCES
))
1692 /* Same for IA_PD's. */
1694 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
1695 for (; oc
!= NULL
; oc
= oc
->next
) {
1696 isc_result_t status
;
1698 /* Start counting resources (prefixes) offered. */
1699 reply
.client_resources
= 0;
1700 reply
.resources_included
= ISC_FALSE
;
1702 status
= reply_process_ia_pd(&reply
, oc
);
1705 * We continue to try other IA_PD's whether we can address
1706 * this one or not. Any other result is an immediate fail.
1708 if ((status
!= ISC_R_SUCCESS
) &&
1709 (status
!= ISC_R_NORESOURCES
))
1714 * Make no reply if we gave no resources and is not
1715 * for Information-Request.
1717 if ((reply
.ia_count
== 0) && (reply
.pd_count
== 0)) {
1718 if (reply
.packet
->dhcpv6_msg_type
!=
1719 DHCPV6_INFORMATION_REQUEST
)
1723 * Because we only execute statements on a per-IA basis,
1724 * we need to execute statements in any non-IA reply to
1725 * source configuration.
1727 execute_statements_in_scope(NULL
, reply
.packet
, NULL
, NULL
,
1728 reply
.packet
->options
,
1729 reply
.opt_state
, &global_scope
,
1730 reply
.shared
->group
, root_group
,
1733 /* Execute statements from class scopes. */
1734 for (i
= reply
.packet
->class_count
; i
> 0; i
--) {
1735 execute_statements_in_scope(NULL
, reply
.packet
,
1737 reply
.packet
->options
,
1740 reply
.packet
->classes
[i
- 1]->group
,
1741 reply
.shared
->group
, NULL
);
1744 /* Bring in any configuration from a host record. */
1745 if (reply
.host
!= NULL
)
1746 execute_statements_in_scope(NULL
, reply
.packet
,
1748 reply
.packet
->options
,
1752 reply
.shared
->group
, NULL
);
1756 * RFC3315 section 17.2.2 (Solicit):
1758 * If the server will not assign any addresses to any IAs in a
1759 * subsequent Request from the client, the server MUST send an
1760 * Advertise message to the client that includes only a Status
1761 * Code option with code NoAddrsAvail and a status message for
1762 * the user, a Server Identifier option with the server's DUID,
1763 * and a Client Identifier option with the client's DUID.
1765 * This has been updated by an errata such that the server
1766 * can always send an IA.
1768 * Section 18.2.1 (Request):
1770 * If the server cannot assign any addresses to an IA in the
1771 * message from the client, the server MUST include the IA in
1772 * the Reply message with no addresses in the IA and a Status
1773 * Code option in the IA containing status code NoAddrsAvail.
1775 * Section 18.1.8 (Client Behavior):
1777 * Leave unchanged any information about addresses the client has
1778 * recorded in the IA but that were not included in the IA from
1780 * Sends a Renew/Rebind if the IA is not in the Reply message.
1784 * Having stored the client's IA's, store any options that
1785 * will fit in the remaining space.
1787 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+ reply
.cursor
,
1788 sizeof(reply
.buf
) - reply
.cursor
,
1789 reply
.opt_state
, reply
.packet
,
1790 required_opts_solicit
,
1793 /* Return our reply to the caller. */
1794 reply_ret
->len
= reply
.cursor
;
1795 reply_ret
->buffer
= NULL
;
1796 if (!buffer_allocate(&reply_ret
->buffer
, reply
.cursor
, MDL
)) {
1797 log_fatal("No memory to store Reply.");
1799 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
, reply
.cursor
);
1800 reply_ret
->data
= reply_ret
->buffer
->data
;
1802 /* If appropriate commit and rotate the lease file */
1803 (void) commit_leases_timed();
1807 if (reply
.shared
!= NULL
)
1808 shared_network_dereference(&reply
.shared
, MDL
);
1809 if (reply
.host
!= NULL
)
1810 host_dereference(&reply
.host
, MDL
);
1811 if (reply
.opt_state
!= NULL
)
1812 option_state_dereference(&reply
.opt_state
, MDL
);
1813 if (reply
.packet
!= NULL
)
1814 packet_dereference(&reply
.packet
, MDL
);
1815 if (reply
.client_id
.data
!= NULL
)
1816 data_string_forget(&reply
.client_id
, MDL
);
1817 if (packet_oro
.buffer
!= NULL
)
1818 data_string_forget(&packet_oro
, MDL
);
1819 reply
.renew
= reply
.rebind
= reply
.prefer
= reply
.valid
= 0;
1823 /* Process a client-supplied IA_NA. This may append options to the tail of
1824 * the reply packet being built in the reply_state structure.
1827 reply_process_ia_na(struct reply_state
*reply
, struct option_cache
*ia
) {
1828 isc_result_t status
= ISC_R_SUCCESS
;
1831 struct option_state
*packet_ia
;
1832 struct option_cache
*oc
;
1833 struct data_string ia_data
, data
;
1835 /* Initialize values that will get cleaned up on return. */
1837 memset(&ia_data
, 0, sizeof(ia_data
));
1838 memset(&data
, 0, sizeof(data
));
1840 * Note that find_client_address() may set reply->lease.
1843 /* Make sure there is at least room for the header. */
1844 if ((reply
->cursor
+ IA_NA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
1845 log_error("reply_process_ia_na: Reply too long for IA.");
1846 return ISC_R_NOSPACE
;
1850 /* Fetch the IA_NA contents. */
1851 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
1852 ia
, IA_NA_OFFSET
)) {
1853 log_error("reply_process_ia_na: error evaluating ia");
1854 status
= ISC_R_FAILURE
;
1858 /* Extract IA_NA header contents. */
1859 iaid
= getULong(ia_data
.data
);
1860 reply
->renew
= getULong(ia_data
.data
+ 4);
1861 reply
->rebind
= getULong(ia_data
.data
+ 8);
1863 /* Create an IA_NA structure. */
1864 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
1865 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
1866 log_error("reply_process_ia_na: no memory for ia.");
1867 status
= ISC_R_NOMEMORY
;
1870 reply
->ia
->ia_type
= D6O_IA_NA
;
1872 /* Cache pre-existing IA, if any. */
1873 ia_hash_lookup(&reply
->old_ia
, ia_na_active
,
1874 (unsigned char *)reply
->ia
->iaid_duid
.data
,
1875 reply
->ia
->iaid_duid
.len
, MDL
);
1878 * Create an option cache to carry the IA_NA option contents, and
1879 * execute any user-supplied values into it.
1881 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
1882 status
= ISC_R_NOMEMORY
;
1886 /* Check & cache the fixed host record. */
1887 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_addr
!= NULL
)) {
1888 struct iaddr tmp_addr
;
1890 if (!evaluate_option_cache(&reply
->fixed
, NULL
, NULL
, NULL
,
1891 NULL
, NULL
, &global_scope
,
1892 reply
->host
->fixed_addr
, MDL
)) {
1893 log_error("reply_process_ia_na: unable to evaluate "
1895 status
= ISC_R_FAILURE
;
1899 if (reply
->fixed
.len
< 16) {
1900 log_error("reply_process_ia_na: invalid fixed address.");
1901 status
= DHCP_R_INVALIDARG
;
1905 /* Find the static lease's subnet. */
1907 memcpy(tmp_addr
.iabuf
, reply
->fixed
.data
, 16);
1909 if (find_grouped_subnet(&reply
->subnet
, reply
->shared
,
1910 tmp_addr
, MDL
) == 0)
1911 log_fatal("Impossible condition at %s:%d.", MDL
);
1913 reply
->static_lease
= ISC_TRUE
;
1915 reply
->static_lease
= ISC_FALSE
;
1918 * Save the cursor position at the start of the IA, so we can
1919 * set length and adjust t1/t2 values later. We write a temporary
1920 * header out now just in case we decide to adjust the packet
1921 * within sub-process functions.
1923 ia_cursor
= reply
->cursor
;
1925 /* Initialize the IA_NA header. First the code. */
1926 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_NA
);
1929 /* Then option length. */
1930 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
1933 /* Then IA_NA header contents; IAID. */
1934 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
1937 /* We store the client's t1 for now, and may over-ride it later. */
1938 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
1941 /* We store the client's t2 for now, and may over-ride it later. */
1942 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
1946 * For each address in this IA_NA, decide what to do about it.
1950 * The client leaves unchanged any information about addresses
1951 * it has recorded but are not included ("cancel/break" below).
1952 * A not included IA ("cleanup" below) could give a Renew/Rebind.
1954 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
1955 reply
->valid
= reply
->prefer
= 0xffffffff;
1956 reply
->client_valid
= reply
->client_prefer
= 0;
1957 for (; oc
!= NULL
; oc
= oc
->next
) {
1958 status
= reply_process_addr(reply
, oc
);
1961 * Canceled means we did not allocate addresses to the
1962 * client, but we're "done" with this IA - we set a status
1963 * code. So transmit this reply, e.g., move on to the next
1966 if (status
== ISC_R_CANCELED
)
1969 if ((status
!= ISC_R_SUCCESS
) &&
1970 (status
!= ISC_R_ADDRINUSE
) &&
1971 (status
!= ISC_R_ADDRNOTAVAIL
))
1978 * If we fell through the above and never gave the client
1979 * an address, give it one now.
1981 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
1982 status
= find_client_address(reply
);
1984 if (status
== ISC_R_NORESOURCES
) {
1985 switch (reply
->packet
->dhcpv6_msg_type
) {
1986 case DHCPV6_SOLICIT
:
1988 * No address for any IA is handled
1993 case DHCPV6_REQUEST
:
1994 /* Section 18.2.1 (Request):
1996 * If the server cannot assign any addresses to
1997 * an IA in the message from the client, the
1998 * server MUST include the IA in the Reply
1999 * message with no addresses in the IA and a
2000 * Status Code option in the IA containing
2001 * status code NoAddrsAvail.
2003 option_state_dereference(&reply
->reply_ia
, MDL
);
2004 if (!option_state_allocate(&reply
->reply_ia
,
2007 log_error("reply_process_ia_na: No "
2008 "memory for option state "
2010 status
= ISC_R_NOMEMORY
;
2014 if (!set_status_code(STATUS_NoAddrsAvail
,
2015 "No addresses available "
2016 "for this interface.",
2018 log_error("reply_process_ia_na: Unable "
2019 "to set NoAddrsAvail status "
2021 status
= ISC_R_FAILURE
;
2025 status
= ISC_R_SUCCESS
;
2030 * RFC 3315 does not tell us to emit a status
2031 * code in this condition, or anything else.
2033 * If we included non-allocated addresses
2034 * (zeroed lifetimes) in an IA, then the client
2035 * will deconfigure them.
2037 * So we want to include the IA even if we
2038 * can't give it a new address if it includes
2039 * zeroed lifetime addresses.
2041 * We don't want to include the IA if we
2042 * provide zero addresses including zeroed
2045 if (reply
->resources_included
)
2046 status
= ISC_R_SUCCESS
;
2053 if (status
!= ISC_R_SUCCESS
)
2057 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2058 sizeof(reply
->buf
) - reply
->cursor
,
2059 reply
->reply_ia
, reply
->packet
,
2060 required_opts_IA
, NULL
);
2062 /* Reset the length of this IA to match what was just written. */
2063 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2064 reply
->cursor
- (ia_cursor
+ 4));
2067 * T1/T2 time selection is kind of weird. We actually use DHCP
2068 * (v4) scoped options as handy existing places where these might
2069 * be configured by an administrator. A value of zero tells the
2070 * client it may choose its own renewal time.
2073 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
2074 DHO_DHCP_RENEWAL_TIME
);
2076 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
2077 reply
->packet
->options
,
2078 reply
->opt_state
, &global_scope
,
2081 log_error("Invalid renewal time.");
2083 reply
->renew
= getULong(data
.data
);
2086 if (data
.data
!= NULL
)
2087 data_string_forget(&data
, MDL
);
2089 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
2093 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
2094 DHO_DHCP_REBINDING_TIME
);
2096 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
2097 reply
->packet
->options
,
2098 reply
->opt_state
, &global_scope
,
2101 log_error("Invalid rebinding time.");
2103 reply
->rebind
= getULong(data
.data
);
2106 if (data
.data
!= NULL
)
2107 data_string_forget(&data
, MDL
);
2109 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
2112 * yes, goto's aren't the best but we also want to avoid extra
2115 if (status
== ISC_R_CANCELED
)
2119 * Handle static leases, we always log stuff and if it's
2120 * a hard binding we run any commit statements that we have
2122 if (reply
->static_lease
) {
2123 char tmp_addr
[INET6_ADDRSTRLEN
];
2124 log_info("%s NA: address %s to client with duid %s iaid = %d "
2126 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2127 inet_ntop(AF_INET6
, reply
->fixed
.data
, tmp_addr
,
2129 print_hex_1(reply
->client_id
.len
,
2130 reply
->client_id
.data
, 60),
2133 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
2134 (reply
->on_star
.on_commit
!= NULL
)) {
2135 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
2136 reply
->packet
->options
,
2137 reply
->opt_state
, NULL
,
2138 reply
->on_star
.on_commit
, NULL
);
2139 executable_statement_dereference
2140 (&reply
->on_star
.on_commit
, MDL
);
2146 * If we have any addresses log what we are doing.
2148 if (reply
->ia
->num_iasubopt
!= 0) {
2149 struct iasubopt
*tmp
;
2151 char tmp_addr
[INET6_ADDRSTRLEN
];
2153 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2154 tmp
= reply
->ia
->iasubopt
[i
];
2156 log_info("%s NA: address %s to client with duid %s "
2157 "iaid = %d valid for %u seconds",
2158 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2159 inet_ntop(AF_INET6
, &tmp
->addr
,
2160 tmp_addr
, sizeof(tmp_addr
)),
2161 print_hex_1(reply
->client_id
.len
,
2162 reply
->client_id
.data
, 60),
2168 * If this is not a 'soft' binding, consume the new changes into
2169 * the database (if any have been attached to the ia_na).
2171 * Loop through the assigned dynamic addresses, referencing the
2172 * leases onto this IA_NA rather than any old ones, and updating
2173 * pool timers for each (if any).
2176 if ((reply
->ia
->num_iasubopt
!= 0) &&
2177 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
2178 struct iasubopt
*tmp
;
2179 struct data_string
*ia_id
;
2182 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2183 tmp
= reply
->ia
->iasubopt
[i
];
2185 if (tmp
->ia
!= NULL
)
2186 ia_dereference(&tmp
->ia
, MDL
);
2187 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2189 /* Commit 'hard' bindings. */
2190 renew_lease6(tmp
->ipv6_pool
, tmp
);
2191 schedule_lease_timeout(tmp
->ipv6_pool
);
2193 /* If we have anything to do on commit do it now */
2194 if (tmp
->on_star
.on_commit
!= NULL
) {
2195 execute_statements(NULL
, reply
->packet
,
2197 reply
->packet
->options
,
2200 tmp
->on_star
.on_commit
,
2202 executable_statement_dereference
2203 (&tmp
->on_star
.on_commit
, MDL
);
2206 #if defined (NSUPDATE)
2208 * Perform ddns updates.
2210 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2213 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2215 reply
->packet
->options
,
2219 ddns_updates(reply
->packet
, NULL
, NULL
,
2220 tmp
, NULL
, reply
->opt_state
);
2223 /* Do our threshold check. */
2224 check_pool6_threshold(reply
, tmp
);
2227 /* Remove any old ia from the hash. */
2228 if (reply
->old_ia
!= NULL
) {
2229 ia_id
= &reply
->old_ia
->iaid_duid
;
2230 ia_hash_delete(ia_na_active
,
2231 (unsigned char *)ia_id
->data
,
2233 ia_dereference(&reply
->old_ia
, MDL
);
2236 /* Put new ia into the hash. */
2237 reply
->ia
->cltt
= cur_time
;
2238 ia_id
= &reply
->ia
->iaid_duid
;
2239 ia_hash_add(ia_na_active
, (unsigned char *)ia_id
->data
,
2240 ia_id
->len
, reply
->ia
, MDL
);
2242 write_ia(reply
->ia
);
2244 schedule_lease_timeout_reply(reply
);
2248 if (packet_ia
!= NULL
)
2249 option_state_dereference(&packet_ia
, MDL
);
2250 if (reply
->reply_ia
!= NULL
)
2251 option_state_dereference(&reply
->reply_ia
, MDL
);
2252 if (ia_data
.data
!= NULL
)
2253 data_string_forget(&ia_data
, MDL
);
2254 if (data
.data
!= NULL
)
2255 data_string_forget(&data
, MDL
);
2256 if (reply
->ia
!= NULL
)
2257 ia_dereference(&reply
->ia
, MDL
);
2258 if (reply
->old_ia
!= NULL
)
2259 ia_dereference(&reply
->old_ia
, MDL
);
2260 if (reply
->lease
!= NULL
)
2261 iasubopt_dereference(&reply
->lease
, MDL
);
2262 if (reply
->fixed
.data
!= NULL
)
2263 data_string_forget(&reply
->fixed
, MDL
);
2264 if (reply
->subnet
!= NULL
)
2265 subnet_dereference(&reply
->subnet
, MDL
);
2266 if (reply
->on_star
.on_expiry
!= NULL
)
2267 executable_statement_dereference
2268 (&reply
->on_star
.on_expiry
, MDL
);
2269 if (reply
->on_star
.on_release
!= NULL
)
2270 executable_statement_dereference
2271 (&reply
->on_star
.on_release
, MDL
);
2274 * ISC_R_CANCELED is a status code used by the addr processing to
2275 * indicate we're replying with a status code. This is still a
2276 * success at higher layers.
2278 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2282 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
2283 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
2284 * in the event we are replying with a status code and do not wish to process
2285 * more IAADDRs within this IA.
2288 reply_process_addr(struct reply_state
*reply
, struct option_cache
*addr
) {
2289 u_int32_t pref_life
, valid_life
;
2290 struct binding_scope
**scope
;
2291 struct group
*group
;
2292 struct subnet
*subnet
;
2293 struct iaddr tmp_addr
;
2294 struct option_cache
*oc
;
2295 struct data_string iaaddr
, data
;
2296 isc_result_t status
= ISC_R_SUCCESS
;
2298 /* Initializes values that will be cleaned up. */
2299 memset(&iaaddr
, 0, sizeof(iaaddr
));
2300 memset(&data
, 0, sizeof(data
));
2301 /* Note that reply->lease may be set by address_is_owned() */
2304 * There is no point trying to process an incoming address if there
2305 * is no room for an outgoing address.
2307 if ((reply
->cursor
+ 28) > sizeof(reply
->buf
)) {
2308 log_error("reply_process_addr: Out of room for address.");
2309 return ISC_R_NOSPACE
;
2312 /* Extract this IAADDR option. */
2313 if (!evaluate_option_cache(&iaaddr
, reply
->packet
, NULL
, NULL
,
2314 reply
->packet
->options
, NULL
, &global_scope
,
2316 (iaaddr
.len
< IAADDR_OFFSET
)) {
2317 log_error("reply_process_addr: error evaluating IAADDR.");
2318 status
= ISC_R_FAILURE
;
2322 /* The first 16 bytes are the IPv6 address. */
2323 pref_life
= getULong(iaaddr
.data
+ 16);
2324 valid_life
= getULong(iaaddr
.data
+ 20);
2326 if ((reply
->client_valid
== 0) ||
2327 (reply
->client_valid
> valid_life
))
2328 reply
->client_valid
= valid_life
;
2330 if ((reply
->client_prefer
== 0) ||
2331 (reply
->client_prefer
> pref_life
))
2332 reply
->client_prefer
= pref_life
;
2335 * Clients may choose to send :: as an address, with the idea to give
2336 * hints about preferred-lifetime or valid-lifetime.
2339 memset(tmp_addr
.iabuf
, 0, 16);
2340 if (!memcmp(iaaddr
.data
, tmp_addr
.iabuf
, 16)) {
2341 /* Status remains success; we just ignore this one. */
2345 /* tmp_addr len remains 16 */
2346 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2349 * Verify that this address is on the client's network.
2351 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
2352 subnet
= subnet
->next_sibling
) {
2353 if (addr_eq(subnet_number(tmp_addr
, subnet
->netmask
),
2358 /* Address not found on shared network. */
2359 if (subnet
== NULL
) {
2360 /* Ignore this address on 'soft' bindings. */
2361 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
2362 /* disable rapid commit */
2363 reply
->buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
2364 delete_option(&dhcpv6_universe
,
2367 /* status remains success */
2372 * RFC3315 section 18.2.1:
2374 * If the server finds that the prefix on one or more IP
2375 * addresses in any IA in the message from the client is not
2376 * appropriate for the link to which the client is connected,
2377 * the server MUST return the IA to the client with a Status
2378 * Code option with the value NotOnLink.
2380 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) {
2381 /* Rewind the IA_NA to empty. */
2382 option_state_dereference(&reply
->reply_ia
, MDL
);
2383 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2384 log_error("reply_process_addr: No memory for "
2385 "option state wipe.");
2386 status
= ISC_R_NOMEMORY
;
2390 /* Append a NotOnLink status code. */
2391 if (!set_status_code(STATUS_NotOnLink
,
2392 "Address not for use on this "
2393 "link.", reply
->reply_ia
)) {
2394 log_error("reply_process_addr: Failure "
2395 "setting status code.");
2396 status
= ISC_R_FAILURE
;
2400 /* Fin (no more IAADDRs). */
2401 status
= ISC_R_CANCELED
;
2406 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2408 * If the server finds that any of the addresses are not
2409 * appropriate for the link to which the client is attached,
2410 * the server returns the address to the client with lifetimes
2413 if ((reply
->packet
->dhcpv6_msg_type
!= DHCPV6_RENEW
) &&
2414 (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
2415 log_error("It is impossible to lease a client that is "
2416 "not sending a solicit, request, renew, or "
2418 status
= ISC_R_FAILURE
;
2422 reply
->send_prefer
= reply
->send_valid
= 0;
2426 /* Verify the address belongs to the client. */
2427 if (!address_is_owned(reply
, &tmp_addr
)) {
2429 * For solicit and request, any addresses included are
2430 * 'requested' addresses. For rebind, we actually have
2431 * no direction on what to do from 3315 section 18.2.4!
2432 * So I think the best bet is to try and give it out, and if
2433 * we can't, zero lifetimes.
2435 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
2436 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
2437 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
2438 status
= reply_process_try_addr(reply
, &tmp_addr
);
2441 * If the address is in use, or isn't in any dynamic
2442 * range, continue as normal. If any other error was
2445 if ((status
!= ISC_R_SUCCESS
) &&
2446 (status
!= ISC_R_ADDRINUSE
) &&
2447 (status
!= ISC_R_ADDRNOTAVAIL
))
2451 * If we didn't honor this lease, for solicit and
2452 * request we simply omit it from our answer. For
2453 * rebind, we send it with zeroed lifetimes.
2455 if (reply
->lease
== NULL
) {
2456 if (reply
->packet
->dhcpv6_msg_type
==
2458 reply
->send_prefer
= 0;
2459 reply
->send_valid
= 0;
2463 /* status remains success - ignore */
2467 * RFC3315 section 18.2.3:
2469 * If the server cannot find a client entry for the IA the
2470 * server returns the IA containing no addresses with a Status
2471 * Code option set to NoBinding in the Reply message.
2473 * On mismatch we (ab)use this pretending we have not the IA
2474 * as soon as we have not an address.
2476 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
2477 /* Rewind the IA_NA to empty. */
2478 option_state_dereference(&reply
->reply_ia
, MDL
);
2479 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2480 log_error("reply_process_addr: No memory for "
2481 "option state wipe.");
2482 status
= ISC_R_NOMEMORY
;
2486 /* Append a NoBinding status code. */
2487 if (!set_status_code(STATUS_NoBinding
,
2488 "Address not bound to this "
2489 "interface.", reply
->reply_ia
)) {
2490 log_error("reply_process_addr: Unable to "
2491 "attach status code.");
2492 status
= ISC_R_FAILURE
;
2496 /* Fin (no more IAADDRs). */
2497 status
= ISC_R_CANCELED
;
2500 log_error("It is impossible to lease a client that is "
2501 "not sending a solicit, request, renew, or "
2503 status
= ISC_R_FAILURE
;
2508 if (reply
->static_lease
) {
2509 if (reply
->host
== NULL
)
2510 log_fatal("Impossible condition at %s:%d.", MDL
);
2512 scope
= &global_scope
;
2513 group
= reply
->subnet
->group
;
2515 if (reply
->lease
== NULL
)
2516 log_fatal("Impossible condition at %s:%d.", MDL
);
2518 scope
= &reply
->lease
->scope
;
2519 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
2523 * If client_resources is nonzero, then the reply_process_is_addressed
2524 * function has executed configuration state into the reply option
2525 * cache. We will use that valid cache to derive configuration for
2526 * whether or not to engage in additional addresses, and similar.
2528 if (reply
->client_resources
!= 0) {
2532 * Does this client have "enough" addresses already? Default
2533 * to one. Everybody gets one, and one should be enough for
2536 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2537 SV_LIMIT_ADDRS_PER_IA
);
2539 if (!evaluate_option_cache(&data
, reply
->packet
,
2541 reply
->packet
->options
,
2545 log_error("reply_process_addr: unable to "
2546 "evaluate addrs-per-ia value.");
2547 status
= ISC_R_FAILURE
;
2551 limit
= getULong(data
.data
);
2552 data_string_forget(&data
, MDL
);
2556 * If we wish to limit the client to a certain number of
2557 * addresses, then omit the address from the reply.
2559 if (reply
->client_resources
>= limit
)
2563 status
= reply_process_is_addressed(reply
, scope
, group
);
2564 if (status
!= ISC_R_SUCCESS
)
2568 status
= reply_process_send_addr(reply
, &tmp_addr
);
2571 if (iaaddr
.data
!= NULL
)
2572 data_string_forget(&iaaddr
, MDL
);
2573 if (data
.data
!= NULL
)
2574 data_string_forget(&data
, MDL
);
2575 if (reply
->lease
!= NULL
)
2576 iasubopt_dereference(&reply
->lease
, MDL
);
2582 * Verify the address belongs to the client. If we've got a host
2583 * record with a fixed address, it has to be the assigned address
2584 * (fault out all else). Otherwise it's a dynamic address, so lookup
2585 * that address and make sure it belongs to this DUID:IAID pair.
2587 static isc_boolean_t
2588 address_is_owned(struct reply_state
*reply
, struct iaddr
*addr
) {
2590 struct ipv6_pond
*pond
;
2593 * This faults out addresses that don't match fixed addresses.
2595 if (reply
->static_lease
) {
2596 if (reply
->fixed
.data
== NULL
)
2597 log_fatal("Impossible condition at %s:%d.", MDL
);
2599 if (memcmp(addr
->iabuf
, reply
->fixed
.data
, 16) == 0)
2605 if ((reply
->old_ia
== NULL
) || (reply
->old_ia
->num_iasubopt
== 0))
2608 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2609 struct iasubopt
*tmp
;
2611 tmp
= reply
->old_ia
->iasubopt
[i
];
2613 if (memcmp(addr
->iabuf
, &tmp
->addr
, 16) == 0) {
2614 if (lease6_usable(tmp
) == ISC_FALSE
) {
2618 pond
= tmp
->ipv6_pool
->ipv6_pond
;
2619 if (((pond
->prohibit_list
!= NULL
) &&
2620 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
2621 ((pond
->permit_list
!= NULL
) &&
2622 (!permitted(reply
->packet
, pond
->permit_list
))))
2625 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
2634 /* Process a client-supplied IA_TA. This may append options to the tail of
2635 * the reply packet being built in the reply_state structure.
2638 reply_process_ia_ta(struct reply_state
*reply
, struct option_cache
*ia
) {
2639 isc_result_t status
= ISC_R_SUCCESS
;
2642 struct option_state
*packet_ia
;
2643 struct option_cache
*oc
;
2644 struct data_string ia_data
, data
;
2645 struct data_string iaaddr
;
2646 u_int32_t pref_life
, valid_life
;
2647 struct iaddr tmp_addr
;
2649 /* Initialize values that will get cleaned up on return. */
2651 memset(&ia_data
, 0, sizeof(ia_data
));
2652 memset(&data
, 0, sizeof(data
));
2653 memset(&iaaddr
, 0, sizeof(iaaddr
));
2655 /* Make sure there is at least room for the header. */
2656 if ((reply
->cursor
+ IA_TA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2657 log_error("reply_process_ia_ta: Reply too long for IA.");
2658 return ISC_R_NOSPACE
;
2662 /* Fetch the IA_TA contents. */
2663 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2664 ia
, IA_TA_OFFSET
)) {
2665 log_error("reply_process_ia_ta: error evaluating ia");
2666 status
= ISC_R_FAILURE
;
2670 /* Extract IA_TA header contents. */
2671 iaid
= getULong(ia_data
.data
);
2673 /* Create an IA_TA structure. */
2674 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2675 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2676 log_error("reply_process_ia_ta: no memory for ia.");
2677 status
= ISC_R_NOMEMORY
;
2680 reply
->ia
->ia_type
= D6O_IA_TA
;
2682 /* Cache pre-existing IA, if any. */
2683 ia_hash_lookup(&reply
->old_ia
, ia_ta_active
,
2684 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2685 reply
->ia
->iaid_duid
.len
, MDL
);
2688 * Create an option cache to carry the IA_TA option contents, and
2689 * execute any user-supplied values into it.
2691 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2692 status
= ISC_R_NOMEMORY
;
2697 * Temporary leases are dynamic by definition.
2699 reply
->static_lease
= ISC_FALSE
;
2702 * Save the cursor position at the start of the IA, so we can
2703 * set length later. We write a temporary
2704 * header out now just in case we decide to adjust the packet
2705 * within sub-process functions.
2707 ia_cursor
= reply
->cursor
;
2709 /* Initialize the IA_TA header. First the code. */
2710 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_TA
);
2713 /* Then option length. */
2714 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x04u
);
2717 /* Then IA_TA header contents; IAID. */
2718 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2722 * Deal with an IAADDR for lifetimes.
2723 * For all or none, process IAADDRs as hints.
2725 reply
->valid
= reply
->prefer
= 0xffffffff;
2726 reply
->client_valid
= reply
->client_prefer
= 0;
2727 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2728 for (; oc
!= NULL
; oc
= oc
->next
) {
2729 memset(&iaaddr
, 0, sizeof(iaaddr
));
2730 if (!evaluate_option_cache(&iaaddr
, reply
->packet
,
2732 reply
->packet
->options
, NULL
,
2733 &global_scope
, oc
, MDL
) ||
2734 (iaaddr
.len
< IAADDR_OFFSET
)) {
2735 log_error("reply_process_ia_ta: error "
2736 "evaluating IAADDR.");
2737 status
= ISC_R_FAILURE
;
2740 /* The first 16 bytes are the IPv6 address. */
2741 pref_life
= getULong(iaaddr
.data
+ 16);
2742 valid_life
= getULong(iaaddr
.data
+ 20);
2744 if ((reply
->client_valid
== 0) ||
2745 (reply
->client_valid
> valid_life
))
2746 reply
->client_valid
= valid_life
;
2748 if ((reply
->client_prefer
== 0) ||
2749 (reply
->client_prefer
> pref_life
))
2750 reply
->client_prefer
= pref_life
;
2752 /* Nothing more if something has failed. */
2753 if (status
== ISC_R_CANCELED
)
2757 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2758 if (!temporary_is_available(reply
, &tmp_addr
))
2760 status
= reply_process_is_addressed(reply
,
2761 &reply
->lease
->scope
,
2762 reply
->lease
->ipv6_pool
->ipv6_pond
->group
);
2763 if (status
!= ISC_R_SUCCESS
)
2765 status
= reply_process_send_addr(reply
, &tmp_addr
);
2766 if (status
!= ISC_R_SUCCESS
)
2768 if (reply
->lease
!= NULL
)
2769 iasubopt_dereference(&reply
->lease
, MDL
);
2773 /* Rewind the IA_TA to empty. */
2774 option_state_dereference(&reply
->reply_ia
, MDL
);
2775 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2776 status
= ISC_R_NOMEMORY
;
2779 status
= ISC_R_CANCELED
;
2780 reply
->client_resources
= 0;
2781 reply
->resources_included
= ISC_FALSE
;
2782 if (reply
->lease
!= NULL
)
2783 iasubopt_dereference(&reply
->lease
, MDL
);
2788 * Give the client temporary addresses.
2790 if (reply
->client_resources
!= 0)
2792 status
= find_client_temporaries(reply
);
2793 if (status
== ISC_R_NORESOURCES
) {
2794 switch (reply
->packet
->dhcpv6_msg_type
) {
2795 case DHCPV6_SOLICIT
:
2797 * No address for any IA is handled
2802 case DHCPV6_REQUEST
:
2803 /* Section 18.2.1 (Request):
2805 * If the server cannot assign any addresses to
2806 * an IA in the message from the client, the
2807 * server MUST include the IA in the Reply
2808 * message with no addresses in the IA and a
2809 * Status Code option in the IA containing
2810 * status code NoAddrsAvail.
2812 option_state_dereference(&reply
->reply_ia
, MDL
);
2813 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2814 log_error("reply_process_ia_ta: No "
2815 "memory for option state wipe.");
2816 status
= ISC_R_NOMEMORY
;
2820 if (!set_status_code(STATUS_NoAddrsAvail
,
2821 "No addresses available "
2822 "for this interface.",
2824 log_error("reply_process_ia_ta: Unable "
2825 "to set NoAddrsAvail status code.");
2826 status
= ISC_R_FAILURE
;
2830 status
= ISC_R_SUCCESS
;
2835 * We don't want to include the IA if we
2836 * provide zero addresses including zeroed
2839 if (reply
->resources_included
)
2840 status
= ISC_R_SUCCESS
;
2845 } else if (status
!= ISC_R_SUCCESS
)
2849 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2850 sizeof(reply
->buf
) - reply
->cursor
,
2851 reply
->reply_ia
, reply
->packet
,
2852 required_opts_IA
, NULL
);
2854 /* Reset the length of this IA to match what was just written. */
2855 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2856 reply
->cursor
- (ia_cursor
+ 4));
2859 * yes, goto's aren't the best but we also want to avoid extra
2862 if (status
== ISC_R_CANCELED
)
2866 * If we have any addresses log what we are doing.
2868 if (reply
->ia
->num_iasubopt
!= 0) {
2869 struct iasubopt
*tmp
;
2871 char tmp_addr
[INET6_ADDRSTRLEN
];
2873 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2874 tmp
= reply
->ia
->iasubopt
[i
];
2876 log_info("%s TA: address %s to client with duid %s "
2877 "iaid = %d valid for %u seconds",
2878 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2879 inet_ntop(AF_INET6
, &tmp
->addr
,
2880 tmp_addr
, sizeof(tmp_addr
)),
2881 print_hex_1(reply
->client_id
.len
,
2882 reply
->client_id
.data
, 60),
2889 * For hard bindings we consume the new changes into
2890 * the database (if any have been attached to the ia_ta).
2892 * Loop through the assigned dynamic addresses, referencing the
2893 * leases onto this IA_TA rather than any old ones, and updating
2894 * pool timers for each (if any).
2896 if ((reply
->ia
->num_iasubopt
!= 0) &&
2897 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
2898 struct iasubopt
*tmp
;
2899 struct data_string
*ia_id
;
2902 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2903 tmp
= reply
->ia
->iasubopt
[i
];
2905 if (tmp
->ia
!= NULL
)
2906 ia_dereference(&tmp
->ia
, MDL
);
2907 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2909 /* Commit 'hard' bindings. */
2910 renew_lease6(tmp
->ipv6_pool
, tmp
);
2911 schedule_lease_timeout(tmp
->ipv6_pool
);
2913 /* If we have anything to do on commit do it now */
2914 if (tmp
->on_star
.on_commit
!= NULL
) {
2915 execute_statements(NULL
, reply
->packet
,
2917 reply
->packet
->options
,
2920 tmp
->on_star
.on_commit
,
2922 executable_statement_dereference
2923 (&tmp
->on_star
.on_commit
, MDL
);
2926 #if defined (NSUPDATE)
2928 * Perform ddns updates.
2930 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2933 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2935 reply
->packet
->options
,
2939 ddns_updates(reply
->packet
, NULL
, NULL
,
2940 tmp
, NULL
, reply
->opt_state
);
2943 /* Do our threshold check. */
2944 check_pool6_threshold(reply
, tmp
);
2947 /* Remove any old ia from the hash. */
2948 if (reply
->old_ia
!= NULL
) {
2949 ia_id
= &reply
->old_ia
->iaid_duid
;
2950 ia_hash_delete(ia_ta_active
,
2951 (unsigned char *)ia_id
->data
,
2953 ia_dereference(&reply
->old_ia
, MDL
);
2956 /* Put new ia into the hash. */
2957 reply
->ia
->cltt
= cur_time
;
2958 ia_id
= &reply
->ia
->iaid_duid
;
2959 ia_hash_add(ia_ta_active
, (unsigned char *)ia_id
->data
,
2960 ia_id
->len
, reply
->ia
, MDL
);
2962 write_ia(reply
->ia
);
2964 schedule_lease_timeout_reply(reply
);
2968 if (packet_ia
!= NULL
)
2969 option_state_dereference(&packet_ia
, MDL
);
2970 if (iaaddr
.data
!= NULL
)
2971 data_string_forget(&iaaddr
, MDL
);
2972 if (reply
->reply_ia
!= NULL
)
2973 option_state_dereference(&reply
->reply_ia
, MDL
);
2974 if (ia_data
.data
!= NULL
)
2975 data_string_forget(&ia_data
, MDL
);
2976 if (data
.data
!= NULL
)
2977 data_string_forget(&data
, MDL
);
2978 if (reply
->ia
!= NULL
)
2979 ia_dereference(&reply
->ia
, MDL
);
2980 if (reply
->old_ia
!= NULL
)
2981 ia_dereference(&reply
->old_ia
, MDL
);
2982 if (reply
->lease
!= NULL
)
2983 iasubopt_dereference(&reply
->lease
, MDL
);
2986 * ISC_R_CANCELED is a status code used by the addr processing to
2987 * indicate we're replying with other addresses. This is still a
2988 * success at higher layers.
2990 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2994 * Verify the temporary address is available.
2996 static isc_boolean_t
2997 temporary_is_available(struct reply_state
*reply
, struct iaddr
*addr
) {
2998 struct in6_addr tmp_addr
;
2999 struct subnet
*subnet
;
3000 struct ipv6_pool
*pool
= NULL
;
3001 struct ipv6_pond
*pond
= NULL
;
3004 memcpy(&tmp_addr
, addr
->iabuf
, sizeof(tmp_addr
));
3006 * Clients may choose to send :: as an address, with the idea to give
3007 * hints about preferred-lifetime or valid-lifetime.
3008 * So this is not a request for this address.
3010 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
))
3014 * Verify that this address is on the client's network.
3016 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
3017 subnet
= subnet
->next_sibling
) {
3018 if (addr_eq(subnet_number(*addr
, subnet
->netmask
),
3023 /* Address not found on shared network. */
3028 * Check if this address is owned (must be before next step).
3030 if (address_is_owned(reply
, addr
))
3034 * Verify that this address is in a temporary pool and try to get it.
3036 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3037 if (((pond
->prohibit_list
!= NULL
) &&
3038 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3039 ((pond
->permit_list
!= NULL
) &&
3040 (!permitted(reply
->packet
, pond
->permit_list
))))
3043 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3044 if (pool
->pool_type
!= D6O_IA_TA
)
3047 if (ipv6_in_pool(&tmp_addr
, pool
))
3057 if (lease6_exists(pool
, &tmp_addr
))
3059 if (iasubopt_allocate(&reply
->lease
, MDL
) != ISC_R_SUCCESS
)
3061 reply
->lease
->addr
= tmp_addr
;
3062 reply
->lease
->plen
= 0;
3063 /* Default is soft binding for 2 minutes. */
3064 if (add_lease6(pool
, reply
->lease
, cur_time
+ 120) != ISC_R_SUCCESS
)
3071 * Get a temporary address per prefix.
3074 find_client_temporaries(struct reply_state
*reply
) {
3076 struct ipv6_pool
*p
= NULL
;
3077 struct ipv6_pond
*pond
;
3078 isc_result_t status
= ISC_R_NORESOURCES
;;
3079 unsigned int attempts
;
3080 struct iaddr send_addr
;
3083 * Do a quick walk through of the ponds and pools
3084 * to see if we have any prefix pools
3086 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3087 if (pond
->ipv6_pools
== NULL
)
3090 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3091 if (p
->pool_type
== D6O_IA_TA
)
3098 /* If we get here and p is NULL we have no useful pools */
3100 log_debug("Unable to get client addresses: "
3101 "no IPv6 pools on this shared network");
3102 return ISC_R_NORESOURCES
;
3106 * We have at least one pool that could provide an address
3107 * Now we walk through the ponds and pools again and check
3108 * to see if the client is permitted and if an address is
3112 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3113 if (((pond
->prohibit_list
!= NULL
) &&
3114 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3115 ((pond
->permit_list
!= NULL
) &&
3116 (!permitted(reply
->packet
, pond
->permit_list
))))
3119 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3120 if (p
->pool_type
!= D6O_IA_TA
) {
3125 * Get an address in this temporary pool.
3127 status
= create_lease6(p
, &reply
->lease
, &attempts
,
3128 &reply
->client_id
, cur_time
+ 120);
3129 if (status
!= ISC_R_SUCCESS
) {
3130 log_debug("Unable to get a temporary address.");
3134 status
= reply_process_is_addressed(reply
,
3135 &reply
->lease
->scope
,
3137 if (status
!= ISC_R_SUCCESS
) {
3141 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3142 status
= reply_process_send_addr(reply
, &send_addr
);
3143 if (status
!= ISC_R_SUCCESS
) {
3147 * reply->lease can't be null as we use it above
3148 * add check if that changes
3150 iasubopt_dereference(&reply
->lease
, MDL
);
3155 if (reply
->lease
!= NULL
) {
3156 iasubopt_dereference(&reply
->lease
, MDL
);
3162 * This function only returns failure on 'hard' failures. If it succeeds,
3163 * it will leave a lease structure behind.
3166 reply_process_try_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3167 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
3168 struct ipv6_pool
*pool
= NULL
;
3169 struct ipv6_pond
*pond
= NULL
;
3171 struct data_string data_addr
;
3173 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
3174 (addr
== NULL
) || (reply
->lease
!= NULL
))
3175 return (DHCP_R_INVALIDARG
);
3178 * Do a quick walk through of the ponds and pools
3179 * to see if we have any NA address pools
3181 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3182 if (pond
->ipv6_pools
== NULL
)
3185 for (i
= 0; ; i
++) {
3186 pool
= pond
->ipv6_pools
[i
];
3187 if ((pool
== NULL
) ||
3188 (pool
->pool_type
== D6O_IA_NA
))
3195 /* If we get here and p is NULL we have no useful pools */
3197 return (ISC_R_ADDRNOTAVAIL
);
3200 memset(&data_addr
, 0, sizeof(data_addr
));
3201 data_addr
.len
= addr
->len
;
3202 data_addr
.data
= addr
->iabuf
;
3205 * We have at least one pool that could provide an address
3206 * Now we walk through the ponds and pools again and check
3207 * to see if the client is permitted and if an address is
3210 * Within a given pond we start looking at the last pool we
3211 * allocated from, unless it had a collision trying to allocate
3212 * an address. This will tend to move us into less-filled pools.
3215 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3216 if (((pond
->prohibit_list
!= NULL
) &&
3217 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3218 ((pond
->permit_list
!= NULL
) &&
3219 (!permitted(reply
->packet
, pond
->permit_list
))))
3222 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3223 if (pool
->pool_type
!= D6O_IA_NA
)
3226 status
= try_client_v6_address(&reply
->lease
, pool
,
3228 if (status
== ISC_R_SUCCESS
)
3232 if (status
== ISC_R_SUCCESS
)
3236 /* Note that this is just pedantry. There is no allocation to free. */
3237 data_string_forget(&data_addr
, MDL
);
3238 /* Return just the most recent status... */
3242 /* Look around for an address to give the client. First, look through the
3243 * old IA for addresses we can extend. Second, try to allocate a new address.
3244 * Finally, actually add that address into the current reply IA.
3247 find_client_address(struct reply_state
*reply
) {
3248 struct iaddr send_addr
;
3249 isc_result_t status
= ISC_R_NORESOURCES
;
3250 struct iasubopt
*lease
, *best_lease
= NULL
;
3251 struct binding_scope
**scope
;
3252 struct group
*group
;
3255 if (reply
->static_lease
) {
3256 if (reply
->host
== NULL
)
3257 return DHCP_R_INVALIDARG
;
3260 memcpy(send_addr
.iabuf
, reply
->fixed
.data
, 16);
3262 scope
= &global_scope
;
3263 group
= reply
->subnet
->group
;
3267 if (reply
->old_ia
!= NULL
) {
3268 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3269 struct shared_network
*candidate_shared
;
3270 struct ipv6_pond
*pond
;
3272 lease
= reply
->old_ia
->iasubopt
[i
];
3273 candidate_shared
= lease
->ipv6_pool
->shared_network
;
3274 pond
= lease
->ipv6_pool
->ipv6_pond
;
3277 * Look for the best lease on the client's shared
3278 * network, that is still permitted
3281 if ((candidate_shared
!= reply
->shared
) ||
3282 (lease6_usable(lease
) != ISC_TRUE
))
3285 if (((pond
->prohibit_list
!= NULL
) &&
3286 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3287 ((pond
->permit_list
!= NULL
) &&
3288 (!permitted(reply
->packet
, pond
->permit_list
))))
3291 best_lease
= lease_compare(lease
, best_lease
);
3295 /* Try to pick a new address if we didn't find one, or if we found an
3298 if ((best_lease
== NULL
) || (best_lease
->state
== FTS_ABANDONED
)) {
3299 status
= pick_v6_address(reply
);
3300 } else if (best_lease
!= NULL
) {
3301 iasubopt_reference(&reply
->lease
, best_lease
, MDL
);
3302 status
= ISC_R_SUCCESS
;
3305 /* Pick the abandoned lease as a last resort. */
3306 if ((status
== ISC_R_NORESOURCES
) && (best_lease
!= NULL
)) {
3307 /* I don't see how this is supposed to be done right now. */
3308 log_error("Best match for DUID %s is an abandoned address,"
3309 " This may be a result of multiple clients attempting"
3310 " to use this DUID",
3311 print_hex_1(reply
->client_id
.len
,
3312 reply
->client_id
.data
, 60));
3313 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
3316 /* Give up now if we didn't find a lease. */
3317 if (status
!= ISC_R_SUCCESS
)
3320 if (reply
->lease
== NULL
)
3321 log_fatal("Impossible condition at %s:%d.", MDL
);
3323 /* Draw binding scopes from the lease's binding scope, and config
3324 * from the lease's containing subnet and higher. Note that it may
3325 * be desirable to place the group attachment directly in the pool.
3327 scope
= &reply
->lease
->scope
;
3328 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
3331 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3334 status
= reply_process_is_addressed(reply
, scope
, group
);
3335 if (status
!= ISC_R_SUCCESS
)
3338 status
= reply_process_send_addr(reply
, &send_addr
);
3342 /* Once an address is found for a client, perform several common functions;
3343 * Calculate and store valid and preferred lease times, draw client options
3344 * into the option state.
3347 reply_process_is_addressed(struct reply_state
*reply
,
3348 struct binding_scope
**scope
, struct group
*group
)
3350 isc_result_t status
= ISC_R_SUCCESS
;
3351 struct data_string data
;
3352 struct option_cache
*oc
;
3353 struct option_state
*tmp_options
= NULL
;
3354 struct on_star
*on_star
;
3357 /* Initialize values we will cleanup. */
3358 memset(&data
, 0, sizeof(data
));
3361 * Find the proper on_star block to use. We use the
3362 * one in the lease if we have a lease or the one in
3363 * the reply if we don't have a lease because this is
3367 on_star
= &reply
->lease
->on_star
;
3369 on_star
= &reply
->on_star
;
3373 * Bring in the root configuration. We only do this to bring
3374 * in the on * statements, as we didn't have the lease available
3375 * we did it the first time.
3377 option_state_allocate(&tmp_options
, MDL
);
3378 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3379 reply
->packet
->options
, tmp_options
,
3380 &global_scope
, root_group
, NULL
,
3382 if (tmp_options
!= NULL
) {
3383 option_state_dereference(&tmp_options
, MDL
);
3387 * Bring configured options into the root packet level cache - start
3388 * with the lease's closest enclosing group (passed in by the caller
3391 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3392 reply
->packet
->options
, reply
->opt_state
,
3393 scope
, group
, root_group
, on_star
);
3395 /* Execute statements from class scopes. */
3396 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3397 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3398 reply
->packet
->options
,
3399 reply
->opt_state
, scope
,
3400 reply
->packet
->classes
[i
- 1]->group
,
3405 * If there is a host record, over-ride with values configured there,
3406 * without re-evaluating configuration from the previously executed
3407 * group or its common enclosers.
3409 if (reply
->host
!= NULL
)
3410 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3411 reply
->packet
->options
,
3412 reply
->opt_state
, scope
,
3413 reply
->host
->group
, group
,
3416 /* Determine valid lifetime. */
3417 if (reply
->client_valid
== 0)
3418 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
3420 reply
->send_valid
= reply
->client_valid
;
3422 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3423 SV_DEFAULT_LEASE_TIME
);
3425 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3426 reply
->packet
->options
,
3430 log_error("reply_process_is_addressed: unable to "
3431 "evaluate default lease time");
3432 status
= ISC_R_FAILURE
;
3436 reply
->send_valid
= getULong(data
.data
);
3437 data_string_forget(&data
, MDL
);
3440 /* Check to see if the lease time would cause us to wrap
3441 * in which case we make it infinite.
3442 * The following doesn't work on at least some systems:
3443 * (cur_time + reply->send_valid < cur_time)
3445 if (reply
->send_valid
!= 0xFFFFFFFF) {
3446 time_t test_time
= cur_time
+ reply
->send_valid
;
3447 if (test_time
< cur_time
)
3448 reply
->send_valid
= 0xFFFFFFFF;
3451 if (reply
->client_prefer
== 0)
3452 reply
->send_prefer
= reply
->send_valid
;
3454 reply
->send_prefer
= reply
->client_prefer
;
3456 if ((reply
->send_prefer
>= reply
->send_valid
) &&
3457 (reply
->send_valid
!= 0xFFFFFFFF))
3458 reply
->send_prefer
= (reply
->send_valid
/ 2) +
3459 (reply
->send_valid
/ 8);
3461 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3462 SV_PREFER_LIFETIME
);
3464 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3465 reply
->packet
->options
,
3469 log_error("reply_process_is_addressed: unable to "
3470 "evaluate preferred lease time");
3471 status
= ISC_R_FAILURE
;
3475 reply
->send_prefer
= getULong(data
.data
);
3476 data_string_forget(&data
, MDL
);
3479 /* Note lowest values for later calculation of renew/rebind times. */
3480 if (reply
->prefer
> reply
->send_prefer
)
3481 reply
->prefer
= reply
->send_prefer
;
3483 if (reply
->valid
> reply
->send_valid
)
3484 reply
->valid
= reply
->send_valid
;
3488 * XXX: Old 4.0.0 alpha code would change the host {} record
3489 * XXX: uid upon lease assignment. This was intended to cover the
3490 * XXX: case where a client first identifies itself using vendor
3491 * XXX: options in a solicit, or request, but later neglects to include
3492 * XXX: these options in a Renew or Rebind. It is not clear that this
3493 * XXX: is required, and has some startling ramifications (such as
3494 * XXX: how to recover this dynamic host {} state across restarts).
3496 if (reply
->host
!= NULL
)
3497 change_host_uid(host
, reply
->client_id
->data
,
3498 reply
->client_id
->len
);
3501 /* Perform dynamic lease related update work. */
3502 if (reply
->lease
!= NULL
) {
3503 /* Cached lifetimes */
3504 reply
->lease
->prefer
= reply
->send_prefer
;
3505 reply
->lease
->valid
= reply
->send_valid
;
3507 /* Advance (or rewind) the valid lifetime.
3508 * In the protocol 0xFFFFFFFF is infinite
3509 * when connecting to the lease file MAX_TIME is
3511 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
3512 if (reply
->send_valid
== 0xFFFFFFFF) {
3513 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
3515 reply
->lease
->soft_lifetime_end_time
=
3516 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 %u 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 /* Check to see if the lease time would cause us to wrap
4729 * in which case we make it infinite.
4730 * The following doesn't work on at least some systems:
4731 * (cur_time + reply->send_valid < cur_time)
4733 if (reply
->send_valid
!= 0xFFFFFFFF) {
4734 time_t test_time
= cur_time
+ reply
->send_valid
;
4735 if (test_time
< cur_time
)
4736 reply
->send_valid
= 0xFFFFFFFF;
4739 if (reply
->client_prefer
== 0)
4740 reply
->send_prefer
= reply
->send_valid
;
4742 reply
->send_prefer
= reply
->client_prefer
;
4744 if ((reply
->send_prefer
>= reply
->send_valid
) &&
4745 (reply
->send_valid
!= 0xFFFFFFFF))
4746 reply
->send_prefer
= (reply
->send_valid
/ 2) +
4747 (reply
->send_valid
/ 8);
4749 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4750 SV_PREFER_LIFETIME
);
4752 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4753 reply
->packet
->options
,
4757 log_error("reply_process_is_prefixed: unable to "
4758 "evaluate preferred prefix time");
4759 status
= ISC_R_FAILURE
;
4763 reply
->send_prefer
= getULong(data
.data
);
4764 data_string_forget(&data
, MDL
);
4767 /* Note lowest values for later calculation of renew/rebind times. */
4768 if (reply
->prefer
> reply
->send_prefer
)
4769 reply
->prefer
= reply
->send_prefer
;
4771 if (reply
->valid
> reply
->send_valid
)
4772 reply
->valid
= reply
->send_valid
;
4774 /* Perform dynamic prefix related update work. */
4775 if (reply
->lease
!= NULL
) {
4776 /* Cached lifetimes */
4777 reply
->lease
->prefer
= reply
->send_prefer
;
4778 reply
->lease
->valid
= reply
->send_valid
;
4780 /* Advance (or rewind) the valid lifetime.
4781 * In the protocol 0xFFFFFFFF is infinite
4782 * when connecting to the lease file MAX_TIME is
4784 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
4785 if (reply
->send_valid
== 0xFFFFFFFF) {
4786 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
4788 reply
->lease
->soft_lifetime_end_time
=
4789 cur_time
+ reply
->send_valid
;
4791 /* Wait before renew! */
4794 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
4795 if (status
!= ISC_R_SUCCESS
) {
4796 log_fatal("reply_process_is_prefixed: Unable to "
4797 "attach prefix to new IA_PD: %s",
4798 isc_result_totext(status
));
4802 * If this is a new prefix, make sure it is attached somewhere.
4804 if (reply
->lease
->ia
== NULL
) {
4805 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
4809 /* Bring a copy of the relevant options into the IA_PD scope. */
4810 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4811 reply
->packet
->options
, reply
->reply_ia
,
4812 scope
, group
, root_group
, NULL
);
4814 /* Execute statements from class scopes. */
4815 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
4816 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4817 reply
->packet
->options
,
4818 reply
->reply_ia
, scope
,
4819 reply
->packet
->classes
[i
- 1]->group
,
4824 * And bring in host record configuration, if any, but not to overlap
4825 * the previous group or its common enclosers.
4827 if (reply
->host
!= NULL
)
4828 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4829 reply
->packet
->options
,
4830 reply
->reply_ia
, scope
,
4831 reply
->host
->group
, group
, NULL
);
4834 if (data
.data
!= NULL
)
4835 data_string_forget(&data
, MDL
);
4837 if (status
== ISC_R_SUCCESS
)
4838 reply
->client_resources
++;
4843 /* Simply send an IAPREFIX within the IA_PD scope as described. */
4845 reply_process_send_prefix(struct reply_state
*reply
,
4846 struct iaddrcidrnet
*pref
) {
4847 isc_result_t status
= ISC_R_SUCCESS
;
4848 struct data_string data
;
4850 memset(&data
, 0, sizeof(data
));
4852 /* Now append the prefix. */
4853 data
.len
= IAPREFIX_OFFSET
;
4854 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
4855 log_error("reply_process_send_prefix: out of memory"
4856 "allocating new IAPREFIX buffer.");
4857 status
= ISC_R_NOMEMORY
;
4860 data
.data
= data
.buffer
->data
;
4862 putULong(data
.buffer
->data
, reply
->send_prefer
);
4863 putULong(data
.buffer
->data
+ 4, reply
->send_valid
);
4864 data
.buffer
->data
[8] = pref
->bits
;
4865 memcpy(data
.buffer
->data
+ 9, pref
->lo_addr
.iabuf
, 16);
4867 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
4868 data
.buffer
, data
.buffer
->data
,
4869 data
.len
, D6O_IAPREFIX
, 0)) {
4870 log_error("reply_process_send_prefix: unable "
4871 "to save IAPREFIX option");
4872 status
= ISC_R_FAILURE
;
4876 reply
->resources_included
= ISC_TRUE
;
4879 if (data
.data
!= NULL
)
4880 data_string_forget(&data
, MDL
);
4885 /* Choose the better of two prefixes. */
4886 static struct iasubopt
*
4887 prefix_compare(struct reply_state
*reply
,
4888 struct iasubopt
*alpha
, struct iasubopt
*beta
) {
4894 if (reply
->preflen
>= 0) {
4895 if ((alpha
->plen
== reply
->preflen
) &&
4896 (beta
->plen
!= reply
->preflen
))
4898 if ((beta
->plen
== reply
->preflen
) &&
4899 (alpha
->plen
!= reply
->preflen
))
4903 switch(alpha
->state
) {
4905 switch(beta
->state
) {
4907 /* Choose the prefix with the longest lifetime (most
4908 * likely the most recently allocated).
4910 if (alpha
->hard_lifetime_end_time
<
4911 beta
->hard_lifetime_end_time
)
4921 log_fatal("Impossible condition at %s:%d.", MDL
);
4926 switch (beta
->state
) {
4931 /* Choose the most recently expired prefix. */
4932 if (alpha
->hard_lifetime_end_time
<
4933 beta
->hard_lifetime_end_time
)
4935 else if ((alpha
->hard_lifetime_end_time
==
4936 beta
->hard_lifetime_end_time
) &&
4937 (alpha
->soft_lifetime_end_time
<
4938 beta
->soft_lifetime_end_time
))
4947 log_fatal("Impossible condition at %s:%d.", MDL
);
4952 switch (beta
->state
) {
4958 /* Choose the prefix that was abandoned longest ago. */
4959 if (alpha
->hard_lifetime_end_time
<
4960 beta
->hard_lifetime_end_time
)
4966 log_fatal("Impossible condition at %s:%d.", MDL
);
4971 log_fatal("Impossible condition at %s:%d.", MDL
);
4974 log_fatal("Triple impossible condition at %s:%d.", MDL
);
4979 * Solicit is how a client starts requesting addresses.
4981 * If the client asks for rapid commit, and we support it, we will
4982 * allocate the addresses and reply.
4984 * Otherwise we will send an advertise message.
4988 dhcpv6_solicit(struct data_string
*reply_ret
, struct packet
*packet
) {
4989 struct data_string client_id
;
4992 * Validate our input.
4994 if (!valid_client_msg(packet
, &client_id
)) {
4998 lease_to_client(reply_ret
, packet
, &client_id
, NULL
);
5003 data_string_forget(&client_id
, MDL
);
5007 * Request is how a client actually requests addresses.
5009 * Very similar to Solicit handling, except the server DUID is required.
5013 dhcpv6_request(struct data_string
*reply_ret
, struct packet
*packet
) {
5014 struct data_string client_id
;
5015 struct data_string server_id
;
5018 * Validate our input.
5020 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5024 /* If the REQUEST arrived via unicast and unicast option isn't set,
5025 * reject it per RFC 3315, Sec 18.2.1 */
5026 if (packet
->unicast
== ISC_TRUE
&&
5027 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5028 unicast_reject(reply_ret
, packet
, &client_id
, &server_id
);
5033 lease_to_client(reply_ret
, packet
, &client_id
, &server_id
);
5039 data_string_forget(&client_id
, MDL
);
5040 data_string_forget(&server_id
, MDL
);
5043 /* Find a DHCPv6 packet's shared network from hints in the packet.
5046 shared_network_from_packet6(struct shared_network
**shared
,
5047 struct packet
*packet
)
5049 const struct packet
*chk_packet
;
5050 const struct in6_addr
*link_addr
, *first_link_addr
;
5051 struct iaddr tmp_addr
;
5052 struct subnet
*subnet
;
5053 isc_result_t status
;
5055 if ((shared
== NULL
) || (*shared
!= NULL
) || (packet
== NULL
))
5056 return DHCP_R_INVALIDARG
;
5059 * First, find the link address where the packet from the client
5060 * first appeared (if this packet was relayed).
5062 first_link_addr
= NULL
;
5063 chk_packet
= packet
->dhcpv6_container_packet
;
5064 while (chk_packet
!= NULL
) {
5065 link_addr
= &chk_packet
->dhcpv6_link_address
;
5066 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
5067 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
5068 first_link_addr
= link_addr
;
5071 chk_packet
= chk_packet
->dhcpv6_container_packet
;
5075 * If there is a relayed link address, find the subnet associated
5076 * with that, and use that to get the appropriate
5079 if (first_link_addr
!= NULL
) {
5080 tmp_addr
.len
= sizeof(*first_link_addr
);
5081 memcpy(tmp_addr
.iabuf
,
5082 first_link_addr
, sizeof(*first_link_addr
));
5084 if (!find_subnet(&subnet
, tmp_addr
, MDL
)) {
5085 log_debug("No subnet found for link-address %s.",
5087 return ISC_R_NOTFOUND
;
5089 status
= shared_network_reference(shared
,
5090 subnet
->shared_network
, MDL
);
5091 subnet_dereference(&subnet
, MDL
);
5094 * If there is no link address, we will use the interface
5095 * that this packet came in on to pick the shared_network.
5097 } else if (packet
->interface
!= NULL
) {
5098 status
= shared_network_reference(shared
,
5099 packet
->interface
->shared_network
,
5101 if (packet
->dhcpv6_container_packet
!= NULL
) {
5102 log_info("[L2 Relay] No link address in relay packet "
5103 "assuming L2 relay and using receiving "
5109 * We shouldn't be able to get here but if there is no link
5110 * address and no interface we don't know where to get the
5111 * pool from log an error and return an error.
5113 log_error("No interface and no link address "
5114 "can't determine pool");
5115 status
= DHCP_R_INVALIDARG
;
5122 * When a client thinks it might be on a new link, it sends a
5125 * From RFC3315 section 18.2.2:
5127 * When the server receives a Confirm message, the server determines
5128 * whether the addresses in the Confirm message are appropriate for the
5129 * link to which the client is attached. If all of the addresses in the
5130 * Confirm message pass this test, the server returns a status of
5131 * Success. If any of the addresses do not pass this test, the server
5132 * returns a status of NotOnLink. If the server is unable to perform
5133 * this test (for example, the server does not have information about
5134 * prefixes on the link to which the client is connected), or there were
5135 * no addresses in any of the IAs sent by the client, the server MUST
5136 * NOT send a reply to the client.
5140 dhcpv6_confirm(struct data_string
*reply_ret
, struct packet
*packet
) {
5141 struct shared_network
*shared
;
5142 struct subnet
*subnet
;
5143 struct option_cache
*ia
, *ta
, *oc
;
5144 struct data_string cli_enc_opt_data
, iaaddr
, client_id
, packet_oro
;
5145 struct option_state
*cli_enc_opt_state
, *opt_state
;
5146 struct iaddr cli_addr
;
5148 isc_boolean_t inappropriate
, has_addrs
;
5149 char reply_data
[65536];
5150 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5151 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5154 * Basic client message validation.
5156 memset(&client_id
, 0, sizeof(client_id
));
5157 if (!valid_client_msg(packet
, &client_id
)) {
5162 * Do not process Confirms that do not have IA's we do not recognize.
5164 ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5165 ta
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
5166 if ((ia
== NULL
) && (ta
== NULL
))
5170 * IA_PD's are simply ignored.
5172 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5175 * Bit of variable initialization.
5177 opt_state
= cli_enc_opt_state
= NULL
;
5178 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5179 memset(&iaaddr
, 0, sizeof(iaaddr
));
5180 memset(&packet_oro
, 0, sizeof(packet_oro
));
5182 /* Determine what shared network the client is connected to. We
5183 * must not respond if we don't have any information about the
5184 * network the client is on.
5187 if ((shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
) ||
5191 /* If there are no recorded subnets, then we have no
5192 * information about this subnet - ignore Confirms.
5194 subnet
= shared
->subnets
;
5198 /* Are the addresses in all the IA's appropriate for that link? */
5199 has_addrs
= inappropriate
= ISC_FALSE
;
5201 while(!inappropriate
) {
5202 /* If we've reached the end of the IA_NA pass, move to the
5205 if ((pass
== D6O_IA_NA
) && (ia
== NULL
)) {
5210 /* If we've reached the end of all passes, we're done. */
5214 if (((pass
== D6O_IA_NA
) &&
5215 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5217 packet
, ia
, IA_NA_OFFSET
)) ||
5218 ((pass
== D6O_IA_TA
) &&
5219 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5221 packet
, ia
, IA_TA_OFFSET
))) {
5225 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5228 for ( ; oc
!= NULL
; oc
= oc
->next
) {
5229 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5230 packet
->options
, NULL
,
5231 &global_scope
, oc
, MDL
) ||
5232 (iaaddr
.len
< IAADDR_OFFSET
)) {
5233 log_error("dhcpv6_confirm: "
5234 "error evaluating IAADDR.");
5238 /* Copy out the IPv6 address for processing. */
5240 memcpy(cli_addr
.iabuf
, iaaddr
.data
, 16);
5242 data_string_forget(&iaaddr
, MDL
);
5244 /* Record that we've processed at least one address. */
5245 has_addrs
= ISC_TRUE
;
5247 /* Find out if any subnets cover this address. */
5248 for (subnet
= shared
->subnets
; subnet
!= NULL
;
5249 subnet
= subnet
->next_sibling
) {
5250 if (addr_eq(subnet_number(cli_addr
,
5256 /* If we reach the end of the subnet list, and no
5257 * subnet matches the client address, then it must
5258 * be inappropriate to the link (so far as our
5259 * configuration says). Once we've found one
5260 * inappropriate address, there is no reason to
5261 * continue searching.
5263 if (subnet
== NULL
) {
5264 inappropriate
= ISC_TRUE
;
5269 option_state_dereference(&cli_enc_opt_state
, MDL
);
5270 data_string_forget(&cli_enc_opt_data
, MDL
);
5272 /* Advance to the next IA_*. */
5276 /* If the client supplied no addresses, do not reply. */
5283 if (!start_reply(packet
, &client_id
, NULL
, &opt_state
, reply
)) {
5290 if (inappropriate
) {
5291 if (!set_status_code(STATUS_NotOnLink
,
5292 "Some of the addresses are not on link.",
5297 if (!set_status_code(STATUS_Success
,
5298 "All addresses still on link.",
5305 * Only one option: add it.
5307 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5308 sizeof(reply_data
)-reply_ofs
,
5310 required_opts
, &packet_oro
);
5313 * Return our reply to the caller.
5315 reply_ret
->len
= reply_ofs
;
5316 reply_ret
->buffer
= NULL
;
5317 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5318 log_fatal("No memory to store reply.");
5320 reply_ret
->data
= reply_ret
->buffer
->data
;
5321 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5324 /* Cleanup any stale data strings. */
5325 if (cli_enc_opt_data
.buffer
!= NULL
)
5326 data_string_forget(&cli_enc_opt_data
, MDL
);
5327 if (iaaddr
.buffer
!= NULL
)
5328 data_string_forget(&iaaddr
, MDL
);
5329 if (client_id
.buffer
!= NULL
)
5330 data_string_forget(&client_id
, MDL
);
5331 if (packet_oro
.buffer
!= NULL
)
5332 data_string_forget(&packet_oro
, MDL
);
5334 /* Release any stale option states. */
5335 if (cli_enc_opt_state
!= NULL
)
5336 option_state_dereference(&cli_enc_opt_state
, MDL
);
5337 if (opt_state
!= NULL
)
5338 option_state_dereference(&opt_state
, MDL
);
5342 * Renew is when a client wants to extend its lease/prefix, at time T1.
5344 * We handle this the same as if the client wants a new lease/prefix,
5345 * except for the error code of when addresses don't match.
5349 dhcpv6_renew(struct data_string
*reply
, struct packet
*packet
) {
5350 struct data_string client_id
;
5351 struct data_string server_id
;
5354 * Validate the request.
5356 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5360 /* If the RENEW arrived via unicast and unicast option isn't set,
5361 * reject it per RFC 3315, Sec 18.2.3 */
5362 if (packet
->unicast
== ISC_TRUE
&&
5363 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5364 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5369 lease_to_client(reply
, packet
, &client_id
, &server_id
);
5375 data_string_forget(&server_id
, MDL
);
5376 data_string_forget(&client_id
, MDL
);
5380 * Rebind is when a client wants to extend its lease, at time T2.
5382 * We handle this the same as if the client wants a new lease, except
5383 * for the error code of when addresses don't match.
5387 dhcpv6_rebind(struct data_string
*reply
, struct packet
*packet
) {
5388 struct data_string client_id
;
5390 if (!valid_client_msg(packet
, &client_id
)) {
5394 lease_to_client(reply
, packet
, &client_id
, NULL
);
5396 data_string_forget(&client_id
, MDL
);
5400 ia_na_match_decline(const struct data_string
*client_id
,
5401 const struct data_string
*iaaddr
,
5402 struct iasubopt
*lease
)
5404 char tmp_addr
[INET6_ADDRSTRLEN
];
5406 log_error("Client %s reports address %s is "
5407 "already in use by another host!",
5408 print_hex_1(client_id
->len
, client_id
->data
, 60),
5409 inet_ntop(AF_INET6
, iaaddr
->data
,
5410 tmp_addr
, sizeof(tmp_addr
)));
5411 if (lease
!= NULL
) {
5412 decline_lease6(lease
->ipv6_pool
, lease
);
5413 lease
->ia
->cltt
= cur_time
;
5414 write_ia(lease
->ia
);
5419 ia_na_nomatch_decline(const struct data_string
*client_id
,
5420 const struct data_string
*iaaddr
,
5421 u_int32_t
*ia_na_id
,
5422 struct packet
*packet
,
5427 char tmp_addr
[INET6_ADDRSTRLEN
];
5428 struct option_state
*host_opt_state
;
5431 log_info("Client %s declines address %s, which is not offered to it.",
5432 print_hex_1(client_id
->len
, client_id
->data
, 60),
5433 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5436 * Create state for this IA_NA.
5438 host_opt_state
= NULL
;
5439 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5440 log_error("ia_na_nomatch_decline: out of memory "
5441 "allocating option_state.");
5445 if (!set_status_code(STATUS_NoBinding
, "Decline for unknown address.",
5451 * Insure we have enough space
5453 if (reply_len
< (*reply_ofs
+ 16)) {
5454 log_error("ia_na_nomatch_decline: "
5455 "out of space for reply packet.");
5460 * Put our status code into the reply packet.
5462 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5463 reply_len
-(*reply_ofs
)-16,
5464 host_opt_state
, packet
,
5465 required_opts_STATUS_CODE
, NULL
);
5468 * Store the non-encapsulated option data for this
5469 * IA_NA into our reply packet. Defined in RFC 3315,
5473 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5475 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5476 /* IA_NA, copied from the client */
5477 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5478 /* t1 and t2, odd that we need them, but here it is */
5479 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5480 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5483 * Get ready for next IA_NA.
5485 *reply_ofs
+= (len
+ 16);
5488 option_state_dereference(&host_opt_state
, MDL
);
5492 iterate_over_ia_na(struct data_string
*reply_ret
,
5493 struct packet
*packet
,
5494 const struct data_string
*client_id
,
5495 const struct data_string
*server_id
,
5496 const char *packet_type
,
5497 void (*ia_na_match
)(),
5498 void (*ia_na_nomatch
)())
5500 struct option_state
*opt_state
;
5501 struct host_decl
*packet_host
;
5502 struct option_cache
*ia
;
5503 struct option_cache
*oc
;
5504 /* cli_enc_... variables come from the IA_NA/IA_TA options */
5505 struct data_string cli_enc_opt_data
;
5506 struct option_state
*cli_enc_opt_state
;
5507 struct host_decl
*host
;
5508 struct option_state
*host_opt_state
;
5509 struct data_string iaaddr
;
5510 struct data_string fixed_addr
;
5511 char reply_data
[65536];
5512 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5513 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5514 char status_msg
[32];
5515 struct iasubopt
*lease
;
5516 struct ia_xx
*existing_ia_na
;
5518 struct data_string key
;
5522 * Initialize to empty values, in case we have to exit early.
5525 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5526 cli_enc_opt_state
= NULL
;
5527 memset(&iaaddr
, 0, sizeof(iaaddr
));
5528 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
5529 host_opt_state
= NULL
;
5533 * Find the host record that matches from the packet, if any.
5536 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
5539 * Set our reply information.
5541 reply
->msg_type
= DHCPV6_REPLY
;
5542 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
5543 sizeof(reply
->transaction_id
));
5546 * Build our option state for reply.
5549 if (!option_state_allocate(&opt_state
, MDL
)) {
5550 log_error("iterate_over_ia_na: no memory for option_state.");
5553 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5554 packet
->options
, opt_state
,
5555 &global_scope
, root_group
, NULL
, NULL
);
5558 * RFC 3315, section 18.2.7 tells us which options to include.
5560 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
5562 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5563 (unsigned char *)server_duid
.data
,
5564 server_duid
.len
, D6O_SERVERID
, 0)) {
5565 log_error("iterate_over_ia_na: "
5566 "error saving server identifier.");
5571 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
5573 (unsigned char *)client_id
->data
,
5576 log_error("iterate_over_ia_na: "
5577 "error saving client identifier.");
5581 snprintf(status_msg
, sizeof(status_msg
), "%s received.", packet_type
);
5582 if (!set_status_code(STATUS_Success
, status_msg
, opt_state
)) {
5587 * Add our options that are not associated with any IA_NA or IA_TA.
5589 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5590 sizeof(reply_data
)-reply_ofs
,
5592 required_opts
, NULL
);
5595 * Loop through the IA_NA reported by the client, and deal with
5596 * addresses reported as already in use.
5598 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5599 ia
!= NULL
; ia
= ia
->next
) {
5601 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
5603 packet
, ia
, IA_NA_OFFSET
)) {
5607 iaid
= getULong(cli_enc_opt_data
.data
);
5610 * XXX: It is possible that we can get multiple addresses
5611 * sent by the client. We don't send multiple
5612 * addresses, so this indicates a client error.
5613 * We should check for multiple IAADDR options, log
5614 * if found, and set as an error.
5616 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5619 /* no address given for this IA, ignore */
5620 option_state_dereference(&cli_enc_opt_state
, MDL
);
5621 data_string_forget(&cli_enc_opt_data
, MDL
);
5625 memset(&iaaddr
, 0, sizeof(iaaddr
));
5626 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5627 packet
->options
, NULL
,
5628 &global_scope
, oc
, MDL
)) {
5629 log_error("iterate_over_ia_na: "
5630 "error evaluating IAADDR.");
5635 * Now we need to figure out which host record matches
5636 * this IA_NA and IAADDR (encapsulated option contents
5637 * matching a host record by option).
5639 * XXX: We don't currently track IA_NA separately, but
5640 * we will need to do this!
5643 if (!find_hosts_by_option(&host
, packet
,
5644 cli_enc_opt_state
, MDL
)) {
5645 if (packet_host
!= NULL
) {
5651 while (host
!= NULL
) {
5652 if (host
->fixed_addr
!= NULL
) {
5653 if (!evaluate_option_cache(&fixed_addr
, NULL
,
5655 NULL
, &global_scope
,
5658 log_error("iterate_over_ia_na: error "
5659 "evaluating host address.");
5662 if ((iaaddr
.len
>= 16) &&
5663 !memcmp(fixed_addr
.data
, iaaddr
.data
, 16)) {
5664 data_string_forget(&fixed_addr
, MDL
);
5667 data_string_forget(&fixed_addr
, MDL
);
5669 host
= host
->n_ipaddr
;
5672 if ((host
== NULL
) && (iaaddr
.len
>= IAADDR_OFFSET
)) {
5674 * Find existing IA_NA.
5676 if (ia_make_key(&key
, iaid
,
5677 (char *)client_id
->data
,
5679 MDL
) != ISC_R_SUCCESS
) {
5680 log_fatal("iterate_over_ia_na: no memory for "
5684 existing_ia_na
= NULL
;
5685 if (ia_hash_lookup(&existing_ia_na
, ia_na_active
,
5686 (unsigned char *)key
.data
,
5689 * Make sure this address is in the IA_NA.
5691 for (i
=0; i
<existing_ia_na
->num_iasubopt
; i
++) {
5692 struct iasubopt
*tmp
;
5693 struct in6_addr
*in6_addr
;
5695 tmp
= existing_ia_na
->iasubopt
[i
];
5696 in6_addr
= &tmp
->addr
;
5697 if (memcmp(in6_addr
,
5698 iaaddr
.data
, 16) == 0) {
5699 iasubopt_reference(&lease
,
5706 data_string_forget(&key
, MDL
);
5709 if ((host
!= NULL
) || (lease
!= NULL
)) {
5710 ia_na_match(client_id
, &iaaddr
, lease
);
5712 ia_na_nomatch(client_id
, &iaaddr
,
5713 (u_int32_t
*)cli_enc_opt_data
.data
,
5714 packet
, reply_data
, &reply_ofs
,
5715 sizeof(reply_data
));
5718 if (lease
!= NULL
) {
5719 iasubopt_dereference(&lease
, MDL
);
5722 data_string_forget(&iaaddr
, MDL
);
5723 option_state_dereference(&cli_enc_opt_state
, MDL
);
5724 data_string_forget(&cli_enc_opt_data
, MDL
);
5728 * Return our reply to the caller.
5730 reply_ret
->len
= reply_ofs
;
5731 reply_ret
->buffer
= NULL
;
5732 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5733 log_fatal("No memory to store reply.");
5735 reply_ret
->data
= reply_ret
->buffer
->data
;
5736 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5739 if (lease
!= NULL
) {
5740 iasubopt_dereference(&lease
, MDL
);
5742 if (host_opt_state
!= NULL
) {
5743 option_state_dereference(&host_opt_state
, MDL
);
5745 if (fixed_addr
.buffer
!= NULL
) {
5746 data_string_forget(&fixed_addr
, MDL
);
5748 if (iaaddr
.buffer
!= NULL
) {
5749 data_string_forget(&iaaddr
, MDL
);
5751 if (cli_enc_opt_state
!= NULL
) {
5752 option_state_dereference(&cli_enc_opt_state
, MDL
);
5754 if (cli_enc_opt_data
.buffer
!= NULL
) {
5755 data_string_forget(&cli_enc_opt_data
, MDL
);
5757 if (opt_state
!= NULL
) {
5758 option_state_dereference(&opt_state
, MDL
);
5763 * Decline means a client has detected that something else is using an
5764 * address we gave it.
5766 * Since we're only dealing with fixed leases for now, there's not
5767 * much we can do, other that log the occurrence.
5769 * When we start issuing addresses from pools, then we will have to
5770 * record our declined addresses and issue another. In general with
5771 * IPv6 there is no worry about DoS by clients exhausting space, but
5772 * we still need to be aware of this possibility.
5777 dhcpv6_decline(struct data_string
*reply
, struct packet
*packet
) {
5778 struct data_string client_id
;
5779 struct data_string server_id
;
5782 * Validate our input.
5784 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5788 /* If the DECLINE arrived via unicast and unicast option isn't set,
5789 * reject it per RFC 3315, Sec 18.2.7 */
5790 if (packet
->unicast
== ISC_TRUE
&&
5791 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5792 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5795 * Undefined for IA_PD.
5797 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5800 * And operate on each IA_NA in this packet.
5802 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
5803 "Decline", ia_na_match_decline
,
5804 ia_na_nomatch_decline
);
5808 data_string_forget(&server_id
, MDL
);
5809 data_string_forget(&client_id
, MDL
);
5813 ia_na_match_release(const struct data_string
*client_id
,
5814 const struct data_string
*iaaddr
,
5815 struct iasubopt
*lease
)
5817 char tmp_addr
[INET6_ADDRSTRLEN
];
5819 log_info("Client %s releases address %s",
5820 print_hex_1(client_id
->len
, client_id
->data
, 60),
5821 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5822 if (lease
!= NULL
) {
5823 release_lease6(lease
->ipv6_pool
, lease
);
5824 lease
->ia
->cltt
= cur_time
;
5825 write_ia(lease
->ia
);
5830 ia_na_nomatch_release(const struct data_string
*client_id
,
5831 const struct data_string
*iaaddr
,
5832 u_int32_t
*ia_na_id
,
5833 struct packet
*packet
,
5838 char tmp_addr
[INET6_ADDRSTRLEN
];
5839 struct option_state
*host_opt_state
;
5842 log_info("Client %s releases address %s, which is not leased to it.",
5843 print_hex_1(client_id
->len
, client_id
->data
, 60),
5844 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5847 * Create state for this IA_NA.
5849 host_opt_state
= NULL
;
5850 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5851 log_error("ia_na_nomatch_release: out of memory "
5852 "allocating option_state.");
5856 if (!set_status_code(STATUS_NoBinding
,
5857 "Release for non-leased address.",
5863 * Insure we have enough space
5865 if (reply_len
< (*reply_ofs
+ 16)) {
5866 log_error("ia_na_nomatch_release: "
5867 "out of space for reply packet.");
5872 * Put our status code into the reply packet.
5874 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5875 reply_len
-(*reply_ofs
)-16,
5876 host_opt_state
, packet
,
5877 required_opts_STATUS_CODE
, NULL
);
5880 * Store the non-encapsulated option data for this
5881 * IA_NA into our reply packet. Defined in RFC 3315,
5885 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5887 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5888 /* IA_NA, copied from the client */
5889 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5890 /* t1 and t2, odd that we need them, but here it is */
5891 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5892 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5895 * Get ready for next IA_NA.
5897 *reply_ofs
+= (len
+ 16);
5900 option_state_dereference(&host_opt_state
, MDL
);
5904 ia_pd_match_release(const struct data_string
*client_id
,
5905 const struct data_string
*iapref
,
5906 struct iasubopt
*prefix
)
5908 char tmp_addr
[INET6_ADDRSTRLEN
];
5910 log_info("Client %s releases prefix %s/%u",
5911 print_hex_1(client_id
->len
, client_id
->data
, 60),
5912 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5913 tmp_addr
, sizeof(tmp_addr
)),
5914 (unsigned) getUChar(iapref
->data
+ 8));
5915 if (prefix
!= NULL
) {
5916 release_lease6(prefix
->ipv6_pool
, prefix
);
5917 prefix
->ia
->cltt
= cur_time
;
5918 write_ia(prefix
->ia
);
5923 ia_pd_nomatch_release(const struct data_string
*client_id
,
5924 const struct data_string
*iapref
,
5925 u_int32_t
*ia_pd_id
,
5926 struct packet
*packet
,
5931 char tmp_addr
[INET6_ADDRSTRLEN
];
5932 struct option_state
*host_opt_state
;
5935 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
5936 print_hex_1(client_id
->len
, client_id
->data
, 60),
5937 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5938 tmp_addr
, sizeof(tmp_addr
)),
5939 (unsigned) getUChar(iapref
->data
+ 8));
5942 * Create state for this IA_PD.
5944 host_opt_state
= NULL
;
5945 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5946 log_error("ia_pd_nomatch_release: out of memory "
5947 "allocating option_state.");
5951 if (!set_status_code(STATUS_NoBinding
,
5952 "Release for non-leased prefix.",
5958 * Insure we have enough space
5960 if (reply_len
< (*reply_ofs
+ 16)) {
5961 log_error("ia_pd_nomatch_release: "
5962 "out of space for reply packet.");
5967 * Put our status code into the reply packet.
5969 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5970 reply_len
-(*reply_ofs
)-16,
5971 host_opt_state
, packet
,
5972 required_opts_STATUS_CODE
, NULL
);
5975 * Store the non-encapsulated option data for this
5976 * IA_PD into our reply packet. Defined in RFC 3315,
5980 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_PD
);
5982 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5983 /* IA_PD, copied from the client */
5984 memcpy(reply_data
+(*reply_ofs
)+4, ia_pd_id
, 4);
5985 /* t1 and t2, odd that we need them, but here it is */
5986 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5987 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5990 * Get ready for next IA_PD.
5992 *reply_ofs
+= (len
+ 16);
5995 option_state_dereference(&host_opt_state
, MDL
);
5999 iterate_over_ia_pd(struct data_string
*reply_ret
,
6000 struct packet
*packet
,
6001 const struct data_string
*client_id
,
6002 const struct data_string
*server_id
,
6003 const char *packet_type
,
6004 void (*ia_pd_match
)(),
6005 void (*ia_pd_nomatch
)())
6007 struct data_string reply_new
;
6009 struct option_state
*opt_state
;
6010 struct host_decl
*packet_host
;
6011 struct option_cache
*ia
;
6012 struct option_cache
*oc
;
6013 /* cli_enc_... variables come from the IA_PD options */
6014 struct data_string cli_enc_opt_data
;
6015 struct option_state
*cli_enc_opt_state
;
6016 struct host_decl
*host
;
6017 struct option_state
*host_opt_state
;
6018 struct data_string iaprefix
;
6019 char reply_data
[65536];
6021 struct iasubopt
*prefix
;
6022 struct ia_xx
*existing_ia_pd
;
6024 struct data_string key
;
6028 * Initialize to empty values, in case we have to exit early.
6030 memset(&reply_new
, 0, sizeof(reply_new
));
6032 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
6033 cli_enc_opt_state
= NULL
;
6034 memset(&iaprefix
, 0, sizeof(iaprefix
));
6035 host_opt_state
= NULL
;
6039 * Compute the available length for the reply.
6041 reply_len
= sizeof(reply_data
) - reply_ret
->len
;
6045 * Find the host record that matches from the packet, if any.
6048 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
6051 * Build our option state for reply.
6054 if (!option_state_allocate(&opt_state
, MDL
)) {
6055 log_error("iterate_over_ia_pd: no memory for option_state.");
6058 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
6059 packet
->options
, opt_state
,
6060 &global_scope
, root_group
, NULL
, NULL
);
6063 * Loop through the IA_PD reported by the client, and deal with
6064 * prefixes reported as already in use.
6066 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
6067 ia
!= NULL
; ia
= ia
->next
) {
6069 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
6071 packet
, ia
, IA_PD_OFFSET
)) {
6075 iaid
= getULong(cli_enc_opt_data
.data
);
6077 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
6080 /* no prefix given for this IA_PD, ignore */
6081 option_state_dereference(&cli_enc_opt_state
, MDL
);
6082 data_string_forget(&cli_enc_opt_data
, MDL
);
6086 for (; oc
!= NULL
; oc
= oc
->next
) {
6087 memset(&iaprefix
, 0, sizeof(iaprefix
));
6088 if (!evaluate_option_cache(&iaprefix
, packet
, NULL
, NULL
,
6089 packet
->options
, NULL
,
6090 &global_scope
, oc
, MDL
)) {
6091 log_error("iterate_over_ia_pd: "
6092 "error evaluating IAPREFIX.");
6097 * Now we need to figure out which host record matches
6098 * this IA_PD and IAPREFIX (encapsulated option contents
6099 * matching a host record by option).
6101 * XXX: We don't currently track IA_PD separately, but
6102 * we will need to do this!
6105 if (!find_hosts_by_option(&host
, packet
,
6106 cli_enc_opt_state
, MDL
)) {
6107 if (packet_host
!= NULL
) {
6113 while (host
!= NULL
) {
6114 if (host
->fixed_prefix
!= NULL
) {
6115 struct iaddrcidrnetlist
*l
;
6116 int plen
= (int) getUChar(iaprefix
.data
+ 8);
6118 for (l
= host
->fixed_prefix
; l
!= NULL
;
6120 if (plen
!= l
->cidrnet
.bits
)
6122 if (memcmp(iaprefix
.data
+ 9,
6123 l
->cidrnet
.lo_addr
.iabuf
,
6127 if ((l
!= NULL
) && (iaprefix
.len
>= 17))
6130 host
= host
->n_ipaddr
;
6133 if ((host
== NULL
) && (iaprefix
.len
>= IAPREFIX_OFFSET
)) {
6135 * Find existing IA_PD.
6137 if (ia_make_key(&key
, iaid
,
6138 (char *)client_id
->data
,
6140 MDL
) != ISC_R_SUCCESS
) {
6141 log_fatal("iterate_over_ia_pd: no memory for "
6145 existing_ia_pd
= NULL
;
6146 if (ia_hash_lookup(&existing_ia_pd
, ia_pd_active
,
6147 (unsigned char *)key
.data
,
6150 * Make sure this prefix is in the IA_PD.
6153 i
< existing_ia_pd
->num_iasubopt
;
6155 struct iasubopt
*tmp
;
6158 plen
= getUChar(iaprefix
.data
+ 8);
6159 tmp
= existing_ia_pd
->iasubopt
[i
];
6160 if ((tmp
->plen
== plen
) &&
6164 iasubopt_reference(&prefix
,
6171 data_string_forget(&key
, MDL
);
6174 if ((host
!= NULL
) || (prefix
!= NULL
)) {
6175 ia_pd_match(client_id
, &iaprefix
, prefix
);
6177 ia_pd_nomatch(client_id
, &iaprefix
,
6178 (u_int32_t
*)cli_enc_opt_data
.data
,
6179 packet
, reply_data
, &reply_ofs
,
6180 reply_len
- reply_ofs
);
6183 if (prefix
!= NULL
) {
6184 iasubopt_dereference(&prefix
, MDL
);
6187 data_string_forget(&iaprefix
, MDL
);
6190 option_state_dereference(&cli_enc_opt_state
, MDL
);
6191 data_string_forget(&cli_enc_opt_data
, MDL
);
6195 * Return our reply to the caller.
6196 * The IA_NA routine has already filled at least the header.
6198 reply_new
.len
= reply_ret
->len
+ reply_ofs
;
6199 if (!buffer_allocate(&reply_new
.buffer
, reply_new
.len
, MDL
)) {
6200 log_fatal("No memory to store reply.");
6202 reply_new
.data
= reply_new
.buffer
->data
;
6203 memcpy(reply_new
.buffer
->data
,
6204 reply_ret
->buffer
->data
, reply_ret
->len
);
6205 memcpy(reply_new
.buffer
->data
+ reply_ret
->len
,
6206 reply_data
, reply_ofs
);
6207 data_string_forget(reply_ret
, MDL
);
6208 data_string_copy(reply_ret
, &reply_new
, MDL
);
6209 data_string_forget(&reply_new
, MDL
);
6212 if (prefix
!= NULL
) {
6213 iasubopt_dereference(&prefix
, MDL
);
6215 if (host_opt_state
!= NULL
) {
6216 option_state_dereference(&host_opt_state
, MDL
);
6218 if (iaprefix
.buffer
!= NULL
) {
6219 data_string_forget(&iaprefix
, MDL
);
6221 if (cli_enc_opt_state
!= NULL
) {
6222 option_state_dereference(&cli_enc_opt_state
, MDL
);
6224 if (cli_enc_opt_data
.buffer
!= NULL
) {
6225 data_string_forget(&cli_enc_opt_data
, MDL
);
6227 if (opt_state
!= NULL
) {
6228 option_state_dereference(&opt_state
, MDL
);
6233 * Release means a client is done with the leases.
6237 dhcpv6_release(struct data_string
*reply
, struct packet
*packet
) {
6238 struct data_string client_id
;
6239 struct data_string server_id
;
6242 * Validate our input.
6244 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
6248 /* If the RELEASE arrived via unicast and unicast option isn't set,
6249 * reject it per RFC 3315, Sec 18.2.6 */
6250 if (packet
->unicast
== ISC_TRUE
&&
6251 is_unicast_option_defined(packet
) == ISC_FALSE
) {
6252 unicast_reject(reply
, packet
, &client_id
, &server_id
);
6255 * And operate on each IA_NA in this packet.
6257 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
6258 "Release", ia_na_match_release
,
6259 ia_na_nomatch_release
);
6262 * And operate on each IA_PD in this packet.
6264 iterate_over_ia_pd(reply
, packet
, &client_id
, &server_id
,
6265 "Release", ia_pd_match_release
,
6266 ia_pd_nomatch_release
);
6269 data_string_forget(&server_id
, MDL
);
6270 data_string_forget(&client_id
, MDL
);
6274 * Information-Request is used by clients who have obtained an address
6275 * from other means, but want configuration information from the server.
6279 dhcpv6_information_request(struct data_string
*reply
, struct packet
*packet
) {
6280 struct data_string client_id
;
6281 struct data_string server_id
;
6284 * Validate our input.
6286 if (!valid_client_info_req(packet
, &server_id
)) {
6291 * Get our client ID, if there is one.
6293 memset(&client_id
, 0, sizeof(client_id
));
6294 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
) {
6295 data_string_forget(&client_id
, MDL
);
6299 * Use the lease_to_client() function. This will work fine,
6300 * because the valid_client_info_req() insures that we
6301 * don't have any IA that would cause us to allocate
6302 * resources to the client.
6304 lease_to_client(reply
, packet
, &client_id
,
6305 server_id
.data
!= NULL
? &server_id
: NULL
);
6310 if (client_id
.data
!= NULL
) {
6311 data_string_forget(&client_id
, MDL
);
6313 data_string_forget(&server_id
, MDL
);
6317 * The Relay-forw message is sent by relays. It typically contains a
6318 * single option, which encapsulates an entire packet.
6320 * We need to build an encapsulated reply.
6323 /* XXX: this is very, very similar to do_packet6(), and should probably
6324 be combined in a clever way */
6326 dhcpv6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
6327 struct option_cache
*oc
;
6328 struct data_string enc_opt_data
;
6329 struct packet
*enc_packet
;
6330 unsigned char msg_type
;
6331 const struct dhcpv6_packet
*msg
;
6332 const struct dhcpv6_relay_packet
*relay
;
6333 struct data_string enc_reply
;
6334 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6335 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6336 struct data_string a_opt
, packet_ero
;
6337 struct option_state
*opt_state
;
6338 static char reply_data
[65536];
6339 struct dhcpv6_relay_packet
*reply
;
6343 * Initialize variables for early exit.
6346 memset(&a_opt
, 0, sizeof(a_opt
));
6347 memset(&packet_ero
, 0, sizeof(packet_ero
));
6348 memset(&enc_reply
, 0, sizeof(enc_reply
));
6349 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6353 * Get our encapsulated relay message.
6355 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
6357 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
6358 link_addr
, sizeof(link_addr
));
6359 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
6360 peer_addr
, sizeof(peer_addr
));
6361 log_info("Relay-forward from %s with link address=%s and "
6362 "peer address=%s missing Relay Message option.",
6363 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
6367 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
6368 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
6369 log_error("dhcpv6_forw_relay: error evaluating "
6370 "relayed message.");
6374 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
6375 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
6380 * Build a packet structure from this encapsulated packet.
6383 if (!packet_allocate(&enc_packet
, MDL
)) {
6384 log_error("dhcpv6_forw_relay: "
6385 "no memory for encapsulated packet.");
6389 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
6390 log_error("dhcpv6_forw_relay: "
6391 "no memory for encapsulated packet's options.");
6395 enc_packet
->client_port
= packet
->client_port
;
6396 enc_packet
->client_addr
= packet
->client_addr
;
6397 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
6398 enc_packet
->dhcpv6_container_packet
= packet
;
6400 msg_type
= enc_opt_data
.data
[0];
6401 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
6402 (msg_type
== DHCPV6_RELAY_REPL
)) {
6403 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6404 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
6405 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
6407 /* relay-specific data */
6408 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
6409 memcpy(&enc_packet
->dhcpv6_link_address
,
6410 relay
->link_address
, sizeof(relay
->link_address
));
6411 memcpy(&enc_packet
->dhcpv6_peer_address
,
6412 relay
->peer_address
, sizeof(relay
->peer_address
));
6414 if (!parse_option_buffer(enc_packet
->options
,
6416 enc_opt_data
.len
- relaylen
,
6417 &dhcpv6_universe
)) {
6418 /* no logging here, as parse_option_buffer() logs all
6419 cases where it fails */
6423 int msglen
= (int)(offsetof(struct dhcpv6_packet
, options
));
6424 msg
= (struct dhcpv6_packet
*)enc_opt_data
.data
;
6425 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
6427 /* message-specific data */
6428 memcpy(enc_packet
->dhcpv6_transaction_id
,
6429 msg
->transaction_id
,
6430 sizeof(enc_packet
->dhcpv6_transaction_id
));
6432 if (!parse_option_buffer(enc_packet
->options
,
6434 enc_opt_data
.len
- msglen
,
6435 &dhcpv6_universe
)) {
6436 /* no logging here, as parse_option_buffer() logs all
6437 cases where it fails */
6443 * This is recursive. It is possible to exceed maximum packet size.
6444 * XXX: This will cause the packet send to fail.
6446 build_dhcpv6_reply(&enc_reply
, enc_packet
);
6449 * If we got no encapsulated data, then it is discarded, and
6450 * our reply-forw is also discarded.
6452 if (enc_reply
.data
== NULL
) {
6457 * Now we can use the reply_data buffer.
6458 * Packet header stuff all comes from the forward message.
6460 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
6461 reply
->msg_type
= DHCPV6_RELAY_REPL
;
6462 reply
->hop_count
= packet
->dhcpv6_hop_count
;
6463 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
6464 sizeof(reply
->link_address
));
6465 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
6466 sizeof(reply
->peer_address
));
6467 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6470 * Get the reply option state.
6473 if (!option_state_allocate(&opt_state
, MDL
)) {
6474 log_error("dhcpv6_relay_forw: no memory for option state.");
6479 * Append the interface-id if present.
6481 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6484 if (!evaluate_option_cache(&a_opt
, packet
,
6486 packet
->options
, NULL
,
6487 &global_scope
, oc
, MDL
)) {
6488 log_error("dhcpv6_relay_forw: error evaluating "
6492 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6493 (unsigned char *)a_opt
.data
,
6495 D6O_INTERFACE_ID
, 0)) {
6496 log_error("dhcpv6_relay_forw: error saving "
6500 data_string_forget(&a_opt
, MDL
);
6504 * Append our encapsulated stuff for caller.
6506 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6507 (unsigned char *)enc_reply
.data
,
6509 D6O_RELAY_MSG
, 0)) {
6510 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
6515 * Get the ERO if any.
6517 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
6522 if (!evaluate_option_cache(&packet_ero
, packet
,
6524 packet
->options
, NULL
,
6525 &global_scope
, oc
, MDL
) ||
6526 (packet_ero
.len
& 1)) {
6527 log_error("dhcpv6_relay_forw: error evaluating ERO.");
6531 /* Decode and apply the ERO. */
6532 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
6533 req
= getUShort(packet_ero
.data
+ i
);
6534 /* Already in the reply? */
6535 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
6538 /* Get it from the packet if present. */
6539 oc
= lookup_option(&dhcpv6_universe
,
6544 if (!evaluate_option_cache(&a_opt
, packet
,
6546 packet
->options
, NULL
,
6547 &global_scope
, oc
, MDL
)) {
6548 log_error("dhcpv6_relay_forw: error "
6549 "evaluating option %u.", req
);
6552 if (!save_option_buffer(&dhcpv6_universe
,
6555 (unsigned char *)a_opt
.data
,
6559 log_error("dhcpv6_relay_forw: error saving "
6563 data_string_forget(&a_opt
, MDL
);
6567 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
6568 sizeof(reply_data
) - reply_ofs
,
6570 required_opts_agent
, &packet_ero
);
6573 * Return our reply to the caller.
6575 reply_ret
->len
= reply_ofs
;
6576 reply_ret
->buffer
= NULL
;
6577 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
6578 log_fatal("No memory to store reply.");
6580 reply_ret
->data
= reply_ret
->buffer
->data
;
6581 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
6584 if (opt_state
!= NULL
)
6585 option_state_dereference(&opt_state
, MDL
);
6586 if (a_opt
.data
!= NULL
) {
6587 data_string_forget(&a_opt
, MDL
);
6589 if (packet_ero
.data
!= NULL
) {
6590 data_string_forget(&packet_ero
, MDL
);
6592 if (enc_reply
.data
!= NULL
) {
6593 data_string_forget(&enc_reply
, MDL
);
6595 if (enc_opt_data
.data
!= NULL
) {
6596 data_string_forget(&enc_opt_data
, MDL
);
6598 if (enc_packet
!= NULL
) {
6599 packet_dereference(&enc_packet
, MDL
);
6604 dhcpv6_discard(struct packet
*packet
) {
6605 /* INSIST(packet->msg_type > 0); */
6606 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
6608 log_debug("Discarding %s from %s; message type not handled by server",
6609 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
6610 piaddr(packet
->client_addr
));
6614 build_dhcpv6_reply(struct data_string
*reply
, struct packet
*packet
) {
6615 memset(reply
, 0, sizeof(*reply
));
6617 /* I would like to classify the client once here, but
6618 * as I don't want to classify all of the incoming packets
6619 * I need to do it before handling specific types.
6620 * We don't need to classify if we are tossing the packet
6621 * or if it is a relay - the classification step will get
6622 * done when we process the inner client packet.
6625 switch (packet
->dhcpv6_msg_type
) {
6626 case DHCPV6_SOLICIT
:
6627 classify_client(packet
);
6628 dhcpv6_solicit(reply
, packet
);
6630 case DHCPV6_ADVERTISE
:
6631 dhcpv6_discard(packet
);
6633 case DHCPV6_REQUEST
:
6634 classify_client(packet
);
6635 dhcpv6_request(reply
, packet
);
6637 case DHCPV6_CONFIRM
:
6638 classify_client(packet
);
6639 dhcpv6_confirm(reply
, packet
);
6642 classify_client(packet
);
6643 dhcpv6_renew(reply
, packet
);
6646 classify_client(packet
);
6647 dhcpv6_rebind(reply
, packet
);
6650 dhcpv6_discard(packet
);
6652 case DHCPV6_RELEASE
:
6653 classify_client(packet
);
6654 dhcpv6_release(reply
, packet
);
6656 case DHCPV6_DECLINE
:
6657 classify_client(packet
);
6658 dhcpv6_decline(reply
, packet
);
6660 case DHCPV6_RECONFIGURE
:
6661 dhcpv6_discard(packet
);
6663 case DHCPV6_INFORMATION_REQUEST
:
6664 classify_client(packet
);
6665 dhcpv6_information_request(reply
, packet
);
6667 case DHCPV6_RELAY_FORW
:
6668 dhcpv6_relay_forw(reply
, packet
);
6670 case DHCPV6_RELAY_REPL
:
6671 dhcpv6_discard(packet
);
6673 case DHCPV6_LEASEQUERY
:
6674 classify_client(packet
);
6675 dhcpv6_leasequery(reply
, packet
);
6677 case DHCPV6_LEASEQUERY_REPLY
:
6678 dhcpv6_discard(packet
);
6681 /* XXX: would be nice if we had "notice" level,
6682 as syslog, for this */
6683 log_info("Discarding unknown DHCPv6 message type %d "
6684 "from %s", packet
->dhcpv6_msg_type
,
6685 piaddr(packet
->client_addr
));
6690 log_packet_in(const struct packet
*packet
) {
6691 struct data_string s
;
6693 char tmp_addr
[INET6_ADDRSTRLEN
];
6696 memset(&s
, 0, sizeof(s
));
6698 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
6699 data_string_sprintfa(&s
, "%s message from %s port %d",
6700 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
6701 piaddr(packet
->client_addr
),
6702 ntohs(packet
->client_port
));
6704 data_string_sprintfa(&s
,
6705 "Unknown message type %d from %s port %d",
6706 packet
->dhcpv6_msg_type
,
6707 piaddr(packet
->client_addr
),
6708 ntohs(packet
->client_port
));
6710 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
6711 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
6712 addr
= &packet
->dhcpv6_link_address
;
6713 data_string_sprintfa(&s
, ", link address %s",
6714 inet_ntop(AF_INET6
, addr
,
6715 tmp_addr
, sizeof(tmp_addr
)));
6716 addr
= &packet
->dhcpv6_peer_address
;
6717 data_string_sprintfa(&s
, ", peer address %s",
6718 inet_ntop(AF_INET6
, addr
,
6719 tmp_addr
, sizeof(tmp_addr
)));
6722 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
6723 data_string_sprintfa(&s
, ", transaction ID 0x%06X", tid
);
6726 oc = lookup_option(&dhcpv6_universe, packet->options,
6729 memset(&tmp_ds, 0, sizeof(tmp_ds_));
6730 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
6731 packet->options, NULL,
6732 &global_scope, oc, MDL)) {
6733 log_error("Error evaluating Client Identifier");
6735 data_strint_sprintf(&s, ", client ID %s",
6737 data_string_forget(&tmp_ds, MDL);
6743 log_info("%s", s
.data
);
6745 data_string_forget(&s
, MDL
);
6749 dhcpv6(struct packet
*packet
) {
6750 struct data_string reply
;
6751 struct sockaddr_in6 to_addr
;
6755 * Log a message that we received this packet.
6757 log_packet_in(packet
);
6760 * Build our reply packet.
6762 build_dhcpv6_reply(&reply
, packet
);
6764 if (reply
.data
!= NULL
) {
6766 * Send our reply, if we have one.
6768 memset(&to_addr
, 0, sizeof(to_addr
));
6769 to_addr
.sin6_family
= AF_INET6
;
6770 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
6771 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
6772 to_addr
.sin6_port
= local_port
;
6774 to_addr
.sin6_port
= remote_port
;
6777 #if defined (REPLY_TO_SOURCE_PORT)
6779 * This appears to have been included for testing so we would
6780 * not need a root client, but was accidently left in the
6781 * final code. We continue to include it in case
6782 * some users have come to rely upon it, but leave
6783 * it off by default as it's a bad idea.
6785 to_addr
.sin6_port
= packet
->client_port
;
6788 memcpy(&to_addr
.sin6_addr
, packet
->client_addr
.iabuf
,
6789 sizeof(to_addr
.sin6_addr
));
6791 log_info("Sending %s to %s port %d",
6792 dhcpv6_type_names
[reply
.data
[0]],
6793 piaddr(packet
->client_addr
),
6794 ntohs(to_addr
.sin6_port
));
6796 send_ret
= send_packet6(packet
->interface
,
6797 reply
.data
, reply
.len
, &to_addr
);
6798 if (send_ret
!= reply
.len
) {
6799 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
6800 send_ret
, reply
.len
);
6802 data_string_forget(&reply
, MDL
);
6807 seek_shared_host(struct host_decl
**hp
, struct shared_network
*shared
) {
6808 struct host_decl
*nofixed
= NULL
;
6809 struct host_decl
*seek
, *hold
= NULL
;
6812 * Seek forward through fixed addresses for the right link.
6814 * Note: how to do this for fixed prefixes???
6816 host_reference(&hold
, *hp
, MDL
);
6817 host_dereference(hp
, MDL
);
6819 while (seek
!= NULL
) {
6820 if (seek
->fixed_addr
== NULL
)
6822 else if (fixed_matches_shared(seek
, shared
))
6825 seek
= seek
->n_ipaddr
;
6828 if ((seek
== NULL
) && (nofixed
!= NULL
))
6832 host_reference(hp
, seek
, MDL
);
6835 static isc_boolean_t
6836 fixed_matches_shared(struct host_decl
*host
, struct shared_network
*shared
) {
6837 struct subnet
*subnet
;
6838 struct data_string addr
;
6839 isc_boolean_t matched
;
6842 if (host
->fixed_addr
== NULL
)
6845 memset(&addr
, 0, sizeof(addr
));
6846 if (!evaluate_option_cache(&addr
, NULL
, NULL
, NULL
, NULL
, NULL
,
6847 &global_scope
, host
->fixed_addr
, MDL
))
6850 if (addr
.len
< 16) {
6851 data_string_forget(&addr
, MDL
);
6856 memcpy(fixed
.iabuf
, addr
.data
, 16);
6858 matched
= ISC_FALSE
;
6859 for (subnet
= shared
->subnets
; subnet
!= NULL
;
6860 subnet
= subnet
->next_sibling
) {
6861 if (addr_eq(subnet_number(fixed
, subnet
->netmask
),
6868 data_string_forget(&addr
, MDL
);
6874 * \brief Constructs a REPLY with status of UseMulticast to a given packet
6876 * Per RFC 3315 Secs 18.2.1,3,6 & 7, when a server rejects a client's
6877 * unicast-sent packet, the response must only contain the client id,
6878 * server id, and a status code option of 5 (UseMulticast). This function
6879 * constructs such a packet and returns it as a data_string.
6881 * \param reply_ret = data_string which will receive the newly constructed
6883 * \param packet = client request which is being rejected
6884 * \param client_id = data_string which contains the client id
6885 * \param server_id = data_string which which contains the server id
6889 unicast_reject(struct data_string
*reply_ret
,
6890 struct packet
*packet
,
6891 const struct data_string
*client_id
,
6892 const struct data_string
*server_id
)
6894 struct reply_state reply
;
6895 memset(&reply
, 0x0, sizeof(struct reply_state
));
6897 /* Locate the client. */
6898 if (shared_network_from_packet6(&reply
.shared
, packet
)
6900 log_error("unicast_reject: could not locate client.");
6904 /* Initialize the reply. */
6905 packet_reference(&reply
.packet
, packet
, MDL
);
6906 data_string_copy(&reply
.client_id
, client_id
, MDL
);
6908 if (start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
6909 &reply
.buf
.reply
)) {
6910 /* Set the UseMulticast status code. */
6911 if (!set_status_code(STATUS_UseMulticast
,
6912 "Unicast not allowed by server.",
6914 log_error("unicast_reject: Unable to set status code.");
6916 /* Set write cursor to just past the reply header. */
6917 reply
.cursor
= REPLY_OPTIONS_INDEX
;
6918 reply
.cursor
+= store_options6(((char *)reply
.buf
.data
6924 unicast_reject_opts
,
6927 /* Return our reply to the caller. */
6928 reply_ret
->len
= reply
.cursor
;
6929 reply_ret
->buffer
= NULL
;
6930 if (!buffer_allocate(&reply_ret
->buffer
,
6931 reply
.cursor
, MDL
)) {
6932 log_fatal("unicast_reject:"
6933 "No memory to store Reply.");
6936 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
,
6938 reply_ret
->data
= reply_ret
->buffer
->data
;
6944 if (reply
.shared
!= NULL
)
6945 shared_network_dereference(&reply
.shared
, MDL
);
6946 if (reply
.opt_state
!= NULL
)
6947 option_state_dereference(&reply
.opt_state
, MDL
);
6948 if (reply
.packet
!= NULL
)
6949 packet_dereference(&reply
.packet
, MDL
);
6950 if (reply
.client_id
.data
!= NULL
)
6951 data_string_forget(&reply
.client_id
, MDL
);
6956 * \brief Checks if the dhcp6.unicast option has been defined
6958 * Scans the option space for the presence of the dhcp6.unicast option. The
6959 * function attempts to map the inbound packet to a shared network first
6960 * by an ip address specified via an D6O_IA_XX option and if that fails then
6961 * by the packet's source information (e.g. relay link, link, or interace).
6962 * Once the packet is mapped to a shared network, the function executes all
6963 * statements from the network's group outward into a local option cache.
6964 * The option cache is then scanned for the presence of unicast option. If
6965 * the packet cannot be mapped to a shared network, the function returns
6967 * \param packet inbound packet from the client
6969 * \return ISC_TRUE if the dhcp6.unicast option is defined, false otherwise.
6973 is_unicast_option_defined(struct packet
*packet
) {
6974 isc_boolean_t is_defined
= ISC_FALSE
;
6975 struct option_state
*opt_state
= NULL
;
6976 struct option_cache
*oc
= NULL
;
6977 struct shared_network
*shared
= NULL
;
6979 if (!option_state_allocate(&opt_state
, MDL
)) {
6980 log_fatal("is_unicast_option_defined:"
6981 "No memory for option state.");
6984 /* We try to map the packet to a network first by an IA_XX value.
6985 * If that fails, we try by packet source. */
6986 if (((shared_network_from_requested_addr(&shared
, packet
)
6987 != ISC_R_SUCCESS
) &&
6988 (shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
))
6989 || (shared
== NULL
)) {
6990 /* @todo what would this really mean? I think wrong network
6991 * logic will catch it */
6992 log_error("is_unicast_option_defined:"
6993 "cannot attribute packet to a network.");
6997 /* Now that we've mapped it to a network, execute statments to that
6998 * scope, looking for the unicast option. We don't care about the
6999 * value of the option, only whether or not it is defined. */
7000 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
, opt_state
,
7001 &global_scope
, shared
->group
, NULL
, NULL
);
7003 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_UNICAST
);
7004 is_defined
= (oc
!= NULL
? ISC_TRUE
: ISC_FALSE
);
7005 log_debug("is_unicast_option_defined: option found : %d", is_defined
);
7007 if (shared
!= NULL
) {
7008 shared_network_dereference(&shared
, MDL
);
7011 if (opt_state
!= NULL
) {
7012 option_state_dereference(&opt_state
, MDL
);
7015 return (is_defined
);
7020 * \brief Maps a packet to a shared network based on the requested IP address
7022 * The function attempts to find a subnet that matches the first requested IP
7023 * address contained within the given packet. Note that it looks first for
7024 * D6O_IA_NAs, then D6O_IA_PDs and lastly D6O_IA_TAs. If a matching network is
7025 * found, a reference to it is returned in the parameter, shared.
7027 * \param shared shared_network pointer which will receive the matching network
7028 * \param packet inbound packet from the client
7030 * \return ISC_R_SUCCESS if the packet can be mapped to a shared_network.
7034 shared_network_from_requested_addr (struct shared_network
**shared
,
7035 struct packet
* packet
) {
7037 struct subnet
* subnet
= NULL
;
7038 isc_result_t status
= ISC_R_FAILURE
;
7040 /* Try to match first IA_ address or prefix we find to a subnet. In
7041 * theory all IA_ values in a given request are supposed to be in the
7042 * same subnet so we only need to try one right? */
7043 if ((get_first_ia_addr_val(packet
, D6O_IA_NA
, &iaddr
) != ISC_R_SUCCESS
)
7044 && (get_first_ia_addr_val(packet
, D6O_IA_PD
, &iaddr
)
7046 && (get_first_ia_addr_val(packet
, D6O_IA_TA
, &iaddr
)
7047 != ISC_R_SUCCESS
)) {
7048 /* we found nothing to match against */
7049 log_debug("share_network_from_request_addr: nothing to match");
7050 return (ISC_R_FAILURE
);
7053 if (!find_subnet(&subnet
, iaddr
, MDL
)) {
7054 log_debug("shared_network_from_requested_addr:"
7055 "No subnet found for addr %s.", piaddr(iaddr
));
7057 status
= shared_network_reference(shared
,
7058 subnet
->shared_network
, MDL
);
7059 subnet_dereference(&subnet
, MDL
);
7060 log_debug("shared_network_from_requested_addr:"
7061 " found shared network %s for address %s.",
7062 ((*shared
)->name
? (*shared
)->name
: "unnamed"),
7067 return (ISC_R_FAILURE
);
7072 * \brief Retrieves the first IP address from a given packet of a given type
7074 * Search a packet for options of a given type (D6O_IA_AN, D6O_IA_PD, or
7075 * D6O_IA_TA) for the first non-blank IA_XX value and return its IP address
7078 * \param packet packet received from the client
7079 * \param addr_type the address option type (D6O_IA_NA , D6O_IA_PD, or
7080 * D6O_IP_TA) to look for within the packet.
7081 * \param iaddr pointer to the iaddr structure which will receive the extracted
7084 * \return ISC_R_SUCCESS if an address was succesfully extracted, ISC_R_FALURE
7089 get_first_ia_addr_val (struct packet
* packet
, int addr_type
,
7090 struct iaddr
* iaddr
) {
7091 struct option_cache
*ia
;
7092 struct option_cache
*oc
= NULL
;
7093 struct data_string cli_enc_opt_data
;
7094 struct option_state
*cli_enc_opt_state
;
7095 int addr_opt_offset
;
7097 int addr_opt_data_len
;
7100 isc_result_t status
= ISC_R_FAILURE
;
7101 memset(iaddr
, 0, sizeof(struct iaddr
));
7103 /* Set up address type specifics */
7104 switch (addr_type
) {
7106 addr_opt_offset
= IA_NA_OFFSET
;
7107 addr_opt
= D6O_IAADDR
;
7108 addr_opt_data_len
= 24;
7112 addr_opt_offset
= IA_TA_OFFSET
;
7113 addr_opt
= D6O_IAADDR
;
7114 addr_opt_data_len
= 24;
7118 addr_opt_offset
= IA_PD_OFFSET
;
7119 addr_opt
= D6O_IAPREFIX
;
7120 addr_opt_data_len
= 25;
7124 /* shouldn't be here */
7125 log_error ("get_first_ia_addr_val: invalid opt type %d",
7127 return (ISC_R_FAILURE
);
7130 /* Find the first, non-blank IA_XX value within an D6O_IA_XX option. */
7131 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, addr_type
);
7132 ia
!= NULL
&& oc
== NULL
; ia
= ia
->next
) {
7133 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
7135 packet
, ia
, addr_opt_offset
)) {
7136 log_debug ("get_first_ia_addr_val:"
7137 " couldn't unroll enclosing option");
7138 return (ISC_R_FAILURE
);
7141 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
7144 /* no address given for this IA, ignore */
7145 option_state_dereference(&cli_enc_opt_state
, MDL
);
7146 data_string_forget(&cli_enc_opt_data
, MDL
);
7150 /* If we found a non-blank IA_XX then extract its ip address. */
7152 struct data_string iaddr_str
;
7154 memset(&iaddr_str
, 0, sizeof(iaddr_str
));
7155 if (!evaluate_option_cache(&iaddr_str
, packet
, NULL
, NULL
,
7156 packet
->options
, NULL
, &global_scope
,
7158 log_error("get_first_ia_addr_val: "
7159 "error evaluating IA_XX option.");
7161 if (iaddr_str
.len
!= addr_opt_data_len
) {
7162 log_error("shared_network_from_requested_addr:"
7163 " invalid length %d, expected %d",
7164 iaddr_str
.len
, addr_opt_data_len
);
7167 memcpy (iaddr
->iabuf
,
7168 iaddr_str
.data
+ ip_addr_offset
, 16);
7169 status
= ISC_R_SUCCESS
;
7171 data_string_forget(&iaddr_str
, MDL
);
7174 option_state_dereference(&cli_enc_opt_state
, MDL
);
7175 data_string_forget(&cli_enc_opt_data
, MDL
);