1 /* $NetBSD: dhcpv6.c,v 1.5 2014/07/12 12:09:38 spz Exp $ */
3 * Copyright (C) 2006-2013 by Internet Systems Consortium, Inc. ("ISC")
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 #include <sys/cdefs.h>
19 __RCSID("$NetBSD: dhcpv6.c,v 1.5 2014/07/12 12:09:38 spz Exp $");
21 /*! \file server/dhcpv6.c */
28 * We use print_hex_1() to output DUID values. We could actually output
29 * the DUID with more information... MAC address if using type 1 or 3,
30 * and so on. However, RFC 3315 contains Grave Warnings against actually
31 * attempting to understand a DUID.
35 * TODO: gettext() or other method of localization for the messages
36 * for status codes (and probably for log formats eventually)
37 * TODO: refactoring (simplify, simplify, simplify)
38 * TODO: support multiple shared_networks on each interface (this
39 * will allow the server to issue multiple IPv6 addresses to
44 * DHCPv6 Reply workflow assist. A Reply packet is built by various
45 * different functions; this gives us one location where we keep state
49 /* root level persistent state */
50 struct shared_network
*shared
;
51 struct host_decl
*host
;
52 struct subnet
*subnet
; /* Used to match fixed-addrs to subnet scopes. */
53 struct option_state
*opt_state
;
54 struct packet
*packet
;
55 struct data_string client_id
;
57 /* IA level persistent state */
60 unsigned client_resources
;
61 isc_boolean_t resources_included
;
62 isc_boolean_t static_lease
;
63 unsigned static_prefixes
;
66 struct option_state
*reply_ia
;
67 struct data_string fixed
;
68 struct iaddrcidrnet fixed_pref
; /* static prefix for logging */
70 /* IAADDR/PREFIX level persistent state */
71 struct iasubopt
*lease
;
74 * "t1", "t2", preferred, and valid lifetimes records for calculating
75 * t1 and t2 (min/max).
77 u_int32_t renew
, rebind
, prefer
, valid
;
79 /* Client-requested valid and preferred lifetimes. */
80 u_int32_t client_valid
, client_prefer
;
82 /* Chosen values to transmit for valid and preferred lifetimes. */
83 u_int32_t send_valid
, send_prefer
;
85 /* Preferred prefix length (-1 is any). */
88 /* Index into the data field that has been consumed. */
91 /* Space for the on commit statements for a fixed host */
92 struct on_star on_star
;
95 unsigned char data
[65536];
96 struct dhcpv6_packet reply
;
101 * Prototypes local to this file.
103 static int get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
104 struct data_string
*enc_opt_data
,
105 struct packet
*packet
,
106 struct option_cache
*oc
,
108 static void build_dhcpv6_reply(struct data_string
*, struct packet
*);
109 static isc_result_t
shared_network_from_packet6(struct shared_network
**shared
,
110 struct packet
*packet
);
111 static void seek_shared_host(struct host_decl
**hp
,
112 struct shared_network
*shared
);
113 static isc_boolean_t
fixed_matches_shared(struct host_decl
*host
,
114 struct shared_network
*shared
);
115 static isc_result_t
reply_process_ia_na(struct reply_state
*reply
,
116 struct option_cache
*ia
);
117 static isc_result_t
reply_process_ia_ta(struct reply_state
*reply
,
118 struct option_cache
*ia
);
119 static isc_result_t
reply_process_addr(struct reply_state
*reply
,
120 struct option_cache
*addr
);
121 static isc_boolean_t
address_is_owned(struct reply_state
*reply
,
123 static isc_boolean_t
temporary_is_available(struct reply_state
*reply
,
125 static isc_result_t
find_client_temporaries(struct reply_state
*reply
);
126 static isc_result_t
reply_process_try_addr(struct reply_state
*reply
,
128 static isc_result_t
find_client_address(struct reply_state
*reply
);
129 static isc_result_t
reply_process_is_addressed(struct reply_state
*reply
,
130 struct binding_scope
**scope
,
131 struct group
*group
);
132 static isc_result_t
reply_process_send_addr(struct reply_state
*reply
,
134 static struct iasubopt
*lease_compare(struct iasubopt
*alpha
,
135 struct iasubopt
*beta
);
136 static isc_result_t
reply_process_ia_pd(struct reply_state
*reply
,
137 struct option_cache
*ia_pd
);
138 static isc_result_t
reply_process_prefix(struct reply_state
*reply
,
139 struct option_cache
*pref
);
140 static isc_boolean_t
prefix_is_owned(struct reply_state
*reply
,
141 struct iaddrcidrnet
*pref
);
142 static isc_result_t
find_client_prefix(struct reply_state
*reply
);
143 static isc_result_t
reply_process_try_prefix(struct reply_state
*reply
,
144 struct iaddrcidrnet
*pref
);
145 static isc_result_t
reply_process_is_prefixed(struct reply_state
*reply
,
146 struct binding_scope
**scope
,
147 struct group
*group
);
148 static isc_result_t
reply_process_send_prefix(struct reply_state
*reply
,
149 struct iaddrcidrnet
*pref
);
150 static struct iasubopt
*prefix_compare(struct reply_state
*reply
,
151 struct iasubopt
*alpha
,
152 struct iasubopt
*beta
);
153 static int find_hosts_by_duid_chaddr(struct host_decl
**host
,
154 const struct data_string
*client_id
);
156 * This function returns the time since DUID time start for the
157 * given time_t value.
160 duid_time(time_t when
) {
162 * This time is modulo 2^32.
164 while ((when
- DUID_TIME_EPOCH
) > 4294967295u) {
165 /* use 2^31 to avoid spurious compiler warnings */
170 return when
- DUID_TIME_EPOCH
;
177 * This must remain the same for the lifetime of this server, because
178 * clients return the server DUID that we sent them in Request packets.
180 * We pick the server DUID like this:
182 * 1. Check dhcpd.conf - any value the administrator has configured
183 * overrides any possible values.
184 * 2. Check the leases.txt - we want to use the previous value if
186 * 3. Check if dhcpd.conf specifies a type of server DUID to use,
187 * and generate that type.
188 * 4. Generate a type 1 (time + hardware address) DUID.
190 static struct data_string server_duid
;
193 * Check if the server_duid has been set.
196 server_duid_isset(void) {
197 return (server_duid
.data
!= NULL
);
201 * Return the server_duid.
204 copy_server_duid(struct data_string
*ds
, const char *file
, int line
) {
205 data_string_copy(ds
, &server_duid
, file
, line
);
209 * Set the server DUID to a specified value. This is used when
210 * the server DUID is stored in persistent memory (basically the
214 set_server_duid(struct data_string
*new_duid
) {
215 /* INSIST(new_duid != NULL); */
216 /* INSIST(new_duid->data != NULL); */
218 if (server_duid_isset()) {
219 data_string_forget(&server_duid
, MDL
);
221 data_string_copy(&server_duid
, new_duid
, MDL
);
226 * Set the server DUID based on the D6O_SERVERID option. This handles
227 * the case where the administrator explicitly put it in the dhcpd.conf
231 set_server_duid_from_option(void) {
232 struct option_state
*opt_state
;
233 struct option_cache
*oc
;
234 struct data_string option_duid
;
235 isc_result_t ret_val
;
238 if (!option_state_allocate(&opt_state
, MDL
)) {
239 log_fatal("No memory for server DUID.");
242 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
,
243 opt_state
, &global_scope
, root_group
,
246 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
248 ret_val
= ISC_R_NOTFOUND
;
250 memset(&option_duid
, 0, sizeof(option_duid
));
251 if (!evaluate_option_cache(&option_duid
, NULL
, NULL
, NULL
,
252 opt_state
, NULL
, &global_scope
,
254 ret_val
= ISC_R_UNEXPECTED
;
256 set_server_duid(&option_duid
);
257 data_string_forget(&option_duid
, MDL
);
258 ret_val
= ISC_R_SUCCESS
;
262 option_state_dereference(&opt_state
, MDL
);
268 * DUID layout, as defined in RFC 3315, section 9.
270 * We support type 1 (hardware address plus time) and type 3 (hardware
273 * We can support type 2 for specific vendors in the future, if they
274 * publish the specification. And of course there may be additional
277 static int server_duid_type
= DUID_LLT
;
283 set_server_duid_type(int type
) {
284 server_duid_type
= type
;
288 * Generate a new server DUID. This is done if there was no DUID in
289 * the leases.txt or in the dhcpd.conf file.
292 generate_new_server_duid(void) {
293 struct interface_info
*p
;
295 struct data_string generated_duid
;
298 * Verify we have a type that we support.
300 if ((server_duid_type
!= DUID_LL
) && (server_duid_type
!= DUID_LLT
)) {
301 log_error("Invalid DUID type %d specified, "
302 "only LL and LLT types supported", server_duid_type
);
303 return DHCP_R_INVALIDARG
;
307 * Find an interface with a hardware address.
310 for (p
= interfaces
; p
!= NULL
; p
= p
->next
) {
311 if (p
->hw_address
.hlen
> 0) {
316 return ISC_R_UNEXPECTED
;
322 memset(&generated_duid
, 0, sizeof(generated_duid
));
323 if (server_duid_type
== DUID_LLT
) {
324 time_val
= duid_time(time(NULL
));
325 generated_duid
.len
= 8 + p
->hw_address
.hlen
- 1;
326 if (!buffer_allocate(&generated_duid
.buffer
,
327 generated_duid
.len
, MDL
)) {
328 log_fatal("No memory for server DUID.");
330 generated_duid
.data
= generated_duid
.buffer
->data
;
331 putUShort(generated_duid
.buffer
->data
, DUID_LLT
);
332 putUShort(generated_duid
.buffer
->data
+ 2,
333 p
->hw_address
.hbuf
[0]);
334 putULong(generated_duid
.buffer
->data
+ 4, time_val
);
335 memcpy(generated_duid
.buffer
->data
+ 8,
336 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
337 } else if (server_duid_type
== DUID_LL
) {
338 generated_duid
.len
= 4 + p
->hw_address
.hlen
- 1;
339 if (!buffer_allocate(&generated_duid
.buffer
,
340 generated_duid
.len
, MDL
)) {
341 log_fatal("No memory for server DUID.");
343 generated_duid
.data
= generated_duid
.buffer
->data
;
344 putUShort(generated_duid
.buffer
->data
, DUID_LL
);
345 putUShort(generated_duid
.buffer
->data
+ 2,
346 p
->hw_address
.hbuf
[0]);
347 memcpy(generated_duid
.buffer
->data
+ 4,
348 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
350 log_fatal("Unsupported server DUID type %d.", server_duid_type
);
353 set_server_duid(&generated_duid
);
354 data_string_forget(&generated_duid
, MDL
);
356 return ISC_R_SUCCESS
;
360 * Get the client identifier from the packet.
363 get_client_id(struct packet
*packet
, struct data_string
*client_id
) {
364 struct option_cache
*oc
;
367 * Verify our client_id structure is empty.
369 if ((client_id
->data
!= NULL
) || (client_id
->len
!= 0)) {
370 return DHCP_R_INVALIDARG
;
373 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_CLIENTID
);
375 return ISC_R_NOTFOUND
;
378 if (!evaluate_option_cache(client_id
, packet
, NULL
, NULL
,
379 packet
->options
, NULL
,
380 &global_scope
, oc
, MDL
)) {
381 return ISC_R_FAILURE
;
384 return ISC_R_SUCCESS
;
388 * Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
390 * Servers MUST discard any Solicit messages that do not include a
391 * Client Identifier option or that do include a Server Identifier
395 valid_client_msg(struct packet
*packet
, struct data_string
*client_id
) {
397 struct option_cache
*oc
;
398 struct data_string data
;
401 memset(client_id
, 0, sizeof(*client_id
));
402 memset(&data
, 0, sizeof(data
));
404 switch (get_client_id(packet
, client_id
)) {
408 log_debug("Discarding %s from %s; "
409 "client identifier missing",
410 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
411 piaddr(packet
->client_addr
));
414 log_error("Error processing %s from %s; "
415 "unable to evaluate Client Identifier",
416 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
417 piaddr(packet
->client_addr
));
422 * Required by RFC 3315, section 15.
424 if (packet
->unicast
) {
425 log_debug("Discarding %s from %s; packet sent unicast "
427 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
428 piaddr(packet
->client_addr
),
429 print_hex_1(client_id
->len
, client_id
->data
, 60));
434 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
436 if (evaluate_option_cache(&data
, packet
, NULL
, NULL
,
437 packet
->options
, NULL
,
438 &global_scope
, oc
, MDL
)) {
439 log_debug("Discarding %s from %s; "
440 "server identifier found "
441 "(CLIENTID %s, SERVERID %s)",
442 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
443 piaddr(packet
->client_addr
),
444 print_hex_1(client_id
->len
,
445 client_id
->data
, 60),
446 print_hex_2(data
.len
,
449 log_debug("Discarding %s from %s; "
450 "server identifier found "
452 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
453 print_hex_1(client_id
->len
,
454 client_id
->data
, 60),
455 piaddr(packet
->client_addr
));
465 data_string_forget(&data
, MDL
);
468 if (client_id
->len
> 0) {
469 data_string_forget(client_id
, MDL
);
476 * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
477 * 15.9 (slightly different wording, but same meaning):
479 * Servers MUST discard any received Request message that meet any of
480 * the following conditions:
482 * - the message does not include a Server Identifier option.
483 * - the contents of the Server Identifier option do not match the
485 * - the message does not include a Client Identifier option.
488 valid_client_resp(struct packet
*packet
,
489 struct data_string
*client_id
,
490 struct data_string
*server_id
)
493 struct option_cache
*oc
;
495 /* INSIST((duid.data != NULL) && (duid.len > 0)); */
498 memset(client_id
, 0, sizeof(*client_id
));
499 memset(server_id
, 0, sizeof(*server_id
));
501 switch (get_client_id(packet
, client_id
)) {
505 log_debug("Discarding %s from %s; "
506 "client identifier missing",
507 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
508 piaddr(packet
->client_addr
));
511 log_error("Error processing %s from %s; "
512 "unable to evaluate Client Identifier",
513 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
514 piaddr(packet
->client_addr
));
518 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
520 log_debug("Discarding %s from %s: "
521 "server identifier missing (CLIENTID %s)",
522 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
523 piaddr(packet
->client_addr
),
524 print_hex_1(client_id
->len
, client_id
->data
, 60));
527 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
528 packet
->options
, NULL
,
529 &global_scope
, oc
, MDL
)) {
530 log_error("Error processing %s from %s; "
531 "unable to evaluate Server Identifier (CLIENTID %s)",
532 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
533 piaddr(packet
->client_addr
),
534 print_hex_1(client_id
->len
, client_id
->data
, 60));
537 if ((server_duid
.len
!= server_id
->len
) ||
538 (memcmp(server_duid
.data
, server_id
->data
, server_duid
.len
) != 0)) {
539 log_debug("Discarding %s from %s; "
540 "not our server identifier "
541 "(CLIENTID %s, SERVERID %s, server DUID %s)",
542 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
543 piaddr(packet
->client_addr
),
544 print_hex_1(client_id
->len
, client_id
->data
, 60),
545 print_hex_2(server_id
->len
, server_id
->data
, 60),
546 print_hex_3(server_duid
.len
, server_duid
.data
, 60));
555 if (server_id
->len
> 0) {
556 data_string_forget(server_id
, MDL
);
558 if (client_id
->len
> 0) {
559 data_string_forget(client_id
, MDL
);
566 * Information request validation, defined in RFC 3315, section 15.12:
568 * Servers MUST discard any received Information-request message that
569 * meets any of the following conditions:
571 * - The message includes a Server Identifier option and the DUID in
572 * the option does not match the server's DUID.
574 * - The message includes an IA option.
577 valid_client_info_req(struct packet
*packet
, struct data_string
*server_id
) {
579 struct option_cache
*oc
;
580 struct data_string client_id
;
581 char client_id_str
[80]; /* print_hex_1() uses maximum 60 characters,
582 plus a few more for extra information */
585 memset(server_id
, 0, sizeof(*server_id
));
586 memset(&client_id
, 0, sizeof(client_id
));
589 * Make a string that we can print out to give more
590 * information about the client if we need to.
592 * By RFC 3315, Section 18.1.5 clients SHOULD have a
593 * client-id on an Information-request packet, but it
594 * is not strictly necessary.
596 if (get_client_id(packet
, &client_id
) == ISC_R_SUCCESS
) {
597 snprintf(client_id_str
, sizeof(client_id_str
), " (CLIENTID %s)",
598 print_hex_1(client_id
.len
, client_id
.data
, 60));
599 data_string_forget(&client_id
, MDL
);
601 client_id_str
[0] = '\0';
605 * Required by RFC 3315, section 15.
607 if (packet
->unicast
) {
608 log_debug("Discarding %s from %s; packet sent unicast%s",
609 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
610 piaddr(packet
->client_addr
), client_id_str
);
614 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
616 log_debug("Discarding %s from %s; "
617 "IA_NA option present%s",
618 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
619 piaddr(packet
->client_addr
), client_id_str
);
622 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
624 log_debug("Discarding %s from %s; "
625 "IA_TA option present%s",
626 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
627 piaddr(packet
->client_addr
), client_id_str
);
630 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
632 log_debug("Discarding %s from %s; "
633 "IA_PD option present%s",
634 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
635 piaddr(packet
->client_addr
), client_id_str
);
639 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
641 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
642 packet
->options
, NULL
,
643 &global_scope
, oc
, MDL
)) {
644 log_error("Error processing %s from %s; "
645 "unable to evaluate Server Identifier%s",
646 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
647 piaddr(packet
->client_addr
), client_id_str
);
650 if ((server_duid
.len
!= server_id
->len
) ||
651 (memcmp(server_duid
.data
, server_id
->data
,
652 server_duid
.len
) != 0)) {
653 log_debug("Discarding %s from %s; "
654 "not our server identifier "
655 "(SERVERID %s, server DUID %s)%s",
656 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
657 piaddr(packet
->client_addr
),
658 print_hex_1(server_id
->len
,
659 server_id
->data
, 60),
660 print_hex_2(server_duid
.len
,
661 server_duid
.data
, 60),
672 if (server_id
->len
> 0) {
673 data_string_forget(server_id
, MDL
);
680 * Options that we want to send, in addition to what was requested
683 static const int required_opts
[] = {
690 static const int required_opts_NAA
[] = {
696 static const int required_opts_solicit
[] = {
708 static const int required_opts_agent
[] = {
713 static const int required_opts_IA
[] = {
718 static const int required_opts_IA_PD
[] = {
723 static const int required_opts_STATUS_CODE
[] = {
729 * Extracts from packet contents an IA_* option, storing the IA structure
730 * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
731 * in enc_opt_state for later lookup and evaluation. The 'offset' indicates
732 * where in the IA_* the DHCPv6 options commence.
735 get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
736 struct data_string
*enc_opt_data
,
737 struct packet
*packet
,
738 struct option_cache
*oc
,
742 * Get the raw data for the encapsulated options.
744 memset(enc_opt_data
, 0, sizeof(*enc_opt_data
));
745 if (!evaluate_option_cache(enc_opt_data
, packet
,
746 NULL
, NULL
, packet
->options
, NULL
,
747 &global_scope
, oc
, MDL
)) {
748 log_error("get_encapsulated_IA_state: "
749 "error evaluating raw option.");
752 if (enc_opt_data
->len
< offset
) {
753 log_error("get_encapsulated_IA_state: raw option too small.");
754 data_string_forget(enc_opt_data
, MDL
);
759 * Now create the option state structure, and pass it to the
760 * function that parses options.
762 *enc_opt_state
= NULL
;
763 if (!option_state_allocate(enc_opt_state
, MDL
)) {
764 log_error("get_encapsulated_IA_state: no memory for options.");
765 data_string_forget(enc_opt_data
, MDL
);
768 if (!parse_option_buffer(*enc_opt_state
,
769 enc_opt_data
->data
+ offset
,
770 enc_opt_data
->len
- offset
,
772 log_error("get_encapsulated_IA_state: error parsing options.");
773 option_state_dereference(enc_opt_state
, MDL
);
774 data_string_forget(enc_opt_data
, MDL
);
782 set_status_code(u_int16_t status_code
, const char *status_message
,
783 struct option_state
*opt_state
)
785 struct data_string d
;
788 memset(&d
, 0, sizeof(d
));
789 d
.len
= sizeof(status_code
) + strlen(status_message
);
790 if (!buffer_allocate(&d
.buffer
, d
.len
, MDL
)) {
791 log_fatal("set_status_code: no memory for status code.");
793 d
.data
= d
.buffer
->data
;
794 putUShort(d
.buffer
->data
, status_code
);
795 memcpy(d
.buffer
->data
+ sizeof(status_code
),
796 status_message
, d
.len
- sizeof(status_code
));
797 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
798 d
.buffer
, (unsigned char *)d
.data
, d
.len
,
799 D6O_STATUS_CODE
, 0)) {
800 log_error("set_status_code: error saving status code.");
805 data_string_forget(&d
, MDL
);
810 * We have a set of operations we do to set up the reply packet, which
811 * is the same for many message types.
814 start_reply(struct packet
*packet
,
815 const struct data_string
*client_id
,
816 const struct data_string
*server_id
,
817 struct option_state
**opt_state
,
818 struct dhcpv6_packet
*reply
)
820 struct option_cache
*oc
;
821 const unsigned char *server_id_data
;
825 * Build our option state for reply.
828 if (!option_state_allocate(opt_state
, MDL
)) {
829 log_error("start_reply: no memory for option_state.");
832 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
833 packet
->options
, *opt_state
,
834 &global_scope
, root_group
, NULL
, NULL
);
837 * A small bit of special handling for Solicit messages.
839 * We could move the logic into a flag, but for now just check
842 if (packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
843 reply
->msg_type
= DHCPV6_ADVERTISE
;
847 * - this message type supports rapid commit (Solicit), and
848 * - the server is configured to supply a rapid commit, and
849 * - the client requests a rapid commit,
850 * Then we add a rapid commit option, and send Reply (instead
853 oc
= lookup_option(&dhcpv6_universe
,
854 *opt_state
, D6O_RAPID_COMMIT
);
856 oc
= lookup_option(&dhcpv6_universe
,
857 packet
->options
, D6O_RAPID_COMMIT
);
859 /* Rapid-commit in action. */
860 reply
->msg_type
= DHCPV6_REPLY
;
862 /* Don't want a rapid-commit in advertise. */
863 delete_option(&dhcpv6_universe
,
864 *opt_state
, D6O_RAPID_COMMIT
);
868 reply
->msg_type
= DHCPV6_REPLY
;
869 /* Delete the rapid-commit from the sent options. */
870 oc
= lookup_option(&dhcpv6_universe
,
871 *opt_state
, D6O_RAPID_COMMIT
);
873 delete_option(&dhcpv6_universe
,
874 *opt_state
, D6O_RAPID_COMMIT
);
879 * Use the client's transaction identifier for the reply.
881 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
882 sizeof(reply
->transaction_id
));
885 * RFC 3315, section 18.2 says we need server identifier and
888 * If the server ID is defined via the configuration file, then
889 * it will already be present in the option state at this point,
890 * so we don't need to set it.
892 * If we have a server ID passed in from the caller,
893 * use that, otherwise use the global DUID.
895 oc
= lookup_option(&dhcpv6_universe
, *opt_state
, D6O_SERVERID
);
897 if (server_id
== NULL
) {
898 server_id_data
= server_duid
.data
;
899 server_id_len
= server_duid
.len
;
901 server_id_data
= server_id
->data
;
902 server_id_len
= server_id
->len
;
904 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
905 NULL
, (unsigned char *)server_id_data
,
906 server_id_len
, D6O_SERVERID
, 0)) {
907 log_error("start_reply: "
908 "error saving server identifier.");
913 if (client_id
->buffer
!= NULL
) {
914 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
916 (unsigned char *)client_id
->data
,
919 log_error("start_reply: error saving "
920 "client identifier.");
926 * If the client accepts reconfiguration, let it know that we
929 * Note: we don't actually do this yet, but DOCSIS requires we
932 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
935 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
936 NULL
, (unsigned char *)"", 0,
937 D6O_RECONF_ACCEPT
, 0)) {
938 log_error("start_reply: "
939 "error saving RECONF_ACCEPT option.");
940 option_state_dereference(opt_state
, MDL
);
949 * Try to get the IPv6 address the client asked for from the
952 * addr is the result (should be a pointer to NULL on entry)
953 * pool is the pool to search in
954 * requested_addr is the address the client wants
957 try_client_v6_address(struct iasubopt
**addr
,
958 struct ipv6_pool
*pool
,
959 const struct data_string
*requested_addr
)
961 struct in6_addr tmp_addr
;
964 if (requested_addr
->len
< sizeof(tmp_addr
)) {
965 return DHCP_R_INVALIDARG
;
967 memcpy(&tmp_addr
, requested_addr
->data
, sizeof(tmp_addr
));
968 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
)) {
969 return ISC_R_FAILURE
;
973 * The address is not covered by this (or possibly any) dynamic
976 if (!ipv6_in_pool(&tmp_addr
, pool
)) {
977 return ISC_R_ADDRNOTAVAIL
;
980 if (lease6_exists(pool
, &tmp_addr
)) {
981 return ISC_R_ADDRINUSE
;
984 result
= iasubopt_allocate(addr
, MDL
);
985 if (result
!= ISC_R_SUCCESS
) {
988 (*addr
)->addr
= tmp_addr
;
991 /* Default is soft binding for 2 minutes. */
992 result
= add_lease6(pool
, *addr
, cur_time
+ 120);
993 if (result
!= ISC_R_SUCCESS
) {
994 iasubopt_dereference(addr
, MDL
);
1002 * \brief Get an IPv6 address for the client.
1004 * Attempt to find a usable address for the client. We walk through
1005 * the ponds checking for permit and deny then through the pools
1006 * seeing if they have an available address.
1008 * \param reply = the state structure for the current work on this request
1009 * if we create a lease we return it using reply->lease
1012 * ISC_R_SUCCESS = we were able to find an address and are returning a
1013 * pointer to the lease
1014 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1015 * is probabalistic. We don't exhaustively try the
1016 * address range, instead we hash the duid and if
1017 * the address derived from the hash is in use we
1018 * hash the address. After a number of failures we
1019 * conclude the pool is basically full.
1022 pick_v6_address(struct reply_state
*reply
)
1024 struct ipv6_pool
*p
= NULL
;
1025 struct ipv6_pond
*pond
;
1028 unsigned int attempts
;
1029 char tmp_buf
[INET6_ADDRSTRLEN
];
1030 struct iasubopt
**addr
= &reply
->lease
;
1033 * Do a quick walk through of the ponds and pools
1034 * to see if we have any NA address pools
1036 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1037 if (pond
->ipv6_pools
== NULL
)
1040 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1041 if (p
->pool_type
== D6O_IA_NA
)
1048 /* If we get here and p is NULL we have no useful pools */
1050 log_debug("Unable to pick client address: "
1051 "no IPv6 pools on this shared network");
1052 return ISC_R_NORESOURCES
;
1056 * We have at least one pool that could provide an address
1057 * Now we walk through the ponds and pools again and check
1058 * to see if the client is permitted and if an address is
1061 * Within a given pond we start looking at the last pool we
1062 * allocated from, unless it had a collision trying to allocate
1063 * an address. This will tend to move us into less-filled pools.
1066 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1067 if (((pond
->prohibit_list
!= NULL
) &&
1068 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1069 ((pond
->permit_list
!= NULL
) &&
1070 (!permitted(reply
->packet
, pond
->permit_list
))))
1073 start_pool
= pond
->last_ipv6_pool
;
1076 p
= pond
->ipv6_pools
[i
];
1077 if ((p
->pool_type
== D6O_IA_NA
) &&
1078 (create_lease6(p
, addr
, &attempts
,
1079 &reply
->ia
->iaid_duid
,
1080 cur_time
+ 120) == ISC_R_SUCCESS
)) {
1082 * Record the pool used (or next one if there
1087 if (pond
->ipv6_pools
[i
] == NULL
) {
1091 pond
->last_ipv6_pool
= i
;
1093 log_debug("Picking pool address %s",
1094 inet_ntop(AF_INET6
, &((*addr
)->addr
),
1095 tmp_buf
, sizeof(tmp_buf
)));
1096 return (ISC_R_SUCCESS
);
1100 if (pond
->ipv6_pools
[i
] == NULL
) {
1103 } while (i
!= start_pool
);
1107 * If we failed to pick an IPv6 address from any of the subnets.
1108 * Presumably that means we have no addresses for the client.
1110 log_debug("Unable to pick client address: no addresses available");
1111 return ISC_R_NORESOURCES
;
1115 * Try to get the IPv6 prefix the client asked for from the
1118 * pref is the result (should be a pointer to NULL on entry)
1119 * pool is the prefix pool to search in
1120 * requested_pref is the address the client wants
1123 try_client_v6_prefix(struct iasubopt
**pref
,
1124 struct ipv6_pool
*pool
,
1125 const struct data_string
*requested_pref
)
1128 struct in6_addr tmp_pref
;
1130 isc_result_t result
;
1132 if (requested_pref
->len
< sizeof(tmp_plen
) + sizeof(tmp_pref
)) {
1133 return DHCP_R_INVALIDARG
;
1135 tmp_plen
= (int) requested_pref
->data
[0];
1136 if ((tmp_plen
< 3) || (tmp_plen
> 128) ||
1137 ((int)tmp_plen
!= pool
->units
)) {
1138 return ISC_R_FAILURE
;
1140 memcpy(&tmp_pref
, requested_pref
->data
+ 1, sizeof(tmp_pref
));
1141 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref
)) {
1142 return ISC_R_FAILURE
;
1145 memcpy(&ia
.iabuf
, &tmp_pref
, 16);
1146 if (!is_cidr_mask_valid(&ia
, (int) tmp_plen
)) {
1147 return ISC_R_FAILURE
;
1150 if (!ipv6_in_pool(&tmp_pref
, pool
)) {
1151 return ISC_R_ADDRNOTAVAIL
;
1154 if (prefix6_exists(pool
, &tmp_pref
, tmp_plen
)) {
1155 return ISC_R_ADDRINUSE
;
1158 result
= iasubopt_allocate(pref
, MDL
);
1159 if (result
!= ISC_R_SUCCESS
) {
1162 (*pref
)->addr
= tmp_pref
;
1163 (*pref
)->plen
= tmp_plen
;
1165 /* Default is soft binding for 2 minutes. */
1166 result
= add_lease6(pool
, *pref
, cur_time
+ 120);
1167 if (result
!= ISC_R_SUCCESS
) {
1168 iasubopt_dereference(pref
, MDL
);
1175 * \brief Get an IPv6 prefix for the client.
1177 * Attempt to find a usable prefix for the client. We walk through
1178 * the ponds checking for permit and deny then through the pools
1179 * seeing if they have an available prefix.
1181 * \param reply = the state structure for the current work on this request
1182 * if we create a lease we return it using reply->lease
1185 * ISC_R_SUCCESS = we were able to find an prefix and are returning a
1186 * pointer to the lease
1187 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1188 * is probabalistic. We don't exhaustively try the
1189 * address range, instead we hash the duid and if
1190 * the address derived from the hash is in use we
1191 * hash the address. After a number of failures we
1192 * conclude the pool is basically full.
1196 pick_v6_prefix(struct reply_state
*reply
)
1198 struct ipv6_pool
*p
= NULL
;
1199 struct ipv6_pond
*pond
;
1201 unsigned int attempts
;
1202 char tmp_buf
[INET6_ADDRSTRLEN
];
1203 struct iasubopt
**pref
= &reply
->lease
;
1206 * Do a quick walk through of the ponds and pools
1207 * to see if we have any prefix pools
1209 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1210 if (pond
->ipv6_pools
== NULL
)
1213 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1214 if (p
->pool_type
== D6O_IA_PD
)
1221 /* If we get here and p is NULL we have no useful pools */
1223 log_debug("Unable to pick client prefix: "
1224 "no IPv6 pools on this shared network");
1225 return ISC_R_NORESOURCES
;
1229 * We have at least one pool that could provide a prefix
1230 * Now we walk through the ponds and pools again and check
1231 * to see if the client is permitted and if an prefix is
1236 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1237 if (((pond
->prohibit_list
!= NULL
) &&
1238 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1239 ((pond
->permit_list
!= NULL
) &&
1240 (!permitted(reply
->packet
, pond
->permit_list
))))
1243 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1244 if (p
->pool_type
!= D6O_IA_PD
) {
1249 * Try only pools with the requested prefix length if any.
1251 if ((reply
->preflen
>= 0) && (p
->units
!= reply
->preflen
)) {
1255 if (create_prefix6(p
, pref
, &attempts
, &reply
->ia
->iaid_duid
,
1256 cur_time
+ 120) == ISC_R_SUCCESS
) {
1257 log_debug("Picking pool prefix %s/%u",
1258 inet_ntop(AF_INET6
, &((*pref
)->addr
),
1259 tmp_buf
, sizeof(tmp_buf
)),
1260 (unsigned) (*pref
)->plen
);
1262 return (ISC_R_SUCCESS
);
1268 * If we failed to pick an IPv6 prefix
1269 * Presumably that means we have no prefixes for the client.
1271 log_debug("Unable to pick client prefix: no prefixes available");
1272 return ISC_R_NORESOURCES
;
1276 *! \file server/dhcpv6.c
1278 * \brief construct a reply containing information about a client's lease
1280 * lease_to_client() is called from several messages to construct a
1281 * reply that contains all that we know about the client's correct lease
1282 * (or projected lease).
1284 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1285 * send what we "may" give them on a request.
1287 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1288 * the client should really use).
1290 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1291 * Rebind out any "wrong" addresses the client sends. This means we send
1292 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1293 * possibly send the address with zeroed lifetimes.
1295 * Information-Request - No binding.
1297 * The basic structure is to traverse the client-supplied data first, and
1298 * validate and echo back any contents that can be. If the client-supplied
1299 * data does not error out (on renew/rebind as above), but we did not send
1300 * any addresses, attempt to allocate one.
1302 * At the end of the this function we call commit_leases_timed() to
1303 * fsync and rotate the file as necessary. commit_leases_timed() will
1304 * check that we have written at least one lease to the file and that
1305 * some time has passed before doing any fsync or file rewrite so we
1306 * don't bother tracking if we did a write_ia during this function.
1308 /* TODO: look at client hints for lease times */
1311 lease_to_client(struct data_string
*reply_ret
,
1312 struct packet
*packet
,
1313 const struct data_string
*client_id
,
1314 const struct data_string
*server_id
)
1316 static struct reply_state reply
;
1317 struct option_cache
*oc
;
1318 struct data_string packet_oro
;
1319 #if defined (RFC3315_PRE_ERRATA_2010_08)
1320 isc_boolean_t no_resources_avail
= ISC_FALSE
;
1324 memset(&packet_oro
, 0, sizeof(packet_oro
));
1326 /* Locate the client. */
1327 if (shared_network_from_packet6(&reply
.shared
,
1328 packet
) != ISC_R_SUCCESS
)
1332 * Initialize the reply.
1334 packet_reference(&reply
.packet
, packet
, MDL
);
1335 data_string_copy(&reply
.client_id
, client_id
, MDL
);
1337 if (!start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
1341 /* Set the write cursor to just past the reply header. */
1342 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1345 * Get the ORO from the packet, if any.
1347 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ORO
);
1349 if (!evaluate_option_cache(&packet_oro
, packet
,
1351 packet
->options
, NULL
,
1352 &global_scope
, oc
, MDL
)) {
1353 log_error("lease_to_client: error evaluating ORO.");
1359 * Find a host record that matches from the packet, if any, and is
1360 * valid for the shared network the client is on.
1362 if (find_hosts_by_uid(&reply
.host
, client_id
->data
, client_id
->len
,
1365 seek_shared_host(&reply
.host
, reply
.shared
);
1368 if ((reply
.host
== NULL
) &&
1369 find_hosts_by_option(&reply
.host
, packet
, packet
->options
, MDL
)) {
1371 seek_shared_host(&reply
.host
, reply
.shared
);
1375 * Check for 'hardware' matches last, as some of the synthesis methods
1376 * are not considered to be as reliable.
1378 if ((reply
.host
== NULL
) &&
1379 find_hosts_by_duid_chaddr(&reply
.host
, client_id
)) {
1381 seek_shared_host(&reply
.host
, reply
.shared
);
1384 /* Process the client supplied IA's onto the reply buffer. */
1386 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
1388 for (; oc
!= NULL
; oc
= oc
->next
) {
1389 isc_result_t status
;
1391 /* Start counting resources (addresses) offered. */
1392 reply
.client_resources
= 0;
1393 reply
.resources_included
= ISC_FALSE
;
1395 status
= reply_process_ia_na(&reply
, oc
);
1398 * We continue to try other IA's whether we can address
1399 * this one or not. Any other result is an immediate fail.
1401 if ((status
!= ISC_R_SUCCESS
) &&
1402 (status
!= ISC_R_NORESOURCES
))
1405 #if defined (RFC3315_PRE_ERRATA_2010_08)
1407 * If any address cannot be given to any IA, then set the
1408 * NoAddrsAvail status code.
1410 if (reply
.client_resources
== 0)
1411 no_resources_avail
= ISC_TRUE
;
1414 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
1415 for (; oc
!= NULL
; oc
= oc
->next
) {
1416 isc_result_t status
;
1418 /* Start counting resources (addresses) offered. */
1419 reply
.client_resources
= 0;
1420 reply
.resources_included
= ISC_FALSE
;
1422 status
= reply_process_ia_ta(&reply
, oc
);
1425 * We continue to try other IA's whether we can address
1426 * this one or not. Any other result is an immediate fail.
1428 if ((status
!= ISC_R_SUCCESS
) &&
1429 (status
!= ISC_R_NORESOURCES
))
1432 #if defined (RFC3315_PRE_ERRATA_2010_08)
1434 * If any address cannot be given to any IA, then set the
1435 * NoAddrsAvail status code.
1437 if (reply
.client_resources
== 0)
1438 no_resources_avail
= ISC_TRUE
;
1442 /* Same for IA_PD's. */
1444 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
1445 for (; oc
!= NULL
; oc
= oc
->next
) {
1446 isc_result_t status
;
1448 /* Start counting resources (prefixes) offered. */
1449 reply
.client_resources
= 0;
1450 reply
.resources_included
= ISC_FALSE
;
1452 status
= reply_process_ia_pd(&reply
, oc
);
1455 * We continue to try other IA_PD's whether we can address
1456 * this one or not. Any other result is an immediate fail.
1458 if ((status
!= ISC_R_SUCCESS
) &&
1459 (status
!= ISC_R_NORESOURCES
))
1464 * Make no reply if we gave no resources and is not
1465 * for Information-Request.
1467 if ((reply
.ia_count
== 0) && (reply
.pd_count
== 0)) {
1468 if (reply
.packet
->dhcpv6_msg_type
!=
1469 DHCPV6_INFORMATION_REQUEST
)
1473 * Because we only execute statements on a per-IA basis,
1474 * we need to execute statements in any non-IA reply to
1475 * source configuration.
1477 execute_statements_in_scope(NULL
, reply
.packet
, NULL
, NULL
,
1478 reply
.packet
->options
,
1479 reply
.opt_state
, &global_scope
,
1480 reply
.shared
->group
, root_group
,
1483 /* Execute statements from class scopes. */
1484 for (i
= reply
.packet
->class_count
; i
> 0; i
--) {
1485 execute_statements_in_scope(NULL
, reply
.packet
,
1487 reply
.packet
->options
,
1490 reply
.packet
->classes
[i
- 1]->group
,
1491 reply
.shared
->group
, NULL
);
1494 /* Bring in any configuration from a host record. */
1495 if (reply
.host
!= NULL
)
1496 execute_statements_in_scope(NULL
, reply
.packet
,
1498 reply
.packet
->options
,
1502 reply
.shared
->group
, NULL
);
1506 * RFC3315 section 17.2.2 (Solicit):
1508 * If the server will not assign any addresses to any IAs in a
1509 * subsequent Request from the client, the server MUST send an
1510 * Advertise message to the client that includes only a Status
1511 * Code option with code NoAddrsAvail and a status message for
1512 * the user, a Server Identifier option with the server's DUID,
1513 * and a Client Identifier option with the client's DUID.
1515 * Section 18.2.1 (Request):
1517 * If the server cannot assign any addresses to an IA in the
1518 * message from the client, the server MUST include the IA in
1519 * the Reply message with no addresses in the IA and a Status
1520 * Code option in the IA containing status code NoAddrsAvail.
1522 * Section 18.1.8 (Client Behavior):
1524 * Leave unchanged any information about addresses the client has
1525 * recorded in the IA but that were not included in the IA from
1527 * Sends a Renew/Rebind if the IA is not in the Reply message.
1529 #if defined (RFC3315_PRE_ERRATA_2010_08)
1530 if (no_resources_avail
&& (reply
.ia_count
!= 0) &&
1531 (reply
.packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
))
1533 /* Set the NoAddrsAvail status code. */
1534 if (!set_status_code(STATUS_NoAddrsAvail
,
1535 "No addresses available for this "
1536 "interface.", reply
.opt_state
)) {
1537 log_error("lease_to_client: Unable to set "
1538 "NoAddrsAvail status code.");
1542 /* Rewind the cursor to the start. */
1543 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1546 * Produce an advertise that includes only:
1552 reply
.buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
1553 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+
1557 reply
.opt_state
, reply
.packet
,
1562 * Having stored the client's IA's, store any options that
1563 * will fit in the remaining space.
1565 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+
1569 reply
.opt_state
, reply
.packet
,
1570 required_opts_solicit
,
1573 #else /* defined (RFC3315_PRE_ERRATA_2010_08) */
1575 * Having stored the client's IA's, store any options that
1576 * will fit in the remaining space.
1578 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+ reply
.cursor
,
1579 sizeof(reply
.buf
) - reply
.cursor
,
1580 reply
.opt_state
, reply
.packet
,
1581 required_opts_solicit
,
1583 #endif /* defined (RFC3315_PRE_ERRATA_2010_08) */
1585 /* Return our reply to the caller. */
1586 reply_ret
->len
= reply
.cursor
;
1587 reply_ret
->buffer
= NULL
;
1588 if (!buffer_allocate(&reply_ret
->buffer
, reply
.cursor
, MDL
)) {
1589 log_fatal("No memory to store Reply.");
1591 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
, reply
.cursor
);
1592 reply_ret
->data
= reply_ret
->buffer
->data
;
1594 /* If appropriate commit and rotate the lease file */
1595 (void) commit_leases_timed();
1599 if (reply
.shared
!= NULL
)
1600 shared_network_dereference(&reply
.shared
, MDL
);
1601 if (reply
.host
!= NULL
)
1602 host_dereference(&reply
.host
, MDL
);
1603 if (reply
.opt_state
!= NULL
)
1604 option_state_dereference(&reply
.opt_state
, MDL
);
1605 if (reply
.packet
!= NULL
)
1606 packet_dereference(&reply
.packet
, MDL
);
1607 if (reply
.client_id
.data
!= NULL
)
1608 data_string_forget(&reply
.client_id
, MDL
);
1609 if (packet_oro
.buffer
!= NULL
)
1610 data_string_forget(&packet_oro
, MDL
);
1611 reply
.renew
= reply
.rebind
= reply
.prefer
= reply
.valid
= 0;
1615 /* Process a client-supplied IA_NA. This may append options to the tail of
1616 * the reply packet being built in the reply_state structure.
1619 reply_process_ia_na(struct reply_state
*reply
, struct option_cache
*ia
) {
1620 isc_result_t status
= ISC_R_SUCCESS
;
1623 struct option_state
*packet_ia
;
1624 struct option_cache
*oc
;
1625 struct data_string ia_data
, data
;
1627 /* Initialize values that will get cleaned up on return. */
1629 memset(&ia_data
, 0, sizeof(ia_data
));
1630 memset(&data
, 0, sizeof(data
));
1632 * Note that find_client_address() may set reply->lease.
1635 /* Make sure there is at least room for the header. */
1636 if ((reply
->cursor
+ IA_NA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
1637 log_error("reply_process_ia_na: Reply too long for IA.");
1638 return ISC_R_NOSPACE
;
1642 /* Fetch the IA_NA contents. */
1643 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
1644 ia
, IA_NA_OFFSET
)) {
1645 log_error("reply_process_ia_na: error evaluating ia");
1646 status
= ISC_R_FAILURE
;
1650 /* Extract IA_NA header contents. */
1651 iaid
= getULong(ia_data
.data
);
1652 reply
->renew
= getULong(ia_data
.data
+ 4);
1653 reply
->rebind
= getULong(ia_data
.data
+ 8);
1655 /* Create an IA_NA structure. */
1656 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
1657 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
1658 log_error("reply_process_ia_na: no memory for ia.");
1659 status
= ISC_R_NOMEMORY
;
1662 reply
->ia
->ia_type
= D6O_IA_NA
;
1664 /* Cache pre-existing IA, if any. */
1665 ia_hash_lookup(&reply
->old_ia
, ia_na_active
,
1666 (unsigned char *)reply
->ia
->iaid_duid
.data
,
1667 reply
->ia
->iaid_duid
.len
, MDL
);
1670 * Create an option cache to carry the IA_NA option contents, and
1671 * execute any user-supplied values into it.
1673 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
1674 status
= ISC_R_NOMEMORY
;
1678 /* Check & cache the fixed host record. */
1679 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_addr
!= NULL
)) {
1680 struct iaddr tmp_addr
;
1682 if (!evaluate_option_cache(&reply
->fixed
, NULL
, NULL
, NULL
,
1683 NULL
, NULL
, &global_scope
,
1684 reply
->host
->fixed_addr
, MDL
)) {
1685 log_error("reply_process_ia_na: unable to evaluate "
1687 status
= ISC_R_FAILURE
;
1691 if (reply
->fixed
.len
< 16) {
1692 log_error("reply_process_ia_na: invalid fixed address.");
1693 status
= DHCP_R_INVALIDARG
;
1697 /* Find the static lease's subnet. */
1699 memcpy(tmp_addr
.iabuf
, reply
->fixed
.data
, 16);
1701 if (find_grouped_subnet(&reply
->subnet
, reply
->shared
,
1702 tmp_addr
, MDL
) == 0)
1703 log_fatal("Impossible condition at %s:%d.", MDL
);
1705 reply
->static_lease
= ISC_TRUE
;
1707 reply
->static_lease
= ISC_FALSE
;
1710 * Save the cursor position at the start of the IA, so we can
1711 * set length and adjust t1/t2 values later. We write a temporary
1712 * header out now just in case we decide to adjust the packet
1713 * within sub-process functions.
1715 ia_cursor
= reply
->cursor
;
1717 /* Initialize the IA_NA header. First the code. */
1718 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_NA
);
1721 /* Then option length. */
1722 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
1725 /* Then IA_NA header contents; IAID. */
1726 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
1729 /* We store the client's t1 for now, and may over-ride it later. */
1730 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
1733 /* We store the client's t2 for now, and may over-ride it later. */
1734 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
1738 * For each address in this IA_NA, decide what to do about it.
1742 * The client leaves unchanged any information about addresses
1743 * it has recorded but are not included ("cancel/break" below).
1744 * A not included IA ("cleanup" below) could give a Renew/Rebind.
1746 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
1747 reply
->valid
= reply
->prefer
= 0xffffffff;
1748 reply
->client_valid
= reply
->client_prefer
= 0;
1749 for (; oc
!= NULL
; oc
= oc
->next
) {
1750 status
= reply_process_addr(reply
, oc
);
1753 * Canceled means we did not allocate addresses to the
1754 * client, but we're "done" with this IA - we set a status
1755 * code. So transmit this reply, e.g., move on to the next
1758 if (status
== ISC_R_CANCELED
)
1761 if ((status
!= ISC_R_SUCCESS
) &&
1762 (status
!= ISC_R_ADDRINUSE
) &&
1763 (status
!= ISC_R_ADDRNOTAVAIL
))
1770 * If we fell through the above and never gave the client
1771 * an address, give it one now.
1773 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
1774 status
= find_client_address(reply
);
1776 if (status
== ISC_R_NORESOURCES
) {
1777 switch (reply
->packet
->dhcpv6_msg_type
) {
1778 case DHCPV6_SOLICIT
:
1780 * No address for any IA is handled
1785 case DHCPV6_REQUEST
:
1786 /* Section 18.2.1 (Request):
1788 * If the server cannot assign any addresses to
1789 * an IA in the message from the client, the
1790 * server MUST include the IA in the Reply
1791 * message with no addresses in the IA and a
1792 * Status Code option in the IA containing
1793 * status code NoAddrsAvail.
1795 option_state_dereference(&reply
->reply_ia
, MDL
);
1796 if (!option_state_allocate(&reply
->reply_ia
,
1799 log_error("reply_process_ia_na: No "
1800 "memory for option state "
1802 status
= ISC_R_NOMEMORY
;
1806 if (!set_status_code(STATUS_NoAddrsAvail
,
1807 "No addresses available "
1808 "for this interface.",
1810 log_error("reply_process_ia_na: Unable "
1811 "to set NoAddrsAvail status "
1813 status
= ISC_R_FAILURE
;
1817 status
= ISC_R_SUCCESS
;
1822 * RFC 3315 does not tell us to emit a status
1823 * code in this condition, or anything else.
1825 * If we included non-allocated addresses
1826 * (zeroed lifetimes) in an IA, then the client
1827 * will deconfigure them.
1829 * So we want to include the IA even if we
1830 * can't give it a new address if it includes
1831 * zeroed lifetime addresses.
1833 * We don't want to include the IA if we
1834 * provide zero addresses including zeroed
1837 if (reply
->resources_included
)
1838 status
= ISC_R_SUCCESS
;
1845 if (status
!= ISC_R_SUCCESS
)
1849 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
1850 sizeof(reply
->buf
) - reply
->cursor
,
1851 reply
->reply_ia
, reply
->packet
,
1852 required_opts_IA
, NULL
);
1854 /* Reset the length of this IA to match what was just written. */
1855 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
1856 reply
->cursor
- (ia_cursor
+ 4));
1859 * T1/T2 time selection is kind of weird. We actually use DHCP
1860 * (v4) scoped options as handy existing places where these might
1861 * be configured by an administrator. A value of zero tells the
1862 * client it may choose its own renewal time.
1865 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
1866 DHO_DHCP_RENEWAL_TIME
);
1868 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
1869 reply
->packet
->options
,
1870 reply
->opt_state
, &global_scope
,
1873 log_error("Invalid renewal time.");
1875 reply
->renew
= getULong(data
.data
);
1878 if (data
.data
!= NULL
)
1879 data_string_forget(&data
, MDL
);
1881 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
1885 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
1886 DHO_DHCP_REBINDING_TIME
);
1888 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
1889 reply
->packet
->options
,
1890 reply
->opt_state
, &global_scope
,
1893 log_error("Invalid rebinding time.");
1895 reply
->rebind
= getULong(data
.data
);
1898 if (data
.data
!= NULL
)
1899 data_string_forget(&data
, MDL
);
1901 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
1904 * yes, goto's aren't the best but we also want to avoid extra
1907 if (status
== ISC_R_CANCELED
)
1911 * Handle static leases, we always log stuff and if it's
1912 * a hard binding we run any commit statements that we have
1914 if (reply
->static_lease
) {
1915 char tmp_addr
[INET6_ADDRSTRLEN
];
1916 log_info("%s NA: address %s to client with duid %s iaid = %d "
1918 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
1919 inet_ntop(AF_INET6
, reply
->fixed
.data
, tmp_addr
,
1921 print_hex_1(reply
->client_id
.len
,
1922 reply
->client_id
.data
, 60),
1925 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
1926 (reply
->on_star
.on_commit
!= NULL
)) {
1927 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
1928 reply
->packet
->options
,
1929 reply
->opt_state
, NULL
,
1930 reply
->on_star
.on_commit
, NULL
);
1931 executable_statement_dereference
1932 (&reply
->on_star
.on_commit
, MDL
);
1938 * If we have any addresses log what we are doing.
1940 if (reply
->ia
->num_iasubopt
!= 0) {
1941 struct iasubopt
*tmp
;
1943 char tmp_addr
[INET6_ADDRSTRLEN
];
1945 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
1946 tmp
= reply
->ia
->iasubopt
[i
];
1948 log_info("%s NA: address %s to client with duid %s "
1949 "iaid = %d valid for %d seconds",
1950 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
1951 inet_ntop(AF_INET6
, &tmp
->addr
,
1952 tmp_addr
, sizeof(tmp_addr
)),
1953 print_hex_1(reply
->client_id
.len
,
1954 reply
->client_id
.data
, 60),
1960 * If this is not a 'soft' binding, consume the new changes into
1961 * the database (if any have been attached to the ia_na).
1963 * Loop through the assigned dynamic addresses, referencing the
1964 * leases onto this IA_NA rather than any old ones, and updating
1965 * pool timers for each (if any).
1968 if ((reply
->ia
->num_iasubopt
!= 0) &&
1969 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
1970 struct iasubopt
*tmp
;
1971 struct data_string
*ia_id
;
1974 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
1975 tmp
= reply
->ia
->iasubopt
[i
];
1977 if (tmp
->ia
!= NULL
)
1978 ia_dereference(&tmp
->ia
, MDL
);
1979 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
1981 /* Commit 'hard' bindings. */
1982 renew_lease6(tmp
->ipv6_pool
, tmp
);
1983 schedule_lease_timeout(tmp
->ipv6_pool
);
1985 /* If we have anything to do on commit do it now */
1986 if (tmp
->on_star
.on_commit
!= NULL
) {
1987 execute_statements(NULL
, reply
->packet
,
1989 reply
->packet
->options
,
1992 tmp
->on_star
.on_commit
,
1994 executable_statement_dereference
1995 (&tmp
->on_star
.on_commit
, MDL
);
1998 #if defined (NSUPDATE)
2000 * Perform ddns updates.
2002 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2005 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2007 reply
->packet
->options
,
2011 ddns_updates(reply
->packet
, NULL
, NULL
,
2012 tmp
, NULL
, reply
->opt_state
);
2017 /* Remove any old ia from the hash. */
2018 if (reply
->old_ia
!= NULL
) {
2019 ia_id
= &reply
->old_ia
->iaid_duid
;
2020 ia_hash_delete(ia_na_active
,
2021 (unsigned char *)ia_id
->data
,
2023 ia_dereference(&reply
->old_ia
, MDL
);
2026 /* Put new ia into the hash. */
2027 reply
->ia
->cltt
= cur_time
;
2028 ia_id
= &reply
->ia
->iaid_duid
;
2029 ia_hash_add(ia_na_active
, (unsigned char *)ia_id
->data
,
2030 ia_id
->len
, reply
->ia
, MDL
);
2032 write_ia(reply
->ia
);
2036 if (packet_ia
!= NULL
)
2037 option_state_dereference(&packet_ia
, MDL
);
2038 if (reply
->reply_ia
!= NULL
)
2039 option_state_dereference(&reply
->reply_ia
, MDL
);
2040 if (ia_data
.data
!= NULL
)
2041 data_string_forget(&ia_data
, MDL
);
2042 if (data
.data
!= NULL
)
2043 data_string_forget(&data
, MDL
);
2044 if (reply
->ia
!= NULL
)
2045 ia_dereference(&reply
->ia
, MDL
);
2046 if (reply
->old_ia
!= NULL
)
2047 ia_dereference(&reply
->old_ia
, MDL
);
2048 if (reply
->lease
!= NULL
)
2049 iasubopt_dereference(&reply
->lease
, MDL
);
2050 if (reply
->fixed
.data
!= NULL
)
2051 data_string_forget(&reply
->fixed
, MDL
);
2052 if (reply
->subnet
!= NULL
)
2053 subnet_dereference(&reply
->subnet
, MDL
);
2054 if (reply
->on_star
.on_expiry
!= NULL
)
2055 executable_statement_dereference
2056 (&reply
->on_star
.on_expiry
, MDL
);
2057 if (reply
->on_star
.on_release
!= NULL
)
2058 executable_statement_dereference
2059 (&reply
->on_star
.on_release
, MDL
);
2062 * ISC_R_CANCELED is a status code used by the addr processing to
2063 * indicate we're replying with a status code. This is still a
2064 * success at higher layers.
2066 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2070 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
2071 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
2072 * in the event we are replying with a status code and do not wish to process
2073 * more IAADDRs within this IA.
2076 reply_process_addr(struct reply_state
*reply
, struct option_cache
*addr
) {
2077 u_int32_t pref_life
, valid_life
;
2078 struct binding_scope
**scope
;
2079 struct group
*group
;
2080 struct subnet
*subnet
;
2081 struct iaddr tmp_addr
;
2082 struct option_cache
*oc
;
2083 struct data_string iaaddr
, data
;
2084 isc_result_t status
= ISC_R_SUCCESS
;
2086 /* Initializes values that will be cleaned up. */
2087 memset(&iaaddr
, 0, sizeof(iaaddr
));
2088 memset(&data
, 0, sizeof(data
));
2089 /* Note that reply->lease may be set by address_is_owned() */
2092 * There is no point trying to process an incoming address if there
2093 * is no room for an outgoing address.
2095 if ((reply
->cursor
+ 28) > sizeof(reply
->buf
)) {
2096 log_error("reply_process_addr: Out of room for address.");
2097 return ISC_R_NOSPACE
;
2100 /* Extract this IAADDR option. */
2101 if (!evaluate_option_cache(&iaaddr
, reply
->packet
, NULL
, NULL
,
2102 reply
->packet
->options
, NULL
, &global_scope
,
2104 (iaaddr
.len
< IAADDR_OFFSET
)) {
2105 log_error("reply_process_addr: error evaluating IAADDR.");
2106 status
= ISC_R_FAILURE
;
2110 /* The first 16 bytes are the IPv6 address. */
2111 pref_life
= getULong(iaaddr
.data
+ 16);
2112 valid_life
= getULong(iaaddr
.data
+ 20);
2114 if ((reply
->client_valid
== 0) ||
2115 (reply
->client_valid
> valid_life
))
2116 reply
->client_valid
= valid_life
;
2118 if ((reply
->client_prefer
== 0) ||
2119 (reply
->client_prefer
> pref_life
))
2120 reply
->client_prefer
= pref_life
;
2123 * Clients may choose to send :: as an address, with the idea to give
2124 * hints about preferred-lifetime or valid-lifetime.
2127 memset(tmp_addr
.iabuf
, 0, 16);
2128 if (!memcmp(iaaddr
.data
, tmp_addr
.iabuf
, 16)) {
2129 /* Status remains success; we just ignore this one. */
2133 /* tmp_addr len remains 16 */
2134 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2137 * Verify that this address is on the client's network.
2139 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
2140 subnet
= subnet
->next_sibling
) {
2141 if (addr_eq(subnet_number(tmp_addr
, subnet
->netmask
),
2146 /* Address not found on shared network. */
2147 if (subnet
== NULL
) {
2148 /* Ignore this address on 'soft' bindings. */
2149 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
2150 /* disable rapid commit */
2151 reply
->buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
2152 delete_option(&dhcpv6_universe
,
2155 /* status remains success */
2160 * RFC3315 section 18.2.1:
2162 * If the server finds that the prefix on one or more IP
2163 * addresses in any IA in the message from the client is not
2164 * appropriate for the link to which the client is connected,
2165 * the server MUST return the IA to the client with a Status
2166 * Code option with the value NotOnLink.
2168 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) {
2169 /* Rewind the IA_NA to empty. */
2170 option_state_dereference(&reply
->reply_ia
, MDL
);
2171 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2172 log_error("reply_process_addr: No memory for "
2173 "option state wipe.");
2174 status
= ISC_R_NOMEMORY
;
2178 /* Append a NotOnLink status code. */
2179 if (!set_status_code(STATUS_NotOnLink
,
2180 "Address not for use on this "
2181 "link.", reply
->reply_ia
)) {
2182 log_error("reply_process_addr: Failure "
2183 "setting status code.");
2184 status
= ISC_R_FAILURE
;
2188 /* Fin (no more IAADDRs). */
2189 status
= ISC_R_CANCELED
;
2194 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2196 * If the server finds that any of the addresses are not
2197 * appropriate for the link to which the client is attached,
2198 * the server returns the address to the client with lifetimes
2201 if ((reply
->packet
->dhcpv6_msg_type
!= DHCPV6_RENEW
) &&
2202 (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
2203 log_error("It is impossible to lease a client that is "
2204 "not sending a solicit, request, renew, or "
2206 status
= ISC_R_FAILURE
;
2210 reply
->send_prefer
= reply
->send_valid
= 0;
2214 /* Verify the address belongs to the client. */
2215 if (!address_is_owned(reply
, &tmp_addr
)) {
2217 * For solicit and request, any addresses included are
2218 * 'requested' addresses. For rebind, we actually have
2219 * no direction on what to do from 3315 section 18.2.4!
2220 * So I think the best bet is to try and give it out, and if
2221 * we can't, zero lifetimes.
2223 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
2224 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
2225 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
2226 status
= reply_process_try_addr(reply
, &tmp_addr
);
2229 * If the address is in use, or isn't in any dynamic
2230 * range, continue as normal. If any other error was
2233 if ((status
!= ISC_R_SUCCESS
) &&
2234 (status
!= ISC_R_ADDRINUSE
) &&
2235 (status
!= ISC_R_ADDRNOTAVAIL
))
2239 * If we didn't honor this lease, for solicit and
2240 * request we simply omit it from our answer. For
2241 * rebind, we send it with zeroed lifetimes.
2243 if (reply
->lease
== NULL
) {
2244 if (reply
->packet
->dhcpv6_msg_type
==
2246 reply
->send_prefer
= 0;
2247 reply
->send_valid
= 0;
2251 /* status remains success - ignore */
2255 * RFC3315 section 18.2.3:
2257 * If the server cannot find a client entry for the IA the
2258 * server returns the IA containing no addresses with a Status
2259 * Code option set to NoBinding in the Reply message.
2261 * On mismatch we (ab)use this pretending we have not the IA
2262 * as soon as we have not an address.
2264 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
2265 /* Rewind the IA_NA to empty. */
2266 option_state_dereference(&reply
->reply_ia
, MDL
);
2267 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2268 log_error("reply_process_addr: No memory for "
2269 "option state wipe.");
2270 status
= ISC_R_NOMEMORY
;
2274 /* Append a NoBinding status code. */
2275 if (!set_status_code(STATUS_NoBinding
,
2276 "Address not bound to this "
2277 "interface.", reply
->reply_ia
)) {
2278 log_error("reply_process_addr: Unable to "
2279 "attach status code.");
2280 status
= ISC_R_FAILURE
;
2284 /* Fin (no more IAADDRs). */
2285 status
= ISC_R_CANCELED
;
2288 log_error("It is impossible to lease a client that is "
2289 "not sending a solicit, request, renew, or "
2291 status
= ISC_R_FAILURE
;
2296 if (reply
->static_lease
) {
2297 if (reply
->host
== NULL
)
2298 log_fatal("Impossible condition at %s:%d.", MDL
);
2300 scope
= &global_scope
;
2301 group
= reply
->subnet
->group
;
2303 if (reply
->lease
== NULL
)
2304 log_fatal("Impossible condition at %s:%d.", MDL
);
2306 scope
= &reply
->lease
->scope
;
2307 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
2311 * If client_resources is nonzero, then the reply_process_is_addressed
2312 * function has executed configuration state into the reply option
2313 * cache. We will use that valid cache to derive configuration for
2314 * whether or not to engage in additional addresses, and similar.
2316 if (reply
->client_resources
!= 0) {
2320 * Does this client have "enough" addresses already? Default
2321 * to one. Everybody gets one, and one should be enough for
2324 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2325 SV_LIMIT_ADDRS_PER_IA
);
2327 if (!evaluate_option_cache(&data
, reply
->packet
,
2329 reply
->packet
->options
,
2333 log_error("reply_process_addr: unable to "
2334 "evaluate addrs-per-ia value.");
2335 status
= ISC_R_FAILURE
;
2339 limit
= getULong(data
.data
);
2340 data_string_forget(&data
, MDL
);
2344 * If we wish to limit the client to a certain number of
2345 * addresses, then omit the address from the reply.
2347 if (reply
->client_resources
>= limit
)
2351 status
= reply_process_is_addressed(reply
, scope
, group
);
2352 if (status
!= ISC_R_SUCCESS
)
2356 status
= reply_process_send_addr(reply
, &tmp_addr
);
2359 if (iaaddr
.data
!= NULL
)
2360 data_string_forget(&iaaddr
, MDL
);
2361 if (data
.data
!= NULL
)
2362 data_string_forget(&data
, MDL
);
2363 if (reply
->lease
!= NULL
)
2364 iasubopt_dereference(&reply
->lease
, MDL
);
2370 * Verify the address belongs to the client. If we've got a host
2371 * record with a fixed address, it has to be the assigned address
2372 * (fault out all else). Otherwise it's a dynamic address, so lookup
2373 * that address and make sure it belongs to this DUID:IAID pair.
2375 static isc_boolean_t
2376 address_is_owned(struct reply_state
*reply
, struct iaddr
*addr
) {
2378 struct ipv6_pond
*pond
;
2381 * This faults out addresses that don't match fixed addresses.
2383 if (reply
->static_lease
) {
2384 if (reply
->fixed
.data
== NULL
)
2385 log_fatal("Impossible condition at %s:%d.", MDL
);
2387 if (memcmp(addr
->iabuf
, reply
->fixed
.data
, 16) == 0)
2393 if ((reply
->old_ia
== NULL
) || (reply
->old_ia
->num_iasubopt
== 0))
2396 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2397 struct iasubopt
*tmp
;
2399 tmp
= reply
->old_ia
->iasubopt
[i
];
2401 if (memcmp(addr
->iabuf
, &tmp
->addr
, 16) == 0) {
2402 if (lease6_usable(tmp
) == ISC_FALSE
) {
2406 pond
= tmp
->ipv6_pool
->ipv6_pond
;
2407 if (((pond
->prohibit_list
!= NULL
) &&
2408 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
2409 ((pond
->permit_list
!= NULL
) &&
2410 (!permitted(reply
->packet
, pond
->permit_list
))))
2413 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
2422 /* Process a client-supplied IA_TA. This may append options to the tail of
2423 * the reply packet being built in the reply_state structure.
2426 reply_process_ia_ta(struct reply_state
*reply
, struct option_cache
*ia
) {
2427 isc_result_t status
= ISC_R_SUCCESS
;
2430 struct option_state
*packet_ia
;
2431 struct option_cache
*oc
;
2432 struct data_string ia_data
, data
;
2433 struct data_string iaaddr
;
2434 u_int32_t pref_life
, valid_life
;
2435 struct iaddr tmp_addr
;
2437 /* Initialize values that will get cleaned up on return. */
2439 memset(&ia_data
, 0, sizeof(ia_data
));
2440 memset(&data
, 0, sizeof(data
));
2441 memset(&iaaddr
, 0, sizeof(iaaddr
));
2443 /* Make sure there is at least room for the header. */
2444 if ((reply
->cursor
+ IA_TA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2445 log_error("reply_process_ia_ta: Reply too long for IA.");
2446 return ISC_R_NOSPACE
;
2450 /* Fetch the IA_TA contents. */
2451 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2452 ia
, IA_TA_OFFSET
)) {
2453 log_error("reply_process_ia_ta: error evaluating ia");
2454 status
= ISC_R_FAILURE
;
2458 /* Extract IA_TA header contents. */
2459 iaid
= getULong(ia_data
.data
);
2461 /* Create an IA_TA structure. */
2462 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2463 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2464 log_error("reply_process_ia_ta: no memory for ia.");
2465 status
= ISC_R_NOMEMORY
;
2468 reply
->ia
->ia_type
= D6O_IA_TA
;
2470 /* Cache pre-existing IA, if any. */
2471 ia_hash_lookup(&reply
->old_ia
, ia_ta_active
,
2472 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2473 reply
->ia
->iaid_duid
.len
, MDL
);
2476 * Create an option cache to carry the IA_TA option contents, and
2477 * execute any user-supplied values into it.
2479 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2480 status
= ISC_R_NOMEMORY
;
2485 * Temporary leases are dynamic by definition.
2487 reply
->static_lease
= ISC_FALSE
;
2490 * Save the cursor position at the start of the IA, so we can
2491 * set length later. We write a temporary
2492 * header out now just in case we decide to adjust the packet
2493 * within sub-process functions.
2495 ia_cursor
= reply
->cursor
;
2497 /* Initialize the IA_TA header. First the code. */
2498 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_TA
);
2501 /* Then option length. */
2502 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x04u
);
2505 /* Then IA_TA header contents; IAID. */
2506 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2510 * Deal with an IAADDR for lifetimes.
2511 * For all or none, process IAADDRs as hints.
2513 reply
->valid
= reply
->prefer
= 0xffffffff;
2514 reply
->client_valid
= reply
->client_prefer
= 0;
2515 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2516 for (; oc
!= NULL
; oc
= oc
->next
) {
2517 memset(&iaaddr
, 0, sizeof(iaaddr
));
2518 if (!evaluate_option_cache(&iaaddr
, reply
->packet
,
2520 reply
->packet
->options
, NULL
,
2521 &global_scope
, oc
, MDL
) ||
2522 (iaaddr
.len
< IAADDR_OFFSET
)) {
2523 log_error("reply_process_ia_ta: error "
2524 "evaluating IAADDR.");
2525 status
= ISC_R_FAILURE
;
2528 /* The first 16 bytes are the IPv6 address. */
2529 pref_life
= getULong(iaaddr
.data
+ 16);
2530 valid_life
= getULong(iaaddr
.data
+ 20);
2532 if ((reply
->client_valid
== 0) ||
2533 (reply
->client_valid
> valid_life
))
2534 reply
->client_valid
= valid_life
;
2536 if ((reply
->client_prefer
== 0) ||
2537 (reply
->client_prefer
> pref_life
))
2538 reply
->client_prefer
= pref_life
;
2540 /* Nothing more if something has failed. */
2541 if (status
== ISC_R_CANCELED
)
2545 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2546 if (!temporary_is_available(reply
, &tmp_addr
))
2548 status
= reply_process_is_addressed(reply
,
2549 &reply
->lease
->scope
,
2550 reply
->lease
->ipv6_pool
->ipv6_pond
->group
);
2551 if (status
!= ISC_R_SUCCESS
)
2553 status
= reply_process_send_addr(reply
, &tmp_addr
);
2554 if (status
!= ISC_R_SUCCESS
)
2556 if (reply
->lease
!= NULL
)
2557 iasubopt_dereference(&reply
->lease
, MDL
);
2561 /* Rewind the IA_TA to empty. */
2562 option_state_dereference(&reply
->reply_ia
, MDL
);
2563 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2564 status
= ISC_R_NOMEMORY
;
2567 status
= ISC_R_CANCELED
;
2568 reply
->client_resources
= 0;
2569 reply
->resources_included
= ISC_FALSE
;
2570 if (reply
->lease
!= NULL
)
2571 iasubopt_dereference(&reply
->lease
, MDL
);
2576 * Give the client temporary addresses.
2578 if (reply
->client_resources
!= 0)
2580 status
= find_client_temporaries(reply
);
2581 if (status
== ISC_R_NORESOURCES
) {
2582 switch (reply
->packet
->dhcpv6_msg_type
) {
2583 case DHCPV6_SOLICIT
:
2585 * No address for any IA is handled
2590 case DHCPV6_REQUEST
:
2591 /* Section 18.2.1 (Request):
2593 * If the server cannot assign any addresses to
2594 * an IA in the message from the client, the
2595 * server MUST include the IA in the Reply
2596 * message with no addresses in the IA and a
2597 * Status Code option in the IA containing
2598 * status code NoAddrsAvail.
2600 option_state_dereference(&reply
->reply_ia
, MDL
);
2601 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2602 log_error("reply_process_ia_ta: No "
2603 "memory for option state wipe.");
2604 status
= ISC_R_NOMEMORY
;
2608 if (!set_status_code(STATUS_NoAddrsAvail
,
2609 "No addresses available "
2610 "for this interface.",
2612 log_error("reply_process_ia_ta: Unable "
2613 "to set NoAddrsAvail status code.");
2614 status
= ISC_R_FAILURE
;
2618 status
= ISC_R_SUCCESS
;
2623 * We don't want to include the IA if we
2624 * provide zero addresses including zeroed
2627 if (reply
->resources_included
)
2628 status
= ISC_R_SUCCESS
;
2633 } else if (status
!= ISC_R_SUCCESS
)
2637 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2638 sizeof(reply
->buf
) - reply
->cursor
,
2639 reply
->reply_ia
, reply
->packet
,
2640 required_opts_IA
, NULL
);
2642 /* Reset the length of this IA to match what was just written. */
2643 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2644 reply
->cursor
- (ia_cursor
+ 4));
2647 * yes, goto's aren't the best but we also want to avoid extra
2650 if (status
== ISC_R_CANCELED
)
2654 * If we have any addresses log what we are doing.
2656 if (reply
->ia
->num_iasubopt
!= 0) {
2657 struct iasubopt
*tmp
;
2659 char tmp_addr
[INET6_ADDRSTRLEN
];
2661 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2662 tmp
= reply
->ia
->iasubopt
[i
];
2664 log_info("%s TA: address %s to client with duid %s "
2665 "iaid = %d valid for %d seconds",
2666 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2667 inet_ntop(AF_INET6
, &tmp
->addr
,
2668 tmp_addr
, sizeof(tmp_addr
)),
2669 print_hex_1(reply
->client_id
.len
,
2670 reply
->client_id
.data
, 60),
2677 * For hard bindings we consume the new changes into
2678 * the database (if any have been attached to the ia_ta).
2680 * Loop through the assigned dynamic addresses, referencing the
2681 * leases onto this IA_TA rather than any old ones, and updating
2682 * pool timers for each (if any).
2684 if ((reply
->ia
->num_iasubopt
!= 0) &&
2685 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
2686 struct iasubopt
*tmp
;
2687 struct data_string
*ia_id
;
2690 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2691 tmp
= reply
->ia
->iasubopt
[i
];
2693 if (tmp
->ia
!= NULL
)
2694 ia_dereference(&tmp
->ia
, MDL
);
2695 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2697 /* Commit 'hard' bindings. */
2698 renew_lease6(tmp
->ipv6_pool
, tmp
);
2699 schedule_lease_timeout(tmp
->ipv6_pool
);
2701 /* If we have anything to do on commit do it now */
2702 if (tmp
->on_star
.on_commit
!= NULL
) {
2703 execute_statements(NULL
, reply
->packet
,
2705 reply
->packet
->options
,
2708 tmp
->on_star
.on_commit
,
2710 executable_statement_dereference
2711 (&tmp
->on_star
.on_commit
, MDL
);
2714 #if defined (NSUPDATE)
2716 * Perform ddns updates.
2718 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2721 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2723 reply
->packet
->options
,
2727 ddns_updates(reply
->packet
, NULL
, NULL
,
2728 tmp
, NULL
, reply
->opt_state
);
2733 /* Remove any old ia from the hash. */
2734 if (reply
->old_ia
!= NULL
) {
2735 ia_id
= &reply
->old_ia
->iaid_duid
;
2736 ia_hash_delete(ia_ta_active
,
2737 (unsigned char *)ia_id
->data
,
2739 ia_dereference(&reply
->old_ia
, MDL
);
2742 /* Put new ia into the hash. */
2743 reply
->ia
->cltt
= cur_time
;
2744 ia_id
= &reply
->ia
->iaid_duid
;
2745 ia_hash_add(ia_ta_active
, (unsigned char *)ia_id
->data
,
2746 ia_id
->len
, reply
->ia
, MDL
);
2748 write_ia(reply
->ia
);
2752 if (packet_ia
!= NULL
)
2753 option_state_dereference(&packet_ia
, MDL
);
2754 if (iaaddr
.data
!= NULL
)
2755 data_string_forget(&iaaddr
, MDL
);
2756 if (reply
->reply_ia
!= NULL
)
2757 option_state_dereference(&reply
->reply_ia
, MDL
);
2758 if (ia_data
.data
!= NULL
)
2759 data_string_forget(&ia_data
, MDL
);
2760 if (data
.data
!= NULL
)
2761 data_string_forget(&data
, MDL
);
2762 if (reply
->ia
!= NULL
)
2763 ia_dereference(&reply
->ia
, MDL
);
2764 if (reply
->old_ia
!= NULL
)
2765 ia_dereference(&reply
->old_ia
, MDL
);
2766 if (reply
->lease
!= NULL
)
2767 iasubopt_dereference(&reply
->lease
, MDL
);
2770 * ISC_R_CANCELED is a status code used by the addr processing to
2771 * indicate we're replying with other addresses. This is still a
2772 * success at higher layers.
2774 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2778 * Verify the temporary address is available.
2780 static isc_boolean_t
2781 temporary_is_available(struct reply_state
*reply
, struct iaddr
*addr
) {
2782 struct in6_addr tmp_addr
;
2783 struct subnet
*subnet
;
2784 struct ipv6_pool
*pool
= NULL
;
2785 struct ipv6_pond
*pond
= NULL
;
2788 memcpy(&tmp_addr
, addr
->iabuf
, sizeof(tmp_addr
));
2790 * Clients may choose to send :: as an address, with the idea to give
2791 * hints about preferred-lifetime or valid-lifetime.
2792 * So this is not a request for this address.
2794 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
))
2798 * Verify that this address is on the client's network.
2800 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
2801 subnet
= subnet
->next_sibling
) {
2802 if (addr_eq(subnet_number(*addr
, subnet
->netmask
),
2807 /* Address not found on shared network. */
2812 * Check if this address is owned (must be before next step).
2814 if (address_is_owned(reply
, addr
))
2818 * Verify that this address is in a temporary pool and try to get it.
2820 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
2821 if (((pond
->prohibit_list
!= NULL
) &&
2822 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
2823 ((pond
->permit_list
!= NULL
) &&
2824 (!permitted(reply
->packet
, pond
->permit_list
))))
2827 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
2828 if (pool
->pool_type
!= D6O_IA_TA
)
2831 if (ipv6_in_pool(&tmp_addr
, pool
))
2841 if (lease6_exists(pool
, &tmp_addr
))
2843 if (iasubopt_allocate(&reply
->lease
, MDL
) != ISC_R_SUCCESS
)
2845 reply
->lease
->addr
= tmp_addr
;
2846 reply
->lease
->plen
= 0;
2847 /* Default is soft binding for 2 minutes. */
2848 if (add_lease6(pool
, reply
->lease
, cur_time
+ 120) != ISC_R_SUCCESS
)
2855 * Get a temporary address per prefix.
2858 find_client_temporaries(struct reply_state
*reply
) {
2860 struct ipv6_pool
*p
= NULL
;
2861 struct ipv6_pond
*pond
;
2862 isc_result_t status
= ISC_R_NORESOURCES
;;
2863 unsigned int attempts
;
2864 struct iaddr send_addr
;
2867 * Do a quick walk through of the ponds and pools
2868 * to see if we have any prefix pools
2870 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
2871 if (pond
->ipv6_pools
== NULL
)
2874 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
2875 if (p
->pool_type
== D6O_IA_TA
)
2882 /* If we get here and p is NULL we have no useful pools */
2884 log_debug("Unable to get client addresses: "
2885 "no IPv6 pools on this shared network");
2886 return ISC_R_NORESOURCES
;
2890 * We have at least one pool that could provide an address
2891 * Now we walk through the ponds and pools again and check
2892 * to see if the client is permitted and if an address is
2896 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
2897 if (((pond
->prohibit_list
!= NULL
) &&
2898 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
2899 ((pond
->permit_list
!= NULL
) &&
2900 (!permitted(reply
->packet
, pond
->permit_list
))))
2903 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
2904 if (p
->pool_type
!= D6O_IA_TA
) {
2909 * Get an address in this temporary pool.
2911 status
= create_lease6(p
, &reply
->lease
, &attempts
,
2912 &reply
->client_id
, cur_time
+ 120);
2913 if (status
!= ISC_R_SUCCESS
) {
2914 log_debug("Unable to get a temporary address.");
2918 status
= reply_process_is_addressed(reply
,
2919 &reply
->lease
->scope
,
2921 if (status
!= ISC_R_SUCCESS
) {
2925 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
2926 status
= reply_process_send_addr(reply
, &send_addr
);
2927 if (status
!= ISC_R_SUCCESS
) {
2931 * reply->lease can't be null as we use it above
2932 * add check if that changes
2934 iasubopt_dereference(&reply
->lease
, MDL
);
2939 if (reply
->lease
!= NULL
) {
2940 iasubopt_dereference(&reply
->lease
, MDL
);
2946 * This function only returns failure on 'hard' failures. If it succeeds,
2947 * it will leave a lease structure behind.
2950 reply_process_try_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
2951 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
2952 struct ipv6_pool
*pool
= NULL
;
2953 struct ipv6_pond
*pond
= NULL
;
2955 struct data_string data_addr
;
2957 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
2958 (addr
== NULL
) || (reply
->lease
!= NULL
))
2959 return (DHCP_R_INVALIDARG
);
2962 * Do a quick walk through of the ponds and pools
2963 * to see if we have any NA address pools
2965 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
2966 if (pond
->ipv6_pools
== NULL
)
2969 for (i
= 0; ; i
++) {
2970 pool
= pond
->ipv6_pools
[i
];
2971 if ((pool
== NULL
) ||
2972 (pool
->pool_type
== D6O_IA_NA
))
2979 /* If we get here and p is NULL we have no useful pools */
2981 return (ISC_R_ADDRNOTAVAIL
);
2984 memset(&data_addr
, 0, sizeof(data_addr
));
2985 data_addr
.len
= addr
->len
;
2986 data_addr
.data
= addr
->iabuf
;
2989 * We have at least one pool that could provide an address
2990 * Now we walk through the ponds and pools again and check
2991 * to see if the client is permitted and if an address is
2994 * Within a given pond we start looking at the last pool we
2995 * allocated from, unless it had a collision trying to allocate
2996 * an address. This will tend to move us into less-filled pools.
2999 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3000 if (((pond
->prohibit_list
!= NULL
) &&
3001 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3002 ((pond
->permit_list
!= NULL
) &&
3003 (!permitted(reply
->packet
, pond
->permit_list
))))
3006 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3007 if (pool
->pool_type
!= D6O_IA_NA
)
3010 status
= try_client_v6_address(&reply
->lease
, pool
,
3012 if (status
== ISC_R_SUCCESS
)
3016 if (status
== ISC_R_SUCCESS
)
3020 /* Note that this is just pedantry. There is no allocation to free. */
3021 data_string_forget(&data_addr
, MDL
);
3022 /* Return just the most recent status... */
3026 /* Look around for an address to give the client. First, look through the
3027 * old IA for addresses we can extend. Second, try to allocate a new address.
3028 * Finally, actually add that address into the current reply IA.
3031 find_client_address(struct reply_state
*reply
) {
3032 struct iaddr send_addr
;
3033 isc_result_t status
= ISC_R_NORESOURCES
;
3034 struct iasubopt
*lease
, *best_lease
= NULL
;
3035 struct binding_scope
**scope
;
3036 struct group
*group
;
3039 if (reply
->static_lease
) {
3040 if (reply
->host
== NULL
)
3041 return DHCP_R_INVALIDARG
;
3044 memcpy(send_addr
.iabuf
, reply
->fixed
.data
, 16);
3046 scope
= &global_scope
;
3047 group
= reply
->subnet
->group
;
3051 if (reply
->old_ia
!= NULL
) {
3052 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3053 struct shared_network
*candidate_shared
;
3054 struct ipv6_pond
*pond
;
3056 lease
= reply
->old_ia
->iasubopt
[i
];
3057 candidate_shared
= lease
->ipv6_pool
->shared_network
;
3058 pond
= lease
->ipv6_pool
->ipv6_pond
;
3061 * Look for the best lease on the client's shared
3062 * network, that is still permitted
3065 if ((candidate_shared
!= reply
->shared
) ||
3066 (lease6_usable(lease
) != ISC_TRUE
))
3069 if (((pond
->prohibit_list
!= NULL
) &&
3070 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3071 ((pond
->permit_list
!= NULL
) &&
3072 (!permitted(reply
->packet
, pond
->permit_list
))))
3075 best_lease
= lease_compare(lease
, best_lease
);
3079 /* Try to pick a new address if we didn't find one, or if we found an
3082 if ((best_lease
== NULL
) || (best_lease
->state
== FTS_ABANDONED
)) {
3083 status
= pick_v6_address(reply
);
3084 } else if (best_lease
!= NULL
) {
3085 iasubopt_reference(&reply
->lease
, best_lease
, MDL
);
3086 status
= ISC_R_SUCCESS
;
3089 /* Pick the abandoned lease as a last resort. */
3090 if ((status
== ISC_R_NORESOURCES
) && (best_lease
!= NULL
)) {
3091 /* I don't see how this is supposed to be done right now. */
3092 log_error("Reclaiming abandoned addresses is not yet "
3093 "supported. Treating this as an out of space "
3095 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
3098 /* Give up now if we didn't find a lease. */
3099 if (status
!= ISC_R_SUCCESS
)
3102 if (reply
->lease
== NULL
)
3103 log_fatal("Impossible condition at %s:%d.", MDL
);
3105 /* Draw binding scopes from the lease's binding scope, and config
3106 * from the lease's containing subnet and higher. Note that it may
3107 * be desirable to place the group attachment directly in the pool.
3109 scope
= &reply
->lease
->scope
;
3110 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
3113 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3116 status
= reply_process_is_addressed(reply
, scope
, group
);
3117 if (status
!= ISC_R_SUCCESS
)
3120 status
= reply_process_send_addr(reply
, &send_addr
);
3124 /* Once an address is found for a client, perform several common functions;
3125 * Calculate and store valid and preferred lease times, draw client options
3126 * into the option state.
3129 reply_process_is_addressed(struct reply_state
*reply
,
3130 struct binding_scope
**scope
, struct group
*group
)
3132 isc_result_t status
= ISC_R_SUCCESS
;
3133 struct data_string data
;
3134 struct option_cache
*oc
;
3135 struct option_state
*tmp_options
= NULL
;
3136 struct on_star
*on_star
;
3139 /* Initialize values we will cleanup. */
3140 memset(&data
, 0, sizeof(data
));
3143 * Find the proper on_star block to use. We use the
3144 * one in the lease if we have a lease or the one in
3145 * the reply if we don't have a lease because this is
3149 on_star
= &reply
->lease
->on_star
;
3151 on_star
= &reply
->on_star
;
3155 * Bring in the root configuration. We only do this to bring
3156 * in the on * statements, as we didn't have the lease available
3157 * we did it the first time.
3159 option_state_allocate(&tmp_options
, MDL
);
3160 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3161 reply
->packet
->options
, tmp_options
,
3162 &global_scope
, root_group
, NULL
,
3164 if (tmp_options
!= NULL
) {
3165 option_state_dereference(&tmp_options
, MDL
);
3169 * Bring configured options into the root packet level cache - start
3170 * with the lease's closest enclosing group (passed in by the caller
3173 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3174 reply
->packet
->options
, reply
->opt_state
,
3175 scope
, group
, root_group
, on_star
);
3177 /* Execute statements from class scopes. */
3178 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3179 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3180 reply
->packet
->options
,
3181 reply
->opt_state
, scope
,
3182 reply
->packet
->classes
[i
- 1]->group
,
3187 * If there is a host record, over-ride with values configured there,
3188 * without re-evaluating configuration from the previously executed
3189 * group or its common enclosers.
3191 if (reply
->host
!= NULL
)
3192 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3193 reply
->packet
->options
,
3194 reply
->opt_state
, scope
,
3195 reply
->host
->group
, group
,
3198 /* Determine valid lifetime. */
3199 if (reply
->client_valid
== 0)
3200 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
3202 reply
->send_valid
= reply
->client_valid
;
3204 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3205 SV_DEFAULT_LEASE_TIME
);
3207 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3208 reply
->packet
->options
,
3212 log_error("reply_process_is_addressed: unable to "
3213 "evaluate default lease time");
3214 status
= ISC_R_FAILURE
;
3218 reply
->send_valid
= getULong(data
.data
);
3219 data_string_forget(&data
, MDL
);
3222 if (reply
->client_prefer
== 0)
3223 reply
->send_prefer
= reply
->send_valid
;
3225 reply
->send_prefer
= reply
->client_prefer
;
3227 if (reply
->send_prefer
>= reply
->send_valid
)
3228 reply
->send_prefer
= (reply
->send_valid
/ 2) +
3229 (reply
->send_valid
/ 8);
3231 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3232 SV_PREFER_LIFETIME
);
3234 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3235 reply
->packet
->options
,
3239 log_error("reply_process_is_addressed: unable to "
3240 "evaluate preferred lease time");
3241 status
= ISC_R_FAILURE
;
3245 reply
->send_prefer
= getULong(data
.data
);
3246 data_string_forget(&data
, MDL
);
3249 /* Note lowest values for later calculation of renew/rebind times. */
3250 if (reply
->prefer
> reply
->send_prefer
)
3251 reply
->prefer
= reply
->send_prefer
;
3253 if (reply
->valid
> reply
->send_valid
)
3254 reply
->valid
= reply
->send_valid
;
3258 * XXX: Old 4.0.0 alpha code would change the host {} record
3259 * XXX: uid upon lease assignment. This was intended to cover the
3260 * XXX: case where a client first identifies itself using vendor
3261 * XXX: options in a solicit, or request, but later neglects to include
3262 * XXX: these options in a Renew or Rebind. It is not clear that this
3263 * XXX: is required, and has some startling ramifications (such as
3264 * XXX: how to recover this dynamic host {} state across restarts).
3266 if (reply
->host
!= NULL
)
3267 change_host_uid(host
, reply
->client_id
->data
,
3268 reply
->client_id
->len
);
3271 /* Perform dynamic lease related update work. */
3272 if (reply
->lease
!= NULL
) {
3273 /* Cached lifetimes */
3274 reply
->lease
->prefer
= reply
->send_prefer
;
3275 reply
->lease
->valid
= reply
->send_valid
;
3277 /* Advance (or rewind) the valid lifetime. */
3278 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
3279 reply
->lease
->soft_lifetime_end_time
=
3280 cur_time
+ reply
->send_valid
;
3281 /* Wait before renew! */
3284 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
3285 if (status
!= ISC_R_SUCCESS
) {
3286 log_fatal("reply_process_is_addressed: Unable to "
3287 "attach lease to new IA: %s",
3288 isc_result_totext(status
));
3292 * If this is a new lease, make sure it is attached somewhere.
3294 if (reply
->lease
->ia
== NULL
) {
3295 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
3299 /* Bring a copy of the relevant options into the IA scope. */
3300 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3301 reply
->packet
->options
, reply
->reply_ia
,
3302 scope
, group
, root_group
, NULL
);
3304 /* Execute statements from class scopes. */
3305 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3306 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3307 reply
->packet
->options
,
3308 reply
->reply_ia
, scope
,
3309 reply
->packet
->classes
[i
- 1]->group
,
3314 * And bring in host record configuration, if any, but not to overlap
3315 * the previous group or its common enclosers.
3317 if (reply
->host
!= NULL
)
3318 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3319 reply
->packet
->options
,
3320 reply
->reply_ia
, scope
,
3321 reply
->host
->group
, group
, NULL
);
3324 if (data
.data
!= NULL
)
3325 data_string_forget(&data
, MDL
);
3327 if (status
== ISC_R_SUCCESS
)
3328 reply
->client_resources
++;
3333 /* Simply send an IAADDR within the IA scope as described. */
3335 reply_process_send_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3336 isc_result_t status
= ISC_R_SUCCESS
;
3337 struct data_string data
;
3339 memset(&data
, 0, sizeof(data
));
3341 /* Now append the lease. */
3342 data
.len
= IAADDR_OFFSET
;
3343 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
3344 log_error("reply_process_send_addr: out of memory"
3345 "allocating new IAADDR buffer.");
3346 status
= ISC_R_NOMEMORY
;
3349 data
.data
= data
.buffer
->data
;
3351 memcpy(data
.buffer
->data
, addr
->iabuf
, 16);
3352 putULong(data
.buffer
->data
+ 16, reply
->send_prefer
);
3353 putULong(data
.buffer
->data
+ 20, reply
->send_valid
);
3355 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
3356 data
.buffer
, data
.buffer
->data
,
3357 data
.len
, D6O_IAADDR
, 0)) {
3358 log_error("reply_process_send_addr: unable "
3359 "to save IAADDR option");
3360 status
= ISC_R_FAILURE
;
3364 reply
->resources_included
= ISC_TRUE
;
3367 if (data
.data
!= NULL
)
3368 data_string_forget(&data
, MDL
);
3373 /* Choose the better of two leases. */
3374 static struct iasubopt
*
3375 lease_compare(struct iasubopt
*alpha
, struct iasubopt
*beta
) {
3381 switch(alpha
->state
) {
3383 switch(beta
->state
) {
3385 /* Choose the lease with the longest lifetime (most
3386 * likely the most recently allocated).
3388 if (alpha
->hard_lifetime_end_time
<
3389 beta
->hard_lifetime_end_time
)
3399 log_fatal("Impossible condition at %s:%d.", MDL
);
3404 switch (beta
->state
) {
3409 /* Choose the most recently expired lease. */
3410 if (alpha
->hard_lifetime_end_time
<
3411 beta
->hard_lifetime_end_time
)
3413 else if ((alpha
->hard_lifetime_end_time
==
3414 beta
->hard_lifetime_end_time
) &&
3415 (alpha
->soft_lifetime_end_time
<
3416 beta
->soft_lifetime_end_time
))
3425 log_fatal("Impossible condition at %s:%d.", MDL
);
3430 switch (beta
->state
) {
3436 /* Choose the lease that was abandoned longest ago. */
3437 if (alpha
->hard_lifetime_end_time
<
3438 beta
->hard_lifetime_end_time
)
3442 log_fatal("Impossible condition at %s:%d.", MDL
);
3447 log_fatal("Impossible condition at %s:%d.", MDL
);
3450 log_fatal("Triple impossible condition at %s:%d.", MDL
);
3454 /* Process a client-supplied IA_PD. This may append options to the tail of
3455 * the reply packet being built in the reply_state structure.
3458 reply_process_ia_pd(struct reply_state
*reply
, struct option_cache
*ia
) {
3459 isc_result_t status
= ISC_R_SUCCESS
;
3462 struct option_state
*packet_ia
;
3463 struct option_cache
*oc
;
3464 struct data_string ia_data
, data
;
3466 /* Initialize values that will get cleaned up on return. */
3468 memset(&ia_data
, 0, sizeof(ia_data
));
3469 memset(&data
, 0, sizeof(data
));
3471 * Note that find_client_prefix() may set reply->lease.
3474 /* Make sure there is at least room for the header. */
3475 if ((reply
->cursor
+ IA_PD_OFFSET
+ 4) > sizeof(reply
->buf
)) {
3476 log_error("reply_process_ia_pd: Reply too long for IA.");
3477 return ISC_R_NOSPACE
;
3481 /* Fetch the IA_PD contents. */
3482 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
3483 ia
, IA_PD_OFFSET
)) {
3484 log_error("reply_process_ia_pd: error evaluating ia");
3485 status
= ISC_R_FAILURE
;
3489 /* Extract IA_PD header contents. */
3490 iaid
= getULong(ia_data
.data
);
3491 reply
->renew
= getULong(ia_data
.data
+ 4);
3492 reply
->rebind
= getULong(ia_data
.data
+ 8);
3494 /* Create an IA_PD structure. */
3495 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
3496 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
3497 log_error("reply_process_ia_pd: no memory for ia.");
3498 status
= ISC_R_NOMEMORY
;
3501 reply
->ia
->ia_type
= D6O_IA_PD
;
3503 /* Cache pre-existing IA_PD, if any. */
3504 ia_hash_lookup(&reply
->old_ia
, ia_pd_active
,
3505 (unsigned char *)reply
->ia
->iaid_duid
.data
,
3506 reply
->ia
->iaid_duid
.len
, MDL
);
3509 * Create an option cache to carry the IA_PD option contents, and
3510 * execute any user-supplied values into it.
3512 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
3513 status
= ISC_R_NOMEMORY
;
3517 /* Check & count the fixed prefix host records. */
3518 reply
->static_prefixes
= 0;
3519 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_prefix
!= NULL
)) {
3520 struct iaddrcidrnetlist
*fp
;
3522 for (fp
= reply
->host
->fixed_prefix
; fp
!= NULL
;
3524 reply
->static_prefixes
+= 1;
3529 * Save the cursor position at the start of the IA_PD, so we can
3530 * set length and adjust t1/t2 values later. We write a temporary
3531 * header out now just in case we decide to adjust the packet
3532 * within sub-process functions.
3534 ia_cursor
= reply
->cursor
;
3536 /* Initialize the IA_PD header. First the code. */
3537 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_PD
);
3540 /* Then option length. */
3541 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
3544 /* Then IA_PD header contents; IAID. */
3545 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
3548 /* We store the client's t1 for now, and may over-ride it later. */
3549 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
3552 /* We store the client's t2 for now, and may over-ride it later. */
3553 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
3557 * For each prefix in this IA_PD, decide what to do about it.
3559 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAPREFIX
);
3560 reply
->valid
= reply
->prefer
= 0xffffffff;
3561 reply
->client_valid
= reply
->client_prefer
= 0;
3562 reply
->preflen
= -1;
3563 for (; oc
!= NULL
; oc
= oc
->next
) {
3564 status
= reply_process_prefix(reply
, oc
);
3567 * Canceled means we did not allocate prefixes to the
3568 * client, but we're "done" with this IA - we set a status
3569 * code. So transmit this reply, e.g., move on to the next
3572 if (status
== ISC_R_CANCELED
)
3575 if ((status
!= ISC_R_SUCCESS
) &&
3576 (status
!= ISC_R_ADDRINUSE
) &&
3577 (status
!= ISC_R_ADDRNOTAVAIL
))
3584 * If we fell through the above and never gave the client
3585 * a prefix, give it one now.
3587 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
3588 status
= find_client_prefix(reply
);
3590 if (status
== ISC_R_NORESOURCES
) {
3591 switch (reply
->packet
->dhcpv6_msg_type
) {
3592 case DHCPV6_SOLICIT
:
3594 * No prefix for any IA is handled
3599 case DHCPV6_REQUEST
:
3600 /* Same than for addresses. */
3601 option_state_dereference(&reply
->reply_ia
, MDL
);
3602 if (!option_state_allocate(&reply
->reply_ia
,
3605 log_error("reply_process_ia_pd: No "
3606 "memory for option state "
3608 status
= ISC_R_NOMEMORY
;
3612 if (!set_status_code(STATUS_NoPrefixAvail
,
3613 "No prefixes available "
3614 "for this interface.",
3616 log_error("reply_process_ia_pd: "
3618 "NoPrefixAvail status "
3620 status
= ISC_R_FAILURE
;
3624 status
= ISC_R_SUCCESS
;
3628 if (reply
->resources_included
)
3629 status
= ISC_R_SUCCESS
;
3636 if (status
!= ISC_R_SUCCESS
)
3640 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
3641 sizeof(reply
->buf
) - reply
->cursor
,
3642 reply
->reply_ia
, reply
->packet
,
3643 required_opts_IA_PD
, NULL
);
3645 /* Reset the length of this IA_PD to match what was just written. */
3646 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
3647 reply
->cursor
- (ia_cursor
+ 4));
3650 * T1/T2 time selection is kind of weird. We actually use DHCP
3651 * (v4) scoped options as handy existing places where these might
3652 * be configured by an administrator. A value of zero tells the
3653 * client it may choose its own renewal time.
3656 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
3657 DHO_DHCP_RENEWAL_TIME
);
3659 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3660 reply
->packet
->options
,
3661 reply
->opt_state
, &global_scope
,
3664 log_error("Invalid renewal time.");
3666 reply
->renew
= getULong(data
.data
);
3669 if (data
.data
!= NULL
)
3670 data_string_forget(&data
, MDL
);
3672 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
3676 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
3677 DHO_DHCP_REBINDING_TIME
);
3679 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3680 reply
->packet
->options
,
3681 reply
->opt_state
, &global_scope
,
3684 log_error("Invalid rebinding time.");
3686 reply
->rebind
= getULong(data
.data
);
3689 if (data
.data
!= NULL
)
3690 data_string_forget(&data
, MDL
);
3692 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
3695 * yes, goto's aren't the best but we also want to avoid extra
3698 if (status
== ISC_R_CANCELED
)
3702 * Handle static prefixes, we always log stuff and if it's
3703 * a hard binding we run any commit statements that we have
3705 if (reply
->static_prefixes
!= 0) {
3706 char tmp_addr
[INET6_ADDRSTRLEN
];
3707 log_info("%s PD: address %s/%d to client with duid %s "
3709 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
3710 inet_ntop(AF_INET6
, reply
->fixed_pref
.lo_addr
.iabuf
,
3711 tmp_addr
, sizeof(tmp_addr
)),
3712 reply
->fixed_pref
.bits
,
3713 print_hex_1(reply
->client_id
.len
,
3714 reply
->client_id
.data
, 60),
3716 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
3717 (reply
->on_star
.on_commit
!= NULL
)) {
3718 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
3719 reply
->packet
->options
,
3721 NULL
, reply
->on_star
.on_commit
,
3723 executable_statement_dereference
3724 (&reply
->on_star
.on_commit
, MDL
);
3730 * If we have any addresses log what we are doing.
3732 if (reply
->ia
->num_iasubopt
!= 0) {
3733 struct iasubopt
*tmp
;
3735 char tmp_addr
[INET6_ADDRSTRLEN
];
3737 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3738 tmp
= reply
->ia
->iasubopt
[i
];
3740 log_info("%s PD: address %s/%d to client with duid %s"
3741 " iaid = %d valid for %d seconds",
3742 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
3743 inet_ntop(AF_INET6
, &tmp
->addr
,
3744 tmp_addr
, sizeof(tmp_addr
)),
3746 print_hex_1(reply
->client_id
.len
,
3747 reply
->client_id
.data
, 60),
3753 * If this is not a 'soft' binding, consume the new changes into
3754 * the database (if any have been attached to the ia_pd).
3756 * Loop through the assigned dynamic prefixes, referencing the
3757 * prefixes onto this IA_PD rather than any old ones, and updating
3758 * prefix pool timers for each (if any).
3760 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
3761 (reply
->ia
->num_iasubopt
!= 0)) {
3762 struct iasubopt
*tmp
;
3763 struct data_string
*ia_id
;
3766 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3767 tmp
= reply
->ia
->iasubopt
[i
];
3769 if (tmp
->ia
!= NULL
)
3770 ia_dereference(&tmp
->ia
, MDL
);
3771 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
3773 /* Commit 'hard' bindings. */
3774 renew_lease6(tmp
->ipv6_pool
, tmp
);
3775 schedule_lease_timeout(tmp
->ipv6_pool
);
3777 /* If we have anything to do on commit do it now */
3778 if (tmp
->on_star
.on_commit
!= NULL
) {
3779 execute_statements(NULL
, reply
->packet
,
3781 reply
->packet
->options
,
3784 tmp
->on_star
.on_commit
,
3786 executable_statement_dereference
3787 (&tmp
->on_star
.on_commit
, MDL
);
3791 /* Remove any old ia from the hash. */
3792 if (reply
->old_ia
!= NULL
) {
3793 ia_id
= &reply
->old_ia
->iaid_duid
;
3794 ia_hash_delete(ia_pd_active
,
3795 (unsigned char *)ia_id
->data
,
3797 ia_dereference(&reply
->old_ia
, MDL
);
3800 /* Put new ia into the hash. */
3801 reply
->ia
->cltt
= cur_time
;
3802 ia_id
= &reply
->ia
->iaid_duid
;
3803 ia_hash_add(ia_pd_active
, (unsigned char *)ia_id
->data
,
3804 ia_id
->len
, reply
->ia
, MDL
);
3806 write_ia(reply
->ia
);
3810 if (packet_ia
!= NULL
)
3811 option_state_dereference(&packet_ia
, MDL
);
3812 if (reply
->reply_ia
!= NULL
)
3813 option_state_dereference(&reply
->reply_ia
, MDL
);
3814 if (ia_data
.data
!= NULL
)
3815 data_string_forget(&ia_data
, MDL
);
3816 if (data
.data
!= NULL
)
3817 data_string_forget(&data
, MDL
);
3818 if (reply
->ia
!= NULL
)
3819 ia_dereference(&reply
->ia
, MDL
);
3820 if (reply
->old_ia
!= NULL
)
3821 ia_dereference(&reply
->old_ia
, MDL
);
3822 if (reply
->lease
!= NULL
)
3823 iasubopt_dereference(&reply
->lease
, MDL
);
3824 if (reply
->on_star
.on_expiry
!= NULL
)
3825 executable_statement_dereference
3826 (&reply
->on_star
.on_expiry
, MDL
);
3827 if (reply
->on_star
.on_release
!= NULL
)
3828 executable_statement_dereference
3829 (&reply
->on_star
.on_release
, MDL
);
3832 * ISC_R_CANCELED is a status code used by the prefix processing to
3833 * indicate we're replying with a status code. This is still a
3834 * success at higher layers.
3836 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
3840 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
3841 * contents into the reply's current ia_pd-scoped option cache. Returns
3842 * ISC_R_CANCELED in the event we are replying with a status code and do
3843 * not wish to process more IAPREFIXes within this IA_PD.
3846 reply_process_prefix(struct reply_state
*reply
, struct option_cache
*pref
) {
3847 u_int32_t pref_life
, valid_life
;
3848 struct binding_scope
**scope
;
3849 struct iaddrcidrnet tmp_pref
;
3850 struct option_cache
*oc
;
3851 struct data_string iapref
, data
;
3852 isc_result_t status
= ISC_R_SUCCESS
;
3853 struct group
*group
;
3855 /* Initializes values that will be cleaned up. */
3856 memset(&iapref
, 0, sizeof(iapref
));
3857 memset(&data
, 0, sizeof(data
));
3858 /* Note that reply->lease may be set by prefix_is_owned() */
3861 * There is no point trying to process an incoming prefix if there
3862 * is no room for an outgoing prefix.
3864 if ((reply
->cursor
+ 29) > sizeof(reply
->buf
)) {
3865 log_error("reply_process_prefix: Out of room for prefix.");
3866 return ISC_R_NOSPACE
;
3869 /* Extract this IAPREFIX option. */
3870 if (!evaluate_option_cache(&iapref
, reply
->packet
, NULL
, NULL
,
3871 reply
->packet
->options
, NULL
, &global_scope
,
3873 (iapref
.len
< IAPREFIX_OFFSET
)) {
3874 log_error("reply_process_prefix: error evaluating IAPREFIX.");
3875 status
= ISC_R_FAILURE
;
3880 * Layout: preferred and valid lifetimes followed by the prefix
3881 * length and the IPv6 address.
3883 pref_life
= getULong(iapref
.data
);
3884 valid_life
= getULong(iapref
.data
+ 4);
3886 if ((reply
->client_valid
== 0) ||
3887 (reply
->client_valid
> valid_life
))
3888 reply
->client_valid
= valid_life
;
3890 if ((reply
->client_prefer
== 0) ||
3891 (reply
->client_prefer
> pref_life
))
3892 reply
->client_prefer
= pref_life
;
3895 * Clients may choose to send ::/0 as a prefix, with the idea to give
3896 * hints about preferred-lifetime or valid-lifetime.
3898 tmp_pref
.lo_addr
.len
= 16;
3899 memset(tmp_pref
.lo_addr
.iabuf
, 0, 16);
3900 if ((iapref
.data
[8] == 0) &&
3901 (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0)) {
3902 /* Status remains success; we just ignore this one. */
3907 * Clients may choose to send ::/X as a prefix to specify a
3908 * preferred/requested prefix length. Note X is never zero here.
3910 tmp_pref
.bits
= (int) iapref
.data
[8];
3911 if (reply
->preflen
< 0) {
3912 /* Cache the first preferred prefix length. */
3913 reply
->preflen
= tmp_pref
.bits
;
3915 if (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0) {
3919 memcpy(tmp_pref
.lo_addr
.iabuf
, iapref
.data
+ 9, 16);
3921 /* Verify the prefix belongs to the client. */
3922 if (!prefix_is_owned(reply
, &tmp_pref
)) {
3923 /* Same than for addresses. */
3924 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
3925 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
3926 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
3927 status
= reply_process_try_prefix(reply
, &tmp_pref
);
3929 /* Either error out or skip this prefix. */
3930 if ((status
!= ISC_R_SUCCESS
) &&
3931 (status
!= ISC_R_ADDRINUSE
) &&
3932 (status
!= ISC_R_ADDRNOTAVAIL
))
3935 if (reply
->lease
== NULL
) {
3936 if (reply
->packet
->dhcpv6_msg_type
==
3938 reply
->send_prefer
= 0;
3939 reply
->send_valid
= 0;
3943 /* status remains success - ignore */
3947 * RFC3633 section 18.2.3:
3949 * If the delegating router cannot find a binding
3950 * for the requesting router's IA_PD the delegating
3951 * router returns the IA_PD containing no prefixes
3952 * with a Status Code option set to NoBinding in the
3955 * On mismatch we (ab)use this pretending we have not the IA
3956 * as soon as we have not a prefix.
3958 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
3959 /* Rewind the IA_PD to empty. */
3960 option_state_dereference(&reply
->reply_ia
, MDL
);
3961 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
3962 log_error("reply_process_prefix: No memory "
3963 "for option state wipe.");
3964 status
= ISC_R_NOMEMORY
;
3968 /* Append a NoBinding status code. */
3969 if (!set_status_code(STATUS_NoBinding
,
3970 "Prefix not bound to this "
3971 "interface.", reply
->reply_ia
)) {
3972 log_error("reply_process_prefix: Unable to "
3973 "attach status code.");
3974 status
= ISC_R_FAILURE
;
3978 /* Fin (no more IAPREFIXes). */
3979 status
= ISC_R_CANCELED
;
3982 log_error("It is impossible to lease a client that is "
3983 "not sending a solicit, request, renew, or "
3985 status
= ISC_R_FAILURE
;
3990 if (reply
->static_prefixes
> 0) {
3991 if (reply
->host
== NULL
)
3992 log_fatal("Impossible condition at %s:%d.", MDL
);
3994 scope
= &global_scope
;
3996 /* Find the static prefixe's subnet. */
3997 if (find_grouped_subnet(&reply
->subnet
, reply
->shared
,
3998 tmp_pref
.lo_addr
, MDL
) == 0)
3999 log_fatal("Impossible condition at %s:%d.", MDL
);
4000 group
= reply
->subnet
->group
;
4001 subnet_dereference(&reply
->subnet
, MDL
);
4003 /* Copy the static prefix for logging purposes */
4004 memcpy(&reply
->fixed_pref
, &tmp_pref
, sizeof(tmp_pref
));
4006 if (reply
->lease
== NULL
)
4007 log_fatal("Impossible condition at %s:%d.", MDL
);
4009 scope
= &reply
->lease
->scope
;
4010 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4014 * If client_resources is nonzero, then the reply_process_is_prefixed
4015 * function has executed configuration state into the reply option
4016 * cache. We will use that valid cache to derive configuration for
4017 * whether or not to engage in additional prefixes, and similar.
4019 if (reply
->client_resources
!= 0) {
4023 * Does this client have "enough" prefixes already? Default
4024 * to one. Everybody gets one, and one should be enough for
4027 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4028 SV_LIMIT_PREFS_PER_IA
);
4030 if (!evaluate_option_cache(&data
, reply
->packet
,
4032 reply
->packet
->options
,
4036 log_error("reply_process_prefix: unable to "
4037 "evaluate prefs-per-ia value.");
4038 status
= ISC_R_FAILURE
;
4042 limit
= getULong(data
.data
);
4043 data_string_forget(&data
, MDL
);
4047 * If we wish to limit the client to a certain number of
4048 * prefixes, then omit the prefix from the reply.
4050 if (reply
->client_resources
>= limit
)
4054 status
= reply_process_is_prefixed(reply
, scope
, group
);
4055 if (status
!= ISC_R_SUCCESS
)
4059 status
= reply_process_send_prefix(reply
, &tmp_pref
);
4062 if (iapref
.data
!= NULL
)
4063 data_string_forget(&iapref
, MDL
);
4064 if (data
.data
!= NULL
)
4065 data_string_forget(&data
, MDL
);
4066 if (reply
->lease
!= NULL
)
4067 iasubopt_dereference(&reply
->lease
, MDL
);
4073 * Verify the prefix belongs to the client. If we've got a host
4074 * record with fixed prefixes, it has to be an assigned prefix
4075 * (fault out all else). Otherwise it's a dynamic prefix, so lookup
4076 * that prefix and make sure it belongs to this DUID:IAID pair.
4078 static isc_boolean_t
4079 prefix_is_owned(struct reply_state
*reply
, struct iaddrcidrnet
*pref
) {
4080 struct iaddrcidrnetlist
*l
;
4082 struct ipv6_pond
*pond
;
4085 * This faults out prefixes that don't match fixed prefixes.
4087 if (reply
->static_prefixes
> 0) {
4088 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4089 if ((pref
->bits
== l
->cidrnet
.bits
) &&
4090 (memcmp(pref
->lo_addr
.iabuf
,
4091 l
->cidrnet
.lo_addr
.iabuf
, 16) == 0))
4097 if ((reply
->old_ia
== NULL
) ||
4098 (reply
->old_ia
->num_iasubopt
== 0))
4101 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4102 struct iasubopt
*tmp
;
4104 tmp
= reply
->old_ia
->iasubopt
[i
];
4106 if ((pref
->bits
== (int) tmp
->plen
) &&
4107 (memcmp(pref
->lo_addr
.iabuf
, &tmp
->addr
, 16) == 0)) {
4108 if (lease6_usable(tmp
) == ISC_FALSE
) {
4112 pond
= tmp
->ipv6_pool
->ipv6_pond
;
4113 if (((pond
->prohibit_list
!= NULL
) &&
4114 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4115 ((pond
->permit_list
!= NULL
) &&
4116 (!permitted(reply
->packet
, pond
->permit_list
))))
4119 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
4128 * This function only returns failure on 'hard' failures. If it succeeds,
4129 * it will leave a prefix structure behind.
4132 reply_process_try_prefix(struct reply_state
*reply
,
4133 struct iaddrcidrnet
*pref
) {
4134 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
4135 struct ipv6_pool
*pool
= NULL
;
4136 struct ipv6_pond
*pond
= NULL
;
4138 struct data_string data_pref
;
4140 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
4141 (pref
== NULL
) || (reply
->lease
!= NULL
))
4142 return (DHCP_R_INVALIDARG
);
4145 * Do a quick walk through of the ponds and pools
4146 * to see if we have any prefix pools
4148 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4149 if (pond
->ipv6_pools
== NULL
)
4152 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4153 if (pool
->pool_type
== D6O_IA_PD
)
4160 /* If we get here and p is NULL we have no useful pools */
4162 return (ISC_R_ADDRNOTAVAIL
);
4165 memset(&data_pref
, 0, sizeof(data_pref
));
4167 if (!buffer_allocate(&data_pref
.buffer
, data_pref
.len
, MDL
)) {
4168 log_error("reply_process_try_prefix: out of memory.");
4169 return (ISC_R_NOMEMORY
);
4171 data_pref
.data
= data_pref
.buffer
->data
;
4172 data_pref
.buffer
->data
[0] = (u_int8_t
) pref
->bits
;
4173 memcpy(data_pref
.buffer
->data
+ 1, pref
->lo_addr
.iabuf
, 16);
4176 * We have at least one pool that could provide a prefix
4177 * Now we walk through the ponds and pools again and check
4178 * to see if the client is permitted and if an prefix is
4183 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4184 if (((pond
->prohibit_list
!= NULL
) &&
4185 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4186 ((pond
->permit_list
!= NULL
) &&
4187 (!permitted(reply
->packet
, pond
->permit_list
))))
4190 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4191 if (pool
->pool_type
!= D6O_IA_PD
) {
4195 status
= try_client_v6_prefix(&reply
->lease
, pool
,
4197 /* If we found it in this pool (either in use or available),
4198 there is no need to look further. */
4199 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4202 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4206 data_string_forget(&data_pref
, MDL
);
4207 /* Return just the most recent status... */
4211 /* Look around for a prefix to give the client. First, look through the old
4212 * IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
4213 * Finally, actually add that prefix into the current reply IA_PD.
4216 find_client_prefix(struct reply_state
*reply
) {
4217 struct iaddrcidrnet send_pref
;
4218 isc_result_t status
= ISC_R_NORESOURCES
;
4219 struct iasubopt
*prefix
, *best_prefix
= NULL
;
4220 struct binding_scope
**scope
;
4222 struct group
*group
;
4224 if (reply
->static_prefixes
> 0) {
4225 struct iaddrcidrnetlist
*l
;
4227 if (reply
->host
== NULL
)
4228 return DHCP_R_INVALIDARG
;
4230 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4231 if (l
->cidrnet
.bits
== reply
->preflen
)
4236 * If no fixed prefix has the preferred length,
4237 * get the first one.
4239 l
= reply
->host
->fixed_prefix
;
4241 memcpy(&send_pref
, &l
->cidrnet
, sizeof(send_pref
));
4243 scope
= &global_scope
;
4245 /* Find the static prefixe's subnet. */
4246 if (find_grouped_subnet(&reply
->subnet
, reply
->shared
,
4247 send_pref
.lo_addr
, MDL
) == 0)
4248 log_fatal("Impossible condition at %s:%d.", MDL
);
4249 group
= reply
->subnet
->group
;
4250 subnet_dereference(&reply
->subnet
, MDL
);
4252 /* Copy the prefix for logging purposes */
4253 memcpy(&reply
->fixed_pref
, &l
->cidrnet
, sizeof(send_pref
));
4258 if (reply
->old_ia
!= NULL
) {
4259 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4260 struct shared_network
*candidate_shared
;
4261 struct ipv6_pond
*pond
;
4263 prefix
= reply
->old_ia
->iasubopt
[i
];
4264 candidate_shared
= prefix
->ipv6_pool
->shared_network
;
4265 pond
= prefix
->ipv6_pool
->ipv6_pond
;
4268 * Consider this prefix if it is in a global pool or
4269 * if it is scoped in a pool under the client's shared
4272 if (((candidate_shared
!= NULL
) &&
4273 (candidate_shared
!= reply
->shared
)) ||
4274 (lease6_usable(prefix
) != ISC_TRUE
))
4278 * And check if the prefix is still permitted
4281 if (((pond
->prohibit_list
!= NULL
) &&
4282 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4283 ((pond
->permit_list
!= NULL
) &&
4284 (!permitted(reply
->packet
, pond
->permit_list
))))
4287 best_prefix
= prefix_compare(reply
, prefix
,
4292 /* Try to pick a new prefix if we didn't find one, or if we found an
4295 if ((best_prefix
== NULL
) || (best_prefix
->state
== FTS_ABANDONED
)) {
4296 status
= pick_v6_prefix(reply
);
4297 } else if (best_prefix
!= NULL
) {
4298 iasubopt_reference(&reply
->lease
, best_prefix
, MDL
);
4299 status
= ISC_R_SUCCESS
;
4302 /* Pick the abandoned prefix as a last resort. */
4303 if ((status
== ISC_R_NORESOURCES
) && (best_prefix
!= NULL
)) {
4304 /* I don't see how this is supposed to be done right now. */
4305 log_error("Reclaiming abandoned prefixes is not yet "
4306 "supported. Treating this as an out of space "
4308 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
4311 /* Give up now if we didn't find a prefix. */
4312 if (status
!= ISC_R_SUCCESS
)
4315 if (reply
->lease
== NULL
)
4316 log_fatal("Impossible condition at %s:%d.", MDL
);
4318 scope
= &reply
->lease
->scope
;
4319 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4321 send_pref
.lo_addr
.len
= 16;
4322 memcpy(send_pref
.lo_addr
.iabuf
, &reply
->lease
->addr
, 16);
4323 send_pref
.bits
= (int) reply
->lease
->plen
;
4326 status
= reply_process_is_prefixed(reply
, scope
, group
);
4327 if (status
!= ISC_R_SUCCESS
)
4330 status
= reply_process_send_prefix(reply
, &send_pref
);
4334 /* Once a prefix is found for a client, perform several common functions;
4335 * Calculate and store valid and preferred prefix times, draw client options
4336 * into the option state.
4339 reply_process_is_prefixed(struct reply_state
*reply
,
4340 struct binding_scope
**scope
, struct group
*group
)
4342 isc_result_t status
= ISC_R_SUCCESS
;
4343 struct data_string data
;
4344 struct option_cache
*oc
;
4345 struct option_state
*tmp_options
= NULL
;
4346 struct on_star
*on_star
;
4349 /* Initialize values we will cleanup. */
4350 memset(&data
, 0, sizeof(data
));
4353 * Find the proper on_star block to use. We use the
4354 * one in the lease if we have a lease or the one in
4355 * the reply if we don't have a lease because this is
4359 on_star
= &reply
->lease
->on_star
;
4361 on_star
= &reply
->on_star
;
4365 * Bring in the root configuration. We only do this to bring
4366 * in the on * statements, as we didn't have the lease available
4367 * we we did it the first time.
4369 option_state_allocate(&tmp_options
, MDL
);
4370 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4371 reply
->packet
->options
, tmp_options
,
4372 &global_scope
, root_group
, NULL
,
4374 if (tmp_options
!= NULL
) {
4375 option_state_dereference(&tmp_options
, MDL
);
4379 * Bring configured options into the root packet level cache - start
4380 * with the lease's closest enclosing group (passed in by the caller
4383 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4384 reply
->packet
->options
, reply
->opt_state
,
4385 scope
, group
, root_group
, on_star
);
4387 /* Execute statements from class scopes. */
4388 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
4389 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4390 reply
->packet
->options
,
4391 reply
->opt_state
, scope
,
4392 reply
->packet
->classes
[i
- 1]->group
,
4397 * If there is a host record, over-ride with values configured there,
4398 * without re-evaluating configuration from the previously executed
4399 * group or its common enclosers.
4401 if (reply
->host
!= NULL
)
4402 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4403 reply
->packet
->options
,
4404 reply
->opt_state
, scope
,
4405 reply
->host
->group
, group
,
4408 /* Determine valid lifetime. */
4409 if (reply
->client_valid
== 0)
4410 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
4412 reply
->send_valid
= reply
->client_valid
;
4414 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4415 SV_DEFAULT_LEASE_TIME
);
4417 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4418 reply
->packet
->options
,
4422 log_error("reply_process_is_prefixed: unable to "
4423 "evaluate default prefix time");
4424 status
= ISC_R_FAILURE
;
4428 reply
->send_valid
= getULong(data
.data
);
4429 data_string_forget(&data
, MDL
);
4432 if (reply
->client_prefer
== 0)
4433 reply
->send_prefer
= reply
->send_valid
;
4435 reply
->send_prefer
= reply
->client_prefer
;
4437 if (reply
->send_prefer
>= reply
->send_valid
)
4438 reply
->send_prefer
= (reply
->send_valid
/ 2) +
4439 (reply
->send_valid
/ 8);
4441 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4442 SV_PREFER_LIFETIME
);
4444 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4445 reply
->packet
->options
,
4449 log_error("reply_process_is_prefixed: unable to "
4450 "evaluate preferred prefix time");
4451 status
= ISC_R_FAILURE
;
4455 reply
->send_prefer
= getULong(data
.data
);
4456 data_string_forget(&data
, MDL
);
4459 /* Note lowest values for later calculation of renew/rebind times. */
4460 if (reply
->prefer
> reply
->send_prefer
)
4461 reply
->prefer
= reply
->send_prefer
;
4463 if (reply
->valid
> reply
->send_valid
)
4464 reply
->valid
= reply
->send_valid
;
4466 /* Perform dynamic prefix related update work. */
4467 if (reply
->lease
!= NULL
) {
4468 /* Cached lifetimes */
4469 reply
->lease
->prefer
= reply
->send_prefer
;
4470 reply
->lease
->valid
= reply
->send_valid
;
4472 /* Advance (or rewind) the valid lifetime. */
4473 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
4474 reply
->lease
->soft_lifetime_end_time
=
4475 cur_time
+ reply
->send_valid
;
4476 /* Wait before renew! */
4479 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
4480 if (status
!= ISC_R_SUCCESS
) {
4481 log_fatal("reply_process_is_prefixed: Unable to "
4482 "attach prefix to new IA_PD: %s",
4483 isc_result_totext(status
));
4487 * If this is a new prefix, make sure it is attached somewhere.
4489 if (reply
->lease
->ia
== NULL
) {
4490 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
4494 /* Bring a copy of the relevant options into the IA_PD scope. */
4495 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4496 reply
->packet
->options
, reply
->reply_ia
,
4497 scope
, group
, root_group
, NULL
);
4499 /* Execute statements from class scopes. */
4500 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
4501 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4502 reply
->packet
->options
,
4503 reply
->reply_ia
, scope
,
4504 reply
->packet
->classes
[i
- 1]->group
,
4509 * And bring in host record configuration, if any, but not to overlap
4510 * the previous group or its common enclosers.
4512 if (reply
->host
!= NULL
)
4513 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4514 reply
->packet
->options
,
4515 reply
->reply_ia
, scope
,
4516 reply
->host
->group
, group
, NULL
);
4519 if (data
.data
!= NULL
)
4520 data_string_forget(&data
, MDL
);
4522 if (status
== ISC_R_SUCCESS
)
4523 reply
->client_resources
++;
4528 /* Simply send an IAPREFIX within the IA_PD scope as described. */
4530 reply_process_send_prefix(struct reply_state
*reply
,
4531 struct iaddrcidrnet
*pref
) {
4532 isc_result_t status
= ISC_R_SUCCESS
;
4533 struct data_string data
;
4535 memset(&data
, 0, sizeof(data
));
4537 /* Now append the prefix. */
4538 data
.len
= IAPREFIX_OFFSET
;
4539 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
4540 log_error("reply_process_send_prefix: out of memory"
4541 "allocating new IAPREFIX buffer.");
4542 status
= ISC_R_NOMEMORY
;
4545 data
.data
= data
.buffer
->data
;
4547 putULong(data
.buffer
->data
, reply
->send_prefer
);
4548 putULong(data
.buffer
->data
+ 4, reply
->send_valid
);
4549 data
.buffer
->data
[8] = pref
->bits
;
4550 memcpy(data
.buffer
->data
+ 9, pref
->lo_addr
.iabuf
, 16);
4552 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
4553 data
.buffer
, data
.buffer
->data
,
4554 data
.len
, D6O_IAPREFIX
, 0)) {
4555 log_error("reply_process_send_prefix: unable "
4556 "to save IAPREFIX option");
4557 status
= ISC_R_FAILURE
;
4561 reply
->resources_included
= ISC_TRUE
;
4564 if (data
.data
!= NULL
)
4565 data_string_forget(&data
, MDL
);
4570 /* Choose the better of two prefixes. */
4571 static struct iasubopt
*
4572 prefix_compare(struct reply_state
*reply
,
4573 struct iasubopt
*alpha
, struct iasubopt
*beta
) {
4579 if (reply
->preflen
>= 0) {
4580 if ((alpha
->plen
== reply
->preflen
) &&
4581 (beta
->plen
!= reply
->preflen
))
4583 if ((beta
->plen
== reply
->preflen
) &&
4584 (alpha
->plen
!= reply
->preflen
))
4588 switch(alpha
->state
) {
4590 switch(beta
->state
) {
4592 /* Choose the prefix with the longest lifetime (most
4593 * likely the most recently allocated).
4595 if (alpha
->hard_lifetime_end_time
<
4596 beta
->hard_lifetime_end_time
)
4606 log_fatal("Impossible condition at %s:%d.", MDL
);
4611 switch (beta
->state
) {
4616 /* Choose the most recently expired prefix. */
4617 if (alpha
->hard_lifetime_end_time
<
4618 beta
->hard_lifetime_end_time
)
4620 else if ((alpha
->hard_lifetime_end_time
==
4621 beta
->hard_lifetime_end_time
) &&
4622 (alpha
->soft_lifetime_end_time
<
4623 beta
->soft_lifetime_end_time
))
4632 log_fatal("Impossible condition at %s:%d.", MDL
);
4637 switch (beta
->state
) {
4643 /* Choose the prefix that was abandoned longest ago. */
4644 if (alpha
->hard_lifetime_end_time
<
4645 beta
->hard_lifetime_end_time
)
4649 log_fatal("Impossible condition at %s:%d.", MDL
);
4654 log_fatal("Impossible condition at %s:%d.", MDL
);
4657 log_fatal("Triple impossible condition at %s:%d.", MDL
);
4662 * Solicit is how a client starts requesting addresses.
4664 * If the client asks for rapid commit, and we support it, we will
4665 * allocate the addresses and reply.
4667 * Otherwise we will send an advertise message.
4671 dhcpv6_solicit(struct data_string
*reply_ret
, struct packet
*packet
) {
4672 struct data_string client_id
;
4675 * Validate our input.
4677 if (!valid_client_msg(packet
, &client_id
)) {
4681 lease_to_client(reply_ret
, packet
, &client_id
, NULL
);
4686 data_string_forget(&client_id
, MDL
);
4690 * Request is how a client actually requests addresses.
4692 * Very similar to Solicit handling, except the server DUID is required.
4695 /* TODO: reject unicast messages, unless we set unicast option */
4697 dhcpv6_request(struct data_string
*reply_ret
, struct packet
*packet
) {
4698 struct data_string client_id
;
4699 struct data_string server_id
;
4702 * Validate our input.
4704 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
4711 lease_to_client(reply_ret
, packet
, &client_id
, &server_id
);
4716 data_string_forget(&client_id
, MDL
);
4717 data_string_forget(&server_id
, MDL
);
4720 /* Find a DHCPv6 packet's shared network from hints in the packet.
4723 shared_network_from_packet6(struct shared_network
**shared
,
4724 struct packet
*packet
)
4726 const struct packet
*chk_packet
;
4727 const struct in6_addr
*link_addr
, *first_link_addr
;
4728 struct iaddr tmp_addr
;
4729 struct subnet
*subnet
;
4730 isc_result_t status
;
4732 if ((shared
== NULL
) || (*shared
!= NULL
) || (packet
== NULL
))
4733 return DHCP_R_INVALIDARG
;
4736 * First, find the link address where the packet from the client
4737 * first appeared (if this packet was relayed).
4739 first_link_addr
= NULL
;
4740 chk_packet
= packet
->dhcpv6_container_packet
;
4741 while (chk_packet
!= NULL
) {
4742 link_addr
= &chk_packet
->dhcpv6_link_address
;
4743 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
4744 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
4745 first_link_addr
= link_addr
;
4748 chk_packet
= chk_packet
->dhcpv6_container_packet
;
4752 * If there is a relayed link address, find the subnet associated
4753 * with that, and use that to get the appropriate
4756 if (first_link_addr
!= NULL
) {
4757 tmp_addr
.len
= sizeof(*first_link_addr
);
4758 memcpy(tmp_addr
.iabuf
,
4759 first_link_addr
, sizeof(*first_link_addr
));
4761 if (!find_subnet(&subnet
, tmp_addr
, MDL
)) {
4762 log_debug("No subnet found for link-address %s.",
4764 return ISC_R_NOTFOUND
;
4766 status
= shared_network_reference(shared
,
4767 subnet
->shared_network
, MDL
);
4768 subnet_dereference(&subnet
, MDL
);
4771 * If there is no link address, we will use the interface
4772 * that this packet came in on to pick the shared_network.
4774 } else if (packet
->interface
!= NULL
) {
4775 status
= shared_network_reference(shared
,
4776 packet
->interface
->shared_network
,
4778 if (packet
->dhcpv6_container_packet
!= NULL
) {
4779 log_info("[L2 Relay] No link address in relay packet "
4780 "assuming L2 relay and using receiving "
4786 * We shouldn't be able to get here but if there is no link
4787 * address and no interface we don't know where to get the
4788 * pool from log an error and return an error.
4790 log_error("No interface and no link address "
4791 "can't determine pool");
4792 status
= DHCP_R_INVALIDARG
;
4799 * When a client thinks it might be on a new link, it sends a
4802 * From RFC3315 section 18.2.2:
4804 * When the server receives a Confirm message, the server determines
4805 * whether the addresses in the Confirm message are appropriate for the
4806 * link to which the client is attached. If all of the addresses in the
4807 * Confirm message pass this test, the server returns a status of
4808 * Success. If any of the addresses do not pass this test, the server
4809 * returns a status of NotOnLink. If the server is unable to perform
4810 * this test (for example, the server does not have information about
4811 * prefixes on the link to which the client is connected), or there were
4812 * no addresses in any of the IAs sent by the client, the server MUST
4813 * NOT send a reply to the client.
4817 dhcpv6_confirm(struct data_string
*reply_ret
, struct packet
*packet
) {
4818 struct shared_network
*shared
;
4819 struct subnet
*subnet
;
4820 struct option_cache
*ia
, *ta
, *oc
;
4821 struct data_string cli_enc_opt_data
, iaaddr
, client_id
, packet_oro
;
4822 struct option_state
*cli_enc_opt_state
, *opt_state
;
4823 struct iaddr cli_addr
;
4825 isc_boolean_t inappropriate
, has_addrs
;
4826 char reply_data
[65536];
4827 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
4828 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
4831 * Basic client message validation.
4833 memset(&client_id
, 0, sizeof(client_id
));
4834 if (!valid_client_msg(packet
, &client_id
)) {
4839 * Do not process Confirms that do not have IA's we do not recognize.
4841 ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
4842 ta
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
4843 if ((ia
== NULL
) && (ta
== NULL
))
4847 * IA_PD's are simply ignored.
4849 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
4852 * Bit of variable initialization.
4854 opt_state
= cli_enc_opt_state
= NULL
;
4855 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
4856 memset(&iaaddr
, 0, sizeof(iaaddr
));
4857 memset(&packet_oro
, 0, sizeof(packet_oro
));
4859 /* Determine what shared network the client is connected to. We
4860 * must not respond if we don't have any information about the
4861 * network the client is on.
4864 if ((shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
) ||
4868 /* If there are no recorded subnets, then we have no
4869 * information about this subnet - ignore Confirms.
4871 subnet
= shared
->subnets
;
4875 /* Are the addresses in all the IA's appropriate for that link? */
4876 has_addrs
= inappropriate
= ISC_FALSE
;
4878 while(!inappropriate
) {
4879 /* If we've reached the end of the IA_NA pass, move to the
4882 if ((pass
== D6O_IA_NA
) && (ia
== NULL
)) {
4887 /* If we've reached the end of all passes, we're done. */
4891 if (((pass
== D6O_IA_NA
) &&
4892 !get_encapsulated_IA_state(&cli_enc_opt_state
,
4894 packet
, ia
, IA_NA_OFFSET
)) ||
4895 ((pass
== D6O_IA_TA
) &&
4896 !get_encapsulated_IA_state(&cli_enc_opt_state
,
4898 packet
, ia
, IA_TA_OFFSET
))) {
4902 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
4905 for ( ; oc
!= NULL
; oc
= oc
->next
) {
4906 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
4907 packet
->options
, NULL
,
4908 &global_scope
, oc
, MDL
) ||
4909 (iaaddr
.len
< IAADDR_OFFSET
)) {
4910 log_error("dhcpv6_confirm: "
4911 "error evaluating IAADDR.");
4915 /* Copy out the IPv6 address for processing. */
4917 memcpy(cli_addr
.iabuf
, iaaddr
.data
, 16);
4919 data_string_forget(&iaaddr
, MDL
);
4921 /* Record that we've processed at least one address. */
4922 has_addrs
= ISC_TRUE
;
4924 /* Find out if any subnets cover this address. */
4925 for (subnet
= shared
->subnets
; subnet
!= NULL
;
4926 subnet
= subnet
->next_sibling
) {
4927 if (addr_eq(subnet_number(cli_addr
,
4933 /* If we reach the end of the subnet list, and no
4934 * subnet matches the client address, then it must
4935 * be inappropriate to the link (so far as our
4936 * configuration says). Once we've found one
4937 * inappropriate address, there is no reason to
4938 * continue searching.
4940 if (subnet
== NULL
) {
4941 inappropriate
= ISC_TRUE
;
4946 option_state_dereference(&cli_enc_opt_state
, MDL
);
4947 data_string_forget(&cli_enc_opt_data
, MDL
);
4949 /* Advance to the next IA_*. */
4953 /* If the client supplied no addresses, do not reply. */
4960 if (!start_reply(packet
, &client_id
, NULL
, &opt_state
, reply
)) {
4967 if (inappropriate
) {
4968 if (!set_status_code(STATUS_NotOnLink
,
4969 "Some of the addresses are not on link.",
4974 if (!set_status_code(STATUS_Success
,
4975 "All addresses still on link.",
4982 * Only one option: add it.
4984 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
4985 sizeof(reply_data
)-reply_ofs
,
4987 required_opts
, &packet_oro
);
4990 * Return our reply to the caller.
4992 reply_ret
->len
= reply_ofs
;
4993 reply_ret
->buffer
= NULL
;
4994 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
4995 log_fatal("No memory to store reply.");
4997 reply_ret
->data
= reply_ret
->buffer
->data
;
4998 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5001 /* Cleanup any stale data strings. */
5002 if (cli_enc_opt_data
.buffer
!= NULL
)
5003 data_string_forget(&cli_enc_opt_data
, MDL
);
5004 if (iaaddr
.buffer
!= NULL
)
5005 data_string_forget(&iaaddr
, MDL
);
5006 if (client_id
.buffer
!= NULL
)
5007 data_string_forget(&client_id
, MDL
);
5008 if (packet_oro
.buffer
!= NULL
)
5009 data_string_forget(&packet_oro
, MDL
);
5011 /* Release any stale option states. */
5012 if (cli_enc_opt_state
!= NULL
)
5013 option_state_dereference(&cli_enc_opt_state
, MDL
);
5014 if (opt_state
!= NULL
)
5015 option_state_dereference(&opt_state
, MDL
);
5019 * Renew is when a client wants to extend its lease/prefix, at time T1.
5021 * We handle this the same as if the client wants a new lease/prefix,
5022 * except for the error code of when addresses don't match.
5025 /* TODO: reject unicast messages, unless we set unicast option */
5027 dhcpv6_renew(struct data_string
*reply
, struct packet
*packet
) {
5028 struct data_string client_id
;
5029 struct data_string server_id
;
5032 * Validate the request.
5034 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5041 lease_to_client(reply
, packet
, &client_id
, &server_id
);
5046 data_string_forget(&server_id
, MDL
);
5047 data_string_forget(&client_id
, MDL
);
5051 * Rebind is when a client wants to extend its lease, at time T2.
5053 * We handle this the same as if the client wants a new lease, except
5054 * for the error code of when addresses don't match.
5058 dhcpv6_rebind(struct data_string
*reply
, struct packet
*packet
) {
5059 struct data_string client_id
;
5061 if (!valid_client_msg(packet
, &client_id
)) {
5065 lease_to_client(reply
, packet
, &client_id
, NULL
);
5067 data_string_forget(&client_id
, MDL
);
5071 ia_na_match_decline(const struct data_string
*client_id
,
5072 const struct data_string
*iaaddr
,
5073 struct iasubopt
*lease
)
5075 char tmp_addr
[INET6_ADDRSTRLEN
];
5077 log_error("Client %s reports address %s is "
5078 "already in use by another host!",
5079 print_hex_1(client_id
->len
, client_id
->data
, 60),
5080 inet_ntop(AF_INET6
, iaaddr
->data
,
5081 tmp_addr
, sizeof(tmp_addr
)));
5082 if (lease
!= NULL
) {
5083 decline_lease6(lease
->ipv6_pool
, lease
);
5084 lease
->ia
->cltt
= cur_time
;
5085 write_ia(lease
->ia
);
5090 ia_na_nomatch_decline(const struct data_string
*client_id
,
5091 const struct data_string
*iaaddr
,
5092 u_int32_t
*ia_na_id
,
5093 struct packet
*packet
,
5098 char tmp_addr
[INET6_ADDRSTRLEN
];
5099 struct option_state
*host_opt_state
;
5102 log_info("Client %s declines address %s, which is not offered to it.",
5103 print_hex_1(client_id
->len
, client_id
->data
, 60),
5104 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5107 * Create state for this IA_NA.
5109 host_opt_state
= NULL
;
5110 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5111 log_error("ia_na_nomatch_decline: out of memory "
5112 "allocating option_state.");
5116 if (!set_status_code(STATUS_NoBinding
, "Decline for unknown address.",
5122 * Insure we have enough space
5124 if (reply_len
< (*reply_ofs
+ 16)) {
5125 log_error("ia_na_nomatch_decline: "
5126 "out of space for reply packet.");
5131 * Put our status code into the reply packet.
5133 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5134 reply_len
-(*reply_ofs
)-16,
5135 host_opt_state
, packet
,
5136 required_opts_STATUS_CODE
, NULL
);
5139 * Store the non-encapsulated option data for this
5140 * IA_NA into our reply packet. Defined in RFC 3315,
5144 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5146 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5147 /* IA_NA, copied from the client */
5148 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5149 /* t1 and t2, odd that we need them, but here it is */
5150 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5151 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5154 * Get ready for next IA_NA.
5156 *reply_ofs
+= (len
+ 16);
5159 option_state_dereference(&host_opt_state
, MDL
);
5163 iterate_over_ia_na(struct data_string
*reply_ret
,
5164 struct packet
*packet
,
5165 const struct data_string
*client_id
,
5166 const struct data_string
*server_id
,
5167 const char *packet_type
,
5168 void (*ia_na_match
)(const struct data_string
*,
5169 const struct data_string
*,
5171 void (*ia_na_nomatch
)(const struct data_string
*,
5172 const struct data_string
*,
5173 u_int32_t
*, struct packet
*, char *,
5176 struct option_state
*opt_state
;
5177 struct host_decl
*packet_host
;
5178 struct option_cache
*ia
;
5179 struct option_cache
*oc
;
5180 /* cli_enc_... variables come from the IA_NA/IA_TA options */
5181 struct data_string cli_enc_opt_data
;
5182 struct option_state
*cli_enc_opt_state
;
5183 struct host_decl
*host
;
5184 struct option_state
*host_opt_state
;
5185 struct data_string iaaddr
;
5186 struct data_string fixed_addr
;
5187 char reply_data
[65536];
5188 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5189 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5190 char status_msg
[32];
5191 struct iasubopt
*lease
;
5192 struct ia_xx
*existing_ia_na
;
5194 struct data_string key
;
5198 * Initialize to empty values, in case we have to exit early.
5201 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5202 cli_enc_opt_state
= NULL
;
5203 memset(&iaaddr
, 0, sizeof(iaaddr
));
5204 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
5205 host_opt_state
= NULL
;
5209 * Find the host record that matches from the packet, if any.
5212 if (!find_hosts_by_uid(&packet_host
,
5213 client_id
->data
, client_id
->len
, MDL
)) {
5216 * Note: In general, we don't expect a client to provide
5217 * enough information to match by option for these
5218 * types of messages, but if we don't have a UID
5219 * match we can check anyway.
5221 if (!find_hosts_by_option(&packet_host
,
5222 packet
, packet
->options
, MDL
)) {
5225 if (!find_hosts_by_duid_chaddr(&packet_host
,
5232 * Set our reply information.
5234 reply
->msg_type
= DHCPV6_REPLY
;
5235 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
5236 sizeof(reply
->transaction_id
));
5239 * Build our option state for reply.
5242 if (!option_state_allocate(&opt_state
, MDL
)) {
5243 log_error("iterate_over_ia_na: no memory for option_state.");
5246 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5247 packet
->options
, opt_state
,
5248 &global_scope
, root_group
, NULL
, NULL
);
5251 * RFC 3315, section 18.2.7 tells us which options to include.
5253 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
5255 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5256 (unsigned char *)server_duid
.data
,
5257 server_duid
.len
, D6O_SERVERID
, 0)) {
5258 log_error("iterate_over_ia_na: "
5259 "error saving server identifier.");
5264 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
5266 (unsigned char *)client_id
->data
,
5269 log_error("iterate_over_ia_na: "
5270 "error saving client identifier.");
5274 snprintf(status_msg
, sizeof(status_msg
), "%s received.", packet_type
);
5275 if (!set_status_code(STATUS_Success
, status_msg
, opt_state
)) {
5280 * Add our options that are not associated with any IA_NA or IA_TA.
5282 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5283 sizeof(reply_data
)-reply_ofs
,
5285 required_opts
, NULL
);
5288 * Loop through the IA_NA reported by the client, and deal with
5289 * addresses reported as already in use.
5291 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5292 ia
!= NULL
; ia
= ia
->next
) {
5294 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
5296 packet
, ia
, IA_NA_OFFSET
)) {
5300 iaid
= getULong(cli_enc_opt_data
.data
);
5303 * XXX: It is possible that we can get multiple addresses
5304 * sent by the client. We don't send multiple
5305 * addresses, so this indicates a client error.
5306 * We should check for multiple IAADDR options, log
5307 * if found, and set as an error.
5309 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5312 /* no address given for this IA, ignore */
5313 option_state_dereference(&cli_enc_opt_state
, MDL
);
5314 data_string_forget(&cli_enc_opt_data
, MDL
);
5318 memset(&iaaddr
, 0, sizeof(iaaddr
));
5319 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5320 packet
->options
, NULL
,
5321 &global_scope
, oc
, MDL
)) {
5322 log_error("iterate_over_ia_na: "
5323 "error evaluating IAADDR.");
5328 * Now we need to figure out which host record matches
5329 * this IA_NA and IAADDR (encapsulated option contents
5330 * matching a host record by option).
5332 * XXX: We don't currently track IA_NA separately, but
5333 * we will need to do this!
5336 if (!find_hosts_by_option(&host
, packet
,
5337 cli_enc_opt_state
, MDL
)) {
5338 if (packet_host
!= NULL
) {
5344 while (host
!= NULL
) {
5345 if (host
->fixed_addr
!= NULL
) {
5346 if (!evaluate_option_cache(&fixed_addr
, NULL
,
5348 NULL
, &global_scope
,
5351 log_error("iterate_over_ia_na: error "
5352 "evaluating host address.");
5355 if ((iaaddr
.len
>= 16) &&
5356 !memcmp(fixed_addr
.data
, iaaddr
.data
, 16)) {
5357 data_string_forget(&fixed_addr
, MDL
);
5360 data_string_forget(&fixed_addr
, MDL
);
5362 host
= host
->n_ipaddr
;
5365 if ((host
== NULL
) && (iaaddr
.len
>= IAADDR_OFFSET
)) {
5367 * Find existing IA_NA.
5369 if (ia_make_key(&key
, iaid
,
5370 (char *)client_id
->data
,
5372 MDL
) != ISC_R_SUCCESS
) {
5373 log_fatal("iterate_over_ia_na: no memory for "
5377 existing_ia_na
= NULL
;
5378 if (ia_hash_lookup(&existing_ia_na
, ia_na_active
,
5379 (unsigned char *)key
.data
,
5382 * Make sure this address is in the IA_NA.
5384 for (i
=0; i
<existing_ia_na
->num_iasubopt
; i
++) {
5385 struct iasubopt
*tmp
;
5386 struct in6_addr
*in6_addr
;
5388 tmp
= existing_ia_na
->iasubopt
[i
];
5389 in6_addr
= &tmp
->addr
;
5390 if (memcmp(in6_addr
,
5391 iaaddr
.data
, 16) == 0) {
5392 iasubopt_reference(&lease
,
5399 data_string_forget(&key
, MDL
);
5402 if ((host
!= NULL
) || (lease
!= NULL
)) {
5403 ia_na_match(client_id
, &iaaddr
, lease
);
5405 ia_na_nomatch(client_id
, &iaaddr
,
5406 (u_int32_t
*)cli_enc_opt_data
.data
,
5407 packet
, reply_data
, &reply_ofs
,
5408 sizeof(reply_data
));
5411 if (lease
!= NULL
) {
5412 iasubopt_dereference(&lease
, MDL
);
5415 data_string_forget(&iaaddr
, MDL
);
5416 option_state_dereference(&cli_enc_opt_state
, MDL
);
5417 data_string_forget(&cli_enc_opt_data
, MDL
);
5421 * Return our reply to the caller.
5423 reply_ret
->len
= reply_ofs
;
5424 reply_ret
->buffer
= NULL
;
5425 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5426 log_fatal("No memory to store reply.");
5428 reply_ret
->data
= reply_ret
->buffer
->data
;
5429 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5432 if (lease
!= NULL
) {
5433 iasubopt_dereference(&lease
, MDL
);
5435 if (host_opt_state
!= NULL
) {
5436 option_state_dereference(&host_opt_state
, MDL
);
5438 if (fixed_addr
.buffer
!= NULL
) {
5439 data_string_forget(&fixed_addr
, MDL
);
5441 if (iaaddr
.buffer
!= NULL
) {
5442 data_string_forget(&iaaddr
, MDL
);
5444 if (cli_enc_opt_state
!= NULL
) {
5445 option_state_dereference(&cli_enc_opt_state
, MDL
);
5447 if (cli_enc_opt_data
.buffer
!= NULL
) {
5448 data_string_forget(&cli_enc_opt_data
, MDL
);
5450 if (opt_state
!= NULL
) {
5451 option_state_dereference(&opt_state
, MDL
);
5456 * Decline means a client has detected that something else is using an
5457 * address we gave it.
5459 * Since we're only dealing with fixed leases for now, there's not
5460 * much we can do, other that log the occurrence.
5462 * When we start issuing addresses from pools, then we will have to
5463 * record our declined addresses and issue another. In general with
5464 * IPv6 there is no worry about DoS by clients exhausting space, but
5465 * we still need to be aware of this possibility.
5468 /* TODO: reject unicast messages, unless we set unicast option */
5471 dhcpv6_decline(struct data_string
*reply
, struct packet
*packet
) {
5472 struct data_string client_id
;
5473 struct data_string server_id
;
5476 * Validate our input.
5478 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5483 * Undefined for IA_PD.
5485 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5488 * And operate on each IA_NA in this packet.
5490 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
, "Decline",
5491 ia_na_match_decline
, ia_na_nomatch_decline
);
5493 data_string_forget(&server_id
, MDL
);
5494 data_string_forget(&client_id
, MDL
);
5498 ia_na_match_release(const struct data_string
*client_id
,
5499 const struct data_string
*iaaddr
,
5500 struct iasubopt
*lease
)
5502 char tmp_addr
[INET6_ADDRSTRLEN
];
5504 log_info("Client %s releases address %s",
5505 print_hex_1(client_id
->len
, client_id
->data
, 60),
5506 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5507 if (lease
!= NULL
) {
5508 release_lease6(lease
->ipv6_pool
, lease
);
5509 lease
->ia
->cltt
= cur_time
;
5510 write_ia(lease
->ia
);
5515 ia_na_nomatch_release(const struct data_string
*client_id
,
5516 const struct data_string
*iaaddr
,
5517 u_int32_t
*ia_na_id
,
5518 struct packet
*packet
,
5523 char tmp_addr
[INET6_ADDRSTRLEN
];
5524 struct option_state
*host_opt_state
;
5527 log_info("Client %s releases address %s, which is not leased to it.",
5528 print_hex_1(client_id
->len
, client_id
->data
, 60),
5529 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5532 * Create state for this IA_NA.
5534 host_opt_state
= NULL
;
5535 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5536 log_error("ia_na_nomatch_release: out of memory "
5537 "allocating option_state.");
5541 if (!set_status_code(STATUS_NoBinding
,
5542 "Release for non-leased address.",
5548 * Insure we have enough space
5550 if (reply_len
< (*reply_ofs
+ 16)) {
5551 log_error("ia_na_nomatch_release: "
5552 "out of space for reply packet.");
5557 * Put our status code into the reply packet.
5559 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5560 reply_len
-(*reply_ofs
)-16,
5561 host_opt_state
, packet
,
5562 required_opts_STATUS_CODE
, NULL
);
5565 * Store the non-encapsulated option data for this
5566 * IA_NA into our reply packet. Defined in RFC 3315,
5570 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5572 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5573 /* IA_NA, copied from the client */
5574 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5575 /* t1 and t2, odd that we need them, but here it is */
5576 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5577 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5580 * Get ready for next IA_NA.
5582 *reply_ofs
+= (len
+ 16);
5585 option_state_dereference(&host_opt_state
, MDL
);
5589 ia_pd_match_release(const struct data_string
*client_id
,
5590 const struct data_string
*iapref
,
5591 struct iasubopt
*prefix
)
5593 char tmp_addr
[INET6_ADDRSTRLEN
];
5595 log_info("Client %s releases prefix %s/%u",
5596 print_hex_1(client_id
->len
, client_id
->data
, 60),
5597 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5598 tmp_addr
, sizeof(tmp_addr
)),
5599 (unsigned) getUChar(iapref
->data
+ 8));
5600 if (prefix
!= NULL
) {
5601 release_lease6(prefix
->ipv6_pool
, prefix
);
5602 prefix
->ia
->cltt
= cur_time
;
5603 write_ia(prefix
->ia
);
5608 ia_pd_nomatch_release(const struct data_string
*client_id
,
5609 const struct data_string
*iapref
,
5610 u_int32_t
*ia_pd_id
,
5611 struct packet
*packet
,
5616 char tmp_addr
[INET6_ADDRSTRLEN
];
5617 struct option_state
*host_opt_state
;
5620 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
5621 print_hex_1(client_id
->len
, client_id
->data
, 60),
5622 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5623 tmp_addr
, sizeof(tmp_addr
)),
5624 (unsigned) getUChar(iapref
->data
+ 8));
5627 * Create state for this IA_PD.
5629 host_opt_state
= NULL
;
5630 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5631 log_error("ia_pd_nomatch_release: out of memory "
5632 "allocating option_state.");
5636 if (!set_status_code(STATUS_NoBinding
,
5637 "Release for non-leased prefix.",
5643 * Insure we have enough space
5645 if (reply_len
< (*reply_ofs
+ 16)) {
5646 log_error("ia_pd_nomatch_release: "
5647 "out of space for reply packet.");
5652 * Put our status code into the reply packet.
5654 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5655 reply_len
-(*reply_ofs
)-16,
5656 host_opt_state
, packet
,
5657 required_opts_STATUS_CODE
, NULL
);
5660 * Store the non-encapsulated option data for this
5661 * IA_PD into our reply packet. Defined in RFC 3315,
5665 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_PD
);
5667 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5668 /* IA_PD, copied from the client */
5669 memcpy(reply_data
+(*reply_ofs
)+4, ia_pd_id
, 4);
5670 /* t1 and t2, odd that we need them, but here it is */
5671 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5672 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5675 * Get ready for next IA_PD.
5677 *reply_ofs
+= (len
+ 16);
5680 option_state_dereference(&host_opt_state
, MDL
);
5684 iterate_over_ia_pd(struct data_string
*reply_ret
,
5685 struct packet
*packet
,
5686 const struct data_string
*client_id
,
5687 const struct data_string
*server_id
,
5688 const char *packet_type
,
5689 void (*ia_pd_match
)(const struct data_string
*,
5690 const struct data_string
*,
5692 void (*ia_pd_nomatch
)(const struct data_string
*,
5693 const struct data_string
*,
5694 u_int32_t
*, struct packet
*, char *,
5697 struct data_string reply_new
;
5699 struct option_state
*opt_state
;
5700 struct host_decl
*packet_host
;
5701 struct option_cache
*ia
;
5702 struct option_cache
*oc
;
5703 /* cli_enc_... variables come from the IA_PD options */
5704 struct data_string cli_enc_opt_data
;
5705 struct option_state
*cli_enc_opt_state
;
5706 struct host_decl
*host
;
5707 struct option_state
*host_opt_state
;
5708 struct data_string iaprefix
;
5709 char reply_data
[65536];
5711 struct iasubopt
*prefix
;
5712 struct ia_xx
*existing_ia_pd
;
5714 struct data_string key
;
5718 * Initialize to empty values, in case we have to exit early.
5720 memset(&reply_new
, 0, sizeof(reply_new
));
5722 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5723 cli_enc_opt_state
= NULL
;
5724 memset(&iaprefix
, 0, sizeof(iaprefix
));
5725 host_opt_state
= NULL
;
5729 * Compute the available length for the reply.
5731 reply_len
= sizeof(reply_data
) - reply_ret
->len
;
5735 * Find the host record that matches from the packet, if any.
5738 if (!find_hosts_by_uid(&packet_host
,
5739 client_id
->data
, client_id
->len
, MDL
)) {
5742 * Note: In general, we don't expect a client to provide
5743 * enough information to match by option for these
5744 * types of messages, but if we don't have a UID
5745 * match we can check anyway.
5747 if (!find_hosts_by_option(&packet_host
,
5748 packet
, packet
->options
, MDL
)) {
5751 if (!find_hosts_by_duid_chaddr(&packet_host
,
5758 * Build our option state for reply.
5761 if (!option_state_allocate(&opt_state
, MDL
)) {
5762 log_error("iterate_over_ia_pd: no memory for option_state.");
5765 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5766 packet
->options
, opt_state
,
5767 &global_scope
, root_group
, NULL
, NULL
);
5770 * Loop through the IA_PD reported by the client, and deal with
5771 * prefixes reported as already in use.
5773 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5774 ia
!= NULL
; ia
= ia
->next
) {
5776 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
5778 packet
, ia
, IA_PD_OFFSET
)) {
5782 iaid
= getULong(cli_enc_opt_data
.data
);
5784 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5787 /* no prefix given for this IA_PD, ignore */
5788 option_state_dereference(&cli_enc_opt_state
, MDL
);
5789 data_string_forget(&cli_enc_opt_data
, MDL
);
5793 for (; oc
!= NULL
; oc
= oc
->next
) {
5794 memset(&iaprefix
, 0, sizeof(iaprefix
));
5795 if (!evaluate_option_cache(&iaprefix
, packet
, NULL
, NULL
,
5796 packet
->options
, NULL
,
5797 &global_scope
, oc
, MDL
)) {
5798 log_error("iterate_over_ia_pd: "
5799 "error evaluating IAPREFIX.");
5804 * Now we need to figure out which host record matches
5805 * this IA_PD and IAPREFIX (encapsulated option contents
5806 * matching a host record by option).
5808 * XXX: We don't currently track IA_PD separately, but
5809 * we will need to do this!
5812 if (!find_hosts_by_option(&host
, packet
,
5813 cli_enc_opt_state
, MDL
)) {
5814 if (packet_host
!= NULL
) {
5820 while (host
!= NULL
) {
5821 if (host
->fixed_prefix
!= NULL
) {
5822 struct iaddrcidrnetlist
*l
;
5823 int plen
= (int) getUChar(iaprefix
.data
+ 8);
5825 for (l
= host
->fixed_prefix
; l
!= NULL
;
5827 if (plen
!= l
->cidrnet
.bits
)
5829 if (memcmp(iaprefix
.data
+ 9,
5830 l
->cidrnet
.lo_addr
.iabuf
,
5834 if ((l
!= NULL
) && (iaprefix
.len
>= 17))
5837 host
= host
->n_ipaddr
;
5840 if ((host
== NULL
) && (iaprefix
.len
>= IAPREFIX_OFFSET
)) {
5842 * Find existing IA_PD.
5844 if (ia_make_key(&key
, iaid
,
5845 (char *)client_id
->data
,
5847 MDL
) != ISC_R_SUCCESS
) {
5848 log_fatal("iterate_over_ia_pd: no memory for "
5852 existing_ia_pd
= NULL
;
5853 if (ia_hash_lookup(&existing_ia_pd
, ia_pd_active
,
5854 (unsigned char *)key
.data
,
5857 * Make sure this prefix is in the IA_PD.
5860 i
< existing_ia_pd
->num_iasubopt
;
5862 struct iasubopt
*tmp
;
5865 plen
= getUChar(iaprefix
.data
+ 8);
5866 tmp
= existing_ia_pd
->iasubopt
[i
];
5867 if ((tmp
->plen
== plen
) &&
5871 iasubopt_reference(&prefix
,
5878 data_string_forget(&key
, MDL
);
5881 if ((host
!= NULL
) || (prefix
!= NULL
)) {
5882 ia_pd_match(client_id
, &iaprefix
, prefix
);
5884 ia_pd_nomatch(client_id
, &iaprefix
,
5885 (u_int32_t
*)cli_enc_opt_data
.data
,
5886 packet
, reply_data
, &reply_ofs
,
5887 reply_len
- reply_ofs
);
5890 if (prefix
!= NULL
) {
5891 iasubopt_dereference(&prefix
, MDL
);
5894 data_string_forget(&iaprefix
, MDL
);
5897 option_state_dereference(&cli_enc_opt_state
, MDL
);
5898 data_string_forget(&cli_enc_opt_data
, MDL
);
5902 * Return our reply to the caller.
5903 * The IA_NA routine has already filled at least the header.
5905 reply_new
.len
= reply_ret
->len
+ reply_ofs
;
5906 if (!buffer_allocate(&reply_new
.buffer
, reply_new
.len
, MDL
)) {
5907 log_fatal("No memory to store reply.");
5909 reply_new
.data
= reply_new
.buffer
->data
;
5910 memcpy(reply_new
.buffer
->data
,
5911 reply_ret
->buffer
->data
, reply_ret
->len
);
5912 memcpy(reply_new
.buffer
->data
+ reply_ret
->len
,
5913 reply_data
, reply_ofs
);
5914 data_string_forget(reply_ret
, MDL
);
5915 data_string_copy(reply_ret
, &reply_new
, MDL
);
5916 data_string_forget(&reply_new
, MDL
);
5919 if (prefix
!= NULL
) {
5920 iasubopt_dereference(&prefix
, MDL
);
5922 if (host_opt_state
!= NULL
) {
5923 option_state_dereference(&host_opt_state
, MDL
);
5925 if (iaprefix
.buffer
!= NULL
) {
5926 data_string_forget(&iaprefix
, MDL
);
5928 if (cli_enc_opt_state
!= NULL
) {
5929 option_state_dereference(&cli_enc_opt_state
, MDL
);
5931 if (cli_enc_opt_data
.buffer
!= NULL
) {
5932 data_string_forget(&cli_enc_opt_data
, MDL
);
5934 if (opt_state
!= NULL
) {
5935 option_state_dereference(&opt_state
, MDL
);
5940 * Release means a client is done with the leases.
5943 /* TODO: reject unicast messages, unless we set unicast option */
5945 dhcpv6_release(struct data_string
*reply
, struct packet
*packet
) {
5946 struct data_string client_id
;
5947 struct data_string server_id
;
5950 * Validate our input.
5952 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5957 * And operate on each IA_NA in this packet.
5959 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
, "Release",
5960 ia_na_match_release
, ia_na_nomatch_release
);
5963 * And operate on each IA_PD in this packet.
5965 iterate_over_ia_pd(reply
, packet
, &client_id
, &server_id
, "Release",
5966 ia_pd_match_release
, ia_pd_nomatch_release
);
5968 data_string_forget(&server_id
, MDL
);
5969 data_string_forget(&client_id
, MDL
);
5973 * Information-Request is used by clients who have obtained an address
5974 * from other means, but want configuration information from the server.
5978 dhcpv6_information_request(struct data_string
*reply
, struct packet
*packet
) {
5979 struct data_string client_id
;
5980 struct data_string server_id
;
5983 * Validate our input.
5985 if (!valid_client_info_req(packet
, &server_id
)) {
5990 * Get our client ID, if there is one.
5992 memset(&client_id
, 0, sizeof(client_id
));
5993 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
) {
5994 data_string_forget(&client_id
, MDL
);
5998 * Use the lease_to_client() function. This will work fine,
5999 * because the valid_client_info_req() insures that we
6000 * don't have any IA that would cause us to allocate
6001 * resources to the client.
6003 lease_to_client(reply
, packet
, &client_id
,
6004 server_id
.data
!= NULL
? &server_id
: NULL
);
6009 if (client_id
.data
!= NULL
) {
6010 data_string_forget(&client_id
, MDL
);
6012 data_string_forget(&server_id
, MDL
);
6016 * The Relay-forw message is sent by relays. It typically contains a
6017 * single option, which encapsulates an entire packet.
6019 * We need to build an encapsulated reply.
6022 /* XXX: this is very, very similar to do_packet6(), and should probably
6023 be combined in a clever way */
6025 dhcpv6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
6026 struct option_cache
*oc
;
6027 struct data_string enc_opt_data
;
6028 struct packet
*enc_packet
;
6029 unsigned char msg_type
;
6030 const struct dhcpv6_packet
*msg
;
6031 const struct dhcpv6_relay_packet
*relay
;
6032 struct data_string enc_reply
;
6033 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6034 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6035 struct data_string a_opt
, packet_ero
;
6036 struct option_state
*opt_state
;
6037 static char reply_data
[65536];
6038 struct dhcpv6_relay_packet
*reply
;
6042 * Initialize variables for early exit.
6045 memset(&a_opt
, 0, sizeof(a_opt
));
6046 memset(&packet_ero
, 0, sizeof(packet_ero
));
6047 memset(&enc_reply
, 0, sizeof(enc_reply
));
6048 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6052 * Get our encapsulated relay message.
6054 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
6056 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
6057 link_addr
, sizeof(link_addr
));
6058 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
6059 peer_addr
, sizeof(peer_addr
));
6060 log_info("Relay-forward from %s with link address=%s and "
6061 "peer address=%s missing Relay Message option.",
6062 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
6066 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
6067 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
6068 log_error("dhcpv6_forw_relay: error evaluating "
6069 "relayed message.");
6073 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
6074 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
6079 * Build a packet structure from this encapsulated packet.
6082 if (!packet_allocate(&enc_packet
, MDL
)) {
6083 log_error("dhcpv6_forw_relay: "
6084 "no memory for encapsulated packet.");
6088 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
6089 log_error("dhcpv6_forw_relay: "
6090 "no memory for encapsulated packet's options.");
6094 enc_packet
->client_port
= packet
->client_port
;
6095 enc_packet
->client_addr
= packet
->client_addr
;
6096 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
6097 enc_packet
->dhcpv6_container_packet
= packet
;
6099 msg_type
= enc_opt_data
.data
[0];
6100 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
6101 (msg_type
== DHCPV6_RELAY_REPL
)) {
6102 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6103 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
6104 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
6106 /* relay-specific data */
6107 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
6108 memcpy(&enc_packet
->dhcpv6_link_address
,
6109 relay
->link_address
, sizeof(relay
->link_address
));
6110 memcpy(&enc_packet
->dhcpv6_peer_address
,
6111 relay
->peer_address
, sizeof(relay
->peer_address
));
6113 if (!parse_option_buffer(enc_packet
->options
,
6115 enc_opt_data
.len
- relaylen
,
6116 &dhcpv6_universe
)) {
6117 /* no logging here, as parse_option_buffer() logs all
6118 cases where it fails */
6122 int msglen
= (int)(offsetof(struct dhcpv6_packet
, options
));
6123 msg
= (struct dhcpv6_packet
*)enc_opt_data
.data
;
6124 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
6126 /* message-specific data */
6127 memcpy(enc_packet
->dhcpv6_transaction_id
,
6128 msg
->transaction_id
,
6129 sizeof(enc_packet
->dhcpv6_transaction_id
));
6131 if (!parse_option_buffer(enc_packet
->options
,
6133 enc_opt_data
.len
- msglen
,
6134 &dhcpv6_universe
)) {
6135 /* no logging here, as parse_option_buffer() logs all
6136 cases where it fails */
6142 * This is recursive. It is possible to exceed maximum packet size.
6143 * XXX: This will cause the packet send to fail.
6145 build_dhcpv6_reply(&enc_reply
, enc_packet
);
6148 * If we got no encapsulated data, then it is discarded, and
6149 * our reply-forw is also discarded.
6151 if (enc_reply
.data
== NULL
) {
6156 * Now we can use the reply_data buffer.
6157 * Packet header stuff all comes from the forward message.
6159 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
6160 reply
->msg_type
= DHCPV6_RELAY_REPL
;
6161 reply
->hop_count
= packet
->dhcpv6_hop_count
;
6162 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
6163 sizeof(reply
->link_address
));
6164 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
6165 sizeof(reply
->peer_address
));
6166 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6169 * Get the reply option state.
6172 if (!option_state_allocate(&opt_state
, MDL
)) {
6173 log_error("dhcpv6_relay_forw: no memory for option state.");
6178 * Append the interface-id if present.
6180 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6183 if (!evaluate_option_cache(&a_opt
, packet
,
6185 packet
->options
, NULL
,
6186 &global_scope
, oc
, MDL
)) {
6187 log_error("dhcpv6_relay_forw: error evaluating "
6191 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6192 (unsigned char *)a_opt
.data
,
6194 D6O_INTERFACE_ID
, 0)) {
6195 log_error("dhcpv6_relay_forw: error saving "
6199 data_string_forget(&a_opt
, MDL
);
6203 * Append our encapsulated stuff for caller.
6205 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6206 (unsigned char *)enc_reply
.data
,
6208 D6O_RELAY_MSG
, 0)) {
6209 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
6214 * Get the ERO if any.
6216 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
6221 if (!evaluate_option_cache(&packet_ero
, packet
,
6223 packet
->options
, NULL
,
6224 &global_scope
, oc
, MDL
) ||
6225 (packet_ero
.len
& 1)) {
6226 log_error("dhcpv6_relay_forw: error evaluating ERO.");
6230 /* Decode and apply the ERO. */
6231 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
6232 req
= getUShort(packet_ero
.data
+ i
);
6233 /* Already in the reply? */
6234 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
6237 /* Get it from the packet if present. */
6238 oc
= lookup_option(&dhcpv6_universe
,
6243 if (!evaluate_option_cache(&a_opt
, packet
,
6245 packet
->options
, NULL
,
6246 &global_scope
, oc
, MDL
)) {
6247 log_error("dhcpv6_relay_forw: error "
6248 "evaluating option %u.", req
);
6251 if (!save_option_buffer(&dhcpv6_universe
,
6254 (unsigned char *)a_opt
.data
,
6258 log_error("dhcpv6_relay_forw: error saving "
6262 data_string_forget(&a_opt
, MDL
);
6266 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
6267 sizeof(reply_data
) - reply_ofs
,
6269 required_opts_agent
, &packet_ero
);
6272 * Return our reply to the caller.
6274 reply_ret
->len
= reply_ofs
;
6275 reply_ret
->buffer
= NULL
;
6276 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
6277 log_fatal("No memory to store reply.");
6279 reply_ret
->data
= reply_ret
->buffer
->data
;
6280 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
6283 if (opt_state
!= NULL
)
6284 option_state_dereference(&opt_state
, MDL
);
6285 if (a_opt
.data
!= NULL
) {
6286 data_string_forget(&a_opt
, MDL
);
6288 if (packet_ero
.data
!= NULL
) {
6289 data_string_forget(&packet_ero
, MDL
);
6291 if (enc_reply
.data
!= NULL
) {
6292 data_string_forget(&enc_reply
, MDL
);
6294 if (enc_opt_data
.data
!= NULL
) {
6295 data_string_forget(&enc_opt_data
, MDL
);
6297 if (enc_packet
!= NULL
) {
6298 packet_dereference(&enc_packet
, MDL
);
6303 dhcpv6_discard(struct packet
*packet
) {
6304 /* INSIST(packet->msg_type > 0); */
6305 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
6307 log_debug("Discarding %s from %s; message type not handled by server",
6308 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
6309 piaddr(packet
->client_addr
));
6313 build_dhcpv6_reply(struct data_string
*reply
, struct packet
*packet
) {
6314 memset(reply
, 0, sizeof(*reply
));
6316 /* I would like to classify the client once here, but
6317 * as I don't want to classify all of the incoming packets
6318 * I need to do it before handling specific types.
6319 * We don't need to classify if we are tossing the packet
6320 * or if it is a relay - the classification step will get
6321 * done when we process the inner client packet.
6324 switch (packet
->dhcpv6_msg_type
) {
6325 case DHCPV6_SOLICIT
:
6326 classify_client(packet
);
6327 dhcpv6_solicit(reply
, packet
);
6329 case DHCPV6_ADVERTISE
:
6330 dhcpv6_discard(packet
);
6332 case DHCPV6_REQUEST
:
6333 classify_client(packet
);
6334 dhcpv6_request(reply
, packet
);
6336 case DHCPV6_CONFIRM
:
6337 classify_client(packet
);
6338 dhcpv6_confirm(reply
, packet
);
6341 classify_client(packet
);
6342 dhcpv6_renew(reply
, packet
);
6345 classify_client(packet
);
6346 dhcpv6_rebind(reply
, packet
);
6349 dhcpv6_discard(packet
);
6351 case DHCPV6_RELEASE
:
6352 classify_client(packet
);
6353 dhcpv6_release(reply
, packet
);
6355 case DHCPV6_DECLINE
:
6356 classify_client(packet
);
6357 dhcpv6_decline(reply
, packet
);
6359 case DHCPV6_RECONFIGURE
:
6360 dhcpv6_discard(packet
);
6362 case DHCPV6_INFORMATION_REQUEST
:
6363 classify_client(packet
);
6364 dhcpv6_information_request(reply
, packet
);
6366 case DHCPV6_RELAY_FORW
:
6367 dhcpv6_relay_forw(reply
, packet
);
6369 case DHCPV6_RELAY_REPL
:
6370 dhcpv6_discard(packet
);
6372 case DHCPV6_LEASEQUERY
:
6373 classify_client(packet
);
6374 dhcpv6_leasequery(reply
, packet
);
6376 case DHCPV6_LEASEQUERY_REPLY
:
6377 dhcpv6_discard(packet
);
6380 /* XXX: would be nice if we had "notice" level,
6381 as syslog, for this */
6382 log_info("Discarding unknown DHCPv6 message type %d "
6383 "from %s", packet
->dhcpv6_msg_type
,
6384 piaddr(packet
->client_addr
));
6389 log_packet_in(const struct packet
*packet
) {
6390 struct data_string s
;
6392 char tmp_addr
[INET6_ADDRSTRLEN
];
6395 memset(&s
, 0, sizeof(s
));
6397 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
6398 data_string_sprintfa(&s
, "%s message from %s port %d",
6399 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
6400 piaddr(packet
->client_addr
),
6401 ntohs(packet
->client_port
));
6403 data_string_sprintfa(&s
,
6404 "Unknown message type %d from %s port %d",
6405 packet
->dhcpv6_msg_type
,
6406 piaddr(packet
->client_addr
),
6407 ntohs(packet
->client_port
));
6409 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
6410 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
6411 addr
= &packet
->dhcpv6_link_address
;
6412 data_string_sprintfa(&s
, ", link address %s",
6413 inet_ntop(AF_INET6
, addr
,
6414 tmp_addr
, sizeof(tmp_addr
)));
6415 addr
= &packet
->dhcpv6_peer_address
;
6416 data_string_sprintfa(&s
, ", peer address %s",
6417 inet_ntop(AF_INET6
, addr
,
6418 tmp_addr
, sizeof(tmp_addr
)));
6421 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
6422 data_string_sprintfa(&s
, ", transaction ID 0x%06X", tid
);
6425 oc = lookup_option(&dhcpv6_universe, packet->options,
6428 memset(&tmp_ds, 0, sizeof(tmp_ds_));
6429 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
6430 packet->options, NULL,
6431 &global_scope, oc, MDL)) {
6432 log_error("Error evaluating Client Identifier");
6434 data_strint_sprintf(&s, ", client ID %s",
6436 data_string_forget(&tmp_ds, MDL);
6442 log_info("%s", s
.data
);
6444 data_string_forget(&s
, MDL
);
6448 dhcpv6(struct packet
*packet
) {
6449 struct data_string reply
;
6450 struct sockaddr_in6 to_addr
;
6454 * Log a message that we received this packet.
6456 log_packet_in(packet
);
6459 * Build our reply packet.
6461 build_dhcpv6_reply(&reply
, packet
);
6463 if (reply
.data
!= NULL
) {
6465 * Send our reply, if we have one.
6467 memset(&to_addr
, 0, sizeof(to_addr
));
6468 to_addr
.sin6_family
= AF_INET6
;
6469 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
6470 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
6471 to_addr
.sin6_port
= local_port
;
6473 to_addr
.sin6_port
= remote_port
;
6476 #if defined (REPLY_TO_SOURCE_PORT)
6478 * This appears to have been included for testing so we would
6479 * not need a root client, but was accidently left in the
6480 * final code. We continue to include it in case
6481 * some users have come to rely upon it, but leave
6482 * it off by default as it's a bad idea.
6484 to_addr
.sin6_port
= packet
->client_port
;
6487 memcpy(&to_addr
.sin6_addr
, packet
->client_addr
.iabuf
,
6488 sizeof(to_addr
.sin6_addr
));
6490 log_info("Sending %s to %s port %d",
6491 dhcpv6_type_names
[reply
.data
[0]],
6492 piaddr(packet
->client_addr
),
6493 ntohs(to_addr
.sin6_port
));
6495 send_ret
= send_packet6(packet
->interface
,
6496 reply
.data
, reply
.len
, &to_addr
);
6497 if (send_ret
!= reply
.len
) {
6498 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
6499 send_ret
, reply
.len
);
6501 data_string_forget(&reply
, MDL
);
6506 seek_shared_host(struct host_decl
**hp
, struct shared_network
*shared
) {
6507 struct host_decl
*nofixed
= NULL
;
6508 struct host_decl
*seek
, *hold
= NULL
;
6511 * Seek forward through fixed addresses for the right link.
6513 * Note: how to do this for fixed prefixes???
6515 host_reference(&hold
, *hp
, MDL
);
6516 host_dereference(hp
, MDL
);
6518 while (seek
!= NULL
) {
6519 if (seek
->fixed_addr
== NULL
)
6521 else if (fixed_matches_shared(seek
, shared
))
6524 seek
= seek
->n_ipaddr
;
6527 if ((seek
== NULL
) && (nofixed
!= NULL
))
6531 host_reference(hp
, seek
, MDL
);
6534 static isc_boolean_t
6535 fixed_matches_shared(struct host_decl
*host
, struct shared_network
*shared
) {
6536 struct subnet
*subnet
;
6537 struct data_string addr
;
6538 isc_boolean_t matched
;
6541 if (host
->fixed_addr
== NULL
)
6544 memset(&addr
, 0, sizeof(addr
));
6545 if (!evaluate_option_cache(&addr
, NULL
, NULL
, NULL
, NULL
, NULL
,
6546 &global_scope
, host
->fixed_addr
, MDL
))
6549 if (addr
.len
< 16) {
6550 data_string_forget(&addr
, MDL
);
6555 memcpy(fixed
.iabuf
, addr
.data
, 16);
6557 matched
= ISC_FALSE
;
6558 for (subnet
= shared
->subnets
; subnet
!= NULL
;
6559 subnet
= subnet
->next_sibling
) {
6560 if (addr_eq(subnet_number(fixed
, subnet
->netmask
),
6567 data_string_forget(&addr
, MDL
);
6572 * find_host_by_duid_chaddr() synthesizes a DHCPv4-like 'hardware'
6573 * parameter from a DHCPv6 supplied DUID (client-identifier option),
6574 * and may seek to use client or relay supplied hardware addresses.
6577 find_hosts_by_duid_chaddr(struct host_decl
**host
,
6578 const struct data_string
*client_id
) {
6579 static int once_htype
;
6581 const unsigned char *chaddr
;
6584 * The DUID-LL and DUID-LLT must have a 2-byte DUID type and 2-byte
6587 if (client_id
->len
< 4)
6591 * The third and fourth octets of the DUID-LL and DUID-LLT
6592 * is the hardware type, but in 16 bits.
6594 htype
= getUShort(client_id
->data
+ 2);
6598 /* The first two octets of the DUID identify the type. */
6599 switch(getUShort(client_id
->data
)) {
6601 if (client_id
->len
> 8) {
6602 hlen
= client_id
->len
- 8;
6603 chaddr
= client_id
->data
+ 8;
6609 * Note that client_id->len must be greater than or equal
6610 * to four to get to this point in the function.
6612 hlen
= client_id
->len
- 4;
6613 chaddr
= client_id
->data
+ 4;
6620 if ((hlen
== 0) || (hlen
> HARDWARE_ADDR_LEN
))
6624 * XXX: DHCPv6 gives a 16-bit field for the htype. DHCPv4 gives an
6625 * 8-bit field. To change the semantics of the generic 'hardware'
6626 * structure, we would have to adjust many DHCPv4 sources (from
6627 * interface to DHCPv4 lease code), and we would have to update the
6628 * 'hardware' config directive (probably being reverse compatible and
6629 * providing a new upgrade/replacement primitive). This is a little
6630 * too much to change for now. Hopefully we will revisit this before
6631 * hardware types exceeding 8 bits are assigned.
6633 if ((htype
& 0xFF00) && !once_htype
) {
6635 log_error("Attention: At least one client advertises a "
6636 "hardware type of %d, which exceeds the software "
6637 "limitation of 255.", htype
);
6640 return find_hosts_by_haddr(host
, htype
, chaddr
, hlen
, MDL
);