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
, min_prefer
, min_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 set_reply_tee_times(struct reply_state
* reply
, unsigned ia_cursor
);
171 * Schedule lease timeouts for all of the iasubopts in the reply.
172 * This is currently used to schedule timeouts for soft leases.
176 schedule_lease_timeout_reply(struct reply_state
*reply
) {
177 struct iasubopt
*tmp
;
180 /* sanity check the reply */
181 if ((reply
== NULL
) || (reply
->ia
== NULL
) || (reply
->ia
->iasubopt
== NULL
))
184 /* walk through the list, scheduling as we go */
185 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
186 tmp
= reply
->ia
->iasubopt
[i
];
187 schedule_lease_timeout(tmp
->ipv6_pool
);
192 * This function returns the time since DUID time start for the
193 * given time_t value.
196 duid_time(time_t when
) {
198 * This time is modulo 2^32.
200 while ((when
- DUID_TIME_EPOCH
) > 4294967295u) {
201 /* use 2^31 to avoid spurious compiler warnings */
206 return when
- DUID_TIME_EPOCH
;
213 * This must remain the same for the lifetime of this server, because
214 * clients return the server DUID that we sent them in Request packets.
216 * We pick the server DUID like this:
218 * 1. Check dhcpd.conf - any value the administrator has configured
219 * overrides any possible values.
220 * 2. Check the leases.txt - we want to use the previous value if
222 * 3. Check if dhcpd.conf specifies a type of server DUID to use,
223 * and generate that type.
224 * 4. Generate a type 1 (time + hardware address) DUID.
226 static struct data_string server_duid
;
229 * Check if the server_duid has been set.
232 server_duid_isset(void) {
233 return (server_duid
.data
!= NULL
);
237 * Return the server_duid.
240 copy_server_duid(struct data_string
*ds
, const char *file
, int line
) {
241 data_string_copy(ds
, &server_duid
, file
, line
);
245 * Set the server DUID to a specified value. This is used when
246 * the server DUID is stored in persistent memory (basically the
250 set_server_duid(struct data_string
*new_duid
) {
251 /* INSIST(new_duid != NULL); */
252 /* INSIST(new_duid->data != NULL); */
254 if (server_duid_isset()) {
255 data_string_forget(&server_duid
, MDL
);
257 data_string_copy(&server_duid
, new_duid
, MDL
);
262 * Set the server DUID based on the D6O_SERVERID option. This handles
263 * the case where the administrator explicitly put it in the dhcpd.conf
267 set_server_duid_from_option(void) {
268 struct option_state
*opt_state
;
269 struct option_cache
*oc
;
270 struct data_string option_duid
;
271 isc_result_t ret_val
;
274 if (!option_state_allocate(&opt_state
, MDL
)) {
275 log_fatal("No memory for server DUID.");
278 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
,
279 opt_state
, &global_scope
, root_group
,
282 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
284 ret_val
= ISC_R_NOTFOUND
;
286 memset(&option_duid
, 0, sizeof(option_duid
));
287 if (!evaluate_option_cache(&option_duid
, NULL
, NULL
, NULL
,
288 opt_state
, NULL
, &global_scope
,
290 ret_val
= ISC_R_UNEXPECTED
;
292 set_server_duid(&option_duid
);
293 data_string_forget(&option_duid
, MDL
);
294 ret_val
= ISC_R_SUCCESS
;
298 option_state_dereference(&opt_state
, MDL
);
304 * DUID layout, as defined in RFC 3315, section 9.
306 * We support type 1 (hardware address plus time) and type 3 (hardware
309 * We can support type 2 for specific vendors in the future, if they
310 * publish the specification. And of course there may be additional
313 static int server_duid_type
= DUID_LLT
;
319 set_server_duid_type(int type
) {
320 server_duid_type
= type
;
324 * Generate a new server DUID. This is done if there was no DUID in
325 * the leases.txt or in the dhcpd.conf file.
328 generate_new_server_duid(void) {
329 struct interface_info
*p
;
331 struct data_string generated_duid
;
334 * Verify we have a type that we support.
336 if ((server_duid_type
!= DUID_LL
) && (server_duid_type
!= DUID_LLT
)) {
337 log_error("Invalid DUID type %d specified, "
338 "only LL and LLT types supported", server_duid_type
);
339 return DHCP_R_INVALIDARG
;
343 * Find an interface with a hardware address.
346 for (p
= interfaces
; p
!= NULL
; p
= p
->next
) {
347 if (p
->hw_address
.hlen
> 0) {
352 return ISC_R_UNEXPECTED
;
358 memset(&generated_duid
, 0, sizeof(generated_duid
));
359 if (server_duid_type
== DUID_LLT
) {
360 time_val
= duid_time(time(NULL
));
361 generated_duid
.len
= 8 + p
->hw_address
.hlen
- 1;
362 if (!buffer_allocate(&generated_duid
.buffer
,
363 generated_duid
.len
, MDL
)) {
364 log_fatal("No memory for server DUID.");
366 generated_duid
.data
= generated_duid
.buffer
->data
;
367 putUShort(generated_duid
.buffer
->data
, DUID_LLT
);
368 putUShort(generated_duid
.buffer
->data
+ 2,
369 p
->hw_address
.hbuf
[0]);
370 putULong(generated_duid
.buffer
->data
+ 4, time_val
);
371 memcpy(generated_duid
.buffer
->data
+ 8,
372 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
373 } else if (server_duid_type
== DUID_LL
) {
374 generated_duid
.len
= 4 + p
->hw_address
.hlen
- 1;
375 if (!buffer_allocate(&generated_duid
.buffer
,
376 generated_duid
.len
, MDL
)) {
377 log_fatal("No memory for server DUID.");
379 generated_duid
.data
= generated_duid
.buffer
->data
;
380 putUShort(generated_duid
.buffer
->data
, DUID_LL
);
381 putUShort(generated_duid
.buffer
->data
+ 2,
382 p
->hw_address
.hbuf
[0]);
383 memcpy(generated_duid
.buffer
->data
+ 4,
384 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
386 log_fatal("Unsupported server DUID type %d.", server_duid_type
);
389 set_server_duid(&generated_duid
);
390 data_string_forget(&generated_duid
, MDL
);
392 return ISC_R_SUCCESS
;
396 * Get the client identifier from the packet.
399 get_client_id(struct packet
*packet
, struct data_string
*client_id
) {
400 struct option_cache
*oc
;
403 * Verify our client_id structure is empty.
405 if ((client_id
->data
!= NULL
) || (client_id
->len
!= 0)) {
406 return DHCP_R_INVALIDARG
;
409 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_CLIENTID
);
411 return ISC_R_NOTFOUND
;
414 if (!evaluate_option_cache(client_id
, packet
, NULL
, NULL
,
415 packet
->options
, NULL
,
416 &global_scope
, oc
, MDL
)) {
417 return ISC_R_FAILURE
;
420 return ISC_R_SUCCESS
;
424 * Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
426 * Servers MUST discard any Solicit messages that do not include a
427 * Client Identifier option or that do include a Server Identifier
431 valid_client_msg(struct packet
*packet
, struct data_string
*client_id
) {
433 struct option_cache
*oc
;
434 struct data_string data
;
437 memset(client_id
, 0, sizeof(*client_id
));
438 memset(&data
, 0, sizeof(data
));
440 switch (get_client_id(packet
, client_id
)) {
444 log_debug("Discarding %s from %s; "
445 "client identifier missing",
446 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
447 piaddr(packet
->client_addr
));
450 log_error("Error processing %s from %s; "
451 "unable to evaluate Client Identifier",
452 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
453 piaddr(packet
->client_addr
));
458 * Required by RFC 3315, section 15.
460 if (packet
->unicast
) {
461 log_debug("Discarding %s from %s; packet sent unicast "
463 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
464 piaddr(packet
->client_addr
),
465 print_hex_1(client_id
->len
, client_id
->data
, 60));
470 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
472 if (evaluate_option_cache(&data
, packet
, NULL
, NULL
,
473 packet
->options
, NULL
,
474 &global_scope
, oc
, MDL
)) {
475 log_debug("Discarding %s from %s; "
476 "server identifier found "
477 "(CLIENTID %s, SERVERID %s)",
478 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
479 piaddr(packet
->client_addr
),
480 print_hex_1(client_id
->len
,
481 client_id
->data
, 60),
482 print_hex_2(data
.len
,
485 log_debug("Discarding %s from %s; "
486 "server identifier found "
488 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
489 print_hex_1(client_id
->len
,
490 client_id
->data
, 60),
491 piaddr(packet
->client_addr
));
501 data_string_forget(&data
, MDL
);
504 if (client_id
->len
> 0) {
505 data_string_forget(client_id
, MDL
);
512 * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
513 * 15.9 (slightly different wording, but same meaning):
515 * Servers MUST discard any received Request message that meet any of
516 * the following conditions:
518 * - the message does not include a Server Identifier option.
519 * - the contents of the Server Identifier option do not match the
521 * - the message does not include a Client Identifier option.
524 valid_client_resp(struct packet
*packet
,
525 struct data_string
*client_id
,
526 struct data_string
*server_id
)
529 struct option_cache
*oc
;
531 /* INSIST((duid.data != NULL) && (duid.len > 0)); */
534 memset(client_id
, 0, sizeof(*client_id
));
535 memset(server_id
, 0, sizeof(*server_id
));
537 switch (get_client_id(packet
, client_id
)) {
541 log_debug("Discarding %s from %s; "
542 "client identifier missing",
543 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
544 piaddr(packet
->client_addr
));
547 log_error("Error processing %s from %s; "
548 "unable to evaluate Client Identifier",
549 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
550 piaddr(packet
->client_addr
));
554 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
556 log_debug("Discarding %s from %s: "
557 "server identifier missing (CLIENTID %s)",
558 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
559 piaddr(packet
->client_addr
),
560 print_hex_1(client_id
->len
, client_id
->data
, 60));
563 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
564 packet
->options
, NULL
,
565 &global_scope
, oc
, MDL
)) {
566 log_error("Error processing %s from %s; "
567 "unable to evaluate Server Identifier (CLIENTID %s)",
568 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
569 piaddr(packet
->client_addr
),
570 print_hex_1(client_id
->len
, client_id
->data
, 60));
573 if ((server_duid
.len
!= server_id
->len
) ||
574 (memcmp(server_duid
.data
, server_id
->data
, server_duid
.len
) != 0)) {
575 log_debug("Discarding %s from %s; "
576 "not our server identifier "
577 "(CLIENTID %s, SERVERID %s, server DUID %s)",
578 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
579 piaddr(packet
->client_addr
),
580 print_hex_1(client_id
->len
, client_id
->data
, 60),
581 print_hex_2(server_id
->len
, server_id
->data
, 60),
582 print_hex_3(server_duid
.len
, server_duid
.data
, 60));
591 if (server_id
->len
> 0) {
592 data_string_forget(server_id
, MDL
);
594 if (client_id
->len
> 0) {
595 data_string_forget(client_id
, MDL
);
602 * Information request validation, defined in RFC 3315, section 15.12:
604 * Servers MUST discard any received Information-request message that
605 * meets any of the following conditions:
607 * - The message includes a Server Identifier option and the DUID in
608 * the option does not match the server's DUID.
610 * - The message includes an IA option.
613 valid_client_info_req(struct packet
*packet
, struct data_string
*server_id
) {
615 struct option_cache
*oc
;
616 struct data_string client_id
;
617 char client_id_str
[80]; /* print_hex_1() uses maximum 60 characters,
618 plus a few more for extra information */
621 memset(server_id
, 0, sizeof(*server_id
));
622 memset(&client_id
, 0, sizeof(client_id
));
625 * Make a string that we can print out to give more
626 * information about the client if we need to.
628 * By RFC 3315, Section 18.1.5 clients SHOULD have a
629 * client-id on an Information-request packet, but it
630 * is not strictly necessary.
632 if (get_client_id(packet
, &client_id
) == ISC_R_SUCCESS
) {
633 snprintf(client_id_str
, sizeof(client_id_str
), " (CLIENTID %s)",
634 print_hex_1(client_id
.len
, client_id
.data
, 60));
635 data_string_forget(&client_id
, MDL
);
637 client_id_str
[0] = '\0';
641 * Required by RFC 3315, section 15.
643 if (packet
->unicast
) {
644 log_debug("Discarding %s from %s; packet sent unicast%s",
645 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
646 piaddr(packet
->client_addr
), client_id_str
);
650 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
652 log_debug("Discarding %s from %s; "
653 "IA_NA option present%s",
654 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
655 piaddr(packet
->client_addr
), client_id_str
);
658 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
660 log_debug("Discarding %s from %s; "
661 "IA_TA option present%s",
662 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
663 piaddr(packet
->client_addr
), client_id_str
);
666 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
668 log_debug("Discarding %s from %s; "
669 "IA_PD option present%s",
670 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
671 piaddr(packet
->client_addr
), client_id_str
);
675 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
677 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
678 packet
->options
, NULL
,
679 &global_scope
, oc
, MDL
)) {
680 log_error("Error processing %s from %s; "
681 "unable to evaluate Server Identifier%s",
682 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
683 piaddr(packet
->client_addr
), client_id_str
);
686 if ((server_duid
.len
!= server_id
->len
) ||
687 (memcmp(server_duid
.data
, server_id
->data
,
688 server_duid
.len
) != 0)) {
689 log_debug("Discarding %s from %s; "
690 "not our server identifier "
691 "(SERVERID %s, server DUID %s)%s",
692 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
693 piaddr(packet
->client_addr
),
694 print_hex_1(server_id
->len
,
695 server_id
->data
, 60),
696 print_hex_2(server_duid
.len
,
697 server_duid
.data
, 60),
708 if (server_id
->len
> 0) {
709 data_string_forget(server_id
, MDL
);
716 * Options that we want to send, in addition to what was requested
719 static const int required_opts
[] = {
726 static const int required_opts_solicit
[] = {
738 static const int required_opts_agent
[] = {
743 static const int required_opts_IA
[] = {
748 static const int required_opts_IA_PD
[] = {
753 static const int required_opts_STATUS_CODE
[] = {
758 static const int unicast_reject_opts
[] = {
767 * Extracts from packet contents an IA_* option, storing the IA structure
768 * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
769 * in enc_opt_state for later lookup and evaluation. The 'offset' indicates
770 * where in the IA_* the DHCPv6 options commence.
773 get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
774 struct data_string
*enc_opt_data
,
775 struct packet
*packet
,
776 struct option_cache
*oc
,
780 * Get the raw data for the encapsulated options.
782 memset(enc_opt_data
, 0, sizeof(*enc_opt_data
));
783 if (!evaluate_option_cache(enc_opt_data
, packet
,
784 NULL
, NULL
, packet
->options
, NULL
,
785 &global_scope
, oc
, MDL
)) {
786 log_error("get_encapsulated_IA_state: "
787 "error evaluating raw option.");
790 if (enc_opt_data
->len
< offset
) {
791 log_error("get_encapsulated_IA_state: raw option too small.");
792 data_string_forget(enc_opt_data
, MDL
);
797 * Now create the option state structure, and pass it to the
798 * function that parses options.
800 *enc_opt_state
= NULL
;
801 if (!option_state_allocate(enc_opt_state
, MDL
)) {
802 log_error("get_encapsulated_IA_state: no memory for options.");
803 data_string_forget(enc_opt_data
, MDL
);
806 if (!parse_option_buffer(*enc_opt_state
,
807 enc_opt_data
->data
+ offset
,
808 enc_opt_data
->len
- offset
,
810 log_error("get_encapsulated_IA_state: error parsing options.");
811 option_state_dereference(enc_opt_state
, MDL
);
812 data_string_forget(enc_opt_data
, MDL
);
820 set_status_code(u_int16_t status_code
, const char *status_message
,
821 struct option_state
*opt_state
)
823 struct data_string d
;
826 memset(&d
, 0, sizeof(d
));
827 d
.len
= sizeof(status_code
) + strlen(status_message
);
828 if (!buffer_allocate(&d
.buffer
, d
.len
, MDL
)) {
829 log_fatal("set_status_code: no memory for status code.");
831 d
.data
= d
.buffer
->data
;
832 putUShort(d
.buffer
->data
, status_code
);
833 memcpy(d
.buffer
->data
+ sizeof(status_code
),
834 status_message
, d
.len
- sizeof(status_code
));
835 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
836 d
.buffer
, (unsigned char *)d
.data
, d
.len
,
837 D6O_STATUS_CODE
, 0)) {
838 log_error("set_status_code: error saving status code.");
843 data_string_forget(&d
, MDL
);
847 void check_pool6_threshold(struct reply_state
*reply
,
848 struct iasubopt
*lease
)
850 struct ipv6_pond
*pond
;
851 isc_uint64_t used
, count
, high_threshold
;
852 int poolhigh
= 0, poollow
= 0;
853 char *shared_name
= "no name";
854 char tmp_addr
[INET6_ADDRSTRLEN
];
856 if ((lease
->ipv6_pool
== NULL
) || (lease
->ipv6_pool
->ipv6_pond
== NULL
))
858 pond
= lease
->ipv6_pool
->ipv6_pond
;
860 /* If the address range is too large to track, just skip all this. */
861 if (pond
->jumbo_range
== 1) {
865 count
= pond
->num_total
;
866 used
= pond
->num_active
;
868 /* get network name for logging */
869 if ((pond
->shared_network
!= NULL
) &&
870 (pond
->shared_network
->name
!= NULL
)) {
871 shared_name
= pond
->shared_network
->name
;
874 /* The logged flag indicates if we have already crossed the high
875 * threshold and emitted a log message. If it is set we check to
876 * see if we have re-crossed the low threshold and need to reset
877 * things. When we cross the high threshold we determine what
878 * the low threshold is and save it into the low_threshold value.
879 * When we cross that threshold we reset the logged flag and
880 * the low_threshold to 0 which allows the high threshold message
881 * to be emitted once again.
882 * if we haven't recrossed the boundry we don't need to do anything.
884 if (pond
->logged
!=0) {
885 if (used
<= pond
->low_threshold
) {
886 pond
->low_threshold
= 0;
888 log_error("Pool threshold reset - shared subnet: %s; "
889 "address: %s; low threshold %llu/%llu.",
891 inet_ntop(AF_INET6
, &lease
->addr
,
892 tmp_addr
, sizeof(tmp_addr
)),
898 /* find the high threshold */
899 if (get_option_int(&poolhigh
, &server_universe
, reply
->packet
, NULL
,
900 NULL
, reply
->packet
->options
, reply
->opt_state
,
901 reply
->opt_state
, &lease
->scope
,
902 SV_LOG_THRESHOLD_HIGH
, MDL
) == 0) {
903 /* no threshold bail out */
907 /* We do have a threshold for this pool, see if its valid */
908 if ((poolhigh
<= 0) || (poolhigh
> 100)) {
913 /* we have a valid value, have we exceeded it */
914 high_threshold
= FIND_POND6_PERCENT(count
, poolhigh
);
915 if (used
< high_threshold
) {
916 /* nope, no more to do */
920 /* we've exceeded it, output a message */
921 log_error("Pool threshold exceeded - shared subnet: %s; "
922 "address: %s; high threshold %d%% %llu/%llu.",
924 inet_ntop(AF_INET6
, &lease
->addr
, tmp_addr
, sizeof(tmp_addr
)),
925 poolhigh
, used
, count
);
927 /* handle the low threshold now, if we don't
928 * have one we default to 0. */
929 if ((get_option_int(&poollow
, &server_universe
, reply
->packet
, NULL
,
930 NULL
, reply
->packet
->options
, reply
->opt_state
,
931 reply
->opt_state
, &lease
->scope
,
932 SV_LOG_THRESHOLD_LOW
, MDL
) == 0) ||
938 * If the low theshold is higher than the high threshold we continue to log
939 * If it isn't then we set the flag saying we already logged and determine
940 * what the reset threshold is.
942 if (poollow
< poolhigh
) {
944 pond
->low_threshold
= FIND_POND6_PERCENT(count
, poollow
);
949 * We have a set of operations we do to set up the reply packet, which
950 * is the same for many message types.
953 start_reply(struct packet
*packet
,
954 const struct data_string
*client_id
,
955 const struct data_string
*server_id
,
956 struct option_state
**opt_state
,
957 struct dhcpv6_packet
*reply
)
959 struct option_cache
*oc
;
960 const unsigned char *server_id_data
;
964 * Build our option state for reply.
967 if (!option_state_allocate(opt_state
, MDL
)) {
968 log_error("start_reply: no memory for option_state.");
971 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
972 packet
->options
, *opt_state
,
973 &global_scope
, root_group
, NULL
, NULL
);
976 * A small bit of special handling for Solicit messages.
978 * We could move the logic into a flag, but for now just check
981 if (packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
982 reply
->msg_type
= DHCPV6_ADVERTISE
;
986 * - this message type supports rapid commit (Solicit), and
987 * - the server is configured to supply a rapid commit, and
988 * - the client requests a rapid commit,
989 * Then we add a rapid commit option, and send Reply (instead
992 oc
= lookup_option(&dhcpv6_universe
,
993 *opt_state
, D6O_RAPID_COMMIT
);
995 oc
= lookup_option(&dhcpv6_universe
,
996 packet
->options
, D6O_RAPID_COMMIT
);
998 /* Rapid-commit in action. */
999 reply
->msg_type
= DHCPV6_REPLY
;
1001 /* Don't want a rapid-commit in advertise. */
1002 delete_option(&dhcpv6_universe
,
1003 *opt_state
, D6O_RAPID_COMMIT
);
1007 reply
->msg_type
= DHCPV6_REPLY
;
1008 /* Delete the rapid-commit from the sent options. */
1009 oc
= lookup_option(&dhcpv6_universe
,
1010 *opt_state
, D6O_RAPID_COMMIT
);
1012 delete_option(&dhcpv6_universe
,
1013 *opt_state
, D6O_RAPID_COMMIT
);
1018 * Use the client's transaction identifier for the reply.
1020 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
1021 sizeof(reply
->transaction_id
));
1024 * RFC 3315, section 18.2 says we need server identifier and
1025 * client identifier.
1027 * If the server ID is defined via the configuration file, then
1028 * it will already be present in the option state at this point,
1029 * so we don't need to set it.
1031 * If we have a server ID passed in from the caller,
1032 * use that, otherwise use the global DUID.
1034 oc
= lookup_option(&dhcpv6_universe
, *opt_state
, D6O_SERVERID
);
1036 if (server_id
== NULL
) {
1037 server_id_data
= server_duid
.data
;
1038 server_id_len
= server_duid
.len
;
1040 server_id_data
= server_id
->data
;
1041 server_id_len
= server_id
->len
;
1043 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1044 NULL
, (unsigned char *)server_id_data
,
1045 server_id_len
, D6O_SERVERID
, 0)) {
1046 log_error("start_reply: "
1047 "error saving server identifier.");
1052 if (client_id
->buffer
!= NULL
) {
1053 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1055 (unsigned char *)client_id
->data
,
1058 log_error("start_reply: error saving "
1059 "client identifier.");
1065 * If the client accepts reconfiguration, let it know that we
1068 * Note: we don't actually do this yet, but DOCSIS requires we
1071 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
1074 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1075 NULL
, (unsigned char *)"", 0,
1076 D6O_RECONF_ACCEPT
, 0)) {
1077 log_error("start_reply: "
1078 "error saving RECONF_ACCEPT option.");
1079 option_state_dereference(opt_state
, MDL
);
1088 * Try to get the IPv6 address the client asked for from the
1091 * addr is the result (should be a pointer to NULL on entry)
1092 * pool is the pool to search in
1093 * requested_addr is the address the client wants
1096 try_client_v6_address(struct iasubopt
**addr
,
1097 struct ipv6_pool
*pool
,
1098 const struct data_string
*requested_addr
)
1100 struct in6_addr tmp_addr
;
1101 isc_result_t result
;
1103 if (requested_addr
->len
< sizeof(tmp_addr
)) {
1104 return DHCP_R_INVALIDARG
;
1106 memcpy(&tmp_addr
, requested_addr
->data
, sizeof(tmp_addr
));
1107 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
)) {
1108 return ISC_R_FAILURE
;
1112 * The address is not covered by this (or possibly any) dynamic
1115 if (!ipv6_in_pool(&tmp_addr
, pool
)) {
1116 return ISC_R_ADDRNOTAVAIL
;
1119 if (lease6_exists(pool
, &tmp_addr
)) {
1120 return ISC_R_ADDRINUSE
;
1123 result
= iasubopt_allocate(addr
, MDL
);
1124 if (result
!= ISC_R_SUCCESS
) {
1127 (*addr
)->addr
= tmp_addr
;
1130 /* Default is soft binding for 2 minutes. */
1131 result
= add_lease6(pool
, *addr
, cur_time
+ 120);
1132 if (result
!= ISC_R_SUCCESS
) {
1133 iasubopt_dereference(addr
, MDL
);
1141 * \brief Get an IPv6 address for the client.
1143 * Attempt to find a usable address for the client. We walk through
1144 * the ponds checking for permit and deny then through the pools
1145 * seeing if they have an available address.
1147 * \param reply = the state structure for the current work on this request
1148 * if we create a lease we return it using reply->lease
1151 * ISC_R_SUCCESS = we were able to find an address and are returning a
1152 * pointer to the lease
1153 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1154 * is probabalistic. We don't exhaustively try the
1155 * address range, instead we hash the duid and if
1156 * the address derived from the hash is in use we
1157 * hash the address. After a number of failures we
1158 * conclude the pool is basically full.
1161 pick_v6_address(struct reply_state
*reply
)
1163 struct ipv6_pool
*p
= NULL
;
1164 struct ipv6_pond
*pond
;
1167 unsigned int attempts
;
1168 char tmp_buf
[INET6_ADDRSTRLEN
];
1169 struct iasubopt
**addr
= &reply
->lease
;
1170 isc_uint64_t total
= 0;
1171 isc_uint64_t active
= 0;
1172 isc_uint64_t abandoned
= 0;
1173 int jumbo_range
= 0;
1174 char *shared_name
= (reply
->shared
->name
?
1175 reply
->shared
->name
: "(no name)");
1178 * Do a quick walk through of the ponds and pools
1179 * to see if we have any NA address pools
1181 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1182 if (pond
->ipv6_pools
== NULL
)
1185 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1186 if (p
->pool_type
== D6O_IA_NA
)
1193 /* If we get here and p is NULL we have no useful pools */
1195 log_debug("Unable to pick client address: "
1196 "no IPv6 pools on this shared network");
1197 return ISC_R_NORESOURCES
;
1201 * We have at least one pool that could provide an address
1202 * Now we walk through the ponds and pools again and check
1203 * to see if the client is permitted and if an address is
1206 * Within a given pond we start looking at the last pool we
1207 * allocated from, unless it had a collision trying to allocate
1208 * an address. This will tend to move us into less-filled pools.
1211 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1212 isc_result_t result
= ISC_R_FAILURE
;
1214 if (((pond
->prohibit_list
!= NULL
) &&
1215 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1216 ((pond
->permit_list
!= NULL
) &&
1217 (!permitted(reply
->packet
, pond
->permit_list
))))
1220 start_pool
= pond
->last_ipv6_pool
;
1223 p
= pond
->ipv6_pools
[i
];
1224 if (p
->pool_type
== D6O_IA_NA
) {
1225 result
= create_lease6(p
, addr
, &attempts
,
1226 &reply
->ia
->iaid_duid
,
1228 if (result
== ISC_R_SUCCESS
) {
1230 * Record the pool used (or next one if
1231 * there was a collision).
1235 if (pond
->ipv6_pools
[i
]
1241 pond
->last_ipv6_pool
= i
;
1243 log_debug("Picking pool address %s",
1246 tmp_buf
, sizeof(tmp_buf
)));
1247 return (ISC_R_SUCCESS
);
1252 if (pond
->ipv6_pools
[i
] == NULL
) {
1255 } while (i
!= start_pool
);
1257 if (result
== ISC_R_NORESOURCES
) {
1258 jumbo_range
+= pond
->jumbo_range
;
1259 total
+= pond
->num_total
;
1260 active
+= pond
->num_active
;
1261 abandoned
+= pond
->num_abandoned
;
1266 * If we failed to pick an IPv6 address from any of the subnets.
1267 * Presumably that means we have no addresses for the client.
1269 if (jumbo_range
!= 0) {
1270 log_debug("Unable to pick client address: "
1271 "no addresses available - shared network %s: "
1272 " 2^64-1 < total, %llu active, %llu abandoned",
1273 shared_name
, active
- abandoned
, abandoned
);
1275 log_debug("Unable to pick client address: "
1276 "no addresses available - shared network %s: "
1277 "%llu total, %llu active, %llu abandoned",
1278 shared_name
, total
, active
- abandoned
, abandoned
);
1281 return ISC_R_NORESOURCES
;
1285 * Try to get the IPv6 prefix the client asked for from the
1288 * pref is the result (should be a pointer to NULL on entry)
1289 * pool is the prefix pool to search in
1290 * requested_pref is the address the client wants
1293 try_client_v6_prefix(struct iasubopt
**pref
,
1294 struct ipv6_pool
*pool
,
1295 const struct data_string
*requested_pref
)
1298 struct in6_addr tmp_pref
;
1300 isc_result_t result
;
1302 if (requested_pref
->len
< sizeof(tmp_plen
) + sizeof(tmp_pref
)) {
1303 return DHCP_R_INVALIDARG
;
1305 tmp_plen
= (int) requested_pref
->data
[0];
1306 if ((tmp_plen
< 3) || (tmp_plen
> 128) ||
1307 ((int)tmp_plen
!= pool
->units
)) {
1308 return ISC_R_FAILURE
;
1310 memcpy(&tmp_pref
, requested_pref
->data
+ 1, sizeof(tmp_pref
));
1311 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref
)) {
1312 return ISC_R_FAILURE
;
1315 memcpy(&ia
.iabuf
, &tmp_pref
, 16);
1316 if (!is_cidr_mask_valid(&ia
, (int) tmp_plen
)) {
1317 return ISC_R_FAILURE
;
1320 if (!ipv6_in_pool(&tmp_pref
, pool
)) {
1321 return ISC_R_ADDRNOTAVAIL
;
1324 if (prefix6_exists(pool
, &tmp_pref
, tmp_plen
)) {
1325 return ISC_R_ADDRINUSE
;
1328 result
= iasubopt_allocate(pref
, MDL
);
1329 if (result
!= ISC_R_SUCCESS
) {
1332 (*pref
)->addr
= tmp_pref
;
1333 (*pref
)->plen
= tmp_plen
;
1335 /* Default is soft binding for 2 minutes. */
1336 result
= add_lease6(pool
, *pref
, cur_time
+ 120);
1337 if (result
!= ISC_R_SUCCESS
) {
1338 iasubopt_dereference(pref
, MDL
);
1345 * \brief Get an IPv6 prefix for the client.
1347 * Attempt to find a usable prefix for the client. Based upon the prefix
1348 * length mode and the plen supplied by the client (if one), we make one
1349 * or more calls to pick_v6_prefix_helper() to find a prefix as follows:
1351 * PLM_IGNORE or client specifies a plen of zero, use the first available
1352 * prefix regardless of it's length.
1354 * PLM_PREFER – look for an exact match to client's plen first, if none
1355 * found, use the first available prefix of any length
1357 * PLM_EXACT – look for an exact match first, if none found then fail. This
1358 * is the default behavior.
1360 * PLM_MAXIMUM - look for an exact match first, then the first available whose
1361 * prefix length is less than client's plen, otherwise fail.
1363 * PLM_MINIMUM - look for an exact match first, then the first available whose
1364 * prefix length is greater than client's plen, otherwise fail.
1366 * Note that the selection mode is configurable at the global scope only via
1369 * \param reply = the state structure for the current work on this request
1370 * if we create a lease we return it using reply->lease
1373 * ISC_R_SUCCESS = we were able to find an prefix and are returning a
1374 * pointer to the lease
1375 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1376 * is probabalistic. We don't exhaustively try the
1377 * address range, instead we hash the duid and if
1378 * the address derived from the hash is in use we
1379 * hash the address. After a number of failures we
1380 * conclude the pool is basically full.
1383 pick_v6_prefix(struct reply_state
*reply
) {
1384 struct ipv6_pool
*p
= NULL
;
1385 struct ipv6_pond
*pond
;
1387 isc_result_t result
;
1390 * Do a quick walk through of the ponds and pools
1391 * to see if we have any prefix pools
1393 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1394 if (pond
->ipv6_pools
== NULL
)
1397 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1398 if (p
->pool_type
== D6O_IA_PD
)
1405 /* If we get here and p is NULL we have no useful pools */
1407 log_debug("Unable to pick client prefix: "
1408 "no IPv6 pools on this shared network");
1409 return ISC_R_NORESOURCES
;
1412 if (reply
->preflen
<= 0) {
1413 /* If we didn't get a plen (-1) or client plen is 0, then just
1414 * select first available (same as PLM_INGORE) */
1415 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1417 switch (prefix_length_mode
) {
1419 /* First we look for an exact match, if not found
1420 * then first available */
1421 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1422 if (result
!= ISC_R_SUCCESS
) {
1423 result
= pick_v6_prefix_helper(reply
,
1429 /* Match exactly or fail */
1430 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1435 /* First we look for an exact match, if not found
1436 * then first available by mode */
1437 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1438 if (result
!= ISC_R_SUCCESS
) {
1439 result
= pick_v6_prefix_helper(reply
,
1440 prefix_length_mode
);
1445 /* First available */
1446 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1451 if (result
== ISC_R_SUCCESS
) {
1452 char tmp_buf
[INET6_ADDRSTRLEN
];
1454 log_debug("Picking pool prefix %s/%u",
1455 inet_ntop(AF_INET6
, &(reply
->lease
->addr
),
1456 tmp_buf
, sizeof(tmp_buf
)),
1457 (unsigned)(reply
->lease
->plen
));
1458 return (ISC_R_SUCCESS
);
1462 * If we failed to pick an IPv6 prefix
1463 * Presumably that means we have no prefixes for the client.
1465 log_debug("Unable to pick client prefix: no prefixes available");
1466 return ISC_R_NORESOURCES
;
1471 * \brief Get an IPv6 prefix for the client based upon selection mode.
1473 * We walk through the ponds checking for permit and deny. If a pond is
1474 * permissable to use, loop through its PD pools checking prefix lengths
1475 * against the client plen based on the prefix length mode, looking for
1476 * available prefixes.
1478 * \param reply = the state structure for the current work on this request
1479 * if we create a lease we return it using reply->lease
1480 * \prefix_mode = selection mode to use
1483 * ISC_R_SUCCESS = we were able to find a prefix and are returning a
1484 * pointer to the lease
1485 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1486 * is probabalistic. We don't exhaustively try the
1487 * address range, instead we hash the duid and if
1488 * the address derived from the hash is in use we
1489 * hash the address. After a number of failures we
1490 * conclude the pool is basically full.
1493 pick_v6_prefix_helper(struct reply_state
*reply
, int prefix_mode
) {
1494 struct ipv6_pool
*p
= NULL
;
1495 struct ipv6_pond
*pond
;
1497 unsigned int attempts
;
1498 struct iasubopt
**pref
= &reply
->lease
;
1500 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1501 if (((pond
->prohibit_list
!= NULL
) &&
1502 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1503 ((pond
->permit_list
!= NULL
) &&
1504 (!permitted(reply
->packet
, pond
->permit_list
))))
1507 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1508 if ((p
->pool_type
== D6O_IA_PD
) &&
1509 (eval_prefix_mode(p
->units
, reply
->preflen
,
1510 prefix_mode
) == 1) &&
1511 (create_prefix6(p
, pref
, &attempts
,
1512 &reply
->ia
->iaid_duid
,
1513 cur_time
+ 120) == ISC_R_SUCCESS
)) {
1514 return (ISC_R_SUCCESS
);
1519 return ISC_R_NORESOURCES
;
1524 * \brief Test a prefix length against another based on prefix length mode
1526 * \param len - prefix length to test
1527 * \param preflen - preferred prefix length against which to test
1528 * \param prefix_mode - prefix selection mode with which to test
1530 * Note that the case of preferred length of 0 is not short-cut here as it
1531 * is assumed to be done at a higher level.
1533 * \return 1 if the given length is usable based upon mode and a preferred
1537 eval_prefix_mode(int len
, int preflen
, int prefix_mode
) {
1539 switch (prefix_mode
) {
1541 use_it
= (len
== preflen
);
1544 /* they asked for a prefix length no "shorter" than preflen */
1545 use_it
= (len
>= preflen
);
1548 /* they asked for a prefix length no "longer" than preflen */
1549 use_it
= (len
<= preflen
);
1552 /* otherwise use it */
1557 log_debug("eval_prefix_mode: "
1558 "len %d, preflen %d, mode %s, use_it %d",
1560 prefix_length_modes
.values
[prefix_mode
].name
, use_it
);
1567 *! \file server/dhcpv6.c
1569 * \brief construct a reply containing information about a client's lease
1571 * lease_to_client() is called from several messages to construct a
1572 * reply that contains all that we know about the client's correct lease
1573 * (or projected lease).
1575 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1576 * send what we "may" give them on a request.
1578 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1579 * the client should really use).
1581 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1582 * Rebind out any "wrong" addresses the client sends. This means we send
1583 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1584 * possibly send the address with zeroed lifetimes.
1586 * Information-Request - No binding.
1588 * The basic structure is to traverse the client-supplied data first, and
1589 * validate and echo back any contents that can be. If the client-supplied
1590 * data does not error out (on renew/rebind as above), but we did not send
1591 * any addresses, attempt to allocate one.
1593 * At the end of the this function we call commit_leases_timed() to
1594 * fsync and rotate the file as necessary. commit_leases_timed() will
1595 * check that we have written at least one lease to the file and that
1596 * some time has passed before doing any fsync or file rewrite so we
1597 * don't bother tracking if we did a write_ia during this function.
1599 /* TODO: look at client hints for lease times */
1602 lease_to_client(struct data_string
*reply_ret
,
1603 struct packet
*packet
,
1604 const struct data_string
*client_id
,
1605 const struct data_string
*server_id
)
1607 static struct reply_state reply
;
1608 struct option_cache
*oc
;
1609 struct data_string packet_oro
;
1612 memset(&packet_oro
, 0, sizeof(packet_oro
));
1614 /* Locate the client. */
1615 if (shared_network_from_packet6(&reply
.shared
,
1616 packet
) != ISC_R_SUCCESS
)
1620 * Initialize the reply.
1622 packet_reference(&reply
.packet
, packet
, MDL
);
1623 data_string_copy(&reply
.client_id
, client_id
, MDL
);
1625 if (!start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
1629 /* Set the write cursor to just past the reply header. */
1630 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1633 * Get the ORO from the packet, if any.
1635 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ORO
);
1637 if (!evaluate_option_cache(&packet_oro
, packet
,
1639 packet
->options
, NULL
,
1640 &global_scope
, oc
, MDL
)) {
1641 log_error("lease_to_client: error evaluating ORO.");
1647 * Find a host record that matches the packet, if any, and is
1648 * valid for the shared network the client is on.
1650 if (find_hosts6(&reply
.host
, packet
, client_id
, MDL
)) {
1652 seek_shared_host(&reply
.host
, reply
.shared
);
1655 /* Process the client supplied IA's onto the reply buffer. */
1657 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
1659 for (; oc
!= NULL
; oc
= oc
->next
) {
1660 isc_result_t status
;
1662 /* Start counting resources (addresses) offered. */
1663 reply
.client_resources
= 0;
1664 reply
.resources_included
= ISC_FALSE
;
1666 status
= reply_process_ia_na(&reply
, oc
);
1669 * We continue to try other IA's whether we can address
1670 * this one or not. Any other result is an immediate fail.
1672 if ((status
!= ISC_R_SUCCESS
) &&
1673 (status
!= ISC_R_NORESOURCES
))
1676 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
1677 for (; oc
!= NULL
; oc
= oc
->next
) {
1678 isc_result_t status
;
1680 /* Start counting resources (addresses) offered. */
1681 reply
.client_resources
= 0;
1682 reply
.resources_included
= ISC_FALSE
;
1684 status
= reply_process_ia_ta(&reply
, oc
);
1687 * We continue to try other IA's whether we can address
1688 * this one or not. Any other result is an immediate fail.
1690 if ((status
!= ISC_R_SUCCESS
) &&
1691 (status
!= ISC_R_NORESOURCES
))
1695 /* Same for IA_PD's. */
1697 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
1698 for (; oc
!= NULL
; oc
= oc
->next
) {
1699 isc_result_t status
;
1701 /* Start counting resources (prefixes) offered. */
1702 reply
.client_resources
= 0;
1703 reply
.resources_included
= ISC_FALSE
;
1705 status
= reply_process_ia_pd(&reply
, oc
);
1708 * We continue to try other IA_PD's whether we can address
1709 * this one or not. Any other result is an immediate fail.
1711 if ((status
!= ISC_R_SUCCESS
) &&
1712 (status
!= ISC_R_NORESOURCES
))
1717 * Make no reply if we gave no resources and is not
1718 * for Information-Request.
1720 if ((reply
.ia_count
== 0) && (reply
.pd_count
== 0)) {
1721 if (reply
.packet
->dhcpv6_msg_type
!=
1722 DHCPV6_INFORMATION_REQUEST
)
1726 * Because we only execute statements on a per-IA basis,
1727 * we need to execute statements in any non-IA reply to
1728 * source configuration.
1730 execute_statements_in_scope(NULL
, reply
.packet
, NULL
, NULL
,
1731 reply
.packet
->options
,
1732 reply
.opt_state
, &global_scope
,
1733 reply
.shared
->group
, root_group
,
1736 /* Execute statements from class scopes. */
1737 for (i
= reply
.packet
->class_count
; i
> 0; i
--) {
1738 execute_statements_in_scope(NULL
, reply
.packet
,
1740 reply
.packet
->options
,
1743 reply
.packet
->classes
[i
- 1]->group
,
1744 reply
.shared
->group
, NULL
);
1747 /* Bring in any configuration from a host record. */
1748 if (reply
.host
!= NULL
)
1749 execute_statements_in_scope(NULL
, reply
.packet
,
1751 reply
.packet
->options
,
1755 reply
.shared
->group
, NULL
);
1759 * RFC3315 section 17.2.2 (Solicit):
1761 * If the server will not assign any addresses to any IAs in a
1762 * subsequent Request from the client, the server MUST send an
1763 * Advertise message to the client that includes only a Status
1764 * Code option with code NoAddrsAvail and a status message for
1765 * the user, a Server Identifier option with the server's DUID,
1766 * and a Client Identifier option with the client's DUID.
1768 * This has been updated by an errata such that the server
1769 * can always send an IA.
1771 * Section 18.2.1 (Request):
1773 * If the server cannot assign any addresses to an IA in the
1774 * message from the client, the server MUST include the IA in
1775 * the Reply message with no addresses in the IA and a Status
1776 * Code option in the IA containing status code NoAddrsAvail.
1778 * Section 18.1.8 (Client Behavior):
1780 * Leave unchanged any information about addresses the client has
1781 * recorded in the IA but that were not included in the IA from
1783 * Sends a Renew/Rebind if the IA is not in the Reply message.
1787 * Having stored the client's IA's, store any options that
1788 * will fit in the remaining space.
1790 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+ reply
.cursor
,
1791 sizeof(reply
.buf
) - reply
.cursor
,
1792 reply
.opt_state
, reply
.packet
,
1793 required_opts_solicit
,
1796 /* Return our reply to the caller. */
1797 reply_ret
->len
= reply
.cursor
;
1798 reply_ret
->buffer
= NULL
;
1799 if (!buffer_allocate(&reply_ret
->buffer
, reply
.cursor
, MDL
)) {
1800 log_fatal("No memory to store Reply.");
1802 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
, reply
.cursor
);
1803 reply_ret
->data
= reply_ret
->buffer
->data
;
1805 /* If appropriate commit and rotate the lease file */
1806 (void) commit_leases_timed();
1810 if (reply
.shared
!= NULL
)
1811 shared_network_dereference(&reply
.shared
, MDL
);
1812 if (reply
.host
!= NULL
)
1813 host_dereference(&reply
.host
, MDL
);
1814 if (reply
.opt_state
!= NULL
)
1815 option_state_dereference(&reply
.opt_state
, MDL
);
1816 if (reply
.packet
!= NULL
)
1817 packet_dereference(&reply
.packet
, MDL
);
1818 if (reply
.client_id
.data
!= NULL
)
1819 data_string_forget(&reply
.client_id
, MDL
);
1820 if (packet_oro
.buffer
!= NULL
)
1821 data_string_forget(&packet_oro
, MDL
);
1822 reply
.renew
= reply
.rebind
= reply
.min_prefer
= reply
.min_valid
= 0;
1826 /* Process a client-supplied IA_NA. This may append options to the tail of
1827 * the reply packet being built in the reply_state structure.
1830 reply_process_ia_na(struct reply_state
*reply
, struct option_cache
*ia
) {
1831 isc_result_t status
= ISC_R_SUCCESS
;
1834 struct option_state
*packet_ia
;
1835 struct option_cache
*oc
;
1836 struct data_string ia_data
, data
;
1838 /* Initialize values that will get cleaned up on return. */
1840 memset(&ia_data
, 0, sizeof(ia_data
));
1841 memset(&data
, 0, sizeof(data
));
1843 * Note that find_client_address() may set reply->lease.
1846 /* Make sure there is at least room for the header. */
1847 if ((reply
->cursor
+ IA_NA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
1848 log_error("reply_process_ia_na: Reply too long for IA.");
1849 return ISC_R_NOSPACE
;
1853 /* Fetch the IA_NA contents. */
1854 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
1855 ia
, IA_NA_OFFSET
)) {
1856 log_error("reply_process_ia_na: error evaluating ia");
1857 status
= ISC_R_FAILURE
;
1861 /* Extract IA_NA header contents. */
1862 iaid
= getULong(ia_data
.data
);
1863 reply
->renew
= getULong(ia_data
.data
+ 4);
1864 reply
->rebind
= getULong(ia_data
.data
+ 8);
1866 /* Create an IA_NA structure. */
1867 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
1868 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
1869 log_error("reply_process_ia_na: no memory for ia.");
1870 status
= ISC_R_NOMEMORY
;
1873 reply
->ia
->ia_type
= D6O_IA_NA
;
1875 /* Cache pre-existing IA, if any. */
1876 ia_hash_lookup(&reply
->old_ia
, ia_na_active
,
1877 (unsigned char *)reply
->ia
->iaid_duid
.data
,
1878 reply
->ia
->iaid_duid
.len
, MDL
);
1881 * Create an option cache to carry the IA_NA option contents, and
1882 * execute any user-supplied values into it.
1884 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
1885 status
= ISC_R_NOMEMORY
;
1889 /* Check & cache the fixed host record. */
1890 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_addr
!= NULL
)) {
1891 struct iaddr tmp_addr
;
1893 if (!evaluate_option_cache(&reply
->fixed
, NULL
, NULL
, NULL
,
1894 NULL
, NULL
, &global_scope
,
1895 reply
->host
->fixed_addr
, MDL
)) {
1896 log_error("reply_process_ia_na: unable to evaluate "
1898 status
= ISC_R_FAILURE
;
1902 if (reply
->fixed
.len
< 16) {
1903 log_error("reply_process_ia_na: invalid fixed address.");
1904 status
= DHCP_R_INVALIDARG
;
1908 /* Find the static lease's subnet. */
1910 memcpy(tmp_addr
.iabuf
, reply
->fixed
.data
, 16);
1912 if (find_grouped_subnet(&reply
->subnet
, reply
->shared
,
1913 tmp_addr
, MDL
) == 0)
1914 log_fatal("Impossible condition at %s:%d.", MDL
);
1916 reply
->static_lease
= ISC_TRUE
;
1918 reply
->static_lease
= ISC_FALSE
;
1921 * Save the cursor position at the start of the IA, so we can
1922 * set length and adjust t1/t2 values later. We write a temporary
1923 * header out now just in case we decide to adjust the packet
1924 * within sub-process functions.
1926 ia_cursor
= reply
->cursor
;
1928 /* Initialize the IA_NA header. First the code. */
1929 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_NA
);
1932 /* Then option length. */
1933 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
1936 /* Then IA_NA header contents; IAID. */
1937 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
1940 /* We store the client's t1 for now, and may over-ride it later. */
1941 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
1944 /* We store the client's t2 for now, and may over-ride it later. */
1945 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
1949 * For each address in this IA_NA, decide what to do about it.
1953 * The client leaves unchanged any information about addresses
1954 * it has recorded but are not included ("cancel/break" below).
1955 * A not included IA ("cleanup" below) could give a Renew/Rebind.
1957 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
1958 reply
->min_valid
= reply
->min_prefer
= 0xffffffff;
1959 reply
->client_valid
= reply
->client_prefer
= 0;
1960 for (; oc
!= NULL
; oc
= oc
->next
) {
1961 status
= reply_process_addr(reply
, oc
);
1964 * Canceled means we did not allocate addresses to the
1965 * client, but we're "done" with this IA - we set a status
1966 * code. So transmit this reply, e.g., move on to the next
1969 if (status
== ISC_R_CANCELED
)
1972 if ((status
!= ISC_R_SUCCESS
) &&
1973 (status
!= ISC_R_ADDRINUSE
) &&
1974 (status
!= ISC_R_ADDRNOTAVAIL
))
1981 * If we fell through the above and never gave the client
1982 * an address, give it one now.
1984 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
1985 status
= find_client_address(reply
);
1987 if (status
== ISC_R_NORESOURCES
) {
1988 switch (reply
->packet
->dhcpv6_msg_type
) {
1989 case DHCPV6_SOLICIT
:
1991 * No address for any IA is handled
1996 case DHCPV6_REQUEST
:
1997 /* Section 18.2.1 (Request):
1999 * If the server cannot assign any addresses to
2000 * an IA in the message from the client, the
2001 * server MUST include the IA in the Reply
2002 * message with no addresses in the IA and a
2003 * Status Code option in the IA containing
2004 * status code NoAddrsAvail.
2006 option_state_dereference(&reply
->reply_ia
, MDL
);
2007 if (!option_state_allocate(&reply
->reply_ia
,
2010 log_error("reply_process_ia_na: No "
2011 "memory for option state "
2013 status
= ISC_R_NOMEMORY
;
2017 if (!set_status_code(STATUS_NoAddrsAvail
,
2018 "No addresses available "
2019 "for this interface.",
2021 log_error("reply_process_ia_na: Unable "
2022 "to set NoAddrsAvail status "
2024 status
= ISC_R_FAILURE
;
2028 status
= ISC_R_SUCCESS
;
2033 * RFC 3315 does not tell us to emit a status
2034 * code in this condition, or anything else.
2036 * If we included non-allocated addresses
2037 * (zeroed lifetimes) in an IA, then the client
2038 * will deconfigure them.
2040 * So we want to include the IA even if we
2041 * can't give it a new address if it includes
2042 * zeroed lifetime addresses.
2044 * We don't want to include the IA if we
2045 * provide zero addresses including zeroed
2048 if (reply
->resources_included
)
2049 status
= ISC_R_SUCCESS
;
2056 if (status
!= ISC_R_SUCCESS
)
2060 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2061 sizeof(reply
->buf
) - reply
->cursor
,
2062 reply
->reply_ia
, reply
->packet
,
2063 required_opts_IA
, NULL
);
2065 /* Reset the length of this IA to match what was just written. */
2066 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2067 reply
->cursor
- (ia_cursor
+ 4));
2069 /* Calculate T1/T2 and stuff them in the reply */
2070 set_reply_tee_times(reply
, ia_cursor
);
2073 * yes, goto's aren't the best but we also want to avoid extra
2076 if (status
== ISC_R_CANCELED
)
2080 * Handle static leases, we always log stuff and if it's
2081 * a hard binding we run any commit statements that we have
2083 if (reply
->static_lease
) {
2084 char tmp_addr
[INET6_ADDRSTRLEN
];
2085 log_info("%s NA: address %s to client with duid %s iaid = %d "
2087 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2088 inet_ntop(AF_INET6
, reply
->fixed
.data
, tmp_addr
,
2090 print_hex_1(reply
->client_id
.len
,
2091 reply
->client_id
.data
, 60),
2094 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
2095 (reply
->on_star
.on_commit
!= NULL
)) {
2096 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
2097 reply
->packet
->options
,
2098 reply
->opt_state
, NULL
,
2099 reply
->on_star
.on_commit
, NULL
);
2100 executable_statement_dereference
2101 (&reply
->on_star
.on_commit
, MDL
);
2107 * If we have any addresses log what we are doing.
2109 if (reply
->ia
->num_iasubopt
!= 0) {
2110 struct iasubopt
*tmp
;
2112 char tmp_addr
[INET6_ADDRSTRLEN
];
2114 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2115 tmp
= reply
->ia
->iasubopt
[i
];
2117 log_info("%s NA: address %s to client with duid %s "
2118 "iaid = %d valid for %u seconds",
2119 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2120 inet_ntop(AF_INET6
, &tmp
->addr
,
2121 tmp_addr
, sizeof(tmp_addr
)),
2122 print_hex_1(reply
->client_id
.len
,
2123 reply
->client_id
.data
, 60),
2129 * If this is not a 'soft' binding, consume the new changes into
2130 * the database (if any have been attached to the ia_na).
2132 * Loop through the assigned dynamic addresses, referencing the
2133 * leases onto this IA_NA rather than any old ones, and updating
2134 * pool timers for each (if any).
2137 if ((reply
->ia
->num_iasubopt
!= 0) &&
2138 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
2139 struct iasubopt
*tmp
;
2140 struct data_string
*ia_id
;
2143 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2144 tmp
= reply
->ia
->iasubopt
[i
];
2146 if (tmp
->ia
!= NULL
)
2147 ia_dereference(&tmp
->ia
, MDL
);
2148 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2150 /* Commit 'hard' bindings. */
2151 renew_lease6(tmp
->ipv6_pool
, tmp
);
2152 schedule_lease_timeout(tmp
->ipv6_pool
);
2154 /* If we have anything to do on commit do it now */
2155 if (tmp
->on_star
.on_commit
!= NULL
) {
2156 execute_statements(NULL
, reply
->packet
,
2158 reply
->packet
->options
,
2161 tmp
->on_star
.on_commit
,
2163 executable_statement_dereference
2164 (&tmp
->on_star
.on_commit
, MDL
);
2167 #if defined (NSUPDATE)
2169 * Perform ddns updates.
2171 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2174 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2176 reply
->packet
->options
,
2180 ddns_updates(reply
->packet
, NULL
, NULL
,
2181 tmp
, NULL
, reply
->opt_state
);
2184 /* Do our threshold check. */
2185 check_pool6_threshold(reply
, tmp
);
2188 /* Remove any old ia from the hash. */
2189 if (reply
->old_ia
!= NULL
) {
2190 ia_id
= &reply
->old_ia
->iaid_duid
;
2191 ia_hash_delete(ia_na_active
,
2192 (unsigned char *)ia_id
->data
,
2194 ia_dereference(&reply
->old_ia
, MDL
);
2197 /* Put new ia into the hash. */
2198 reply
->ia
->cltt
= cur_time
;
2199 ia_id
= &reply
->ia
->iaid_duid
;
2200 ia_hash_add(ia_na_active
, (unsigned char *)ia_id
->data
,
2201 ia_id
->len
, reply
->ia
, MDL
);
2203 write_ia(reply
->ia
);
2205 schedule_lease_timeout_reply(reply
);
2209 if (packet_ia
!= NULL
)
2210 option_state_dereference(&packet_ia
, MDL
);
2211 if (reply
->reply_ia
!= NULL
)
2212 option_state_dereference(&reply
->reply_ia
, MDL
);
2213 if (ia_data
.data
!= NULL
)
2214 data_string_forget(&ia_data
, MDL
);
2215 if (data
.data
!= NULL
)
2216 data_string_forget(&data
, MDL
);
2217 if (reply
->ia
!= NULL
)
2218 ia_dereference(&reply
->ia
, MDL
);
2219 if (reply
->old_ia
!= NULL
)
2220 ia_dereference(&reply
->old_ia
, MDL
);
2221 if (reply
->lease
!= NULL
)
2222 iasubopt_dereference(&reply
->lease
, MDL
);
2223 if (reply
->fixed
.data
!= NULL
)
2224 data_string_forget(&reply
->fixed
, MDL
);
2225 if (reply
->subnet
!= NULL
)
2226 subnet_dereference(&reply
->subnet
, MDL
);
2227 if (reply
->on_star
.on_expiry
!= NULL
)
2228 executable_statement_dereference
2229 (&reply
->on_star
.on_expiry
, MDL
);
2230 if (reply
->on_star
.on_release
!= NULL
)
2231 executable_statement_dereference
2232 (&reply
->on_star
.on_release
, MDL
);
2235 * ISC_R_CANCELED is a status code used by the addr processing to
2236 * indicate we're replying with a status code. This is still a
2237 * success at higher layers.
2239 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2243 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
2244 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
2245 * in the event we are replying with a status code and do not wish to process
2246 * more IAADDRs within this IA.
2249 reply_process_addr(struct reply_state
*reply
, struct option_cache
*addr
) {
2250 u_int32_t pref_life
, valid_life
;
2251 struct binding_scope
**scope
;
2252 struct group
*group
;
2253 struct subnet
*subnet
;
2254 struct iaddr tmp_addr
;
2255 struct option_cache
*oc
;
2256 struct data_string iaaddr
, data
;
2257 isc_result_t status
= ISC_R_SUCCESS
;
2259 /* Initializes values that will be cleaned up. */
2260 memset(&iaaddr
, 0, sizeof(iaaddr
));
2261 memset(&data
, 0, sizeof(data
));
2262 /* Note that reply->lease may be set by address_is_owned() */
2265 * There is no point trying to process an incoming address if there
2266 * is no room for an outgoing address.
2268 if ((reply
->cursor
+ 28) > sizeof(reply
->buf
)) {
2269 log_error("reply_process_addr: Out of room for address.");
2270 return ISC_R_NOSPACE
;
2273 /* Extract this IAADDR option. */
2274 if (!evaluate_option_cache(&iaaddr
, reply
->packet
, NULL
, NULL
,
2275 reply
->packet
->options
, NULL
, &global_scope
,
2277 (iaaddr
.len
< IAADDR_OFFSET
)) {
2278 log_error("reply_process_addr: error evaluating IAADDR.");
2279 status
= ISC_R_FAILURE
;
2283 /* The first 16 bytes are the IPv6 address. */
2284 pref_life
= getULong(iaaddr
.data
+ 16);
2285 valid_life
= getULong(iaaddr
.data
+ 20);
2287 if ((reply
->client_valid
== 0) ||
2288 (reply
->client_valid
> valid_life
))
2289 reply
->client_valid
= valid_life
;
2291 if ((reply
->client_prefer
== 0) ||
2292 (reply
->client_prefer
> pref_life
))
2293 reply
->client_prefer
= pref_life
;
2296 * Clients may choose to send :: as an address, with the idea to give
2297 * hints about preferred-lifetime or valid-lifetime.
2300 memset(tmp_addr
.iabuf
, 0, 16);
2301 if (!memcmp(iaaddr
.data
, tmp_addr
.iabuf
, 16)) {
2302 /* Status remains success; we just ignore this one. */
2306 /* tmp_addr len remains 16 */
2307 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2310 * Verify that this address is on the client's network.
2312 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
2313 subnet
= subnet
->next_sibling
) {
2314 if (addr_eq(subnet_number(tmp_addr
, subnet
->netmask
),
2319 /* Address not found on shared network. */
2320 if (subnet
== NULL
) {
2321 /* Ignore this address on 'soft' bindings. */
2322 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
2323 /* disable rapid commit */
2324 reply
->buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
2325 delete_option(&dhcpv6_universe
,
2328 /* status remains success */
2333 * RFC3315 section 18.2.1:
2335 * If the server finds that the prefix on one or more IP
2336 * addresses in any IA in the message from the client is not
2337 * appropriate for the link to which the client is connected,
2338 * the server MUST return the IA to the client with a Status
2339 * Code option with the value NotOnLink.
2341 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) {
2342 /* Rewind the IA_NA to empty. */
2343 option_state_dereference(&reply
->reply_ia
, MDL
);
2344 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2345 log_error("reply_process_addr: No memory for "
2346 "option state wipe.");
2347 status
= ISC_R_NOMEMORY
;
2351 /* Append a NotOnLink status code. */
2352 if (!set_status_code(STATUS_NotOnLink
,
2353 "Address not for use on this "
2354 "link.", reply
->reply_ia
)) {
2355 log_error("reply_process_addr: Failure "
2356 "setting status code.");
2357 status
= ISC_R_FAILURE
;
2361 /* Fin (no more IAADDRs). */
2362 status
= ISC_R_CANCELED
;
2367 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2369 * If the server finds that any of the addresses are not
2370 * appropriate for the link to which the client is attached,
2371 * the server returns the address to the client with lifetimes
2374 if ((reply
->packet
->dhcpv6_msg_type
!= DHCPV6_RENEW
) &&
2375 (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
2376 log_error("It is impossible to lease a client that is "
2377 "not sending a solicit, request, renew, or "
2379 status
= ISC_R_FAILURE
;
2383 reply
->send_prefer
= reply
->send_valid
= 0;
2387 /* Verify the address belongs to the client. */
2388 if (!address_is_owned(reply
, &tmp_addr
)) {
2390 * For solicit and request, any addresses included are
2391 * 'requested' addresses. For rebind, we actually have
2392 * no direction on what to do from 3315 section 18.2.4!
2393 * So I think the best bet is to try and give it out, and if
2394 * we can't, zero lifetimes.
2396 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
2397 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
2398 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
2399 status
= reply_process_try_addr(reply
, &tmp_addr
);
2402 * If the address is in use, or isn't in any dynamic
2403 * range, continue as normal. If any other error was
2406 if ((status
!= ISC_R_SUCCESS
) &&
2407 (status
!= ISC_R_ADDRINUSE
) &&
2408 (status
!= ISC_R_ADDRNOTAVAIL
))
2412 * If we didn't honor this lease, for solicit and
2413 * request we simply omit it from our answer. For
2414 * rebind, we send it with zeroed lifetimes.
2416 if (reply
->lease
== NULL
) {
2417 if (reply
->packet
->dhcpv6_msg_type
==
2419 reply
->send_prefer
= 0;
2420 reply
->send_valid
= 0;
2424 /* status remains success - ignore */
2428 * RFC3315 section 18.2.3:
2430 * If the server cannot find a client entry for the IA the
2431 * server returns the IA containing no addresses with a Status
2432 * Code option set to NoBinding in the Reply message.
2434 * On mismatch we (ab)use this pretending we have not the IA
2435 * as soon as we have not an address.
2437 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
2438 /* Rewind the IA_NA to empty. */
2439 option_state_dereference(&reply
->reply_ia
, MDL
);
2440 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2441 log_error("reply_process_addr: No memory for "
2442 "option state wipe.");
2443 status
= ISC_R_NOMEMORY
;
2447 /* Append a NoBinding status code. */
2448 if (!set_status_code(STATUS_NoBinding
,
2449 "Address not bound to this "
2450 "interface.", reply
->reply_ia
)) {
2451 log_error("reply_process_addr: Unable to "
2452 "attach status code.");
2453 status
= ISC_R_FAILURE
;
2457 /* Fin (no more IAADDRs). */
2458 status
= ISC_R_CANCELED
;
2461 log_error("It is impossible to lease a client that is "
2462 "not sending a solicit, request, renew, or "
2464 status
= ISC_R_FAILURE
;
2469 if (reply
->static_lease
) {
2470 if (reply
->host
== NULL
)
2471 log_fatal("Impossible condition at %s:%d.", MDL
);
2473 scope
= &global_scope
;
2474 group
= reply
->subnet
->group
;
2476 if (reply
->lease
== NULL
)
2477 log_fatal("Impossible condition at %s:%d.", MDL
);
2479 scope
= &reply
->lease
->scope
;
2480 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
2484 * If client_resources is nonzero, then the reply_process_is_addressed
2485 * function has executed configuration state into the reply option
2486 * cache. We will use that valid cache to derive configuration for
2487 * whether or not to engage in additional addresses, and similar.
2489 if (reply
->client_resources
!= 0) {
2493 * Does this client have "enough" addresses already? Default
2494 * to one. Everybody gets one, and one should be enough for
2497 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2498 SV_LIMIT_ADDRS_PER_IA
);
2500 if (!evaluate_option_cache(&data
, reply
->packet
,
2502 reply
->packet
->options
,
2506 log_error("reply_process_addr: unable to "
2507 "evaluate addrs-per-ia value.");
2508 status
= ISC_R_FAILURE
;
2512 limit
= getULong(data
.data
);
2513 data_string_forget(&data
, MDL
);
2517 * If we wish to limit the client to a certain number of
2518 * addresses, then omit the address from the reply.
2520 if (reply
->client_resources
>= limit
)
2524 status
= reply_process_is_addressed(reply
, scope
, group
);
2525 if (status
!= ISC_R_SUCCESS
)
2529 status
= reply_process_send_addr(reply
, &tmp_addr
);
2532 if (iaaddr
.data
!= NULL
)
2533 data_string_forget(&iaaddr
, MDL
);
2534 if (data
.data
!= NULL
)
2535 data_string_forget(&data
, MDL
);
2536 if (reply
->lease
!= NULL
)
2537 iasubopt_dereference(&reply
->lease
, MDL
);
2543 * Verify the address belongs to the client. If we've got a host
2544 * record with a fixed address, it has to be the assigned address
2545 * (fault out all else). Otherwise it's a dynamic address, so lookup
2546 * that address and make sure it belongs to this DUID:IAID pair.
2548 static isc_boolean_t
2549 address_is_owned(struct reply_state
*reply
, struct iaddr
*addr
) {
2551 struct ipv6_pond
*pond
;
2554 * This faults out addresses that don't match fixed addresses.
2556 if (reply
->static_lease
) {
2557 if (reply
->fixed
.data
== NULL
)
2558 log_fatal("Impossible condition at %s:%d.", MDL
);
2560 if (memcmp(addr
->iabuf
, reply
->fixed
.data
, 16) == 0)
2566 if ((reply
->old_ia
== NULL
) || (reply
->old_ia
->num_iasubopt
== 0))
2569 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2570 struct iasubopt
*tmp
;
2572 tmp
= reply
->old_ia
->iasubopt
[i
];
2574 if (memcmp(addr
->iabuf
, &tmp
->addr
, 16) == 0) {
2575 if (lease6_usable(tmp
) == ISC_FALSE
) {
2579 pond
= tmp
->ipv6_pool
->ipv6_pond
;
2580 if (((pond
->prohibit_list
!= NULL
) &&
2581 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
2582 ((pond
->permit_list
!= NULL
) &&
2583 (!permitted(reply
->packet
, pond
->permit_list
))))
2586 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
2595 /* Process a client-supplied IA_TA. This may append options to the tail of
2596 * the reply packet being built in the reply_state structure.
2599 reply_process_ia_ta(struct reply_state
*reply
, struct option_cache
*ia
) {
2600 isc_result_t status
= ISC_R_SUCCESS
;
2603 struct option_state
*packet_ia
;
2604 struct option_cache
*oc
;
2605 struct data_string ia_data
, data
;
2606 struct data_string iaaddr
;
2607 u_int32_t pref_life
, valid_life
;
2608 struct iaddr tmp_addr
;
2610 /* Initialize values that will get cleaned up on return. */
2612 memset(&ia_data
, 0, sizeof(ia_data
));
2613 memset(&data
, 0, sizeof(data
));
2614 memset(&iaaddr
, 0, sizeof(iaaddr
));
2616 /* Make sure there is at least room for the header. */
2617 if ((reply
->cursor
+ IA_TA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2618 log_error("reply_process_ia_ta: Reply too long for IA.");
2619 return ISC_R_NOSPACE
;
2623 /* Fetch the IA_TA contents. */
2624 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2625 ia
, IA_TA_OFFSET
)) {
2626 log_error("reply_process_ia_ta: error evaluating ia");
2627 status
= ISC_R_FAILURE
;
2631 /* Extract IA_TA header contents. */
2632 iaid
= getULong(ia_data
.data
);
2634 /* Create an IA_TA structure. */
2635 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2636 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2637 log_error("reply_process_ia_ta: no memory for ia.");
2638 status
= ISC_R_NOMEMORY
;
2641 reply
->ia
->ia_type
= D6O_IA_TA
;
2643 /* Cache pre-existing IA, if any. */
2644 ia_hash_lookup(&reply
->old_ia
, ia_ta_active
,
2645 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2646 reply
->ia
->iaid_duid
.len
, MDL
);
2649 * Create an option cache to carry the IA_TA option contents, and
2650 * execute any user-supplied values into it.
2652 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2653 status
= ISC_R_NOMEMORY
;
2658 * Temporary leases are dynamic by definition.
2660 reply
->static_lease
= ISC_FALSE
;
2663 * Save the cursor position at the start of the IA, so we can
2664 * set length later. We write a temporary
2665 * header out now just in case we decide to adjust the packet
2666 * within sub-process functions.
2668 ia_cursor
= reply
->cursor
;
2670 /* Initialize the IA_TA header. First the code. */
2671 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_TA
);
2674 /* Then option length. */
2675 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x04u
);
2678 /* Then IA_TA header contents; IAID. */
2679 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2683 * Deal with an IAADDR for lifetimes.
2684 * For all or none, process IAADDRs as hints.
2686 reply
->min_valid
= reply
->min_prefer
= 0xffffffff;
2687 reply
->client_valid
= reply
->client_prefer
= 0;
2688 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2689 for (; oc
!= NULL
; oc
= oc
->next
) {
2690 memset(&iaaddr
, 0, sizeof(iaaddr
));
2691 if (!evaluate_option_cache(&iaaddr
, reply
->packet
,
2693 reply
->packet
->options
, NULL
,
2694 &global_scope
, oc
, MDL
) ||
2695 (iaaddr
.len
< IAADDR_OFFSET
)) {
2696 log_error("reply_process_ia_ta: error "
2697 "evaluating IAADDR.");
2698 status
= ISC_R_FAILURE
;
2701 /* The first 16 bytes are the IPv6 address. */
2702 pref_life
= getULong(iaaddr
.data
+ 16);
2703 valid_life
= getULong(iaaddr
.data
+ 20);
2705 if ((reply
->client_valid
== 0) ||
2706 (reply
->client_valid
> valid_life
))
2707 reply
->client_valid
= valid_life
;
2709 if ((reply
->client_prefer
== 0) ||
2710 (reply
->client_prefer
> pref_life
))
2711 reply
->client_prefer
= pref_life
;
2713 /* Nothing more if something has failed. */
2714 if (status
== ISC_R_CANCELED
)
2718 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2719 if (!temporary_is_available(reply
, &tmp_addr
))
2721 status
= reply_process_is_addressed(reply
,
2722 &reply
->lease
->scope
,
2723 reply
->lease
->ipv6_pool
->ipv6_pond
->group
);
2724 if (status
!= ISC_R_SUCCESS
)
2726 status
= reply_process_send_addr(reply
, &tmp_addr
);
2727 if (status
!= ISC_R_SUCCESS
)
2729 if (reply
->lease
!= NULL
)
2730 iasubopt_dereference(&reply
->lease
, MDL
);
2734 /* Rewind the IA_TA to empty. */
2735 option_state_dereference(&reply
->reply_ia
, MDL
);
2736 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2737 status
= ISC_R_NOMEMORY
;
2740 status
= ISC_R_CANCELED
;
2741 reply
->client_resources
= 0;
2742 reply
->resources_included
= ISC_FALSE
;
2743 if (reply
->lease
!= NULL
)
2744 iasubopt_dereference(&reply
->lease
, MDL
);
2749 * Give the client temporary addresses.
2751 if (reply
->client_resources
!= 0)
2753 status
= find_client_temporaries(reply
);
2754 if (status
== ISC_R_NORESOURCES
) {
2755 switch (reply
->packet
->dhcpv6_msg_type
) {
2756 case DHCPV6_SOLICIT
:
2758 * No address for any IA is handled
2763 case DHCPV6_REQUEST
:
2764 /* Section 18.2.1 (Request):
2766 * If the server cannot assign any addresses to
2767 * an IA in the message from the client, the
2768 * server MUST include the IA in the Reply
2769 * message with no addresses in the IA and a
2770 * Status Code option in the IA containing
2771 * status code NoAddrsAvail.
2773 option_state_dereference(&reply
->reply_ia
, MDL
);
2774 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2775 log_error("reply_process_ia_ta: No "
2776 "memory for option state wipe.");
2777 status
= ISC_R_NOMEMORY
;
2781 if (!set_status_code(STATUS_NoAddrsAvail
,
2782 "No addresses available "
2783 "for this interface.",
2785 log_error("reply_process_ia_ta: Unable "
2786 "to set NoAddrsAvail status code.");
2787 status
= ISC_R_FAILURE
;
2791 status
= ISC_R_SUCCESS
;
2796 * We don't want to include the IA if we
2797 * provide zero addresses including zeroed
2800 if (reply
->resources_included
)
2801 status
= ISC_R_SUCCESS
;
2806 } else if (status
!= ISC_R_SUCCESS
)
2810 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2811 sizeof(reply
->buf
) - reply
->cursor
,
2812 reply
->reply_ia
, reply
->packet
,
2813 required_opts_IA
, NULL
);
2815 /* Reset the length of this IA to match what was just written. */
2816 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2817 reply
->cursor
- (ia_cursor
+ 4));
2820 * yes, goto's aren't the best but we also want to avoid extra
2823 if (status
== ISC_R_CANCELED
)
2827 * If we have any addresses log what we are doing.
2829 if (reply
->ia
->num_iasubopt
!= 0) {
2830 struct iasubopt
*tmp
;
2832 char tmp_addr
[INET6_ADDRSTRLEN
];
2834 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2835 tmp
= reply
->ia
->iasubopt
[i
];
2837 log_info("%s TA: address %s to client with duid %s "
2838 "iaid = %d valid for %u seconds",
2839 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2840 inet_ntop(AF_INET6
, &tmp
->addr
,
2841 tmp_addr
, sizeof(tmp_addr
)),
2842 print_hex_1(reply
->client_id
.len
,
2843 reply
->client_id
.data
, 60),
2850 * For hard bindings we consume the new changes into
2851 * the database (if any have been attached to the ia_ta).
2853 * Loop through the assigned dynamic addresses, referencing the
2854 * leases onto this IA_TA rather than any old ones, and updating
2855 * pool timers for each (if any).
2857 if ((reply
->ia
->num_iasubopt
!= 0) &&
2858 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
2859 struct iasubopt
*tmp
;
2860 struct data_string
*ia_id
;
2863 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2864 tmp
= reply
->ia
->iasubopt
[i
];
2866 if (tmp
->ia
!= NULL
)
2867 ia_dereference(&tmp
->ia
, MDL
);
2868 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2870 /* Commit 'hard' bindings. */
2871 renew_lease6(tmp
->ipv6_pool
, tmp
);
2872 schedule_lease_timeout(tmp
->ipv6_pool
);
2874 /* If we have anything to do on commit do it now */
2875 if (tmp
->on_star
.on_commit
!= NULL
) {
2876 execute_statements(NULL
, reply
->packet
,
2878 reply
->packet
->options
,
2881 tmp
->on_star
.on_commit
,
2883 executable_statement_dereference
2884 (&tmp
->on_star
.on_commit
, MDL
);
2887 #if defined (NSUPDATE)
2889 * Perform ddns updates.
2891 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2894 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2896 reply
->packet
->options
,
2900 ddns_updates(reply
->packet
, NULL
, NULL
,
2901 tmp
, NULL
, reply
->opt_state
);
2904 /* Do our threshold check. */
2905 check_pool6_threshold(reply
, tmp
);
2908 /* Remove any old ia from the hash. */
2909 if (reply
->old_ia
!= NULL
) {
2910 ia_id
= &reply
->old_ia
->iaid_duid
;
2911 ia_hash_delete(ia_ta_active
,
2912 (unsigned char *)ia_id
->data
,
2914 ia_dereference(&reply
->old_ia
, MDL
);
2917 /* Put new ia into the hash. */
2918 reply
->ia
->cltt
= cur_time
;
2919 ia_id
= &reply
->ia
->iaid_duid
;
2920 ia_hash_add(ia_ta_active
, (unsigned char *)ia_id
->data
,
2921 ia_id
->len
, reply
->ia
, MDL
);
2923 write_ia(reply
->ia
);
2925 schedule_lease_timeout_reply(reply
);
2929 if (packet_ia
!= NULL
)
2930 option_state_dereference(&packet_ia
, MDL
);
2931 if (iaaddr
.data
!= NULL
)
2932 data_string_forget(&iaaddr
, MDL
);
2933 if (reply
->reply_ia
!= NULL
)
2934 option_state_dereference(&reply
->reply_ia
, MDL
);
2935 if (ia_data
.data
!= NULL
)
2936 data_string_forget(&ia_data
, MDL
);
2937 if (data
.data
!= NULL
)
2938 data_string_forget(&data
, MDL
);
2939 if (reply
->ia
!= NULL
)
2940 ia_dereference(&reply
->ia
, MDL
);
2941 if (reply
->old_ia
!= NULL
)
2942 ia_dereference(&reply
->old_ia
, MDL
);
2943 if (reply
->lease
!= NULL
)
2944 iasubopt_dereference(&reply
->lease
, MDL
);
2947 * ISC_R_CANCELED is a status code used by the addr processing to
2948 * indicate we're replying with other addresses. This is still a
2949 * success at higher layers.
2951 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2955 * Verify the temporary address is available.
2957 static isc_boolean_t
2958 temporary_is_available(struct reply_state
*reply
, struct iaddr
*addr
) {
2959 struct in6_addr tmp_addr
;
2960 struct subnet
*subnet
;
2961 struct ipv6_pool
*pool
= NULL
;
2962 struct ipv6_pond
*pond
= NULL
;
2965 memcpy(&tmp_addr
, addr
->iabuf
, sizeof(tmp_addr
));
2967 * Clients may choose to send :: as an address, with the idea to give
2968 * hints about preferred-lifetime or valid-lifetime.
2969 * So this is not a request for this address.
2971 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
))
2975 * Verify that this address is on the client's network.
2977 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
2978 subnet
= subnet
->next_sibling
) {
2979 if (addr_eq(subnet_number(*addr
, subnet
->netmask
),
2984 /* Address not found on shared network. */
2989 * Check if this address is owned (must be before next step).
2991 if (address_is_owned(reply
, addr
))
2995 * Verify that this address is in a temporary pool and try to get it.
2997 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
2998 if (((pond
->prohibit_list
!= NULL
) &&
2999 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3000 ((pond
->permit_list
!= NULL
) &&
3001 (!permitted(reply
->packet
, pond
->permit_list
))))
3004 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3005 if (pool
->pool_type
!= D6O_IA_TA
)
3008 if (ipv6_in_pool(&tmp_addr
, pool
))
3018 if (lease6_exists(pool
, &tmp_addr
))
3020 if (iasubopt_allocate(&reply
->lease
, MDL
) != ISC_R_SUCCESS
)
3022 reply
->lease
->addr
= tmp_addr
;
3023 reply
->lease
->plen
= 0;
3024 /* Default is soft binding for 2 minutes. */
3025 if (add_lease6(pool
, reply
->lease
, cur_time
+ 120) != ISC_R_SUCCESS
)
3032 * Get a temporary address per prefix.
3035 find_client_temporaries(struct reply_state
*reply
) {
3037 struct ipv6_pool
*p
= NULL
;
3038 struct ipv6_pond
*pond
;
3039 isc_result_t status
= ISC_R_NORESOURCES
;;
3040 unsigned int attempts
;
3041 struct iaddr send_addr
;
3044 * Do a quick walk through of the ponds and pools
3045 * to see if we have any prefix pools
3047 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3048 if (pond
->ipv6_pools
== NULL
)
3051 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3052 if (p
->pool_type
== D6O_IA_TA
)
3059 /* If we get here and p is NULL we have no useful pools */
3061 log_debug("Unable to get client addresses: "
3062 "no IPv6 pools on this shared network");
3063 return ISC_R_NORESOURCES
;
3067 * We have at least one pool that could provide an address
3068 * Now we walk through the ponds and pools again and check
3069 * to see if the client is permitted and if an address is
3073 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3074 if (((pond
->prohibit_list
!= NULL
) &&
3075 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3076 ((pond
->permit_list
!= NULL
) &&
3077 (!permitted(reply
->packet
, pond
->permit_list
))))
3080 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3081 if (p
->pool_type
!= D6O_IA_TA
) {
3086 * Get an address in this temporary pool.
3088 status
= create_lease6(p
, &reply
->lease
, &attempts
,
3089 &reply
->client_id
, cur_time
+ 120);
3090 if (status
!= ISC_R_SUCCESS
) {
3091 log_debug("Unable to get a temporary address.");
3095 status
= reply_process_is_addressed(reply
,
3096 &reply
->lease
->scope
,
3098 if (status
!= ISC_R_SUCCESS
) {
3102 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3103 status
= reply_process_send_addr(reply
, &send_addr
);
3104 if (status
!= ISC_R_SUCCESS
) {
3108 * reply->lease can't be null as we use it above
3109 * add check if that changes
3111 iasubopt_dereference(&reply
->lease
, MDL
);
3116 if (reply
->lease
!= NULL
) {
3117 iasubopt_dereference(&reply
->lease
, MDL
);
3123 * This function only returns failure on 'hard' failures. If it succeeds,
3124 * it will leave a lease structure behind.
3127 reply_process_try_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3128 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
3129 struct ipv6_pool
*pool
= NULL
;
3130 struct ipv6_pond
*pond
= NULL
;
3132 struct data_string data_addr
;
3134 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
3135 (addr
== NULL
) || (reply
->lease
!= NULL
))
3136 return (DHCP_R_INVALIDARG
);
3139 * Do a quick walk through of the ponds and pools
3140 * to see if we have any NA address pools
3142 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3143 if (pond
->ipv6_pools
== NULL
)
3146 for (i
= 0; ; i
++) {
3147 pool
= pond
->ipv6_pools
[i
];
3148 if ((pool
== NULL
) ||
3149 (pool
->pool_type
== D6O_IA_NA
))
3156 /* If we get here and p is NULL we have no useful pools */
3158 return (ISC_R_ADDRNOTAVAIL
);
3161 memset(&data_addr
, 0, sizeof(data_addr
));
3162 data_addr
.len
= addr
->len
;
3163 data_addr
.data
= addr
->iabuf
;
3166 * We have at least one pool that could provide an address
3167 * Now we walk through the ponds and pools again and check
3168 * to see if the client is permitted and if an address is
3171 * Within a given pond we start looking at the last pool we
3172 * allocated from, unless it had a collision trying to allocate
3173 * an address. This will tend to move us into less-filled pools.
3176 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3177 if (((pond
->prohibit_list
!= NULL
) &&
3178 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3179 ((pond
->permit_list
!= NULL
) &&
3180 (!permitted(reply
->packet
, pond
->permit_list
))))
3183 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3184 if (pool
->pool_type
!= D6O_IA_NA
)
3187 status
= try_client_v6_address(&reply
->lease
, pool
,
3189 if (status
== ISC_R_SUCCESS
)
3193 if (status
== ISC_R_SUCCESS
)
3197 /* Note that this is just pedantry. There is no allocation to free. */
3198 data_string_forget(&data_addr
, MDL
);
3199 /* Return just the most recent status... */
3203 /* Look around for an address to give the client. First, look through the
3204 * old IA for addresses we can extend. Second, try to allocate a new address.
3205 * Finally, actually add that address into the current reply IA.
3208 find_client_address(struct reply_state
*reply
) {
3209 struct iaddr send_addr
;
3210 isc_result_t status
= ISC_R_NORESOURCES
;
3211 struct iasubopt
*lease
, *best_lease
= NULL
;
3212 struct binding_scope
**scope
;
3213 struct group
*group
;
3216 if (reply
->static_lease
) {
3217 if (reply
->host
== NULL
)
3218 return DHCP_R_INVALIDARG
;
3221 memcpy(send_addr
.iabuf
, reply
->fixed
.data
, 16);
3223 scope
= &global_scope
;
3224 group
= reply
->subnet
->group
;
3228 if (reply
->old_ia
!= NULL
) {
3229 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3230 struct shared_network
*candidate_shared
;
3231 struct ipv6_pond
*pond
;
3233 lease
= reply
->old_ia
->iasubopt
[i
];
3234 candidate_shared
= lease
->ipv6_pool
->shared_network
;
3235 pond
= lease
->ipv6_pool
->ipv6_pond
;
3238 * Look for the best lease on the client's shared
3239 * network, that is still permitted
3242 if ((candidate_shared
!= reply
->shared
) ||
3243 (lease6_usable(lease
) != ISC_TRUE
))
3246 if (((pond
->prohibit_list
!= NULL
) &&
3247 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3248 ((pond
->permit_list
!= NULL
) &&
3249 (!permitted(reply
->packet
, pond
->permit_list
))))
3252 best_lease
= lease_compare(lease
, best_lease
);
3256 /* Try to pick a new address if we didn't find one, or if we found an
3259 if ((best_lease
== NULL
) || (best_lease
->state
== FTS_ABANDONED
)) {
3260 status
= pick_v6_address(reply
);
3261 } else if (best_lease
!= NULL
) {
3262 iasubopt_reference(&reply
->lease
, best_lease
, MDL
);
3263 status
= ISC_R_SUCCESS
;
3266 /* Pick the abandoned lease as a last resort. */
3267 if ((status
== ISC_R_NORESOURCES
) && (best_lease
!= NULL
)) {
3268 /* I don't see how this is supposed to be done right now. */
3269 log_error("Best match for DUID %s is an abandoned address,"
3270 " This may be a result of multiple clients attempting"
3271 " to use this DUID",
3272 print_hex_1(reply
->client_id
.len
,
3273 reply
->client_id
.data
, 60));
3274 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
3277 /* Give up now if we didn't find a lease. */
3278 if (status
!= ISC_R_SUCCESS
)
3281 if (reply
->lease
== NULL
)
3282 log_fatal("Impossible condition at %s:%d.", MDL
);
3284 /* Draw binding scopes from the lease's binding scope, and config
3285 * from the lease's containing subnet and higher. Note that it may
3286 * be desirable to place the group attachment directly in the pool.
3288 scope
= &reply
->lease
->scope
;
3289 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
3292 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3295 status
= reply_process_is_addressed(reply
, scope
, group
);
3296 if (status
!= ISC_R_SUCCESS
)
3299 status
= reply_process_send_addr(reply
, &send_addr
);
3303 /* Once an address is found for a client, perform several common functions;
3304 * Calculate and store valid and preferred lease times, draw client options
3305 * into the option state.
3308 reply_process_is_addressed(struct reply_state
*reply
,
3309 struct binding_scope
**scope
, struct group
*group
)
3311 isc_result_t status
= ISC_R_SUCCESS
;
3312 struct data_string data
;
3313 struct option_cache
*oc
;
3314 struct option_state
*tmp_options
= NULL
;
3315 struct on_star
*on_star
;
3318 /* Initialize values we will cleanup. */
3319 memset(&data
, 0, sizeof(data
));
3322 * Find the proper on_star block to use. We use the
3323 * one in the lease if we have a lease or the one in
3324 * the reply if we don't have a lease because this is
3328 on_star
= &reply
->lease
->on_star
;
3330 on_star
= &reply
->on_star
;
3334 * Bring in the root configuration. We only do this to bring
3335 * in the on * statements, as we didn't have the lease available
3336 * we did it the first time.
3338 option_state_allocate(&tmp_options
, MDL
);
3339 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3340 reply
->packet
->options
, tmp_options
,
3341 &global_scope
, root_group
, NULL
,
3343 if (tmp_options
!= NULL
) {
3344 option_state_dereference(&tmp_options
, MDL
);
3348 * Bring configured options into the root packet level cache - start
3349 * with the lease's closest enclosing group (passed in by the caller
3352 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3353 reply
->packet
->options
, reply
->opt_state
,
3354 scope
, group
, root_group
, on_star
);
3356 /* Execute statements from class scopes. */
3357 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3358 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3359 reply
->packet
->options
,
3360 reply
->opt_state
, scope
,
3361 reply
->packet
->classes
[i
- 1]->group
,
3366 * If there is a host record, over-ride with values configured there,
3367 * without re-evaluating configuration from the previously executed
3368 * group or its common enclosers.
3370 if (reply
->host
!= NULL
)
3371 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3372 reply
->packet
->options
,
3373 reply
->opt_state
, scope
,
3374 reply
->host
->group
, group
,
3377 /* Determine valid lifetime. */
3378 if (reply
->client_valid
== 0)
3379 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
3381 reply
->send_valid
= reply
->client_valid
;
3383 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3384 SV_DEFAULT_LEASE_TIME
);
3386 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3387 reply
->packet
->options
,
3391 log_error("reply_process_is_addressed: unable to "
3392 "evaluate default lease time");
3393 status
= ISC_R_FAILURE
;
3397 reply
->send_valid
= getULong(data
.data
);
3398 data_string_forget(&data
, MDL
);
3401 /* Check to see if the lease time would cause us to wrap
3402 * in which case we make it infinite.
3403 * The following doesn't work on at least some systems:
3404 * (cur_time + reply->send_valid < cur_time)
3406 if (reply
->send_valid
!= 0xFFFFFFFF) {
3407 time_t test_time
= cur_time
+ reply
->send_valid
;
3408 if (test_time
< cur_time
)
3409 reply
->send_valid
= 0xFFFFFFFF;
3412 if (reply
->client_prefer
== 0)
3413 reply
->send_prefer
= reply
->send_valid
;
3415 reply
->send_prefer
= reply
->client_prefer
;
3417 if ((reply
->send_prefer
>= reply
->send_valid
) &&
3418 (reply
->send_valid
!= 0xFFFFFFFF))
3419 reply
->send_prefer
= (reply
->send_valid
/ 2) +
3420 (reply
->send_valid
/ 8);
3422 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3423 SV_PREFER_LIFETIME
);
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 preferred lease time");
3432 status
= ISC_R_FAILURE
;
3436 reply
->send_prefer
= getULong(data
.data
);
3437 data_string_forget(&data
, MDL
);
3440 /* Note lowest values for later calculation of renew/rebind times. */
3441 if (reply
->min_prefer
> reply
->send_prefer
)
3442 reply
->min_prefer
= reply
->send_prefer
;
3444 if (reply
->min_valid
> reply
->send_valid
)
3445 reply
->min_valid
= reply
->send_valid
;
3449 * XXX: Old 4.0.0 alpha code would change the host {} record
3450 * XXX: uid upon lease assignment. This was intended to cover the
3451 * XXX: case where a client first identifies itself using vendor
3452 * XXX: options in a solicit, or request, but later neglects to include
3453 * XXX: these options in a Renew or Rebind. It is not clear that this
3454 * XXX: is required, and has some startling ramifications (such as
3455 * XXX: how to recover this dynamic host {} state across restarts).
3457 if (reply
->host
!= NULL
)
3458 change_host_uid(host
, reply
->client_id
->data
,
3459 reply
->client_id
->len
);
3462 /* Perform dynamic lease related update work. */
3463 if (reply
->lease
!= NULL
) {
3464 /* Cached lifetimes */
3465 reply
->lease
->prefer
= reply
->send_prefer
;
3466 reply
->lease
->valid
= reply
->send_valid
;
3468 /* Advance (or rewind) the valid lifetime.
3469 * In the protocol 0xFFFFFFFF is infinite
3470 * when connecting to the lease file MAX_TIME is
3472 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
3473 if (reply
->send_valid
== 0xFFFFFFFF) {
3474 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
3476 reply
->lease
->soft_lifetime_end_time
=
3477 cur_time
+ reply
->send_valid
;
3479 /* Wait before renew! */
3482 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
3483 if (status
!= ISC_R_SUCCESS
) {
3484 log_fatal("reply_process_is_addressed: Unable to "
3485 "attach lease to new IA: %s",
3486 isc_result_totext(status
));
3490 * If this is a new lease, make sure it is attached somewhere.
3492 if (reply
->lease
->ia
== NULL
) {
3493 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
3497 /* Bring a copy of the relevant options into the IA scope. */
3498 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3499 reply
->packet
->options
, reply
->reply_ia
,
3500 scope
, group
, root_group
, NULL
);
3502 /* Execute statements from class scopes. */
3503 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3504 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3505 reply
->packet
->options
,
3506 reply
->reply_ia
, scope
,
3507 reply
->packet
->classes
[i
- 1]->group
,
3512 * And bring in host record configuration, if any, but not to overlap
3513 * the previous group or its common enclosers.
3515 if (reply
->host
!= NULL
)
3516 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3517 reply
->packet
->options
,
3518 reply
->reply_ia
, scope
,
3519 reply
->host
->group
, group
, NULL
);
3522 if (data
.data
!= NULL
)
3523 data_string_forget(&data
, MDL
);
3525 if (status
== ISC_R_SUCCESS
)
3526 reply
->client_resources
++;
3531 /* Simply send an IAADDR within the IA scope as described. */
3533 reply_process_send_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3534 isc_result_t status
= ISC_R_SUCCESS
;
3535 struct data_string data
;
3537 memset(&data
, 0, sizeof(data
));
3539 /* Now append the lease. */
3540 data
.len
= IAADDR_OFFSET
;
3541 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
3542 log_error("reply_process_send_addr: out of memory"
3543 "allocating new IAADDR buffer.");
3544 status
= ISC_R_NOMEMORY
;
3547 data
.data
= data
.buffer
->data
;
3549 memcpy(data
.buffer
->data
, addr
->iabuf
, 16);
3550 putULong(data
.buffer
->data
+ 16, reply
->send_prefer
);
3551 putULong(data
.buffer
->data
+ 20, reply
->send_valid
);
3553 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
3554 data
.buffer
, data
.buffer
->data
,
3555 data
.len
, D6O_IAADDR
, 0)) {
3556 log_error("reply_process_send_addr: unable "
3557 "to save IAADDR option");
3558 status
= ISC_R_FAILURE
;
3562 reply
->resources_included
= ISC_TRUE
;
3565 if (data
.data
!= NULL
)
3566 data_string_forget(&data
, MDL
);
3571 /* Choose the better of two leases. */
3572 static struct iasubopt
*
3573 lease_compare(struct iasubopt
*alpha
, struct iasubopt
*beta
) {
3579 switch(alpha
->state
) {
3581 switch(beta
->state
) {
3583 /* Choose the lease with the longest lifetime (most
3584 * likely the most recently allocated).
3586 if (alpha
->hard_lifetime_end_time
<
3587 beta
->hard_lifetime_end_time
)
3597 log_fatal("Impossible condition at %s:%d.", MDL
);
3602 switch (beta
->state
) {
3607 /* Choose the most recently expired lease. */
3608 if (alpha
->hard_lifetime_end_time
<
3609 beta
->hard_lifetime_end_time
)
3611 else if ((alpha
->hard_lifetime_end_time
==
3612 beta
->hard_lifetime_end_time
) &&
3613 (alpha
->soft_lifetime_end_time
<
3614 beta
->soft_lifetime_end_time
))
3623 log_fatal("Impossible condition at %s:%d.", MDL
);
3628 switch (beta
->state
) {
3634 /* Choose the lease that was abandoned longest ago. */
3635 if (alpha
->hard_lifetime_end_time
<
3636 beta
->hard_lifetime_end_time
)
3642 log_fatal("Impossible condition at %s:%d.", MDL
);
3647 log_fatal("Impossible condition at %s:%d.", MDL
);
3650 log_fatal("Triple impossible condition at %s:%d.", MDL
);
3654 /* Process a client-supplied IA_PD. This may append options to the tail of
3655 * the reply packet being built in the reply_state structure.
3658 reply_process_ia_pd(struct reply_state
*reply
, struct option_cache
*ia
) {
3659 isc_result_t status
= ISC_R_SUCCESS
;
3662 struct option_state
*packet_ia
;
3663 struct option_cache
*oc
;
3664 struct data_string ia_data
, data
;
3666 /* Initialize values that will get cleaned up on return. */
3668 memset(&ia_data
, 0, sizeof(ia_data
));
3669 memset(&data
, 0, sizeof(data
));
3671 * Note that find_client_prefix() may set reply->lease.
3674 /* Make sure there is at least room for the header. */
3675 if ((reply
->cursor
+ IA_PD_OFFSET
+ 4) > sizeof(reply
->buf
)) {
3676 log_error("reply_process_ia_pd: Reply too long for IA.");
3677 return ISC_R_NOSPACE
;
3681 /* Fetch the IA_PD contents. */
3682 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
3683 ia
, IA_PD_OFFSET
)) {
3684 log_error("reply_process_ia_pd: error evaluating ia");
3685 status
= ISC_R_FAILURE
;
3689 /* Extract IA_PD header contents. */
3690 iaid
= getULong(ia_data
.data
);
3691 reply
->renew
= getULong(ia_data
.data
+ 4);
3692 reply
->rebind
= getULong(ia_data
.data
+ 8);
3694 /* Create an IA_PD structure. */
3695 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
3696 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
3697 log_error("reply_process_ia_pd: no memory for ia.");
3698 status
= ISC_R_NOMEMORY
;
3701 reply
->ia
->ia_type
= D6O_IA_PD
;
3703 /* Cache pre-existing IA_PD, if any. */
3704 ia_hash_lookup(&reply
->old_ia
, ia_pd_active
,
3705 (unsigned char *)reply
->ia
->iaid_duid
.data
,
3706 reply
->ia
->iaid_duid
.len
, MDL
);
3709 * Create an option cache to carry the IA_PD option contents, and
3710 * execute any user-supplied values into it.
3712 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
3713 status
= ISC_R_NOMEMORY
;
3717 /* Check & count the fixed prefix host records. */
3718 reply
->static_prefixes
= 0;
3719 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_prefix
!= NULL
)) {
3720 struct iaddrcidrnetlist
*fp
;
3722 for (fp
= reply
->host
->fixed_prefix
; fp
!= NULL
;
3724 reply
->static_prefixes
+= 1;
3729 * Save the cursor position at the start of the IA_PD, so we can
3730 * set length and adjust t1/t2 values later. We write a temporary
3731 * header out now just in case we decide to adjust the packet
3732 * within sub-process functions.
3734 ia_cursor
= reply
->cursor
;
3736 /* Initialize the IA_PD header. First the code. */
3737 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_PD
);
3740 /* Then option length. */
3741 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
3744 /* Then IA_PD header contents; IAID. */
3745 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
3748 /* We store the client's t1 for now, and may over-ride it later. */
3749 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
3752 /* We store the client's t2 for now, and may over-ride it later. */
3753 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
3757 * For each prefix in this IA_PD, decide what to do about it.
3759 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAPREFIX
);
3760 reply
->min_valid
= reply
->min_prefer
= 0xffffffff;
3761 reply
->client_valid
= reply
->client_prefer
= 0;
3762 reply
->preflen
= -1;
3763 for (; oc
!= NULL
; oc
= oc
->next
) {
3764 status
= reply_process_prefix(reply
, oc
);
3767 * Canceled means we did not allocate prefixes to the
3768 * client, but we're "done" with this IA - we set a status
3769 * code. So transmit this reply, e.g., move on to the next
3772 if (status
== ISC_R_CANCELED
)
3775 if ((status
!= ISC_R_SUCCESS
) &&
3776 (status
!= ISC_R_ADDRINUSE
) &&
3777 (status
!= ISC_R_ADDRNOTAVAIL
))
3784 * If we fell through the above and never gave the client
3785 * a prefix, give it one now.
3787 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
3788 status
= find_client_prefix(reply
);
3790 if (status
== ISC_R_NORESOURCES
) {
3791 switch (reply
->packet
->dhcpv6_msg_type
) {
3792 case DHCPV6_SOLICIT
:
3794 * No prefix for any IA is handled
3799 case DHCPV6_REQUEST
:
3800 /* Same than for addresses. */
3801 option_state_dereference(&reply
->reply_ia
, MDL
);
3802 if (!option_state_allocate(&reply
->reply_ia
,
3805 log_error("reply_process_ia_pd: No "
3806 "memory for option state "
3808 status
= ISC_R_NOMEMORY
;
3812 if (!set_status_code(STATUS_NoPrefixAvail
,
3813 "No prefixes available "
3814 "for this interface.",
3816 log_error("reply_process_ia_pd: "
3818 "NoPrefixAvail status "
3820 status
= ISC_R_FAILURE
;
3824 status
= ISC_R_SUCCESS
;
3828 if (reply
->resources_included
)
3829 status
= ISC_R_SUCCESS
;
3836 if (status
!= ISC_R_SUCCESS
)
3840 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
3841 sizeof(reply
->buf
) - reply
->cursor
,
3842 reply
->reply_ia
, reply
->packet
,
3843 required_opts_IA_PD
, NULL
);
3845 /* Reset the length of this IA_PD to match what was just written. */
3846 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
3847 reply
->cursor
- (ia_cursor
+ 4));
3849 /* Calculate T1/T2 and stuff them in the reply */
3850 set_reply_tee_times(reply
, ia_cursor
);
3853 * yes, goto's aren't the best but we also want to avoid extra
3856 if (status
== ISC_R_CANCELED
)
3860 * Handle static prefixes, we always log stuff and if it's
3861 * a hard binding we run any commit statements that we have
3863 if (reply
->static_prefixes
!= 0) {
3864 char tmp_addr
[INET6_ADDRSTRLEN
];
3865 log_info("%s PD: address %s/%d to client with duid %s "
3867 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
3868 inet_ntop(AF_INET6
, reply
->fixed_pref
.lo_addr
.iabuf
,
3869 tmp_addr
, sizeof(tmp_addr
)),
3870 reply
->fixed_pref
.bits
,
3871 print_hex_1(reply
->client_id
.len
,
3872 reply
->client_id
.data
, 60),
3874 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
3875 (reply
->on_star
.on_commit
!= NULL
)) {
3876 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
3877 reply
->packet
->options
,
3879 NULL
, reply
->on_star
.on_commit
,
3881 executable_statement_dereference
3882 (&reply
->on_star
.on_commit
, MDL
);
3888 * If we have any addresses log what we are doing.
3890 if (reply
->ia
->num_iasubopt
!= 0) {
3891 struct iasubopt
*tmp
;
3893 char tmp_addr
[INET6_ADDRSTRLEN
];
3895 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3896 tmp
= reply
->ia
->iasubopt
[i
];
3898 log_info("%s PD: address %s/%d to client with duid %s"
3899 " iaid = %d valid for %u seconds",
3900 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
3901 inet_ntop(AF_INET6
, &tmp
->addr
,
3902 tmp_addr
, sizeof(tmp_addr
)),
3904 print_hex_1(reply
->client_id
.len
,
3905 reply
->client_id
.data
, 60),
3911 * If this is not a 'soft' binding, consume the new changes into
3912 * the database (if any have been attached to the ia_pd).
3914 * Loop through the assigned dynamic prefixes, referencing the
3915 * prefixes onto this IA_PD rather than any old ones, and updating
3916 * prefix pool timers for each (if any).
3918 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
3919 (reply
->ia
->num_iasubopt
!= 0)) {
3920 struct iasubopt
*tmp
;
3921 struct data_string
*ia_id
;
3924 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3925 tmp
= reply
->ia
->iasubopt
[i
];
3927 if (tmp
->ia
!= NULL
)
3928 ia_dereference(&tmp
->ia
, MDL
);
3929 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
3931 /* Commit 'hard' bindings. */
3932 renew_lease6(tmp
->ipv6_pool
, tmp
);
3933 schedule_lease_timeout(tmp
->ipv6_pool
);
3935 /* If we have anything to do on commit do it now */
3936 if (tmp
->on_star
.on_commit
!= NULL
) {
3937 execute_statements(NULL
, reply
->packet
,
3939 reply
->packet
->options
,
3942 tmp
->on_star
.on_commit
,
3944 executable_statement_dereference
3945 (&tmp
->on_star
.on_commit
, MDL
);
3948 /* Do our threshold check. */
3949 check_pool6_threshold(reply
, tmp
);
3952 /* Remove any old ia from the hash. */
3953 if (reply
->old_ia
!= NULL
) {
3954 ia_id
= &reply
->old_ia
->iaid_duid
;
3955 ia_hash_delete(ia_pd_active
,
3956 (unsigned char *)ia_id
->data
,
3958 ia_dereference(&reply
->old_ia
, MDL
);
3961 /* Put new ia into the hash. */
3962 reply
->ia
->cltt
= cur_time
;
3963 ia_id
= &reply
->ia
->iaid_duid
;
3964 ia_hash_add(ia_pd_active
, (unsigned char *)ia_id
->data
,
3965 ia_id
->len
, reply
->ia
, MDL
);
3967 write_ia(reply
->ia
);
3969 schedule_lease_timeout_reply(reply
);
3973 if (packet_ia
!= NULL
)
3974 option_state_dereference(&packet_ia
, MDL
);
3975 if (reply
->reply_ia
!= NULL
)
3976 option_state_dereference(&reply
->reply_ia
, MDL
);
3977 if (ia_data
.data
!= NULL
)
3978 data_string_forget(&ia_data
, MDL
);
3979 if (data
.data
!= NULL
)
3980 data_string_forget(&data
, MDL
);
3981 if (reply
->ia
!= NULL
)
3982 ia_dereference(&reply
->ia
, MDL
);
3983 if (reply
->old_ia
!= NULL
)
3984 ia_dereference(&reply
->old_ia
, MDL
);
3985 if (reply
->lease
!= NULL
)
3986 iasubopt_dereference(&reply
->lease
, MDL
);
3987 if (reply
->on_star
.on_expiry
!= NULL
)
3988 executable_statement_dereference
3989 (&reply
->on_star
.on_expiry
, MDL
);
3990 if (reply
->on_star
.on_release
!= NULL
)
3991 executable_statement_dereference
3992 (&reply
->on_star
.on_release
, MDL
);
3995 * ISC_R_CANCELED is a status code used by the prefix processing to
3996 * indicate we're replying with a status code. This is still a
3997 * success at higher layers.
3999 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
4004 * \brief Find the proper scoping group for use with a v6 static prefix.
4006 * We start by trying to find a subnet based on the given prefix and
4007 * the shared network. If we don't find one then the prefix has been
4008 * declared outside of any subnets. If there is a static address
4009 * associated with the host we use it to try and find a subnet (this
4010 * should succeed). If there isn't a static address we fall back
4011 * to the shared subnet itself.
4012 * Once we have a subnet we extract the group from it and return it.
4014 * \param reply - the reply structure we use to collect information
4015 * we will use the fields shared, fixed_pref and host
4016 * from the structure
4018 * \return a pointer to the group structure to use for scoping
4021 static struct group
*
4022 find_group_by_prefix(struct reply_state
*reply
) {
4023 /* default group if we don't find anything better */
4024 struct group
*group
= reply
->shared
->group
;
4025 struct subnet
*subnet
= NULL
;
4026 struct iaddr tmp_addr
;
4027 struct data_string fixed_addr
;
4029 /* Try with the prefix first */
4030 if (find_grouped_subnet(&subnet
, reply
->shared
,
4031 reply
->fixed_pref
.lo_addr
, MDL
) != 0) {
4032 group
= subnet
->group
;
4033 subnet_dereference(&subnet
, MDL
);
4037 /* Didn't find a subnet via prefix, what about fixed address */
4038 /* The caller has already tested reply->host != NULL */
4040 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
4042 if ((reply
->host
->fixed_addr
!= NULL
) &&
4043 (evaluate_option_cache(&fixed_addr
, NULL
, NULL
, NULL
,
4044 NULL
, NULL
, &global_scope
,
4045 reply
->host
->fixed_addr
, MDL
))) {
4046 if (fixed_addr
.len
>= 16) {
4048 memcpy(tmp_addr
.iabuf
, fixed_addr
.data
, 16);
4049 if (find_grouped_subnet(&subnet
, reply
->shared
,
4050 tmp_addr
, MDL
) != 0) {
4051 group
= subnet
->group
;
4052 subnet_dereference(&subnet
, MDL
);
4055 data_string_forget(&fixed_addr
, MDL
);
4058 /* return whatever we got */
4063 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
4064 * contents into the reply's current ia_pd-scoped option cache. Returns
4065 * ISC_R_CANCELED in the event we are replying with a status code and do
4066 * not wish to process more IAPREFIXes within this IA_PD.
4069 reply_process_prefix(struct reply_state
*reply
, struct option_cache
*pref
) {
4070 u_int32_t pref_life
, valid_life
;
4071 struct binding_scope
**scope
;
4072 struct iaddrcidrnet tmp_pref
;
4073 struct option_cache
*oc
;
4074 struct data_string iapref
, data
;
4075 isc_result_t status
= ISC_R_SUCCESS
;
4076 struct group
*group
;
4078 /* Initializes values that will be cleaned up. */
4079 memset(&iapref
, 0, sizeof(iapref
));
4080 memset(&data
, 0, sizeof(data
));
4081 /* Note that reply->lease may be set by prefix_is_owned() */
4084 * There is no point trying to process an incoming prefix if there
4085 * is no room for an outgoing prefix.
4087 if ((reply
->cursor
+ 29) > sizeof(reply
->buf
)) {
4088 log_error("reply_process_prefix: Out of room for prefix.");
4089 return ISC_R_NOSPACE
;
4092 /* Extract this IAPREFIX option. */
4093 if (!evaluate_option_cache(&iapref
, reply
->packet
, NULL
, NULL
,
4094 reply
->packet
->options
, NULL
, &global_scope
,
4096 (iapref
.len
< IAPREFIX_OFFSET
)) {
4097 log_error("reply_process_prefix: error evaluating IAPREFIX.");
4098 status
= ISC_R_FAILURE
;
4103 * Layout: preferred and valid lifetimes followed by the prefix
4104 * length and the IPv6 address.
4106 pref_life
= getULong(iapref
.data
);
4107 valid_life
= getULong(iapref
.data
+ 4);
4109 if ((reply
->client_valid
== 0) ||
4110 (reply
->client_valid
> valid_life
))
4111 reply
->client_valid
= valid_life
;
4113 if ((reply
->client_prefer
== 0) ||
4114 (reply
->client_prefer
> pref_life
))
4115 reply
->client_prefer
= pref_life
;
4118 * Clients may choose to send ::/0 as a prefix, with the idea to give
4119 * hints about preferred-lifetime or valid-lifetime.
4121 tmp_pref
.lo_addr
.len
= 16;
4122 memset(tmp_pref
.lo_addr
.iabuf
, 0, 16);
4123 if ((iapref
.data
[8] == 0) &&
4124 (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0)) {
4125 /* Status remains success; we just ignore this one. */
4130 * Clients may choose to send ::/X as a prefix to specify a
4131 * preferred/requested prefix length. Note X is never zero here.
4133 tmp_pref
.bits
= (int) iapref
.data
[8];
4134 if (reply
->preflen
< 0) {
4135 /* Cache the first preferred prefix length. */
4136 reply
->preflen
= tmp_pref
.bits
;
4138 if (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0) {
4142 memcpy(tmp_pref
.lo_addr
.iabuf
, iapref
.data
+ 9, 16);
4144 /* Verify the prefix belongs to the client. */
4145 if (!prefix_is_owned(reply
, &tmp_pref
)) {
4146 /* Same than for addresses. */
4147 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
4148 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
4149 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
4150 status
= reply_process_try_prefix(reply
, &tmp_pref
);
4152 /* Either error out or skip this prefix. */
4153 if ((status
!= ISC_R_SUCCESS
) &&
4154 (status
!= ISC_R_ADDRINUSE
) &&
4155 (status
!= ISC_R_ADDRNOTAVAIL
))
4158 if (reply
->lease
== NULL
) {
4159 if (reply
->packet
->dhcpv6_msg_type
==
4161 reply
->send_prefer
= 0;
4162 reply
->send_valid
= 0;
4166 /* status remains success - ignore */
4170 * RFC3633 section 18.2.3:
4172 * If the delegating router cannot find a binding
4173 * for the requesting router's IA_PD the delegating
4174 * router returns the IA_PD containing no prefixes
4175 * with a Status Code option set to NoBinding in the
4178 * On mismatch we (ab)use this pretending we have not the IA
4179 * as soon as we have not a prefix.
4181 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
4182 /* Rewind the IA_PD to empty. */
4183 option_state_dereference(&reply
->reply_ia
, MDL
);
4184 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
4185 log_error("reply_process_prefix: No memory "
4186 "for option state wipe.");
4187 status
= ISC_R_NOMEMORY
;
4191 /* Append a NoBinding status code. */
4192 if (!set_status_code(STATUS_NoBinding
,
4193 "Prefix not bound to this "
4194 "interface.", reply
->reply_ia
)) {
4195 log_error("reply_process_prefix: Unable to "
4196 "attach status code.");
4197 status
= ISC_R_FAILURE
;
4201 /* Fin (no more IAPREFIXes). */
4202 status
= ISC_R_CANCELED
;
4205 log_error("It is impossible to lease a client that is "
4206 "not sending a solicit, request, renew, or "
4208 status
= ISC_R_FAILURE
;
4213 if (reply
->static_prefixes
> 0) {
4214 if (reply
->host
== NULL
)
4215 log_fatal("Impossible condition at %s:%d.", MDL
);
4217 scope
= &global_scope
;
4219 /* Copy the static prefix for logging and finding the group */
4220 memcpy(&reply
->fixed_pref
, &tmp_pref
, sizeof(tmp_pref
));
4222 /* Try to find a group for the static prefix */
4223 group
= find_group_by_prefix(reply
);
4225 if (reply
->lease
== NULL
)
4226 log_fatal("Impossible condition at %s:%d.", MDL
);
4228 scope
= &reply
->lease
->scope
;
4229 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4233 * If client_resources is nonzero, then the reply_process_is_prefixed
4234 * function has executed configuration state into the reply option
4235 * cache. We will use that valid cache to derive configuration for
4236 * whether or not to engage in additional prefixes, and similar.
4238 if (reply
->client_resources
!= 0) {
4242 * Does this client have "enough" prefixes already? Default
4243 * to one. Everybody gets one, and one should be enough for
4246 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4247 SV_LIMIT_PREFS_PER_IA
);
4249 if (!evaluate_option_cache(&data
, reply
->packet
,
4251 reply
->packet
->options
,
4255 log_error("reply_process_prefix: unable to "
4256 "evaluate prefs-per-ia value.");
4257 status
= ISC_R_FAILURE
;
4261 limit
= getULong(data
.data
);
4262 data_string_forget(&data
, MDL
);
4266 * If we wish to limit the client to a certain number of
4267 * prefixes, then omit the prefix from the reply.
4269 if (reply
->client_resources
>= limit
)
4273 status
= reply_process_is_prefixed(reply
, scope
, group
);
4274 if (status
!= ISC_R_SUCCESS
)
4278 status
= reply_process_send_prefix(reply
, &tmp_pref
);
4281 if (iapref
.data
!= NULL
)
4282 data_string_forget(&iapref
, MDL
);
4283 if (data
.data
!= NULL
)
4284 data_string_forget(&data
, MDL
);
4285 if (reply
->lease
!= NULL
)
4286 iasubopt_dereference(&reply
->lease
, MDL
);
4292 * Verify the prefix belongs to the client. If we've got a host
4293 * record with fixed prefixes, it has to be an assigned prefix
4294 * (fault out all else). Otherwise it's a dynamic prefix, so lookup
4295 * that prefix and make sure it belongs to this DUID:IAID pair.
4297 static isc_boolean_t
4298 prefix_is_owned(struct reply_state
*reply
, struct iaddrcidrnet
*pref
) {
4299 struct iaddrcidrnetlist
*l
;
4301 struct ipv6_pond
*pond
;
4304 * This faults out prefixes that don't match fixed prefixes.
4306 if (reply
->static_prefixes
> 0) {
4307 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4308 if ((pref
->bits
== l
->cidrnet
.bits
) &&
4309 (memcmp(pref
->lo_addr
.iabuf
,
4310 l
->cidrnet
.lo_addr
.iabuf
, 16) == 0))
4316 if ((reply
->old_ia
== NULL
) ||
4317 (reply
->old_ia
->num_iasubopt
== 0))
4320 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4321 struct iasubopt
*tmp
;
4323 tmp
= reply
->old_ia
->iasubopt
[i
];
4325 if ((pref
->bits
== (int) tmp
->plen
) &&
4326 (memcmp(pref
->lo_addr
.iabuf
, &tmp
->addr
, 16) == 0)) {
4327 if (lease6_usable(tmp
) == ISC_FALSE
) {
4331 pond
= tmp
->ipv6_pool
->ipv6_pond
;
4332 if (((pond
->prohibit_list
!= NULL
) &&
4333 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4334 ((pond
->permit_list
!= NULL
) &&
4335 (!permitted(reply
->packet
, pond
->permit_list
))))
4338 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
4347 * This function only returns failure on 'hard' failures. If it succeeds,
4348 * it will leave a prefix structure behind.
4351 reply_process_try_prefix(struct reply_state
*reply
,
4352 struct iaddrcidrnet
*pref
) {
4353 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
4354 struct ipv6_pool
*pool
= NULL
;
4355 struct ipv6_pond
*pond
= NULL
;
4357 struct data_string data_pref
;
4359 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
4360 (pref
== NULL
) || (reply
->lease
!= NULL
))
4361 return (DHCP_R_INVALIDARG
);
4364 * Do a quick walk through of the ponds and pools
4365 * to see if we have any prefix pools
4367 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4368 if (pond
->ipv6_pools
== NULL
)
4371 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4372 if (pool
->pool_type
== D6O_IA_PD
)
4379 /* If we get here and p is NULL we have no useful pools */
4381 return (ISC_R_ADDRNOTAVAIL
);
4384 memset(&data_pref
, 0, sizeof(data_pref
));
4386 if (!buffer_allocate(&data_pref
.buffer
, data_pref
.len
, MDL
)) {
4387 log_error("reply_process_try_prefix: out of memory.");
4388 return (ISC_R_NOMEMORY
);
4390 data_pref
.data
= data_pref
.buffer
->data
;
4391 data_pref
.buffer
->data
[0] = (u_int8_t
) pref
->bits
;
4392 memcpy(data_pref
.buffer
->data
+ 1, pref
->lo_addr
.iabuf
, 16);
4395 * We have at least one pool that could provide a prefix
4396 * Now we walk through the ponds and pools again and check
4397 * to see if the client is permitted and if an prefix is
4402 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4403 if (((pond
->prohibit_list
!= NULL
) &&
4404 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4405 ((pond
->permit_list
!= NULL
) &&
4406 (!permitted(reply
->packet
, pond
->permit_list
))))
4409 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4410 if (pool
->pool_type
!= D6O_IA_PD
) {
4414 status
= try_client_v6_prefix(&reply
->lease
, pool
,
4416 /* If we found it in this pool (either in use or available),
4417 there is no need to look further. */
4418 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4421 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4425 data_string_forget(&data_pref
, MDL
);
4426 /* Return just the most recent status... */
4430 /* Look around for a prefix to give the client. First, look through the old
4431 * IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
4432 * Finally, actually add that prefix into the current reply IA_PD.
4435 find_client_prefix(struct reply_state
*reply
) {
4436 struct iaddrcidrnet send_pref
;
4437 isc_result_t status
= ISC_R_NORESOURCES
;
4438 struct iasubopt
*prefix
, *best_prefix
= NULL
;
4439 struct binding_scope
**scope
;
4441 struct group
*group
;
4443 if (reply
->static_prefixes
> 0) {
4444 struct iaddrcidrnetlist
*l
;
4446 if (reply
->host
== NULL
)
4447 return DHCP_R_INVALIDARG
;
4449 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4450 if (l
->cidrnet
.bits
== reply
->preflen
)
4455 * If no fixed prefix has the preferred length,
4456 * get the first one.
4458 l
= reply
->host
->fixed_prefix
;
4460 memcpy(&send_pref
, &l
->cidrnet
, sizeof(send_pref
));
4462 scope
= &global_scope
;
4464 /* Copy the prefix for logging purposes */
4465 memcpy(&reply
->fixed_pref
, &l
->cidrnet
, sizeof(send_pref
));
4467 /* Try to find a group for the static prefix */
4468 group
= find_group_by_prefix(reply
);
4473 if (reply
->old_ia
!= NULL
) {
4474 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4475 struct shared_network
*candidate_shared
;
4476 struct ipv6_pond
*pond
;
4478 prefix
= reply
->old_ia
->iasubopt
[i
];
4479 candidate_shared
= prefix
->ipv6_pool
->shared_network
;
4480 pond
= prefix
->ipv6_pool
->ipv6_pond
;
4483 * Consider this prefix if it is in a global pool or
4484 * if it is scoped in a pool under the client's shared
4487 if (((candidate_shared
!= NULL
) &&
4488 (candidate_shared
!= reply
->shared
)) ||
4489 (lease6_usable(prefix
) != ISC_TRUE
))
4493 * And check if the prefix is still permitted
4496 if (((pond
->prohibit_list
!= NULL
) &&
4497 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4498 ((pond
->permit_list
!= NULL
) &&
4499 (!permitted(reply
->packet
, pond
->permit_list
))))
4502 best_prefix
= prefix_compare(reply
, prefix
,
4507 /* Try to pick a new prefix if we didn't find one, or if we found an
4510 if ((best_prefix
== NULL
) || (best_prefix
->state
== FTS_ABANDONED
)) {
4511 status
= pick_v6_prefix(reply
);
4512 } else if (best_prefix
!= NULL
) {
4513 iasubopt_reference(&reply
->lease
, best_prefix
, MDL
);
4514 status
= ISC_R_SUCCESS
;
4517 /* Pick the abandoned prefix as a last resort. */
4518 if ((status
== ISC_R_NORESOURCES
) && (best_prefix
!= NULL
)) {
4519 /* I don't see how this is supposed to be done right now. */
4520 log_error("Reclaiming abandoned prefixes is not yet "
4521 "supported. Treating this as an out of space "
4523 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
4526 /* Give up now if we didn't find a prefix. */
4527 if (status
!= ISC_R_SUCCESS
)
4530 if (reply
->lease
== NULL
)
4531 log_fatal("Impossible condition at %s:%d.", MDL
);
4533 scope
= &reply
->lease
->scope
;
4534 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4536 send_pref
.lo_addr
.len
= 16;
4537 memcpy(send_pref
.lo_addr
.iabuf
, &reply
->lease
->addr
, 16);
4538 send_pref
.bits
= (int) reply
->lease
->plen
;
4541 status
= reply_process_is_prefixed(reply
, scope
, group
);
4542 if (status
!= ISC_R_SUCCESS
)
4545 status
= reply_process_send_prefix(reply
, &send_pref
);
4549 /* Once a prefix is found for a client, perform several common functions;
4550 * Calculate and store valid and preferred prefix times, draw client options
4551 * into the option state.
4554 reply_process_is_prefixed(struct reply_state
*reply
,
4555 struct binding_scope
**scope
, struct group
*group
)
4557 isc_result_t status
= ISC_R_SUCCESS
;
4558 struct data_string data
;
4559 struct option_cache
*oc
;
4560 struct option_state
*tmp_options
= NULL
;
4561 struct on_star
*on_star
;
4564 /* Initialize values we will cleanup. */
4565 memset(&data
, 0, sizeof(data
));
4568 * Find the proper on_star block to use. We use the
4569 * one in the lease if we have a lease or the one in
4570 * the reply if we don't have a lease because this is
4574 on_star
= &reply
->lease
->on_star
;
4576 on_star
= &reply
->on_star
;
4580 * Bring in the root configuration. We only do this to bring
4581 * in the on * statements, as we didn't have the lease available
4582 * we we did it the first time.
4584 option_state_allocate(&tmp_options
, MDL
);
4585 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4586 reply
->packet
->options
, tmp_options
,
4587 &global_scope
, root_group
, NULL
,
4589 if (tmp_options
!= NULL
) {
4590 option_state_dereference(&tmp_options
, MDL
);
4594 * Bring configured options into the root packet level cache - start
4595 * with the lease's closest enclosing group (passed in by the caller
4598 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4599 reply
->packet
->options
, reply
->opt_state
,
4600 scope
, group
, root_group
, on_star
);
4602 /* Execute statements from class scopes. */
4603 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
4604 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4605 reply
->packet
->options
,
4606 reply
->opt_state
, scope
,
4607 reply
->packet
->classes
[i
- 1]->group
,
4612 * If there is a host record, over-ride with values configured there,
4613 * without re-evaluating configuration from the previously executed
4614 * group or its common enclosers.
4616 if (reply
->host
!= NULL
)
4617 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4618 reply
->packet
->options
,
4619 reply
->opt_state
, scope
,
4620 reply
->host
->group
, group
,
4623 /* Determine valid lifetime. */
4624 if (reply
->client_valid
== 0)
4625 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
4627 reply
->send_valid
= reply
->client_valid
;
4629 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4630 SV_DEFAULT_LEASE_TIME
);
4632 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4633 reply
->packet
->options
,
4637 log_error("reply_process_is_prefixed: unable to "
4638 "evaluate default prefix time");
4639 status
= ISC_R_FAILURE
;
4643 reply
->send_valid
= getULong(data
.data
);
4644 data_string_forget(&data
, MDL
);
4647 /* Check to see if the lease time would cause us to wrap
4648 * in which case we make it infinite.
4649 * The following doesn't work on at least some systems:
4650 * (cur_time + reply->send_valid < cur_time)
4652 if (reply
->send_valid
!= 0xFFFFFFFF) {
4653 time_t test_time
= cur_time
+ reply
->send_valid
;
4654 if (test_time
< cur_time
)
4655 reply
->send_valid
= 0xFFFFFFFF;
4658 if (reply
->client_prefer
== 0)
4659 reply
->send_prefer
= reply
->send_valid
;
4661 reply
->send_prefer
= reply
->client_prefer
;
4663 if ((reply
->send_prefer
>= reply
->send_valid
) &&
4664 (reply
->send_valid
!= 0xFFFFFFFF))
4665 reply
->send_prefer
= (reply
->send_valid
/ 2) +
4666 (reply
->send_valid
/ 8);
4668 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4669 SV_PREFER_LIFETIME
);
4671 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4672 reply
->packet
->options
,
4676 log_error("reply_process_is_prefixed: unable to "
4677 "evaluate preferred prefix time");
4678 status
= ISC_R_FAILURE
;
4682 reply
->send_prefer
= getULong(data
.data
);
4683 data_string_forget(&data
, MDL
);
4686 /* Note lowest values for later calculation of renew/rebind times. */
4687 if (reply
->min_prefer
> reply
->send_prefer
)
4688 reply
->min_prefer
= reply
->send_prefer
;
4690 if (reply
->min_valid
> reply
->send_valid
)
4691 reply
->min_valid
= reply
->send_valid
;
4693 /* Perform dynamic prefix related update work. */
4694 if (reply
->lease
!= NULL
) {
4695 /* Cached lifetimes */
4696 reply
->lease
->prefer
= reply
->send_prefer
;
4697 reply
->lease
->valid
= reply
->send_valid
;
4699 /* Advance (or rewind) the valid lifetime.
4700 * In the protocol 0xFFFFFFFF is infinite
4701 * when connecting to the lease file MAX_TIME is
4703 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
4704 if (reply
->send_valid
== 0xFFFFFFFF) {
4705 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
4707 reply
->lease
->soft_lifetime_end_time
=
4708 cur_time
+ reply
->send_valid
;
4710 /* Wait before renew! */
4713 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
4714 if (status
!= ISC_R_SUCCESS
) {
4715 log_fatal("reply_process_is_prefixed: Unable to "
4716 "attach prefix to new IA_PD: %s",
4717 isc_result_totext(status
));
4721 * If this is a new prefix, make sure it is attached somewhere.
4723 if (reply
->lease
->ia
== NULL
) {
4724 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
4728 /* Bring a copy of the relevant options into the IA_PD scope. */
4729 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4730 reply
->packet
->options
, reply
->reply_ia
,
4731 scope
, group
, root_group
, NULL
);
4733 /* Execute statements from class scopes. */
4734 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
4735 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4736 reply
->packet
->options
,
4737 reply
->reply_ia
, scope
,
4738 reply
->packet
->classes
[i
- 1]->group
,
4743 * And bring in host record configuration, if any, but not to overlap
4744 * the previous group or its common enclosers.
4746 if (reply
->host
!= NULL
)
4747 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4748 reply
->packet
->options
,
4749 reply
->reply_ia
, scope
,
4750 reply
->host
->group
, group
, NULL
);
4753 if (data
.data
!= NULL
)
4754 data_string_forget(&data
, MDL
);
4756 if (status
== ISC_R_SUCCESS
)
4757 reply
->client_resources
++;
4762 /* Simply send an IAPREFIX within the IA_PD scope as described. */
4764 reply_process_send_prefix(struct reply_state
*reply
,
4765 struct iaddrcidrnet
*pref
) {
4766 isc_result_t status
= ISC_R_SUCCESS
;
4767 struct data_string data
;
4769 memset(&data
, 0, sizeof(data
));
4771 /* Now append the prefix. */
4772 data
.len
= IAPREFIX_OFFSET
;
4773 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
4774 log_error("reply_process_send_prefix: out of memory"
4775 "allocating new IAPREFIX buffer.");
4776 status
= ISC_R_NOMEMORY
;
4779 data
.data
= data
.buffer
->data
;
4781 putULong(data
.buffer
->data
, reply
->send_prefer
);
4782 putULong(data
.buffer
->data
+ 4, reply
->send_valid
);
4783 data
.buffer
->data
[8] = pref
->bits
;
4784 memcpy(data
.buffer
->data
+ 9, pref
->lo_addr
.iabuf
, 16);
4786 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
4787 data
.buffer
, data
.buffer
->data
,
4788 data
.len
, D6O_IAPREFIX
, 0)) {
4789 log_error("reply_process_send_prefix: unable "
4790 "to save IAPREFIX option");
4791 status
= ISC_R_FAILURE
;
4795 reply
->resources_included
= ISC_TRUE
;
4798 if (data
.data
!= NULL
)
4799 data_string_forget(&data
, MDL
);
4804 /* Choose the better of two prefixes. */
4805 static struct iasubopt
*
4806 prefix_compare(struct reply_state
*reply
,
4807 struct iasubopt
*alpha
, struct iasubopt
*beta
) {
4813 if (reply
->preflen
>= 0) {
4814 if ((alpha
->plen
== reply
->preflen
) &&
4815 (beta
->plen
!= reply
->preflen
))
4817 if ((beta
->plen
== reply
->preflen
) &&
4818 (alpha
->plen
!= reply
->preflen
))
4822 switch(alpha
->state
) {
4824 switch(beta
->state
) {
4826 /* Choose the prefix with the longest lifetime (most
4827 * likely the most recently allocated).
4829 if (alpha
->hard_lifetime_end_time
<
4830 beta
->hard_lifetime_end_time
)
4840 log_fatal("Impossible condition at %s:%d.", MDL
);
4845 switch (beta
->state
) {
4850 /* Choose the most recently expired prefix. */
4851 if (alpha
->hard_lifetime_end_time
<
4852 beta
->hard_lifetime_end_time
)
4854 else if ((alpha
->hard_lifetime_end_time
==
4855 beta
->hard_lifetime_end_time
) &&
4856 (alpha
->soft_lifetime_end_time
<
4857 beta
->soft_lifetime_end_time
))
4866 log_fatal("Impossible condition at %s:%d.", MDL
);
4871 switch (beta
->state
) {
4877 /* Choose the prefix that was abandoned longest ago. */
4878 if (alpha
->hard_lifetime_end_time
<
4879 beta
->hard_lifetime_end_time
)
4885 log_fatal("Impossible condition at %s:%d.", MDL
);
4890 log_fatal("Impossible condition at %s:%d.", MDL
);
4893 log_fatal("Triple impossible condition at %s:%d.", MDL
);
4898 * Solicit is how a client starts requesting addresses.
4900 * If the client asks for rapid commit, and we support it, we will
4901 * allocate the addresses and reply.
4903 * Otherwise we will send an advertise message.
4907 dhcpv6_solicit(struct data_string
*reply_ret
, struct packet
*packet
) {
4908 struct data_string client_id
;
4911 * Validate our input.
4913 if (!valid_client_msg(packet
, &client_id
)) {
4917 lease_to_client(reply_ret
, packet
, &client_id
, NULL
);
4922 data_string_forget(&client_id
, MDL
);
4926 * Request is how a client actually requests addresses.
4928 * Very similar to Solicit handling, except the server DUID is required.
4932 dhcpv6_request(struct data_string
*reply_ret
, struct packet
*packet
) {
4933 struct data_string client_id
;
4934 struct data_string server_id
;
4937 * Validate our input.
4939 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
4943 /* If the REQUEST arrived via unicast and unicast option isn't set,
4944 * reject it per RFC 3315, Sec 18.2.1 */
4945 if (packet
->unicast
== ISC_TRUE
&&
4946 is_unicast_option_defined(packet
) == ISC_FALSE
) {
4947 unicast_reject(reply_ret
, packet
, &client_id
, &server_id
);
4952 lease_to_client(reply_ret
, packet
, &client_id
, &server_id
);
4958 data_string_forget(&client_id
, MDL
);
4959 data_string_forget(&server_id
, MDL
);
4962 /* Find a DHCPv6 packet's shared network from hints in the packet.
4965 shared_network_from_packet6(struct shared_network
**shared
,
4966 struct packet
*packet
)
4968 const struct packet
*chk_packet
;
4969 const struct in6_addr
*link_addr
, *first_link_addr
;
4970 struct iaddr tmp_addr
;
4971 struct subnet
*subnet
;
4972 isc_result_t status
;
4974 if ((shared
== NULL
) || (*shared
!= NULL
) || (packet
== NULL
))
4975 return DHCP_R_INVALIDARG
;
4978 * First, find the link address where the packet from the client
4979 * first appeared (if this packet was relayed).
4981 first_link_addr
= NULL
;
4982 chk_packet
= packet
->dhcpv6_container_packet
;
4983 while (chk_packet
!= NULL
) {
4984 link_addr
= &chk_packet
->dhcpv6_link_address
;
4985 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
4986 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
4987 first_link_addr
= link_addr
;
4990 chk_packet
= chk_packet
->dhcpv6_container_packet
;
4994 * If there is a relayed link address, find the subnet associated
4995 * with that, and use that to get the appropriate
4998 if (first_link_addr
!= NULL
) {
4999 tmp_addr
.len
= sizeof(*first_link_addr
);
5000 memcpy(tmp_addr
.iabuf
,
5001 first_link_addr
, sizeof(*first_link_addr
));
5003 if (!find_subnet(&subnet
, tmp_addr
, MDL
)) {
5004 log_debug("No subnet found for link-address %s.",
5006 return ISC_R_NOTFOUND
;
5008 status
= shared_network_reference(shared
,
5009 subnet
->shared_network
, MDL
);
5010 subnet_dereference(&subnet
, MDL
);
5013 * If there is no link address, we will use the interface
5014 * that this packet came in on to pick the shared_network.
5016 } else if (packet
->interface
!= NULL
) {
5017 status
= shared_network_reference(shared
,
5018 packet
->interface
->shared_network
,
5020 if (packet
->dhcpv6_container_packet
!= NULL
) {
5021 log_info("[L2 Relay] No link address in relay packet "
5022 "assuming L2 relay and using receiving "
5028 * We shouldn't be able to get here but if there is no link
5029 * address and no interface we don't know where to get the
5030 * pool from log an error and return an error.
5032 log_error("No interface and no link address "
5033 "can't determine pool");
5034 status
= DHCP_R_INVALIDARG
;
5041 * When a client thinks it might be on a new link, it sends a
5044 * From RFC3315 section 18.2.2:
5046 * When the server receives a Confirm message, the server determines
5047 * whether the addresses in the Confirm message are appropriate for the
5048 * link to which the client is attached. If all of the addresses in the
5049 * Confirm message pass this test, the server returns a status of
5050 * Success. If any of the addresses do not pass this test, the server
5051 * returns a status of NotOnLink. If the server is unable to perform
5052 * this test (for example, the server does not have information about
5053 * prefixes on the link to which the client is connected), or there were
5054 * no addresses in any of the IAs sent by the client, the server MUST
5055 * NOT send a reply to the client.
5059 dhcpv6_confirm(struct data_string
*reply_ret
, struct packet
*packet
) {
5060 struct shared_network
*shared
;
5061 struct subnet
*subnet
;
5062 struct option_cache
*ia
, *ta
, *oc
;
5063 struct data_string cli_enc_opt_data
, iaaddr
, client_id
, packet_oro
;
5064 struct option_state
*cli_enc_opt_state
, *opt_state
;
5065 struct iaddr cli_addr
;
5067 isc_boolean_t inappropriate
, has_addrs
;
5068 char reply_data
[65536];
5069 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5070 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5073 * Basic client message validation.
5075 memset(&client_id
, 0, sizeof(client_id
));
5076 if (!valid_client_msg(packet
, &client_id
)) {
5081 * Do not process Confirms that do not have IA's we do not recognize.
5083 ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5084 ta
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
5085 if ((ia
== NULL
) && (ta
== NULL
))
5089 * IA_PD's are simply ignored.
5091 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5094 * Bit of variable initialization.
5096 opt_state
= cli_enc_opt_state
= NULL
;
5097 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5098 memset(&iaaddr
, 0, sizeof(iaaddr
));
5099 memset(&packet_oro
, 0, sizeof(packet_oro
));
5101 /* Determine what shared network the client is connected to. We
5102 * must not respond if we don't have any information about the
5103 * network the client is on.
5106 if ((shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
) ||
5110 /* If there are no recorded subnets, then we have no
5111 * information about this subnet - ignore Confirms.
5113 subnet
= shared
->subnets
;
5117 /* Are the addresses in all the IA's appropriate for that link? */
5118 has_addrs
= inappropriate
= ISC_FALSE
;
5120 while(!inappropriate
) {
5121 /* If we've reached the end of the IA_NA pass, move to the
5124 if ((pass
== D6O_IA_NA
) && (ia
== NULL
)) {
5129 /* If we've reached the end of all passes, we're done. */
5133 if (((pass
== D6O_IA_NA
) &&
5134 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5136 packet
, ia
, IA_NA_OFFSET
)) ||
5137 ((pass
== D6O_IA_TA
) &&
5138 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5140 packet
, ia
, IA_TA_OFFSET
))) {
5144 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5147 for ( ; oc
!= NULL
; oc
= oc
->next
) {
5148 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5149 packet
->options
, NULL
,
5150 &global_scope
, oc
, MDL
) ||
5151 (iaaddr
.len
< IAADDR_OFFSET
)) {
5152 log_error("dhcpv6_confirm: "
5153 "error evaluating IAADDR.");
5157 /* Copy out the IPv6 address for processing. */
5159 memcpy(cli_addr
.iabuf
, iaaddr
.data
, 16);
5161 data_string_forget(&iaaddr
, MDL
);
5163 /* Record that we've processed at least one address. */
5164 has_addrs
= ISC_TRUE
;
5166 /* Find out if any subnets cover this address. */
5167 for (subnet
= shared
->subnets
; subnet
!= NULL
;
5168 subnet
= subnet
->next_sibling
) {
5169 if (addr_eq(subnet_number(cli_addr
,
5175 /* If we reach the end of the subnet list, and no
5176 * subnet matches the client address, then it must
5177 * be inappropriate to the link (so far as our
5178 * configuration says). Once we've found one
5179 * inappropriate address, there is no reason to
5180 * continue searching.
5182 if (subnet
== NULL
) {
5183 inappropriate
= ISC_TRUE
;
5188 option_state_dereference(&cli_enc_opt_state
, MDL
);
5189 data_string_forget(&cli_enc_opt_data
, MDL
);
5191 /* Advance to the next IA_*. */
5195 /* If the client supplied no addresses, do not reply. */
5202 if (!start_reply(packet
, &client_id
, NULL
, &opt_state
, reply
)) {
5209 if (inappropriate
) {
5210 if (!set_status_code(STATUS_NotOnLink
,
5211 "Some of the addresses are not on link.",
5216 if (!set_status_code(STATUS_Success
,
5217 "All addresses still on link.",
5224 * Only one option: add it.
5226 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5227 sizeof(reply_data
)-reply_ofs
,
5229 required_opts
, &packet_oro
);
5232 * Return our reply to the caller.
5234 reply_ret
->len
= reply_ofs
;
5235 reply_ret
->buffer
= NULL
;
5236 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5237 log_fatal("No memory to store reply.");
5239 reply_ret
->data
= reply_ret
->buffer
->data
;
5240 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5243 /* Cleanup any stale data strings. */
5244 if (cli_enc_opt_data
.buffer
!= NULL
)
5245 data_string_forget(&cli_enc_opt_data
, MDL
);
5246 if (iaaddr
.buffer
!= NULL
)
5247 data_string_forget(&iaaddr
, MDL
);
5248 if (client_id
.buffer
!= NULL
)
5249 data_string_forget(&client_id
, MDL
);
5250 if (packet_oro
.buffer
!= NULL
)
5251 data_string_forget(&packet_oro
, MDL
);
5253 /* Release any stale option states. */
5254 if (cli_enc_opt_state
!= NULL
)
5255 option_state_dereference(&cli_enc_opt_state
, MDL
);
5256 if (opt_state
!= NULL
)
5257 option_state_dereference(&opt_state
, MDL
);
5261 * Renew is when a client wants to extend its lease/prefix, at time T1.
5263 * We handle this the same as if the client wants a new lease/prefix,
5264 * except for the error code of when addresses don't match.
5268 dhcpv6_renew(struct data_string
*reply
, struct packet
*packet
) {
5269 struct data_string client_id
;
5270 struct data_string server_id
;
5273 * Validate the request.
5275 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5279 /* If the RENEW arrived via unicast and unicast option isn't set,
5280 * reject it per RFC 3315, Sec 18.2.3 */
5281 if (packet
->unicast
== ISC_TRUE
&&
5282 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5283 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5288 lease_to_client(reply
, packet
, &client_id
, &server_id
);
5294 data_string_forget(&server_id
, MDL
);
5295 data_string_forget(&client_id
, MDL
);
5299 * Rebind is when a client wants to extend its lease, at time T2.
5301 * We handle this the same as if the client wants a new lease, except
5302 * for the error code of when addresses don't match.
5306 dhcpv6_rebind(struct data_string
*reply
, struct packet
*packet
) {
5307 struct data_string client_id
;
5309 if (!valid_client_msg(packet
, &client_id
)) {
5313 lease_to_client(reply
, packet
, &client_id
, NULL
);
5315 data_string_forget(&client_id
, MDL
);
5319 ia_na_match_decline(const struct data_string
*client_id
,
5320 const struct data_string
*iaaddr
,
5321 struct iasubopt
*lease
)
5323 char tmp_addr
[INET6_ADDRSTRLEN
];
5325 log_error("Client %s reports address %s is "
5326 "already in use by another host!",
5327 print_hex_1(client_id
->len
, client_id
->data
, 60),
5328 inet_ntop(AF_INET6
, iaaddr
->data
,
5329 tmp_addr
, sizeof(tmp_addr
)));
5330 if (lease
!= NULL
) {
5331 decline_lease6(lease
->ipv6_pool
, lease
);
5332 lease
->ia
->cltt
= cur_time
;
5333 write_ia(lease
->ia
);
5338 ia_na_nomatch_decline(const struct data_string
*client_id
,
5339 const struct data_string
*iaaddr
,
5340 u_int32_t
*ia_na_id
,
5341 struct packet
*packet
,
5346 char tmp_addr
[INET6_ADDRSTRLEN
];
5347 struct option_state
*host_opt_state
;
5350 log_info("Client %s declines address %s, which is not offered to it.",
5351 print_hex_1(client_id
->len
, client_id
->data
, 60),
5352 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5355 * Create state for this IA_NA.
5357 host_opt_state
= NULL
;
5358 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5359 log_error("ia_na_nomatch_decline: out of memory "
5360 "allocating option_state.");
5364 if (!set_status_code(STATUS_NoBinding
, "Decline for unknown address.",
5370 * Insure we have enough space
5372 if (reply_len
< (*reply_ofs
+ 16)) {
5373 log_error("ia_na_nomatch_decline: "
5374 "out of space for reply packet.");
5379 * Put our status code into the reply packet.
5381 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5382 reply_len
-(*reply_ofs
)-16,
5383 host_opt_state
, packet
,
5384 required_opts_STATUS_CODE
, NULL
);
5387 * Store the non-encapsulated option data for this
5388 * IA_NA into our reply packet. Defined in RFC 3315,
5392 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5394 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5395 /* IA_NA, copied from the client */
5396 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5397 /* t1 and t2, odd that we need them, but here it is */
5398 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5399 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5402 * Get ready for next IA_NA.
5404 *reply_ofs
+= (len
+ 16);
5407 option_state_dereference(&host_opt_state
, MDL
);
5411 iterate_over_ia_na(struct data_string
*reply_ret
,
5412 struct packet
*packet
,
5413 const struct data_string
*client_id
,
5414 const struct data_string
*server_id
,
5415 const char *packet_type
,
5416 void (*ia_na_match
)(),
5417 void (*ia_na_nomatch
)())
5419 struct option_state
*opt_state
;
5420 struct host_decl
*packet_host
;
5421 struct option_cache
*ia
;
5422 struct option_cache
*oc
;
5423 /* cli_enc_... variables come from the IA_NA/IA_TA options */
5424 struct data_string cli_enc_opt_data
;
5425 struct option_state
*cli_enc_opt_state
;
5426 struct host_decl
*host
;
5427 struct option_state
*host_opt_state
;
5428 struct data_string iaaddr
;
5429 struct data_string fixed_addr
;
5430 char reply_data
[65536];
5431 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5432 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5433 char status_msg
[32];
5434 struct iasubopt
*lease
;
5435 struct ia_xx
*existing_ia_na
;
5437 struct data_string key
;
5441 * Initialize to empty values, in case we have to exit early.
5444 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5445 cli_enc_opt_state
= NULL
;
5446 memset(&iaaddr
, 0, sizeof(iaaddr
));
5447 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
5448 host_opt_state
= NULL
;
5452 * Find the host record that matches from the packet, if any.
5455 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
5458 * Set our reply information.
5460 reply
->msg_type
= DHCPV6_REPLY
;
5461 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
5462 sizeof(reply
->transaction_id
));
5465 * Build our option state for reply.
5468 if (!option_state_allocate(&opt_state
, MDL
)) {
5469 log_error("iterate_over_ia_na: no memory for option_state.");
5472 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5473 packet
->options
, opt_state
,
5474 &global_scope
, root_group
, NULL
, NULL
);
5477 * RFC 3315, section 18.2.7 tells us which options to include.
5479 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
5481 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5482 (unsigned char *)server_duid
.data
,
5483 server_duid
.len
, D6O_SERVERID
, 0)) {
5484 log_error("iterate_over_ia_na: "
5485 "error saving server identifier.");
5490 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
5492 (unsigned char *)client_id
->data
,
5495 log_error("iterate_over_ia_na: "
5496 "error saving client identifier.");
5500 snprintf(status_msg
, sizeof(status_msg
), "%s received.", packet_type
);
5501 if (!set_status_code(STATUS_Success
, status_msg
, opt_state
)) {
5506 * Add our options that are not associated with any IA_NA or IA_TA.
5508 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5509 sizeof(reply_data
)-reply_ofs
,
5511 required_opts
, NULL
);
5514 * Loop through the IA_NA reported by the client, and deal with
5515 * addresses reported as already in use.
5517 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5518 ia
!= NULL
; ia
= ia
->next
) {
5520 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
5522 packet
, ia
, IA_NA_OFFSET
)) {
5526 iaid
= getULong(cli_enc_opt_data
.data
);
5529 * XXX: It is possible that we can get multiple addresses
5530 * sent by the client. We don't send multiple
5531 * addresses, so this indicates a client error.
5532 * We should check for multiple IAADDR options, log
5533 * if found, and set as an error.
5535 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5538 /* no address given for this IA, ignore */
5539 option_state_dereference(&cli_enc_opt_state
, MDL
);
5540 data_string_forget(&cli_enc_opt_data
, MDL
);
5544 memset(&iaaddr
, 0, sizeof(iaaddr
));
5545 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5546 packet
->options
, NULL
,
5547 &global_scope
, oc
, MDL
)) {
5548 log_error("iterate_over_ia_na: "
5549 "error evaluating IAADDR.");
5554 * Now we need to figure out which host record matches
5555 * this IA_NA and IAADDR (encapsulated option contents
5556 * matching a host record by option).
5558 * XXX: We don't currently track IA_NA separately, but
5559 * we will need to do this!
5562 if (!find_hosts_by_option(&host
, packet
,
5563 cli_enc_opt_state
, MDL
)) {
5564 if (packet_host
!= NULL
) {
5570 while (host
!= NULL
) {
5571 if (host
->fixed_addr
!= NULL
) {
5572 if (!evaluate_option_cache(&fixed_addr
, NULL
,
5574 NULL
, &global_scope
,
5577 log_error("iterate_over_ia_na: error "
5578 "evaluating host address.");
5581 if ((iaaddr
.len
>= 16) &&
5582 !memcmp(fixed_addr
.data
, iaaddr
.data
, 16)) {
5583 data_string_forget(&fixed_addr
, MDL
);
5586 data_string_forget(&fixed_addr
, MDL
);
5588 host
= host
->n_ipaddr
;
5591 if ((host
== NULL
) && (iaaddr
.len
>= IAADDR_OFFSET
)) {
5593 * Find existing IA_NA.
5595 if (ia_make_key(&key
, iaid
,
5596 (char *)client_id
->data
,
5598 MDL
) != ISC_R_SUCCESS
) {
5599 log_fatal("iterate_over_ia_na: no memory for "
5603 existing_ia_na
= NULL
;
5604 if (ia_hash_lookup(&existing_ia_na
, ia_na_active
,
5605 (unsigned char *)key
.data
,
5608 * Make sure this address is in the IA_NA.
5610 for (i
=0; i
<existing_ia_na
->num_iasubopt
; i
++) {
5611 struct iasubopt
*tmp
;
5612 struct in6_addr
*in6_addr
;
5614 tmp
= existing_ia_na
->iasubopt
[i
];
5615 in6_addr
= &tmp
->addr
;
5616 if (memcmp(in6_addr
,
5617 iaaddr
.data
, 16) == 0) {
5618 iasubopt_reference(&lease
,
5625 data_string_forget(&key
, MDL
);
5628 if ((host
!= NULL
) || (lease
!= NULL
)) {
5629 ia_na_match(client_id
, &iaaddr
, lease
);
5631 ia_na_nomatch(client_id
, &iaaddr
,
5632 (u_int32_t
*)cli_enc_opt_data
.data
,
5633 packet
, reply_data
, &reply_ofs
,
5634 sizeof(reply_data
));
5637 if (lease
!= NULL
) {
5638 iasubopt_dereference(&lease
, MDL
);
5641 data_string_forget(&iaaddr
, MDL
);
5642 option_state_dereference(&cli_enc_opt_state
, MDL
);
5643 data_string_forget(&cli_enc_opt_data
, MDL
);
5647 * Return our reply to the caller.
5649 reply_ret
->len
= reply_ofs
;
5650 reply_ret
->buffer
= NULL
;
5651 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5652 log_fatal("No memory to store reply.");
5654 reply_ret
->data
= reply_ret
->buffer
->data
;
5655 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5658 if (lease
!= NULL
) {
5659 iasubopt_dereference(&lease
, MDL
);
5661 if (host_opt_state
!= NULL
) {
5662 option_state_dereference(&host_opt_state
, MDL
);
5664 if (fixed_addr
.buffer
!= NULL
) {
5665 data_string_forget(&fixed_addr
, MDL
);
5667 if (iaaddr
.buffer
!= NULL
) {
5668 data_string_forget(&iaaddr
, MDL
);
5670 if (cli_enc_opt_state
!= NULL
) {
5671 option_state_dereference(&cli_enc_opt_state
, MDL
);
5673 if (cli_enc_opt_data
.buffer
!= NULL
) {
5674 data_string_forget(&cli_enc_opt_data
, MDL
);
5676 if (opt_state
!= NULL
) {
5677 option_state_dereference(&opt_state
, MDL
);
5682 * Decline means a client has detected that something else is using an
5683 * address we gave it.
5685 * Since we're only dealing with fixed leases for now, there's not
5686 * much we can do, other that log the occurrence.
5688 * When we start issuing addresses from pools, then we will have to
5689 * record our declined addresses and issue another. In general with
5690 * IPv6 there is no worry about DoS by clients exhausting space, but
5691 * we still need to be aware of this possibility.
5696 dhcpv6_decline(struct data_string
*reply
, struct packet
*packet
) {
5697 struct data_string client_id
;
5698 struct data_string server_id
;
5701 * Validate our input.
5703 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5707 /* If the DECLINE arrived via unicast and unicast option isn't set,
5708 * reject it per RFC 3315, Sec 18.2.7 */
5709 if (packet
->unicast
== ISC_TRUE
&&
5710 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5711 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5714 * Undefined for IA_PD.
5716 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5719 * And operate on each IA_NA in this packet.
5721 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
5722 "Decline", ia_na_match_decline
,
5723 ia_na_nomatch_decline
);
5727 data_string_forget(&server_id
, MDL
);
5728 data_string_forget(&client_id
, MDL
);
5732 ia_na_match_release(const struct data_string
*client_id
,
5733 const struct data_string
*iaaddr
,
5734 struct iasubopt
*lease
)
5736 char tmp_addr
[INET6_ADDRSTRLEN
];
5738 log_info("Client %s releases address %s",
5739 print_hex_1(client_id
->len
, client_id
->data
, 60),
5740 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5741 if (lease
!= NULL
) {
5742 release_lease6(lease
->ipv6_pool
, lease
);
5743 lease
->ia
->cltt
= cur_time
;
5744 write_ia(lease
->ia
);
5749 ia_na_nomatch_release(const struct data_string
*client_id
,
5750 const struct data_string
*iaaddr
,
5751 u_int32_t
*ia_na_id
,
5752 struct packet
*packet
,
5757 char tmp_addr
[INET6_ADDRSTRLEN
];
5758 struct option_state
*host_opt_state
;
5761 log_info("Client %s releases address %s, which is not leased to it.",
5762 print_hex_1(client_id
->len
, client_id
->data
, 60),
5763 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5766 * Create state for this IA_NA.
5768 host_opt_state
= NULL
;
5769 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5770 log_error("ia_na_nomatch_release: out of memory "
5771 "allocating option_state.");
5775 if (!set_status_code(STATUS_NoBinding
,
5776 "Release for non-leased address.",
5782 * Insure we have enough space
5784 if (reply_len
< (*reply_ofs
+ 16)) {
5785 log_error("ia_na_nomatch_release: "
5786 "out of space for reply packet.");
5791 * Put our status code into the reply packet.
5793 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5794 reply_len
-(*reply_ofs
)-16,
5795 host_opt_state
, packet
,
5796 required_opts_STATUS_CODE
, NULL
);
5799 * Store the non-encapsulated option data for this
5800 * IA_NA into our reply packet. Defined in RFC 3315,
5804 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5806 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5807 /* IA_NA, copied from the client */
5808 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5809 /* t1 and t2, odd that we need them, but here it is */
5810 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5811 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5814 * Get ready for next IA_NA.
5816 *reply_ofs
+= (len
+ 16);
5819 option_state_dereference(&host_opt_state
, MDL
);
5823 ia_pd_match_release(const struct data_string
*client_id
,
5824 const struct data_string
*iapref
,
5825 struct iasubopt
*prefix
)
5827 char tmp_addr
[INET6_ADDRSTRLEN
];
5829 log_info("Client %s releases prefix %s/%u",
5830 print_hex_1(client_id
->len
, client_id
->data
, 60),
5831 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5832 tmp_addr
, sizeof(tmp_addr
)),
5833 (unsigned) getUChar(iapref
->data
+ 8));
5834 if (prefix
!= NULL
) {
5835 release_lease6(prefix
->ipv6_pool
, prefix
);
5836 prefix
->ia
->cltt
= cur_time
;
5837 write_ia(prefix
->ia
);
5842 ia_pd_nomatch_release(const struct data_string
*client_id
,
5843 const struct data_string
*iapref
,
5844 u_int32_t
*ia_pd_id
,
5845 struct packet
*packet
,
5850 char tmp_addr
[INET6_ADDRSTRLEN
];
5851 struct option_state
*host_opt_state
;
5854 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
5855 print_hex_1(client_id
->len
, client_id
->data
, 60),
5856 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5857 tmp_addr
, sizeof(tmp_addr
)),
5858 (unsigned) getUChar(iapref
->data
+ 8));
5861 * Create state for this IA_PD.
5863 host_opt_state
= NULL
;
5864 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5865 log_error("ia_pd_nomatch_release: out of memory "
5866 "allocating option_state.");
5870 if (!set_status_code(STATUS_NoBinding
,
5871 "Release for non-leased prefix.",
5877 * Insure we have enough space
5879 if (reply_len
< (*reply_ofs
+ 16)) {
5880 log_error("ia_pd_nomatch_release: "
5881 "out of space for reply packet.");
5886 * Put our status code into the reply packet.
5888 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5889 reply_len
-(*reply_ofs
)-16,
5890 host_opt_state
, packet
,
5891 required_opts_STATUS_CODE
, NULL
);
5894 * Store the non-encapsulated option data for this
5895 * IA_PD into our reply packet. Defined in RFC 3315,
5899 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_PD
);
5901 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5902 /* IA_PD, copied from the client */
5903 memcpy(reply_data
+(*reply_ofs
)+4, ia_pd_id
, 4);
5904 /* t1 and t2, odd that we need them, but here it is */
5905 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5906 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5909 * Get ready for next IA_PD.
5911 *reply_ofs
+= (len
+ 16);
5914 option_state_dereference(&host_opt_state
, MDL
);
5918 iterate_over_ia_pd(struct data_string
*reply_ret
,
5919 struct packet
*packet
,
5920 const struct data_string
*client_id
,
5921 const struct data_string
*server_id
,
5922 const char *packet_type
,
5923 void (*ia_pd_match
)(),
5924 void (*ia_pd_nomatch
)())
5926 struct data_string reply_new
;
5928 struct option_state
*opt_state
;
5929 struct host_decl
*packet_host
;
5930 struct option_cache
*ia
;
5931 struct option_cache
*oc
;
5932 /* cli_enc_... variables come from the IA_PD options */
5933 struct data_string cli_enc_opt_data
;
5934 struct option_state
*cli_enc_opt_state
;
5935 struct host_decl
*host
;
5936 struct option_state
*host_opt_state
;
5937 struct data_string iaprefix
;
5938 char reply_data
[65536];
5940 struct iasubopt
*prefix
;
5941 struct ia_xx
*existing_ia_pd
;
5943 struct data_string key
;
5947 * Initialize to empty values, in case we have to exit early.
5949 memset(&reply_new
, 0, sizeof(reply_new
));
5951 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5952 cli_enc_opt_state
= NULL
;
5953 memset(&iaprefix
, 0, sizeof(iaprefix
));
5954 host_opt_state
= NULL
;
5958 * Compute the available length for the reply.
5960 reply_len
= sizeof(reply_data
) - reply_ret
->len
;
5964 * Find the host record that matches from the packet, if any.
5967 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
5970 * Build our option state for reply.
5973 if (!option_state_allocate(&opt_state
, MDL
)) {
5974 log_error("iterate_over_ia_pd: no memory for option_state.");
5977 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5978 packet
->options
, opt_state
,
5979 &global_scope
, root_group
, NULL
, NULL
);
5982 * Loop through the IA_PD reported by the client, and deal with
5983 * prefixes reported as already in use.
5985 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5986 ia
!= NULL
; ia
= ia
->next
) {
5988 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
5990 packet
, ia
, IA_PD_OFFSET
)) {
5994 iaid
= getULong(cli_enc_opt_data
.data
);
5996 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5999 /* no prefix given for this IA_PD, ignore */
6000 option_state_dereference(&cli_enc_opt_state
, MDL
);
6001 data_string_forget(&cli_enc_opt_data
, MDL
);
6005 for (; oc
!= NULL
; oc
= oc
->next
) {
6006 memset(&iaprefix
, 0, sizeof(iaprefix
));
6007 if (!evaluate_option_cache(&iaprefix
, packet
, NULL
, NULL
,
6008 packet
->options
, NULL
,
6009 &global_scope
, oc
, MDL
)) {
6010 log_error("iterate_over_ia_pd: "
6011 "error evaluating IAPREFIX.");
6016 * Now we need to figure out which host record matches
6017 * this IA_PD and IAPREFIX (encapsulated option contents
6018 * matching a host record by option).
6020 * XXX: We don't currently track IA_PD separately, but
6021 * we will need to do this!
6024 if (!find_hosts_by_option(&host
, packet
,
6025 cli_enc_opt_state
, MDL
)) {
6026 if (packet_host
!= NULL
) {
6032 while (host
!= NULL
) {
6033 if (host
->fixed_prefix
!= NULL
) {
6034 struct iaddrcidrnetlist
*l
;
6035 int plen
= (int) getUChar(iaprefix
.data
+ 8);
6037 for (l
= host
->fixed_prefix
; l
!= NULL
;
6039 if (plen
!= l
->cidrnet
.bits
)
6041 if (memcmp(iaprefix
.data
+ 9,
6042 l
->cidrnet
.lo_addr
.iabuf
,
6046 if ((l
!= NULL
) && (iaprefix
.len
>= 17))
6049 host
= host
->n_ipaddr
;
6052 if ((host
== NULL
) && (iaprefix
.len
>= IAPREFIX_OFFSET
)) {
6054 * Find existing IA_PD.
6056 if (ia_make_key(&key
, iaid
,
6057 (char *)client_id
->data
,
6059 MDL
) != ISC_R_SUCCESS
) {
6060 log_fatal("iterate_over_ia_pd: no memory for "
6064 existing_ia_pd
= NULL
;
6065 if (ia_hash_lookup(&existing_ia_pd
, ia_pd_active
,
6066 (unsigned char *)key
.data
,
6069 * Make sure this prefix is in the IA_PD.
6072 i
< existing_ia_pd
->num_iasubopt
;
6074 struct iasubopt
*tmp
;
6077 plen
= getUChar(iaprefix
.data
+ 8);
6078 tmp
= existing_ia_pd
->iasubopt
[i
];
6079 if ((tmp
->plen
== plen
) &&
6083 iasubopt_reference(&prefix
,
6090 data_string_forget(&key
, MDL
);
6093 if ((host
!= NULL
) || (prefix
!= NULL
)) {
6094 ia_pd_match(client_id
, &iaprefix
, prefix
);
6096 ia_pd_nomatch(client_id
, &iaprefix
,
6097 (u_int32_t
*)cli_enc_opt_data
.data
,
6098 packet
, reply_data
, &reply_ofs
,
6099 reply_len
- reply_ofs
);
6102 if (prefix
!= NULL
) {
6103 iasubopt_dereference(&prefix
, MDL
);
6106 data_string_forget(&iaprefix
, MDL
);
6109 option_state_dereference(&cli_enc_opt_state
, MDL
);
6110 data_string_forget(&cli_enc_opt_data
, MDL
);
6114 * Return our reply to the caller.
6115 * The IA_NA routine has already filled at least the header.
6117 reply_new
.len
= reply_ret
->len
+ reply_ofs
;
6118 if (!buffer_allocate(&reply_new
.buffer
, reply_new
.len
, MDL
)) {
6119 log_fatal("No memory to store reply.");
6121 reply_new
.data
= reply_new
.buffer
->data
;
6122 memcpy(reply_new
.buffer
->data
,
6123 reply_ret
->buffer
->data
, reply_ret
->len
);
6124 memcpy(reply_new
.buffer
->data
+ reply_ret
->len
,
6125 reply_data
, reply_ofs
);
6126 data_string_forget(reply_ret
, MDL
);
6127 data_string_copy(reply_ret
, &reply_new
, MDL
);
6128 data_string_forget(&reply_new
, MDL
);
6131 if (prefix
!= NULL
) {
6132 iasubopt_dereference(&prefix
, MDL
);
6134 if (host_opt_state
!= NULL
) {
6135 option_state_dereference(&host_opt_state
, MDL
);
6137 if (iaprefix
.buffer
!= NULL
) {
6138 data_string_forget(&iaprefix
, MDL
);
6140 if (cli_enc_opt_state
!= NULL
) {
6141 option_state_dereference(&cli_enc_opt_state
, MDL
);
6143 if (cli_enc_opt_data
.buffer
!= NULL
) {
6144 data_string_forget(&cli_enc_opt_data
, MDL
);
6146 if (opt_state
!= NULL
) {
6147 option_state_dereference(&opt_state
, MDL
);
6152 * Release means a client is done with the leases.
6156 dhcpv6_release(struct data_string
*reply
, struct packet
*packet
) {
6157 struct data_string client_id
;
6158 struct data_string server_id
;
6161 * Validate our input.
6163 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
6167 /* If the RELEASE arrived via unicast and unicast option isn't set,
6168 * reject it per RFC 3315, Sec 18.2.6 */
6169 if (packet
->unicast
== ISC_TRUE
&&
6170 is_unicast_option_defined(packet
) == ISC_FALSE
) {
6171 unicast_reject(reply
, packet
, &client_id
, &server_id
);
6174 * And operate on each IA_NA in this packet.
6176 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
6177 "Release", ia_na_match_release
,
6178 ia_na_nomatch_release
);
6181 * And operate on each IA_PD in this packet.
6183 iterate_over_ia_pd(reply
, packet
, &client_id
, &server_id
,
6184 "Release", ia_pd_match_release
,
6185 ia_pd_nomatch_release
);
6188 data_string_forget(&server_id
, MDL
);
6189 data_string_forget(&client_id
, MDL
);
6193 * Information-Request is used by clients who have obtained an address
6194 * from other means, but want configuration information from the server.
6198 dhcpv6_information_request(struct data_string
*reply
, struct packet
*packet
) {
6199 struct data_string client_id
;
6200 struct data_string server_id
;
6203 * Validate our input.
6205 if (!valid_client_info_req(packet
, &server_id
)) {
6210 * Get our client ID, if there is one.
6212 memset(&client_id
, 0, sizeof(client_id
));
6213 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
) {
6214 data_string_forget(&client_id
, MDL
);
6218 * Use the lease_to_client() function. This will work fine,
6219 * because the valid_client_info_req() insures that we
6220 * don't have any IA that would cause us to allocate
6221 * resources to the client.
6223 lease_to_client(reply
, packet
, &client_id
,
6224 server_id
.data
!= NULL
? &server_id
: NULL
);
6229 if (client_id
.data
!= NULL
) {
6230 data_string_forget(&client_id
, MDL
);
6232 data_string_forget(&server_id
, MDL
);
6236 * The Relay-forw message is sent by relays. It typically contains a
6237 * single option, which encapsulates an entire packet.
6239 * We need to build an encapsulated reply.
6242 /* XXX: this is very, very similar to do_packet6(), and should probably
6243 be combined in a clever way */
6245 dhcpv6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
6246 struct option_cache
*oc
;
6247 struct data_string enc_opt_data
;
6248 struct packet
*enc_packet
;
6249 unsigned char msg_type
;
6250 const struct dhcpv6_packet
*msg
;
6251 const struct dhcpv6_relay_packet
*relay
;
6252 struct data_string enc_reply
;
6253 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6254 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6255 struct data_string a_opt
, packet_ero
;
6256 struct option_state
*opt_state
;
6257 static char reply_data
[65536];
6258 struct dhcpv6_relay_packet
*reply
;
6262 * Initialize variables for early exit.
6265 memset(&a_opt
, 0, sizeof(a_opt
));
6266 memset(&packet_ero
, 0, sizeof(packet_ero
));
6267 memset(&enc_reply
, 0, sizeof(enc_reply
));
6268 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6272 * Get our encapsulated relay message.
6274 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
6276 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
6277 link_addr
, sizeof(link_addr
));
6278 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
6279 peer_addr
, sizeof(peer_addr
));
6280 log_info("Relay-forward from %s with link address=%s and "
6281 "peer address=%s missing Relay Message option.",
6282 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
6286 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
6287 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
6288 log_error("dhcpv6_forw_relay: error evaluating "
6289 "relayed message.");
6293 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
6294 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
6299 * Build a packet structure from this encapsulated packet.
6302 if (!packet_allocate(&enc_packet
, MDL
)) {
6303 log_error("dhcpv6_forw_relay: "
6304 "no memory for encapsulated packet.");
6308 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
6309 log_error("dhcpv6_forw_relay: "
6310 "no memory for encapsulated packet's options.");
6314 enc_packet
->client_port
= packet
->client_port
;
6315 enc_packet
->client_addr
= packet
->client_addr
;
6316 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
6317 enc_packet
->dhcpv6_container_packet
= packet
;
6319 msg_type
= enc_opt_data
.data
[0];
6320 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
6321 (msg_type
== DHCPV6_RELAY_REPL
)) {
6322 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6323 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
6324 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
6326 /* relay-specific data */
6327 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
6328 memcpy(&enc_packet
->dhcpv6_link_address
,
6329 relay
->link_address
, sizeof(relay
->link_address
));
6330 memcpy(&enc_packet
->dhcpv6_peer_address
,
6331 relay
->peer_address
, sizeof(relay
->peer_address
));
6333 if (!parse_option_buffer(enc_packet
->options
,
6335 enc_opt_data
.len
- relaylen
,
6336 &dhcpv6_universe
)) {
6337 /* no logging here, as parse_option_buffer() logs all
6338 cases where it fails */
6342 int msglen
= (int)(offsetof(struct dhcpv6_packet
, options
));
6343 msg
= (struct dhcpv6_packet
*)enc_opt_data
.data
;
6344 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
6346 /* message-specific data */
6347 memcpy(enc_packet
->dhcpv6_transaction_id
,
6348 msg
->transaction_id
,
6349 sizeof(enc_packet
->dhcpv6_transaction_id
));
6351 if (!parse_option_buffer(enc_packet
->options
,
6353 enc_opt_data
.len
- msglen
,
6354 &dhcpv6_universe
)) {
6355 /* no logging here, as parse_option_buffer() logs all
6356 cases where it fails */
6362 * This is recursive. It is possible to exceed maximum packet size.
6363 * XXX: This will cause the packet send to fail.
6365 build_dhcpv6_reply(&enc_reply
, enc_packet
);
6368 * If we got no encapsulated data, then it is discarded, and
6369 * our reply-forw is also discarded.
6371 if (enc_reply
.data
== NULL
) {
6376 * Now we can use the reply_data buffer.
6377 * Packet header stuff all comes from the forward message.
6379 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
6380 reply
->msg_type
= DHCPV6_RELAY_REPL
;
6381 reply
->hop_count
= packet
->dhcpv6_hop_count
;
6382 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
6383 sizeof(reply
->link_address
));
6384 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
6385 sizeof(reply
->peer_address
));
6386 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6389 * Get the reply option state.
6392 if (!option_state_allocate(&opt_state
, MDL
)) {
6393 log_error("dhcpv6_relay_forw: no memory for option state.");
6398 * Append the interface-id if present.
6400 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6403 if (!evaluate_option_cache(&a_opt
, packet
,
6405 packet
->options
, NULL
,
6406 &global_scope
, oc
, MDL
)) {
6407 log_error("dhcpv6_relay_forw: error evaluating "
6411 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6412 (unsigned char *)a_opt
.data
,
6414 D6O_INTERFACE_ID
, 0)) {
6415 log_error("dhcpv6_relay_forw: error saving "
6419 data_string_forget(&a_opt
, MDL
);
6423 * Append our encapsulated stuff for caller.
6425 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6426 (unsigned char *)enc_reply
.data
,
6428 D6O_RELAY_MSG
, 0)) {
6429 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
6434 * Get the ERO if any.
6436 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
6441 if (!evaluate_option_cache(&packet_ero
, packet
,
6443 packet
->options
, NULL
,
6444 &global_scope
, oc
, MDL
) ||
6445 (packet_ero
.len
& 1)) {
6446 log_error("dhcpv6_relay_forw: error evaluating ERO.");
6450 /* Decode and apply the ERO. */
6451 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
6452 req
= getUShort(packet_ero
.data
+ i
);
6453 /* Already in the reply? */
6454 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
6457 /* Get it from the packet if present. */
6458 oc
= lookup_option(&dhcpv6_universe
,
6463 if (!evaluate_option_cache(&a_opt
, packet
,
6465 packet
->options
, NULL
,
6466 &global_scope
, oc
, MDL
)) {
6467 log_error("dhcpv6_relay_forw: error "
6468 "evaluating option %u.", req
);
6471 if (!save_option_buffer(&dhcpv6_universe
,
6474 (unsigned char *)a_opt
.data
,
6478 log_error("dhcpv6_relay_forw: error saving "
6482 data_string_forget(&a_opt
, MDL
);
6486 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
6487 sizeof(reply_data
) - reply_ofs
,
6489 required_opts_agent
, &packet_ero
);
6492 * Return our reply to the caller.
6494 reply_ret
->len
= reply_ofs
;
6495 reply_ret
->buffer
= NULL
;
6496 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
6497 log_fatal("No memory to store reply.");
6499 reply_ret
->data
= reply_ret
->buffer
->data
;
6500 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
6503 if (opt_state
!= NULL
)
6504 option_state_dereference(&opt_state
, MDL
);
6505 if (a_opt
.data
!= NULL
) {
6506 data_string_forget(&a_opt
, MDL
);
6508 if (packet_ero
.data
!= NULL
) {
6509 data_string_forget(&packet_ero
, MDL
);
6511 if (enc_reply
.data
!= NULL
) {
6512 data_string_forget(&enc_reply
, MDL
);
6514 if (enc_opt_data
.data
!= NULL
) {
6515 data_string_forget(&enc_opt_data
, MDL
);
6517 if (enc_packet
!= NULL
) {
6518 packet_dereference(&enc_packet
, MDL
);
6523 dhcpv6_discard(struct packet
*packet
) {
6524 /* INSIST(packet->msg_type > 0); */
6525 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
6527 log_debug("Discarding %s from %s; message type not handled by server",
6528 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
6529 piaddr(packet
->client_addr
));
6533 build_dhcpv6_reply(struct data_string
*reply
, struct packet
*packet
) {
6534 memset(reply
, 0, sizeof(*reply
));
6536 /* I would like to classify the client once here, but
6537 * as I don't want to classify all of the incoming packets
6538 * I need to do it before handling specific types.
6539 * We don't need to classify if we are tossing the packet
6540 * or if it is a relay - the classification step will get
6541 * done when we process the inner client packet.
6544 switch (packet
->dhcpv6_msg_type
) {
6545 case DHCPV6_SOLICIT
:
6546 classify_client(packet
);
6547 dhcpv6_solicit(reply
, packet
);
6549 case DHCPV6_ADVERTISE
:
6550 dhcpv6_discard(packet
);
6552 case DHCPV6_REQUEST
:
6553 classify_client(packet
);
6554 dhcpv6_request(reply
, packet
);
6556 case DHCPV6_CONFIRM
:
6557 classify_client(packet
);
6558 dhcpv6_confirm(reply
, packet
);
6561 classify_client(packet
);
6562 dhcpv6_renew(reply
, packet
);
6565 classify_client(packet
);
6566 dhcpv6_rebind(reply
, packet
);
6569 dhcpv6_discard(packet
);
6571 case DHCPV6_RELEASE
:
6572 classify_client(packet
);
6573 dhcpv6_release(reply
, packet
);
6575 case DHCPV6_DECLINE
:
6576 classify_client(packet
);
6577 dhcpv6_decline(reply
, packet
);
6579 case DHCPV6_RECONFIGURE
:
6580 dhcpv6_discard(packet
);
6582 case DHCPV6_INFORMATION_REQUEST
:
6583 classify_client(packet
);
6584 dhcpv6_information_request(reply
, packet
);
6586 case DHCPV6_RELAY_FORW
:
6587 dhcpv6_relay_forw(reply
, packet
);
6589 case DHCPV6_RELAY_REPL
:
6590 dhcpv6_discard(packet
);
6592 case DHCPV6_LEASEQUERY
:
6593 classify_client(packet
);
6594 dhcpv6_leasequery(reply
, packet
);
6596 case DHCPV6_LEASEQUERY_REPLY
:
6597 dhcpv6_discard(packet
);
6600 /* XXX: would be nice if we had "notice" level,
6601 as syslog, for this */
6602 log_info("Discarding unknown DHCPv6 message type %d "
6603 "from %s", packet
->dhcpv6_msg_type
,
6604 piaddr(packet
->client_addr
));
6609 log_packet_in(const struct packet
*packet
) {
6610 struct data_string s
;
6612 char tmp_addr
[INET6_ADDRSTRLEN
];
6615 memset(&s
, 0, sizeof(s
));
6617 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
6618 data_string_sprintfa(&s
, "%s message from %s port %d",
6619 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
6620 piaddr(packet
->client_addr
),
6621 ntohs(packet
->client_port
));
6623 data_string_sprintfa(&s
,
6624 "Unknown message type %d from %s port %d",
6625 packet
->dhcpv6_msg_type
,
6626 piaddr(packet
->client_addr
),
6627 ntohs(packet
->client_port
));
6629 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
6630 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
6631 addr
= &packet
->dhcpv6_link_address
;
6632 data_string_sprintfa(&s
, ", link address %s",
6633 inet_ntop(AF_INET6
, addr
,
6634 tmp_addr
, sizeof(tmp_addr
)));
6635 addr
= &packet
->dhcpv6_peer_address
;
6636 data_string_sprintfa(&s
, ", peer address %s",
6637 inet_ntop(AF_INET6
, addr
,
6638 tmp_addr
, sizeof(tmp_addr
)));
6641 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
6642 data_string_sprintfa(&s
, ", transaction ID 0x%06X", tid
);
6645 oc = lookup_option(&dhcpv6_universe, packet->options,
6648 memset(&tmp_ds, 0, sizeof(tmp_ds_));
6649 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
6650 packet->options, NULL,
6651 &global_scope, oc, MDL)) {
6652 log_error("Error evaluating Client Identifier");
6654 data_strint_sprintf(&s, ", client ID %s",
6656 data_string_forget(&tmp_ds, MDL);
6662 log_info("%s", s
.data
);
6664 data_string_forget(&s
, MDL
);
6668 dhcpv6(struct packet
*packet
) {
6669 struct data_string reply
;
6670 struct sockaddr_in6 to_addr
;
6674 * Log a message that we received this packet.
6676 log_packet_in(packet
);
6679 * Build our reply packet.
6681 build_dhcpv6_reply(&reply
, packet
);
6683 if (reply
.data
!= NULL
) {
6685 * Send our reply, if we have one.
6687 memset(&to_addr
, 0, sizeof(to_addr
));
6688 to_addr
.sin6_family
= AF_INET6
;
6689 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
6690 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
6691 to_addr
.sin6_port
= local_port
;
6693 to_addr
.sin6_port
= remote_port
;
6696 #if defined (REPLY_TO_SOURCE_PORT)
6698 * This appears to have been included for testing so we would
6699 * not need a root client, but was accidently left in the
6700 * final code. We continue to include it in case
6701 * some users have come to rely upon it, but leave
6702 * it off by default as it's a bad idea.
6704 to_addr
.sin6_port
= packet
->client_port
;
6707 memcpy(&to_addr
.sin6_addr
, packet
->client_addr
.iabuf
,
6708 sizeof(to_addr
.sin6_addr
));
6710 log_info("Sending %s to %s port %d",
6711 dhcpv6_type_names
[reply
.data
[0]],
6712 piaddr(packet
->client_addr
),
6713 ntohs(to_addr
.sin6_port
));
6715 send_ret
= send_packet6(packet
->interface
,
6716 reply
.data
, reply
.len
, &to_addr
);
6717 if (send_ret
!= reply
.len
) {
6718 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
6719 send_ret
, reply
.len
);
6721 data_string_forget(&reply
, MDL
);
6726 seek_shared_host(struct host_decl
**hp
, struct shared_network
*shared
) {
6727 struct host_decl
*nofixed
= NULL
;
6728 struct host_decl
*seek
, *hold
= NULL
;
6731 * Seek forward through fixed addresses for the right link.
6733 * Note: how to do this for fixed prefixes???
6735 host_reference(&hold
, *hp
, MDL
);
6736 host_dereference(hp
, MDL
);
6738 while (seek
!= NULL
) {
6739 if (seek
->fixed_addr
== NULL
)
6741 else if (fixed_matches_shared(seek
, shared
))
6744 seek
= seek
->n_ipaddr
;
6747 if ((seek
== NULL
) && (nofixed
!= NULL
))
6751 host_reference(hp
, seek
, MDL
);
6754 static isc_boolean_t
6755 fixed_matches_shared(struct host_decl
*host
, struct shared_network
*shared
) {
6756 struct subnet
*subnet
;
6757 struct data_string addr
;
6758 isc_boolean_t matched
;
6761 if (host
->fixed_addr
== NULL
)
6764 memset(&addr
, 0, sizeof(addr
));
6765 if (!evaluate_option_cache(&addr
, NULL
, NULL
, NULL
, NULL
, NULL
,
6766 &global_scope
, host
->fixed_addr
, MDL
))
6769 if (addr
.len
< 16) {
6770 data_string_forget(&addr
, MDL
);
6775 memcpy(fixed
.iabuf
, addr
.data
, 16);
6777 matched
= ISC_FALSE
;
6778 for (subnet
= shared
->subnets
; subnet
!= NULL
;
6779 subnet
= subnet
->next_sibling
) {
6780 if (addr_eq(subnet_number(fixed
, subnet
->netmask
),
6787 data_string_forget(&addr
, MDL
);
6793 * \brief Constructs a REPLY with status of UseMulticast to a given packet
6795 * Per RFC 3315 Secs 18.2.1,3,6 & 7, when a server rejects a client's
6796 * unicast-sent packet, the response must only contain the client id,
6797 * server id, and a status code option of 5 (UseMulticast). This function
6798 * constructs such a packet and returns it as a data_string.
6800 * \param reply_ret = data_string which will receive the newly constructed
6802 * \param packet = client request which is being rejected
6803 * \param client_id = data_string which contains the client id
6804 * \param server_id = data_string which which contains the server id
6808 unicast_reject(struct data_string
*reply_ret
,
6809 struct packet
*packet
,
6810 const struct data_string
*client_id
,
6811 const struct data_string
*server_id
)
6813 struct reply_state reply
;
6814 memset(&reply
, 0x0, sizeof(struct reply_state
));
6816 /* Locate the client. */
6817 if (shared_network_from_packet6(&reply
.shared
, packet
)
6819 log_error("unicast_reject: could not locate client.");
6823 /* Initialize the reply. */
6824 packet_reference(&reply
.packet
, packet
, MDL
);
6825 data_string_copy(&reply
.client_id
, client_id
, MDL
);
6827 if (start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
6828 &reply
.buf
.reply
)) {
6829 /* Set the UseMulticast status code. */
6830 if (!set_status_code(STATUS_UseMulticast
,
6831 "Unicast not allowed by server.",
6833 log_error("unicast_reject: Unable to set status code.");
6835 /* Set write cursor to just past the reply header. */
6836 reply
.cursor
= REPLY_OPTIONS_INDEX
;
6837 reply
.cursor
+= store_options6(((char *)reply
.buf
.data
6843 unicast_reject_opts
,
6846 /* Return our reply to the caller. */
6847 reply_ret
->len
= reply
.cursor
;
6848 reply_ret
->buffer
= NULL
;
6849 if (!buffer_allocate(&reply_ret
->buffer
,
6850 reply
.cursor
, MDL
)) {
6851 log_fatal("unicast_reject:"
6852 "No memory to store Reply.");
6855 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
,
6857 reply_ret
->data
= reply_ret
->buffer
->data
;
6863 if (reply
.shared
!= NULL
)
6864 shared_network_dereference(&reply
.shared
, MDL
);
6865 if (reply
.opt_state
!= NULL
)
6866 option_state_dereference(&reply
.opt_state
, MDL
);
6867 if (reply
.packet
!= NULL
)
6868 packet_dereference(&reply
.packet
, MDL
);
6869 if (reply
.client_id
.data
!= NULL
)
6870 data_string_forget(&reply
.client_id
, MDL
);
6875 * \brief Checks if the dhcp6.unicast option has been defined
6877 * Scans the option space for the presence of the dhcp6.unicast option. The
6878 * function attempts to map the inbound packet to a shared network first
6879 * by an ip address specified via an D6O_IA_XX option and if that fails then
6880 * by the packet's source information (e.g. relay link, link, or interace).
6881 * Once the packet is mapped to a shared network, the function executes all
6882 * statements from the network's group outward into a local option cache.
6883 * The option cache is then scanned for the presence of unicast option. If
6884 * the packet cannot be mapped to a shared network, the function returns
6886 * \param packet inbound packet from the client
6888 * \return ISC_TRUE if the dhcp6.unicast option is defined, false otherwise.
6892 is_unicast_option_defined(struct packet
*packet
) {
6893 isc_boolean_t is_defined
= ISC_FALSE
;
6894 struct option_state
*opt_state
= NULL
;
6895 struct option_cache
*oc
= NULL
;
6896 struct shared_network
*shared
= NULL
;
6898 if (!option_state_allocate(&opt_state
, MDL
)) {
6899 log_fatal("is_unicast_option_defined:"
6900 "No memory for option state.");
6903 /* We try to map the packet to a network first by an IA_XX value.
6904 * If that fails, we try by packet source. */
6905 if (((shared_network_from_requested_addr(&shared
, packet
)
6906 != ISC_R_SUCCESS
) &&
6907 (shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
))
6908 || (shared
== NULL
)) {
6909 /* @todo what would this really mean? I think wrong network
6910 * logic will catch it */
6911 log_error("is_unicast_option_defined:"
6912 "cannot attribute packet to a network.");
6916 /* Now that we've mapped it to a network, execute statments to that
6917 * scope, looking for the unicast option. We don't care about the
6918 * value of the option, only whether or not it is defined. */
6919 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
, opt_state
,
6920 &global_scope
, shared
->group
, NULL
, NULL
);
6922 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_UNICAST
);
6923 is_defined
= (oc
!= NULL
? ISC_TRUE
: ISC_FALSE
);
6924 log_debug("is_unicast_option_defined: option found : %d", is_defined
);
6926 if (shared
!= NULL
) {
6927 shared_network_dereference(&shared
, MDL
);
6930 if (opt_state
!= NULL
) {
6931 option_state_dereference(&opt_state
, MDL
);
6934 return (is_defined
);
6939 * \brief Maps a packet to a shared network based on the requested IP address
6941 * The function attempts to find a subnet that matches the first requested IP
6942 * address contained within the given packet. Note that it looks first for
6943 * D6O_IA_NAs, then D6O_IA_PDs and lastly D6O_IA_TAs. If a matching network is
6944 * found, a reference to it is returned in the parameter, shared.
6946 * \param shared shared_network pointer which will receive the matching network
6947 * \param packet inbound packet from the client
6949 * \return ISC_R_SUCCESS if the packet can be mapped to a shared_network.
6953 shared_network_from_requested_addr (struct shared_network
**shared
,
6954 struct packet
* packet
) {
6956 struct subnet
* subnet
= NULL
;
6957 isc_result_t status
= ISC_R_FAILURE
;
6959 /* Try to match first IA_ address or prefix we find to a subnet. In
6960 * theory all IA_ values in a given request are supposed to be in the
6961 * same subnet so we only need to try one right? */
6962 if ((get_first_ia_addr_val(packet
, D6O_IA_NA
, &iaddr
) != ISC_R_SUCCESS
)
6963 && (get_first_ia_addr_val(packet
, D6O_IA_PD
, &iaddr
)
6965 && (get_first_ia_addr_val(packet
, D6O_IA_TA
, &iaddr
)
6966 != ISC_R_SUCCESS
)) {
6967 /* we found nothing to match against */
6968 log_debug("share_network_from_request_addr: nothing to match");
6969 return (ISC_R_FAILURE
);
6972 if (!find_subnet(&subnet
, iaddr
, MDL
)) {
6973 log_debug("shared_network_from_requested_addr:"
6974 "No subnet found for addr %s.", piaddr(iaddr
));
6976 status
= shared_network_reference(shared
,
6977 subnet
->shared_network
, MDL
);
6978 subnet_dereference(&subnet
, MDL
);
6979 log_debug("shared_network_from_requested_addr:"
6980 " found shared network %s for address %s.",
6981 ((*shared
)->name
? (*shared
)->name
: "unnamed"),
6986 return (ISC_R_FAILURE
);
6991 * \brief Retrieves the first IP address from a given packet of a given type
6993 * Search a packet for options of a given type (D6O_IA_AN, D6O_IA_PD, or
6994 * D6O_IA_TA) for the first non-blank IA_XX value and return its IP address
6997 * \param packet packet received from the client
6998 * \param addr_type the address option type (D6O_IA_NA , D6O_IA_PD, or
6999 * D6O_IP_TA) to look for within the packet.
7000 * \param iaddr pointer to the iaddr structure which will receive the extracted
7003 * \return ISC_R_SUCCESS if an address was succesfully extracted, ISC_R_FALURE
7008 get_first_ia_addr_val (struct packet
* packet
, int addr_type
,
7009 struct iaddr
* iaddr
) {
7010 struct option_cache
*ia
;
7011 struct option_cache
*oc
= NULL
;
7012 struct data_string cli_enc_opt_data
;
7013 struct option_state
*cli_enc_opt_state
;
7014 int addr_opt_offset
;
7016 int addr_opt_data_len
;
7019 isc_result_t status
= ISC_R_FAILURE
;
7020 memset(iaddr
, 0, sizeof(struct iaddr
));
7022 /* Set up address type specifics */
7023 switch (addr_type
) {
7025 addr_opt_offset
= IA_NA_OFFSET
;
7026 addr_opt
= D6O_IAADDR
;
7027 addr_opt_data_len
= 24;
7031 addr_opt_offset
= IA_TA_OFFSET
;
7032 addr_opt
= D6O_IAADDR
;
7033 addr_opt_data_len
= 24;
7037 addr_opt_offset
= IA_PD_OFFSET
;
7038 addr_opt
= D6O_IAPREFIX
;
7039 addr_opt_data_len
= 25;
7043 /* shouldn't be here */
7044 log_error ("get_first_ia_addr_val: invalid opt type %d",
7046 return (ISC_R_FAILURE
);
7049 /* Find the first, non-blank IA_XX value within an D6O_IA_XX option. */
7050 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, addr_type
);
7051 ia
!= NULL
&& oc
== NULL
; ia
= ia
->next
) {
7052 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
7054 packet
, ia
, addr_opt_offset
)) {
7055 log_debug ("get_first_ia_addr_val:"
7056 " couldn't unroll enclosing option");
7057 return (ISC_R_FAILURE
);
7060 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
7063 /* no address given for this IA, ignore */
7064 option_state_dereference(&cli_enc_opt_state
, MDL
);
7065 data_string_forget(&cli_enc_opt_data
, MDL
);
7069 /* If we found a non-blank IA_XX then extract its ip address. */
7071 struct data_string iaddr_str
;
7073 memset(&iaddr_str
, 0, sizeof(iaddr_str
));
7074 if (!evaluate_option_cache(&iaddr_str
, packet
, NULL
, NULL
,
7075 packet
->options
, NULL
, &global_scope
,
7077 log_error("get_first_ia_addr_val: "
7078 "error evaluating IA_XX option.");
7080 if (iaddr_str
.len
!= addr_opt_data_len
) {
7081 log_error("shared_network_from_requested_addr:"
7082 " invalid length %d, expected %d",
7083 iaddr_str
.len
, addr_opt_data_len
);
7086 memcpy (iaddr
->iabuf
,
7087 iaddr_str
.data
+ ip_addr_offset
, 16);
7088 status
= ISC_R_SUCCESS
;
7090 data_string_forget(&iaddr_str
, MDL
);
7093 option_state_dereference(&cli_enc_opt_state
, MDL
);
7094 data_string_forget(&cli_enc_opt_data
, MDL
);
7101 * \brief Calculates the reply T1/T2 times and stuffs them in outbound buffer
7103 * T1/T2 time selection is kind of weird. We actually use DHCP * (v4) scoped
7104 * options, dhcp-renewal-time and dhcp-rebinding-time, as handy existing places
7105 * where these can be configured by an administrator. A value of zero tells the
7106 * client it may choose its own value.
7108 * When those options are not defined, the values will be set to zero unless
7109 * the global option, dhcpv6-set-tee-times is enabled. When this option is
7110 * enabled the values are calculated as recommended by RFC 3315, Section 22.4:
7112 * T1 will be set to 0.5 times the shortest preferred lifetime
7113 * in the IA_XX option. If the "shortest" preferred lifetime is
7114 * 0xFFFFFFFF, T1 will set to 0xFFFFFFFF.
7116 * T2 will be set to 0.8 times the shortest preferred lifetime
7117 * in the IA_XX option. If the "shortest" preferred lifetime is
7118 * 0xFFFFFFFF, T2 will set to 0xFFFFFFFF.
7120 * Note that dhcpv6-set-tee-times is intended to be transitional and will
7121 * likely be removed in 4.4.0, leaving the behavior as getting the values
7122 * either from the configured parameters (if you want zeros, define them as
7123 * zeros) or by calculating them per the RFC.
7125 * \param reply - pointer to the reply_state structure
7126 * \param ia_cursor - offset of the beginning of the IA_XX option within the
7127 * reply's outbound data buffer
7130 set_reply_tee_times(struct reply_state
* reply
, unsigned ia_cursor
)
7132 struct option_cache
*oc
;
7135 /* Found out if calculated values are enabled. */
7136 oc
= lookup_option(&server_universe
, reply
->opt_state
,
7137 SV_DHCPV6_SET_TEE_TIMES
);
7138 set_tee_times
= (oc
&&
7139 evaluate_boolean_option_cache(NULL
, reply
->packet
,
7141 reply
->packet
->options
,
7143 &global_scope
, oc
, MDL
));
7145 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
7146 DHO_DHCP_RENEWAL_TIME
);
7148 /* dhcp-renewal-time is defined, use it */
7149 struct data_string data
;
7150 memset(&data
, 0x00, sizeof(data
));
7152 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
7153 reply
->packet
->options
,
7154 reply
->opt_state
, &global_scope
,
7157 log_error("Invalid renewal time.");
7160 reply
->renew
= getULong(data
.data
);
7163 if (data
.data
!= NULL
)
7164 data_string_forget(&data
, MDL
);
7165 } else if (set_tee_times
) {
7166 /* Setting them is enabled so T1 is either infinite or
7167 * 0.5 * the shortest preferred lifetime in the IA_XX */
7168 reply
->renew
= (reply
->min_prefer
== 0xFFFFFFFF ? 0xFFFFFFFF
7169 : reply
->min_prefer
/ 2);
7171 /* Default is to let the client choose */
7175 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
7178 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
7179 DHO_DHCP_REBINDING_TIME
);
7181 /* dhcp-rebinding-time is defined, use it */
7182 struct data_string data
;
7183 memset(&data
, 0x00, sizeof(data
));
7185 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
7186 reply
->packet
->options
,
7187 reply
->opt_state
, &global_scope
,
7190 log_error("Invalid rebinding time.");
7193 reply
->rebind
= getULong(data
.data
);
7196 if (data
.data
!= NULL
)
7197 data_string_forget(&data
, MDL
);
7198 } else if (set_tee_times
) {
7199 /* Setting them is enabled so T2 is either infinite or
7200 * 0.8 * the shortest preferred lifetime in the reply */
7201 reply
->rebind
= (reply
->min_prefer
== 0xFFFFFFFF ? 0xFFFFFFFF
7202 : (reply
->min_prefer
/ 5) * 4);
7204 /* Default is to let the client choose */
7208 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);