2 * Copyright (C) 2006-2017 by Internet Systems Consortium, Inc. ("ISC")
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
17 /*! \file server/dhcpv6.c */
24 static void forw_dhcpv4_query(struct packet
*packet
);
25 static void send_dhcpv4_response(struct data_string
*raw
);
27 static void recv_dhcpv4_query(struct data_string
*raw
);
28 static void dhcp4o6_dhcpv4_query(struct data_string
*reply_ret
,
29 struct packet
*packet
);
33 * We use print_hex_1() to output DUID values. We could actually output
34 * the DUID with more information... MAC address if using type 1 or 3,
35 * and so on. However, RFC 3315 contains Grave Warnings against actually
36 * attempting to understand a DUID.
40 * TODO: gettext() or other method of localization for the messages
41 * for status codes (and probably for log formats eventually)
42 * TODO: refactoring (simplify, simplify, simplify)
43 * TODO: support multiple shared_networks on each interface (this
44 * will allow the server to issue multiple IPv6 addresses to
49 * DHCPv6 Reply workflow assist. A Reply packet is built by various
50 * different functions; this gives us one location where we keep state
54 /* root level persistent state */
55 struct shared_network
*shared
;
56 struct host_decl
*host
;
57 struct subnet
*subnet
; /* Used to match fixed-addrs to subnet scopes. */
58 struct option_state
*opt_state
;
59 struct packet
*packet
;
60 struct data_string client_id
;
62 /* IA level persistent state */
65 unsigned client_resources
;
66 isc_boolean_t resources_included
;
67 isc_boolean_t static_lease
;
68 unsigned static_prefixes
;
71 struct option_state
*reply_ia
;
72 struct data_string fixed
;
73 struct iaddrcidrnet fixed_pref
; /* static prefix for logging */
75 /* IAADDR/PREFIX level persistent state */
76 struct iasubopt
*lease
;
79 * "t1", "t2", preferred, and valid lifetimes records for calculating
80 * t1 and t2 (min/max).
82 u_int32_t renew
, rebind
, min_prefer
, min_valid
;
84 /* Client-requested valid and preferred lifetimes. */
85 u_int32_t client_valid
, client_prefer
;
87 /* Chosen values to transmit for valid and preferred lifetimes. */
88 u_int32_t send_valid
, send_prefer
;
90 /* Preferred prefix length (-1 is any). */
93 /* Index into the data field that has been consumed. */
96 /* Space for the on commit statements for a fixed host */
97 struct on_star on_star
;
100 unsigned char data
[65536];
101 struct dhcpv6_packet reply
;
106 * Prototypes local to this file.
108 static int get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
109 struct data_string
*enc_opt_data
,
110 struct packet
*packet
,
111 struct option_cache
*oc
,
113 static void build_dhcpv6_reply(struct data_string
*, struct packet
*);
114 static isc_result_t
shared_network_from_packet6(struct shared_network
**shared
,
115 struct packet
*packet
);
116 static void seek_shared_host(struct host_decl
**hp
,
117 struct shared_network
*shared
);
118 static isc_boolean_t
fixed_matches_shared(struct host_decl
*host
,
119 struct shared_network
*shared
);
120 static isc_result_t
reply_process_ia_na(struct reply_state
*reply
,
121 struct option_cache
*ia
);
122 static isc_result_t
reply_process_ia_ta(struct reply_state
*reply
,
123 struct option_cache
*ia
);
124 static isc_result_t
reply_process_addr(struct reply_state
*reply
,
125 struct option_cache
*addr
);
126 static isc_boolean_t
address_is_owned(struct reply_state
*reply
,
128 static isc_boolean_t
temporary_is_available(struct reply_state
*reply
,
130 static isc_result_t
find_client_temporaries(struct reply_state
*reply
);
131 static isc_result_t
reply_process_try_addr(struct reply_state
*reply
,
133 static isc_result_t
find_client_address(struct reply_state
*reply
);
134 static isc_result_t
reply_process_is_addressed(struct reply_state
*reply
,
135 struct binding_scope
**scope
,
136 struct group
*group
);
137 static isc_result_t
reply_process_send_addr(struct reply_state
*reply
,
139 static struct iasubopt
*lease_compare(struct iasubopt
*alpha
,
140 struct iasubopt
*beta
);
141 static isc_result_t
reply_process_ia_pd(struct reply_state
*reply
,
142 struct option_cache
*ia_pd
);
143 static struct group
*find_group_by_prefix(struct reply_state
*reply
);
144 static isc_result_t
reply_process_prefix(struct reply_state
*reply
,
145 struct option_cache
*pref
);
146 static isc_boolean_t
prefix_is_owned(struct reply_state
*reply
,
147 struct iaddrcidrnet
*pref
);
148 static isc_result_t
find_client_prefix(struct reply_state
*reply
);
149 static isc_result_t
reply_process_try_prefix(struct reply_state
*reply
,
150 struct iaddrcidrnet
*pref
);
151 static isc_result_t
reply_process_is_prefixed(struct reply_state
*reply
,
152 struct binding_scope
**scope
,
153 struct group
*group
);
154 static isc_result_t
reply_process_send_prefix(struct reply_state
*reply
,
155 struct iaddrcidrnet
*pref
);
156 static struct iasubopt
*prefix_compare(struct reply_state
*reply
,
157 struct iasubopt
*alpha
,
158 struct iasubopt
*beta
);
159 static void schedule_lease_timeout_reply(struct reply_state
*reply
);
161 static int eval_prefix_mode(int thislen
, int preflen
, int prefix_mode
);
162 static isc_result_t
pick_v6_prefix_helper(struct reply_state
*reply
,
165 static void unicast_reject(struct data_string
*reply_ret
, struct packet
*packet
,
166 const struct data_string
*client_id
,
167 const struct data_string
*server_id
);
169 static isc_boolean_t
is_unicast_option_defined(struct packet
*packet
);
170 static isc_result_t
shared_network_from_requested_addr (struct shared_network
172 struct packet
* packet
);
173 static isc_result_t
get_first_ia_addr_val (struct packet
* packet
, int addr_type
,
174 struct iaddr
* iaddr
);
177 set_reply_tee_times(struct reply_state
* reply
, unsigned ia_cursor
);
179 static const char *iasubopt_plen_str(struct iasubopt
*lease
);
180 static int release_on_roam(struct reply_state
*reply
);
184 * \brief Omapi I/O handler
186 * The inter-process communication receive handler.
187 * Get the message, put it into the raw data_string
188 * and call \ref send_dhcpv4_response() (DHCPv6 side) or
189 * \ref recv_dhcpv4_query() (DHCPv4 side)
191 * \param h the OMAPI object
192 * \return a result for I/O success or error (used by the I/O subsystem)
194 isc_result_t
dhcpv4o6_handler(omapi_object_t
*h
) {
196 struct data_string raw
;
199 if (h
->type
!= dhcp4o6_type
)
200 return DHCP_R_INVALIDARG
;
202 cc
= recv(dhcp4o6_fd
, buf
, sizeof(buf
), 0);
204 if (cc
< DHCP_FIXED_NON_UDP
+ 32)
205 return ISC_R_UNEXPECTED
;
206 memset(&raw
, 0, sizeof(raw
));
207 if (!buffer_allocate(&raw
.buffer
, cc
, MDL
)) {
208 log_error("dhcpv4o6_handler: no memory buffer.");
209 return ISC_R_NOMEMORY
;
211 raw
.data
= raw
.buffer
->data
;
213 memcpy(raw
.buffer
->data
, buf
, cc
);
215 if (local_family
== AF_INET6
) {
216 send_dhcpv4_response(&raw
);
218 recv_dhcpv4_query(&raw
);
221 data_string_forget(&raw
, MDL
);
223 return ISC_R_SUCCESS
;
227 * \brief Send the DHCPv4-response back to the DHCPv6 side
228 * (DHCPv6 server function)
230 * Format: interface:16 + address:16 + DHCPv6 DHCPv4-response message
232 * \param raw the IPC message content
234 static void send_dhcpv4_response(struct data_string
*raw
) {
235 struct interface_info
*ip
;
237 struct sockaddr_in6 to_addr
;
238 char pbuf
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
241 memset(name
, 0, sizeof(name
));
242 memcpy(name
, raw
->data
, 16);
243 for (ip
= interfaces
; ip
!= NULL
; ip
= ip
->next
) {
244 if (!strcmp(name
, ip
->name
))
248 log_error("send_dhcpv4_response: can't find interface %s.",
253 memset(&to_addr
, 0, sizeof(to_addr
));
254 to_addr
.sin6_family
= AF_INET6
;
255 memcpy(&to_addr
.sin6_addr
, raw
->data
+ 16, 16);
256 if ((raw
->data
[32] == DHCPV6_RELAY_FORW
) ||
257 (raw
->data
[32] == DHCPV6_RELAY_REPL
)) {
258 to_addr
.sin6_port
= local_port
;
260 to_addr
.sin6_port
= remote_port
;
263 log_info("send_dhcpv4_response(): sending %s on %s to %s port %d",
264 dhcpv6_type_names
[raw
->data
[32]],
266 inet_ntop(AF_INET6
, raw
->data
+ 16, pbuf
, sizeof(pbuf
)),
267 ntohs(to_addr
.sin6_port
));
269 send_ret
= send_packet6(ip
, raw
->data
+ 32, raw
->len
- 32, &to_addr
);
271 log_error("send_dhcpv4_response: send_packet6(): %m");
272 } else if (send_ret
!= raw
->len
- 32) {
273 log_error("send_dhcpv4_response: send_packet6() "
274 "sent %d of %d bytes",
275 send_ret
, raw
->len
- 32);
281 * Schedule lease timeouts for all of the iasubopts in the reply.
282 * This is currently used to schedule timeouts for soft leases.
286 schedule_lease_timeout_reply(struct reply_state
*reply
) {
287 struct iasubopt
*tmp
;
290 /* sanity check the reply */
291 if ((reply
== NULL
) || (reply
->ia
== NULL
) || (reply
->ia
->iasubopt
== NULL
))
294 /* walk through the list, scheduling as we go */
295 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
296 tmp
= reply
->ia
->iasubopt
[i
];
297 schedule_lease_timeout(tmp
->ipv6_pool
);
302 * This function returns the time since DUID time start for the
303 * given time_t value.
306 duid_time(time_t when
) {
308 * This time is modulo 2^32.
310 while ((when
- DUID_TIME_EPOCH
) > 4294967295u) {
311 /* use 2^31 to avoid spurious compiler warnings */
316 return when
- DUID_TIME_EPOCH
;
323 * This must remain the same for the lifetime of this server, because
324 * clients return the server DUID that we sent them in Request packets.
326 * We pick the server DUID like this:
328 * 1. Check dhcpd.conf - any value the administrator has configured
329 * overrides any possible values.
330 * 2. Check the leases.txt - we want to use the previous value if
332 * 3. Check if dhcpd.conf specifies a type of server DUID to use,
333 * and generate that type.
334 * 4. Generate a type 1 (time + hardware address) DUID.
336 static struct data_string server_duid
;
339 * Check if the server_duid has been set.
342 server_duid_isset(void) {
343 return (server_duid
.data
!= NULL
);
347 * Return the server_duid.
350 copy_server_duid(struct data_string
*ds
, const char *file
, int line
) {
351 data_string_copy(ds
, &server_duid
, file
, line
);
355 * Set the server DUID to a specified value. This is used when
356 * the server DUID is stored in persistent memory (basically the
360 set_server_duid(struct data_string
*new_duid
) {
361 /* INSIST(new_duid != NULL); */
362 /* INSIST(new_duid->data != NULL); */
364 if (server_duid_isset()) {
365 data_string_forget(&server_duid
, MDL
);
367 data_string_copy(&server_duid
, new_duid
, MDL
);
372 * Set the server DUID based on the D6O_SERVERID option. This handles
373 * the case where the administrator explicitly put it in the dhcpd.conf
377 set_server_duid_from_option(void) {
378 struct option_state
*opt_state
;
379 struct option_cache
*oc
;
380 struct data_string option_duid
;
381 isc_result_t ret_val
;
384 if (!option_state_allocate(&opt_state
, MDL
)) {
385 log_fatal("No memory for server DUID.");
388 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
,
389 opt_state
, &global_scope
, root_group
,
392 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
394 ret_val
= ISC_R_NOTFOUND
;
396 memset(&option_duid
, 0, sizeof(option_duid
));
397 if (!evaluate_option_cache(&option_duid
, NULL
, NULL
, NULL
,
398 opt_state
, NULL
, &global_scope
,
400 ret_val
= ISC_R_UNEXPECTED
;
402 set_server_duid(&option_duid
);
403 data_string_forget(&option_duid
, MDL
);
404 ret_val
= ISC_R_SUCCESS
;
408 option_state_dereference(&opt_state
, MDL
);
414 * DUID layout, as defined in RFC 3315, section 9.
416 * We support type 1 (hardware address plus time) and type 3 (hardware
419 * We can support type 2 for specific vendors in the future, if they
420 * publish the specification. And of course there may be additional
423 static int server_duid_type
= DUID_LLT
;
429 set_server_duid_type(int type
) {
430 server_duid_type
= type
;
434 * Generate a new server DUID. This is done if there was no DUID in
435 * the leases.txt or in the dhcpd.conf file.
438 generate_new_server_duid(void) {
439 struct interface_info
*p
;
441 struct data_string generated_duid
;
444 * Verify we have a type that we support.
446 if ((server_duid_type
!= DUID_LL
) && (server_duid_type
!= DUID_LLT
)) {
447 log_error("Invalid DUID type %d specified, "
448 "only LL and LLT types supported", server_duid_type
);
449 return DHCP_R_INVALIDARG
;
453 * Find an interface with a hardware address.
456 for (p
= interfaces
; p
!= NULL
; p
= p
->next
) {
457 if (p
->hw_address
.hlen
> 0) {
462 return ISC_R_UNEXPECTED
;
468 memset(&generated_duid
, 0, sizeof(generated_duid
));
469 if (server_duid_type
== DUID_LLT
) {
470 time_val
= duid_time(time(NULL
));
471 generated_duid
.len
= 8 + p
->hw_address
.hlen
- 1;
472 if (!buffer_allocate(&generated_duid
.buffer
,
473 generated_duid
.len
, MDL
)) {
474 log_fatal("No memory for server DUID.");
476 generated_duid
.data
= generated_duid
.buffer
->data
;
477 putUShort(generated_duid
.buffer
->data
, DUID_LLT
);
478 putUShort(generated_duid
.buffer
->data
+ 2,
479 p
->hw_address
.hbuf
[0]);
480 putULong(generated_duid
.buffer
->data
+ 4, time_val
);
481 memcpy(generated_duid
.buffer
->data
+ 8,
482 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
483 } else if (server_duid_type
== DUID_LL
) {
484 generated_duid
.len
= 4 + p
->hw_address
.hlen
- 1;
485 if (!buffer_allocate(&generated_duid
.buffer
,
486 generated_duid
.len
, MDL
)) {
487 log_fatal("No memory for server DUID.");
489 generated_duid
.data
= generated_duid
.buffer
->data
;
490 putUShort(generated_duid
.buffer
->data
, DUID_LL
);
491 putUShort(generated_duid
.buffer
->data
+ 2,
492 p
->hw_address
.hbuf
[0]);
493 memcpy(generated_duid
.buffer
->data
+ 4,
494 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
496 log_fatal("Unsupported server DUID type %d.", server_duid_type
);
499 set_server_duid(&generated_duid
);
500 data_string_forget(&generated_duid
, MDL
);
502 return ISC_R_SUCCESS
;
506 * Get the client identifier from the packet.
509 get_client_id(struct packet
*packet
, struct data_string
*client_id
) {
510 struct option_cache
*oc
;
513 * Verify our client_id structure is empty.
515 if ((client_id
->data
!= NULL
) || (client_id
->len
!= 0)) {
516 return DHCP_R_INVALIDARG
;
519 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_CLIENTID
);
521 return ISC_R_NOTFOUND
;
524 if (!evaluate_option_cache(client_id
, packet
, NULL
, NULL
,
525 packet
->options
, NULL
,
526 &global_scope
, oc
, MDL
)) {
527 return ISC_R_FAILURE
;
530 return ISC_R_SUCCESS
;
534 * Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
536 * Servers MUST discard any Solicit messages that do not include a
537 * Client Identifier option or that do include a Server Identifier
541 valid_client_msg(struct packet
*packet
, struct data_string
*client_id
) {
543 struct option_cache
*oc
;
544 struct data_string data
;
547 memset(client_id
, 0, sizeof(*client_id
));
548 memset(&data
, 0, sizeof(data
));
550 switch (get_client_id(packet
, client_id
)) {
554 log_debug("Discarding %s from %s; "
555 "client identifier missing",
556 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
557 piaddr(packet
->client_addr
));
560 log_error("Error processing %s from %s; "
561 "unable to evaluate Client Identifier",
562 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
563 piaddr(packet
->client_addr
));
568 * Required by RFC 3315, section 15.
570 if (packet
->unicast
) {
571 log_debug("Discarding %s from %s; packet sent unicast "
573 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
574 piaddr(packet
->client_addr
),
575 print_hex_1(client_id
->len
, client_id
->data
, 60));
580 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
582 if (evaluate_option_cache(&data
, packet
, NULL
, NULL
,
583 packet
->options
, NULL
,
584 &global_scope
, oc
, MDL
)) {
585 log_debug("Discarding %s from %s; "
586 "server identifier found "
587 "(CLIENTID %s, SERVERID %s)",
588 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
589 piaddr(packet
->client_addr
),
590 print_hex_1(client_id
->len
,
591 client_id
->data
, 60),
592 print_hex_2(data
.len
,
595 log_debug("Discarding %s from %s; "
596 "server identifier found "
598 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
599 print_hex_1(client_id
->len
,
600 client_id
->data
, 60),
601 piaddr(packet
->client_addr
));
611 data_string_forget(&data
, MDL
);
614 if (client_id
->len
> 0) {
615 data_string_forget(client_id
, MDL
);
622 * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
623 * 15.9 (slightly different wording, but same meaning):
625 * Servers MUST discard any received Request message that meet any of
626 * the following conditions:
628 * - the message does not include a Server Identifier option.
629 * - the contents of the Server Identifier option do not match the
631 * - the message does not include a Client Identifier option.
634 valid_client_resp(struct packet
*packet
,
635 struct data_string
*client_id
,
636 struct data_string
*server_id
)
639 struct option_cache
*oc
;
641 /* INSIST((duid.data != NULL) && (duid.len > 0)); */
644 memset(client_id
, 0, sizeof(*client_id
));
645 memset(server_id
, 0, sizeof(*server_id
));
647 switch (get_client_id(packet
, client_id
)) {
651 log_debug("Discarding %s from %s; "
652 "client identifier missing",
653 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
654 piaddr(packet
->client_addr
));
657 log_error("Error processing %s from %s; "
658 "unable to evaluate Client Identifier",
659 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
660 piaddr(packet
->client_addr
));
664 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
666 log_debug("Discarding %s from %s: "
667 "server identifier missing (CLIENTID %s)",
668 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
669 piaddr(packet
->client_addr
),
670 print_hex_1(client_id
->len
, client_id
->data
, 60));
673 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
674 packet
->options
, NULL
,
675 &global_scope
, oc
, MDL
)) {
676 log_error("Error processing %s from %s; "
677 "unable to evaluate Server Identifier (CLIENTID %s)",
678 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
679 piaddr(packet
->client_addr
),
680 print_hex_1(client_id
->len
, client_id
->data
, 60));
683 if ((server_duid
.len
!= server_id
->len
) ||
684 (memcmp(server_duid
.data
, server_id
->data
, server_duid
.len
) != 0)) {
685 log_debug("Discarding %s from %s; "
686 "not our server identifier "
687 "(CLIENTID %s, SERVERID %s, server DUID %s)",
688 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
689 piaddr(packet
->client_addr
),
690 print_hex_1(client_id
->len
, client_id
->data
, 60),
691 print_hex_2(server_id
->len
, server_id
->data
, 60),
692 print_hex_3(server_duid
.len
, server_duid
.data
, 60));
701 if (server_id
->len
> 0) {
702 data_string_forget(server_id
, MDL
);
704 if (client_id
->len
> 0) {
705 data_string_forget(client_id
, MDL
);
712 * Information request validation, defined in RFC 3315, section 15.12:
714 * Servers MUST discard any received Information-request message that
715 * meets any of the following conditions:
717 * - The message includes a Server Identifier option and the DUID in
718 * the option does not match the server's DUID.
720 * - The message includes an IA option.
723 valid_client_info_req(struct packet
*packet
, struct data_string
*server_id
) {
725 struct option_cache
*oc
;
726 struct data_string client_id
;
727 char client_id_str
[80]; /* print_hex_1() uses maximum 60 characters,
728 plus a few more for extra information */
731 memset(server_id
, 0, sizeof(*server_id
));
732 memset(&client_id
, 0, sizeof(client_id
));
735 * Make a string that we can print out to give more
736 * information about the client if we need to.
738 * By RFC 3315, Section 18.1.5 clients SHOULD have a
739 * client-id on an Information-request packet, but it
740 * is not strictly necessary.
742 if (get_client_id(packet
, &client_id
) == ISC_R_SUCCESS
) {
743 snprintf(client_id_str
, sizeof(client_id_str
), " (CLIENTID %s)",
744 print_hex_1(client_id
.len
, client_id
.data
, 60));
745 data_string_forget(&client_id
, MDL
);
747 client_id_str
[0] = '\0';
751 * Required by RFC 3315, section 15.
753 if (packet
->unicast
) {
754 log_debug("Discarding %s from %s; packet sent unicast%s",
755 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
756 piaddr(packet
->client_addr
), client_id_str
);
760 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
762 log_debug("Discarding %s from %s; "
763 "IA_NA option present%s",
764 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
765 piaddr(packet
->client_addr
), client_id_str
);
768 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
770 log_debug("Discarding %s from %s; "
771 "IA_TA option present%s",
772 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
773 piaddr(packet
->client_addr
), client_id_str
);
776 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
778 log_debug("Discarding %s from %s; "
779 "IA_PD option present%s",
780 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
781 piaddr(packet
->client_addr
), client_id_str
);
785 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
787 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
788 packet
->options
, NULL
,
789 &global_scope
, oc
, MDL
)) {
790 log_error("Error processing %s from %s; "
791 "unable to evaluate Server Identifier%s",
792 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
793 piaddr(packet
->client_addr
), client_id_str
);
796 if ((server_duid
.len
!= server_id
->len
) ||
797 (memcmp(server_duid
.data
, server_id
->data
,
798 server_duid
.len
) != 0)) {
799 log_debug("Discarding %s from %s; "
800 "not our server identifier "
801 "(SERVERID %s, server DUID %s)%s",
802 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
803 piaddr(packet
->client_addr
),
804 print_hex_1(server_id
->len
,
805 server_id
->data
, 60),
806 print_hex_2(server_duid
.len
,
807 server_duid
.data
, 60),
818 if (server_id
->len
> 0) {
819 data_string_forget(server_id
, MDL
);
826 * Options that we want to send, in addition to what was requested
829 static const int required_opts
[] = {
836 static const int required_opts_solicit
[] = {
848 static const int required_opts_agent
[] = {
853 static const int required_opts_IA
[] = {
858 static const int required_opts_IA_PD
[] = {
863 static const int required_opts_STATUS_CODE
[] = {
868 static const int required_opts_4o6
[] = {
874 static const int unicast_reject_opts
[] = {
883 * Extracts from packet contents an IA_* option, storing the IA structure
884 * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
885 * in enc_opt_state for later lookup and evaluation. The 'offset' indicates
886 * where in the IA_* the DHCPv6 options commence.
889 get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
890 struct data_string
*enc_opt_data
,
891 struct packet
*packet
,
892 struct option_cache
*oc
,
896 * Get the raw data for the encapsulated options.
898 memset(enc_opt_data
, 0, sizeof(*enc_opt_data
));
899 if (!evaluate_option_cache(enc_opt_data
, packet
,
900 NULL
, NULL
, packet
->options
, NULL
,
901 &global_scope
, oc
, MDL
)) {
902 log_error("get_encapsulated_IA_state: "
903 "error evaluating raw option.");
906 if (enc_opt_data
->len
< offset
) {
907 log_error("get_encapsulated_IA_state: raw option too small.");
908 data_string_forget(enc_opt_data
, MDL
);
913 * Now create the option state structure, and pass it to the
914 * function that parses options.
916 *enc_opt_state
= NULL
;
917 if (!option_state_allocate(enc_opt_state
, MDL
)) {
918 log_error("get_encapsulated_IA_state: no memory for options.");
919 data_string_forget(enc_opt_data
, MDL
);
922 if (!parse_option_buffer(*enc_opt_state
,
923 enc_opt_data
->data
+ offset
,
924 enc_opt_data
->len
- offset
,
926 log_error("get_encapsulated_IA_state: error parsing options.");
927 option_state_dereference(enc_opt_state
, MDL
);
928 data_string_forget(enc_opt_data
, MDL
);
936 set_status_code(u_int16_t status_code
, const char *status_message
,
937 struct option_state
*opt_state
)
939 struct data_string d
;
942 memset(&d
, 0, sizeof(d
));
943 d
.len
= sizeof(status_code
) + strlen(status_message
);
944 if (!buffer_allocate(&d
.buffer
, d
.len
, MDL
)) {
945 log_fatal("set_status_code: no memory for status code.");
947 d
.data
= d
.buffer
->data
;
948 putUShort(d
.buffer
->data
, status_code
);
949 memcpy(d
.buffer
->data
+ sizeof(status_code
),
950 status_message
, d
.len
- sizeof(status_code
));
951 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
952 d
.buffer
, (unsigned char *)d
.data
, d
.len
,
953 D6O_STATUS_CODE
, 0)) {
954 log_error("set_status_code: error saving status code.");
959 data_string_forget(&d
, MDL
);
963 void check_pool6_threshold(struct reply_state
*reply
,
964 struct iasubopt
*lease
)
966 struct ipv6_pond
*pond
;
967 isc_uint64_t used
, count
, high_threshold
;
968 int poolhigh
= 0, poollow
= 0;
969 char *shared_name
= "no name";
970 char tmp_addr
[INET6_ADDRSTRLEN
];
972 if ((lease
->ipv6_pool
== NULL
) || (lease
->ipv6_pool
->ipv6_pond
== NULL
))
974 pond
= lease
->ipv6_pool
->ipv6_pond
;
976 /* If the address range is too large to track, just skip all this. */
977 if (pond
->jumbo_range
== 1) {
981 count
= pond
->num_total
;
982 used
= pond
->num_active
;
984 /* get network name for logging */
985 if ((pond
->shared_network
!= NULL
) &&
986 (pond
->shared_network
->name
!= NULL
)) {
987 shared_name
= pond
->shared_network
->name
;
990 /* The logged flag indicates if we have already crossed the high
991 * threshold and emitted a log message. If it is set we check to
992 * see if we have re-crossed the low threshold and need to reset
993 * things. When we cross the high threshold we determine what
994 * the low threshold is and save it into the low_threshold value.
995 * When we cross that threshold we reset the logged flag and
996 * the low_threshold to 0 which allows the high threshold message
997 * to be emitted once again.
998 * if we haven't recrossed the boundry we don't need to do anything.
1000 if (pond
->logged
!=0) {
1001 if (used
<= pond
->low_threshold
) {
1002 pond
->low_threshold
= 0;
1004 log_error("Pool threshold reset - shared subnet: %s; "
1005 "address: %s; low threshold %llu/%llu.",
1007 inet_ntop(AF_INET6
, &lease
->addr
,
1008 tmp_addr
, sizeof(tmp_addr
)),
1014 /* find the high threshold */
1015 if (get_option_int(&poolhigh
, &server_universe
, reply
->packet
, NULL
,
1016 NULL
, reply
->packet
->options
, reply
->opt_state
,
1017 reply
->opt_state
, &lease
->scope
,
1018 SV_LOG_THRESHOLD_HIGH
, MDL
) == 0) {
1019 /* no threshold bail out */
1023 /* We do have a threshold for this pool, see if its valid */
1024 if ((poolhigh
<= 0) || (poolhigh
> 100)) {
1029 /* we have a valid value, have we exceeded it */
1030 high_threshold
= FIND_POND6_PERCENT(count
, poolhigh
);
1031 if (used
< high_threshold
) {
1032 /* nope, no more to do */
1036 /* we've exceeded it, output a message */
1037 log_error("Pool threshold exceeded - shared subnet: %s; "
1038 "address: %s; high threshold %d%% %llu/%llu.",
1040 inet_ntop(AF_INET6
, &lease
->addr
, tmp_addr
, sizeof(tmp_addr
)),
1041 poolhigh
, used
, count
);
1043 /* handle the low threshold now, if we don't
1044 * have one we default to 0. */
1045 if ((get_option_int(&poollow
, &server_universe
, reply
->packet
, NULL
,
1046 NULL
, reply
->packet
->options
, reply
->opt_state
,
1047 reply
->opt_state
, &lease
->scope
,
1048 SV_LOG_THRESHOLD_LOW
, MDL
) == 0) ||
1054 * If the low theshold is higher than the high threshold we continue to log
1055 * If it isn't then we set the flag saying we already logged and determine
1056 * what the reset threshold is.
1058 if (poollow
< poolhigh
) {
1060 pond
->low_threshold
= FIND_POND6_PERCENT(count
, poollow
);
1065 * We have a set of operations we do to set up the reply packet, which
1066 * is the same for many message types.
1069 start_reply(struct packet
*packet
,
1070 const struct data_string
*client_id
,
1071 const struct data_string
*server_id
,
1072 struct option_state
**opt_state
,
1073 struct dhcpv6_packet
*reply
)
1075 struct option_cache
*oc
;
1076 const unsigned char *server_id_data
;
1080 * Build our option state for reply.
1083 if (!option_state_allocate(opt_state
, MDL
)) {
1084 log_error("start_reply: no memory for option_state.");
1087 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1088 packet
->options
, *opt_state
,
1089 &global_scope
, root_group
, NULL
, NULL
);
1092 * A small bit of special handling for Solicit messages.
1094 * We could move the logic into a flag, but for now just check
1097 if (packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
1098 reply
->msg_type
= DHCPV6_ADVERTISE
;
1102 * - this message type supports rapid commit (Solicit), and
1103 * - the server is configured to supply a rapid commit, and
1104 * - the client requests a rapid commit,
1105 * Then we add a rapid commit option, and send Reply (instead
1108 oc
= lookup_option(&dhcpv6_universe
,
1109 *opt_state
, D6O_RAPID_COMMIT
);
1111 oc
= lookup_option(&dhcpv6_universe
,
1112 packet
->options
, D6O_RAPID_COMMIT
);
1114 /* Rapid-commit in action. */
1115 reply
->msg_type
= DHCPV6_REPLY
;
1117 /* Don't want a rapid-commit in advertise. */
1118 delete_option(&dhcpv6_universe
,
1119 *opt_state
, D6O_RAPID_COMMIT
);
1123 reply
->msg_type
= DHCPV6_REPLY
;
1124 /* Delete the rapid-commit from the sent options. */
1125 oc
= lookup_option(&dhcpv6_universe
,
1126 *opt_state
, D6O_RAPID_COMMIT
);
1128 delete_option(&dhcpv6_universe
,
1129 *opt_state
, D6O_RAPID_COMMIT
);
1134 * Use the client's transaction identifier for the reply.
1136 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
1137 sizeof(reply
->transaction_id
));
1140 * RFC 3315, section 18.2 says we need server identifier and
1141 * client identifier.
1143 * If the server ID is defined via the configuration file, then
1144 * it will already be present in the option state at this point,
1145 * so we don't need to set it.
1147 * If we have a server ID passed in from the caller,
1148 * use that, otherwise use the global DUID.
1150 oc
= lookup_option(&dhcpv6_universe
, *opt_state
, D6O_SERVERID
);
1152 if (server_id
== NULL
) {
1153 server_id_data
= server_duid
.data
;
1154 server_id_len
= server_duid
.len
;
1156 server_id_data
= server_id
->data
;
1157 server_id_len
= server_id
->len
;
1159 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1160 NULL
, (unsigned char *)server_id_data
,
1161 server_id_len
, D6O_SERVERID
, 0)) {
1162 log_error("start_reply: "
1163 "error saving server identifier.");
1168 if (client_id
->buffer
!= NULL
) {
1169 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1171 (unsigned char *)client_id
->data
,
1174 log_error("start_reply: error saving "
1175 "client identifier.");
1181 * If the client accepts reconfiguration, let it know that we
1184 * Note: we don't actually do this yet, but DOCSIS requires we
1187 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
1190 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1191 NULL
, (unsigned char *)"", 0,
1192 D6O_RECONF_ACCEPT
, 0)) {
1193 log_error("start_reply: "
1194 "error saving RECONF_ACCEPT option.");
1195 option_state_dereference(opt_state
, MDL
);
1204 * Try to get the IPv6 address the client asked for from the
1207 * addr is the result (should be a pointer to NULL on entry)
1208 * pool is the pool to search in
1209 * requested_addr is the address the client wants
1212 try_client_v6_address(struct iasubopt
**addr
,
1213 struct ipv6_pool
*pool
,
1214 const struct data_string
*requested_addr
)
1216 struct in6_addr tmp_addr
;
1217 isc_result_t result
;
1219 if (requested_addr
->len
< sizeof(tmp_addr
)) {
1220 return DHCP_R_INVALIDARG
;
1222 memcpy(&tmp_addr
, requested_addr
->data
, sizeof(tmp_addr
));
1223 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
)) {
1224 return ISC_R_FAILURE
;
1228 * The address is not covered by this (or possibly any) dynamic
1231 if (!ipv6_in_pool(&tmp_addr
, pool
)) {
1232 return ISC_R_ADDRNOTAVAIL
;
1235 if (lease6_exists(pool
, &tmp_addr
)) {
1236 return ISC_R_ADDRINUSE
;
1239 result
= iasubopt_allocate(addr
, MDL
);
1240 if (result
!= ISC_R_SUCCESS
) {
1243 (*addr
)->addr
= tmp_addr
;
1246 /* Default is soft binding for 2 minutes. */
1247 result
= add_lease6(pool
, *addr
, cur_time
+ 120);
1248 if (result
!= ISC_R_SUCCESS
) {
1249 iasubopt_dereference(addr
, MDL
);
1256 * \brief Get an IPv6 address for the client.
1258 * Attempt to find a usable address for the client. We walk through
1259 * the ponds checking for permit and deny then through the pools
1260 * seeing if they have an available address.
1262 * \param reply = the state structure for the current work on this request
1263 * if we create a lease we return it using reply->lease
1266 * ISC_R_SUCCESS = we were able to find an address and are returning a
1267 * pointer to the lease
1268 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1269 * is probabalistic. We don't exhaustively try the
1270 * address range, instead we hash the duid and if
1271 * the address derived from the hash is in use we
1272 * hash the address. After a number of failures we
1273 * conclude the pool is basically full.
1276 pick_v6_address(struct reply_state
*reply
)
1278 struct ipv6_pool
*p
= NULL
;
1279 struct ipv6_pond
*pond
;
1282 unsigned int attempts
;
1283 char tmp_buf
[INET6_ADDRSTRLEN
];
1284 struct iasubopt
**addr
= &reply
->lease
;
1285 isc_uint64_t total
= 0;
1286 isc_uint64_t active
= 0;
1287 isc_uint64_t abandoned
= 0;
1288 int jumbo_range
= 0;
1289 char *shared_name
= (reply
->shared
->name
?
1290 reply
->shared
->name
: "(no name)");
1293 * Do a quick walk through of the ponds and pools
1294 * to see if we have any NA address pools
1296 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1297 if (pond
->ipv6_pools
== NULL
)
1300 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1301 if (p
->pool_type
== D6O_IA_NA
)
1308 /* If we get here and p is NULL we have no useful pools */
1310 log_debug("Unable to pick client address: "
1311 "no IPv6 pools on this shared network");
1312 return ISC_R_NORESOURCES
;
1316 * We have at least one pool that could provide an address
1317 * Now we walk through the ponds and pools again and check
1318 * to see if the client is permitted and if an address is
1321 * Within a given pond we start looking at the last pool we
1322 * allocated from, unless it had a collision trying to allocate
1323 * an address. This will tend to move us into less-filled pools.
1326 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1327 isc_result_t result
= ISC_R_FAILURE
;
1329 if (((pond
->prohibit_list
!= NULL
) &&
1330 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1331 ((pond
->permit_list
!= NULL
) &&
1332 (!permitted(reply
->packet
, pond
->permit_list
))))
1336 /* If pond is EUI-64 but client duid isn't a valid EUI-64
1337 * id, then skip this pond */
1338 if (pond
->use_eui_64
&&
1339 !valid_eui_64_duid(&reply
->ia
->iaid_duid
, IAID_LEN
)) {
1344 start_pool
= pond
->last_ipv6_pool
;
1347 p
= pond
->ipv6_pools
[i
];
1348 if (p
->pool_type
== D6O_IA_NA
) {
1350 if (pond
->use_eui_64
) {
1352 create_lease6_eui_64(p
, addr
,
1353 &reply
->ia
->iaid_duid
,
1360 create_lease6(p
, addr
, &attempts
,
1361 &reply
->ia
->iaid_duid
,
1366 if (result
== ISC_R_SUCCESS
) {
1368 * Record the pool used (or next one if
1369 * there was a collision).
1373 if (pond
->ipv6_pools
[i
]
1379 pond
->last_ipv6_pool
= i
;
1381 log_debug("Picking pool address %s",
1384 tmp_buf
, sizeof(tmp_buf
)));
1385 return (ISC_R_SUCCESS
);
1390 if (pond
->ipv6_pools
[i
] == NULL
) {
1393 } while (i
!= start_pool
);
1395 if (result
== ISC_R_NORESOURCES
) {
1396 jumbo_range
+= pond
->jumbo_range
;
1397 total
+= pond
->num_total
;
1398 active
+= pond
->num_active
;
1399 abandoned
+= pond
->num_abandoned
;
1404 * If we failed to pick an IPv6 address from any of the subnets.
1405 * Presumably that means we have no addresses for the client.
1407 if (jumbo_range
!= 0) {
1408 log_debug("Unable to pick client address: "
1409 "no addresses available - shared network %s: "
1410 " 2^64-1 < total, %llu active, %llu abandoned",
1411 shared_name
, active
- abandoned
, abandoned
);
1413 log_debug("Unable to pick client address: "
1414 "no addresses available - shared network %s: "
1415 "%llu total, %llu active, %llu abandoned",
1416 shared_name
, total
, active
- abandoned
, abandoned
);
1419 return ISC_R_NORESOURCES
;
1423 * Try to get the IPv6 prefix the client asked for from the
1426 * pref is the result (should be a pointer to NULL on entry)
1427 * pool is the prefix pool to search in
1428 * requested_pref is the address the client wants
1431 try_client_v6_prefix(struct iasubopt
**pref
,
1432 struct ipv6_pool
*pool
,
1433 const struct data_string
*requested_pref
)
1436 struct in6_addr tmp_pref
;
1438 isc_result_t result
;
1440 if (requested_pref
->len
< sizeof(tmp_plen
) + sizeof(tmp_pref
)) {
1441 return DHCP_R_INVALIDARG
;
1444 tmp_plen
= (int) requested_pref
->data
[0];
1445 if ((tmp_plen
< 3) || (tmp_plen
> 128)) {
1446 return ISC_R_FAILURE
;
1449 memcpy(&tmp_pref
, requested_pref
->data
+ 1, sizeof(tmp_pref
));
1450 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref
)) {
1451 return ISC_R_FAILURE
;
1455 memcpy(&ia
.iabuf
, &tmp_pref
, 16);
1456 if (!is_cidr_mask_valid(&ia
, (int) tmp_plen
)) {
1457 return ISC_R_FAILURE
;
1460 if (!ipv6_in_pool(&tmp_pref
, pool
) ||
1461 ((int)tmp_plen
!= pool
->units
)) {
1462 return ISC_R_ADDRNOTAVAIL
;
1465 if (prefix6_exists(pool
, &tmp_pref
, tmp_plen
)) {
1466 return ISC_R_ADDRINUSE
;
1469 result
= iasubopt_allocate(pref
, MDL
);
1470 if (result
!= ISC_R_SUCCESS
) {
1474 (*pref
)->addr
= tmp_pref
;
1475 (*pref
)->plen
= tmp_plen
;
1477 /* Default is soft binding for 2 minutes. */
1478 result
= add_lease6(pool
, *pref
, cur_time
+ 120);
1479 if (result
!= ISC_R_SUCCESS
) {
1480 iasubopt_dereference(pref
, MDL
);
1488 * \brief Get an IPv6 prefix for the client.
1490 * Attempt to find a usable prefix for the client. Based upon the prefix
1491 * length mode and the plen supplied by the client (if one), we make one
1492 * or more calls to pick_v6_prefix_helper() to find a prefix as follows:
1494 * PLM_IGNORE or client specifies a plen of zero, use the first available
1495 * prefix regardless of it's length.
1497 * PLM_PREFER – look for an exact match to client's plen first, if none
1498 * found, use the first available prefix of any length
1500 * PLM_EXACT – look for an exact match first, if none found then fail. This
1501 * is the default behavior.
1503 * PLM_MAXIMUM - look for an exact match first, then the first available whose
1504 * prefix length is less than client's plen, otherwise fail.
1506 * PLM_MINIMUM - look for an exact match first, then the first available whose
1507 * prefix length is greater than client's plen, otherwise fail.
1509 * Note that the selection mode is configurable at the global scope only via
1512 * \param reply = the state structure for the current work on this request
1513 * if we create a lease we return it using reply->lease
1516 * ISC_R_SUCCESS = we were able to find an prefix and are returning a
1517 * pointer to the lease
1518 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1519 * is probabalistic. We don't exhaustively try the
1520 * address range, instead we hash the duid and if
1521 * the address derived from the hash is in use we
1522 * hash the address. After a number of failures we
1523 * conclude the pool is basically full.
1526 pick_v6_prefix(struct reply_state
*reply
) {
1527 struct ipv6_pool
*p
= NULL
;
1528 struct ipv6_pond
*pond
;
1530 isc_result_t result
;
1533 * Do a quick walk through of the ponds and pools
1534 * to see if we have any prefix pools
1536 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1537 if (pond
->ipv6_pools
== NULL
)
1540 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1541 if (p
->pool_type
== D6O_IA_PD
)
1548 /* If we get here and p is NULL we have no useful pools */
1550 log_debug("Unable to pick client prefix: "
1551 "no IPv6 pools on this shared network");
1552 return ISC_R_NORESOURCES
;
1555 if (reply
->preflen
<= 0) {
1556 /* If we didn't get a plen (-1) or client plen is 0, then just
1557 * select first available (same as PLM_INGORE) */
1558 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1560 switch (prefix_length_mode
) {
1562 /* First we look for an exact match, if not found
1563 * then first available */
1564 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1565 if (result
!= ISC_R_SUCCESS
) {
1566 result
= pick_v6_prefix_helper(reply
,
1572 /* Match exactly or fail */
1573 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1578 /* First we look for an exact match, if not found
1579 * then first available by mode */
1580 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1581 if (result
!= ISC_R_SUCCESS
) {
1582 result
= pick_v6_prefix_helper(reply
,
1583 prefix_length_mode
);
1588 /* First available */
1589 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1594 if (result
== ISC_R_SUCCESS
) {
1595 char tmp_buf
[INET6_ADDRSTRLEN
];
1597 log_debug("Picking pool prefix %s/%u",
1598 inet_ntop(AF_INET6
, &(reply
->lease
->addr
),
1599 tmp_buf
, sizeof(tmp_buf
)),
1600 (unsigned)(reply
->lease
->plen
));
1601 return (ISC_R_SUCCESS
);
1605 * If we failed to pick an IPv6 prefix
1606 * Presumably that means we have no prefixes for the client.
1608 log_debug("Unable to pick client prefix: no prefixes available");
1609 return ISC_R_NORESOURCES
;
1614 * \brief Get an IPv6 prefix for the client based upon selection mode.
1616 * We walk through the ponds checking for permit and deny. If a pond is
1617 * permissable to use, loop through its PD pools checking prefix lengths
1618 * against the client plen based on the prefix length mode, looking for
1619 * available prefixes.
1621 * \param reply = the state structure for the current work on this request
1622 * if we create a lease we return it using reply->lease
1623 * \prefix_mode = selection mode to use
1626 * ISC_R_SUCCESS = we were able to find a prefix and are returning a
1627 * pointer to the lease
1628 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1629 * is probabalistic. We don't exhaustively try the
1630 * address range, instead we hash the duid and if
1631 * the address derived from the hash is in use we
1632 * hash the address. After a number of failures we
1633 * conclude the pool is basically full.
1636 pick_v6_prefix_helper(struct reply_state
*reply
, int prefix_mode
) {
1637 struct ipv6_pool
*p
= NULL
;
1638 struct ipv6_pond
*pond
;
1640 unsigned int attempts
;
1641 struct iasubopt
**pref
= &reply
->lease
;
1643 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1644 if (((pond
->prohibit_list
!= NULL
) &&
1645 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1646 ((pond
->permit_list
!= NULL
) &&
1647 (!permitted(reply
->packet
, pond
->permit_list
))))
1650 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1651 if ((p
->pool_type
== D6O_IA_PD
) &&
1652 (eval_prefix_mode(p
->units
, reply
->preflen
,
1653 prefix_mode
) == 1) &&
1654 (create_prefix6(p
, pref
, &attempts
,
1655 &reply
->ia
->iaid_duid
,
1656 cur_time
+ 120) == ISC_R_SUCCESS
)) {
1657 return (ISC_R_SUCCESS
);
1662 return ISC_R_NORESOURCES
;
1667 * \brief Test a prefix length against another based on prefix length mode
1669 * \param len - prefix length to test
1670 * \param preflen - preferred prefix length against which to test
1671 * \param prefix_mode - prefix selection mode with which to test
1673 * Note that the case of preferred length of 0 is not short-cut here as it
1674 * is assumed to be done at a higher level.
1676 * \return 1 if the given length is usable based upon mode and a preferred
1680 eval_prefix_mode(int len
, int preflen
, int prefix_mode
) {
1682 switch (prefix_mode
) {
1684 use_it
= (len
== preflen
);
1687 /* they asked for a prefix length no "shorter" than preflen */
1688 use_it
= (len
>= preflen
);
1691 /* they asked for a prefix length no "longer" than preflen */
1692 use_it
= (len
<= preflen
);
1695 /* otherwise use it */
1703 *! \file server/dhcpv6.c
1705 * \brief construct a reply containing information about a client's lease
1707 * lease_to_client() is called from several messages to construct a
1708 * reply that contains all that we know about the client's correct lease
1709 * (or projected lease).
1711 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1712 * send what we "may" give them on a request.
1714 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1715 * the client should really use).
1717 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1718 * Rebind out any "wrong" addresses the client sends. This means we send
1719 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1720 * possibly send the address with zeroed lifetimes.
1722 * Information-Request - No binding.
1724 * The basic structure is to traverse the client-supplied data first, and
1725 * validate and echo back any contents that can be. If the client-supplied
1726 * data does not error out (on renew/rebind as above), but we did not send
1727 * any addresses, attempt to allocate one.
1729 * At the end of the this function we call commit_leases_timed() to
1730 * fsync and rotate the file as necessary. commit_leases_timed() will
1731 * check that we have written at least one lease to the file and that
1732 * some time has passed before doing any fsync or file rewrite so we
1733 * don't bother tracking if we did a write_ia during this function.
1735 /* TODO: look at client hints for lease times */
1738 lease_to_client(struct data_string
*reply_ret
,
1739 struct packet
*packet
,
1740 const struct data_string
*client_id
,
1741 const struct data_string
*server_id
)
1743 static struct reply_state reply
;
1744 struct option_cache
*oc
;
1745 struct data_string packet_oro
;
1748 memset(&packet_oro
, 0, sizeof(packet_oro
));
1750 /* Locate the client. */
1751 if (shared_network_from_packet6(&reply
.shared
,
1752 packet
) != ISC_R_SUCCESS
)
1756 * Initialize the reply.
1758 packet_reference(&reply
.packet
, packet
, MDL
);
1759 data_string_copy(&reply
.client_id
, client_id
, MDL
);
1761 if (!start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
1765 /* Set the write cursor to just past the reply header. */
1766 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1769 * Get the ORO from the packet, if any.
1771 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ORO
);
1773 if (!evaluate_option_cache(&packet_oro
, packet
,
1775 packet
->options
, NULL
,
1776 &global_scope
, oc
, MDL
)) {
1777 log_error("lease_to_client: error evaluating ORO.");
1783 * Find a host record that matches the packet, if any, and is
1784 * valid for the shared network the client is on.
1786 if (find_hosts6(&reply
.host
, packet
, client_id
, MDL
)) {
1788 seek_shared_host(&reply
.host
, reply
.shared
);
1791 /* Process the client supplied IA's onto the reply buffer. */
1793 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
1795 for (; oc
!= NULL
; oc
= oc
->next
) {
1796 isc_result_t status
;
1798 /* Start counting resources (addresses) offered. */
1799 reply
.client_resources
= 0;
1800 reply
.resources_included
= ISC_FALSE
;
1802 status
= reply_process_ia_na(&reply
, oc
);
1805 * We continue to try other IA's whether we can address
1806 * this one or not. Any other result is an immediate fail.
1808 if ((status
!= ISC_R_SUCCESS
) &&
1809 (status
!= ISC_R_NORESOURCES
))
1812 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
1813 for (; oc
!= NULL
; oc
= oc
->next
) {
1814 isc_result_t status
;
1816 /* Start counting resources (addresses) offered. */
1817 reply
.client_resources
= 0;
1818 reply
.resources_included
= ISC_FALSE
;
1820 status
= reply_process_ia_ta(&reply
, oc
);
1823 * We continue to try other IA's whether we can address
1824 * this one or not. Any other result is an immediate fail.
1826 if ((status
!= ISC_R_SUCCESS
) &&
1827 (status
!= ISC_R_NORESOURCES
))
1831 /* Same for IA_PD's. */
1833 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
1834 for (; oc
!= NULL
; oc
= oc
->next
) {
1835 isc_result_t status
;
1837 /* Start counting resources (prefixes) offered. */
1838 reply
.client_resources
= 0;
1839 reply
.resources_included
= ISC_FALSE
;
1841 status
= reply_process_ia_pd(&reply
, oc
);
1844 * We continue to try other IA_PD's whether we can address
1845 * this one or not. Any other result is an immediate fail.
1847 if ((status
!= ISC_R_SUCCESS
) &&
1848 (status
!= ISC_R_NORESOURCES
))
1853 * Make no reply if we gave no resources and is not
1854 * for Information-Request.
1856 if ((reply
.ia_count
== 0) && (reply
.pd_count
== 0)) {
1857 if (reply
.packet
->dhcpv6_msg_type
!=
1858 DHCPV6_INFORMATION_REQUEST
)
1862 * Because we only execute statements on a per-IA basis,
1863 * we need to execute statements in any non-IA reply to
1864 * source configuration.
1866 execute_statements_in_scope(NULL
, reply
.packet
, NULL
, NULL
,
1867 reply
.packet
->options
,
1868 reply
.opt_state
, &global_scope
,
1869 reply
.shared
->group
, root_group
,
1872 /* Execute statements from class scopes. */
1873 for (i
= reply
.packet
->class_count
; i
> 0; i
--) {
1874 execute_statements_in_scope(NULL
, reply
.packet
,
1876 reply
.packet
->options
,
1879 reply
.packet
->classes
[i
- 1]->group
,
1880 reply
.shared
->group
, NULL
);
1883 /* Bring in any configuration from a host record. */
1884 if (reply
.host
!= NULL
)
1885 execute_statements_in_scope(NULL
, reply
.packet
,
1887 reply
.packet
->options
,
1891 reply
.shared
->group
, NULL
);
1895 * RFC3315 section 17.2.2 (Solicit):
1897 * If the server will not assign any addresses to any IAs in a
1898 * subsequent Request from the client, the server MUST send an
1899 * Advertise message to the client that includes only a Status
1900 * Code option with code NoAddrsAvail and a status message for
1901 * the user, a Server Identifier option with the server's DUID,
1902 * and a Client Identifier option with the client's DUID.
1904 * This has been updated by an errata such that the server
1905 * can always send an IA.
1907 * Section 18.2.1 (Request):
1909 * If the server cannot assign any addresses to an IA in the
1910 * message from the client, the server MUST include the IA in
1911 * the Reply message with no addresses in the IA and a Status
1912 * Code option in the IA containing status code NoAddrsAvail.
1914 * Section 18.1.8 (Client Behavior):
1916 * Leave unchanged any information about addresses the client has
1917 * recorded in the IA but that were not included in the IA from
1919 * Sends a Renew/Rebind if the IA is not in the Reply message.
1923 * Having stored the client's IA's, store any options that
1924 * will fit in the remaining space.
1926 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+ reply
.cursor
,
1927 sizeof(reply
.buf
) - reply
.cursor
,
1928 reply
.opt_state
, reply
.packet
,
1929 required_opts_solicit
,
1932 /* Return our reply to the caller. */
1933 reply_ret
->len
= reply
.cursor
;
1934 reply_ret
->buffer
= NULL
;
1935 if (!buffer_allocate(&reply_ret
->buffer
, reply
.cursor
, MDL
)) {
1936 log_fatal("No memory to store Reply.");
1938 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
, reply
.cursor
);
1939 reply_ret
->data
= reply_ret
->buffer
->data
;
1941 /* If appropriate commit and rotate the lease file */
1942 (void) commit_leases_timed();
1946 if (reply
.shared
!= NULL
)
1947 shared_network_dereference(&reply
.shared
, MDL
);
1948 if (reply
.host
!= NULL
)
1949 host_dereference(&reply
.host
, MDL
);
1950 if (reply
.opt_state
!= NULL
)
1951 option_state_dereference(&reply
.opt_state
, MDL
);
1952 if (reply
.packet
!= NULL
)
1953 packet_dereference(&reply
.packet
, MDL
);
1954 if (reply
.client_id
.data
!= NULL
)
1955 data_string_forget(&reply
.client_id
, MDL
);
1956 if (packet_oro
.buffer
!= NULL
)
1957 data_string_forget(&packet_oro
, MDL
);
1958 reply
.renew
= reply
.rebind
= reply
.min_prefer
= reply
.min_valid
= 0;
1962 /* Process a client-supplied IA_NA. This may append options to the tail of
1963 * the reply packet being built in the reply_state structure.
1966 reply_process_ia_na(struct reply_state
*reply
, struct option_cache
*ia
) {
1967 isc_result_t status
= ISC_R_SUCCESS
;
1970 struct option_state
*packet_ia
;
1971 struct option_cache
*oc
;
1972 struct data_string ia_data
, data
;
1974 /* Initialize values that will get cleaned up on return. */
1976 memset(&ia_data
, 0, sizeof(ia_data
));
1977 memset(&data
, 0, sizeof(data
));
1979 * Note that find_client_address() may set reply->lease.
1982 /* Make sure there is at least room for the header. */
1983 if ((reply
->cursor
+ IA_NA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
1984 log_error("reply_process_ia_na: Reply too long for IA.");
1985 return ISC_R_NOSPACE
;
1989 /* Fetch the IA_NA contents. */
1990 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
1991 ia
, IA_NA_OFFSET
)) {
1992 log_error("reply_process_ia_na: error evaluating ia");
1993 status
= ISC_R_FAILURE
;
1997 /* Extract IA_NA header contents. */
1998 iaid
= getULong(ia_data
.data
);
1999 reply
->renew
= getULong(ia_data
.data
+ 4);
2000 reply
->rebind
= getULong(ia_data
.data
+ 8);
2002 /* Create an IA_NA structure. */
2003 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2004 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2005 log_error("reply_process_ia_na: no memory for ia.");
2006 status
= ISC_R_NOMEMORY
;
2009 reply
->ia
->ia_type
= D6O_IA_NA
;
2011 /* Cache pre-existing IA, if any. */
2012 ia_hash_lookup(&reply
->old_ia
, ia_na_active
,
2013 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2014 reply
->ia
->iaid_duid
.len
, MDL
);
2017 * Create an option cache to carry the IA_NA option contents, and
2018 * execute any user-supplied values into it.
2020 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2021 status
= ISC_R_NOMEMORY
;
2025 /* Check & cache the fixed host record. */
2026 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_addr
!= NULL
)) {
2027 struct iaddr tmp_addr
;
2029 if (!evaluate_option_cache(&reply
->fixed
, NULL
, NULL
, NULL
,
2030 NULL
, NULL
, &global_scope
,
2031 reply
->host
->fixed_addr
, MDL
)) {
2032 log_error("reply_process_ia_na: unable to evaluate "
2034 status
= ISC_R_FAILURE
;
2038 if (reply
->fixed
.len
< 16) {
2039 log_error("reply_process_ia_na: invalid fixed address.");
2040 status
= DHCP_R_INVALIDARG
;
2044 /* Find the static lease's subnet. */
2046 memcpy(tmp_addr
.iabuf
, reply
->fixed
.data
, 16);
2048 if (find_grouped_subnet(&reply
->subnet
, reply
->shared
,
2049 tmp_addr
, MDL
) == 0)
2050 log_fatal("Impossible condition at %s:%d.", MDL
);
2052 reply
->static_lease
= ISC_TRUE
;
2054 reply
->static_lease
= ISC_FALSE
;
2057 * Save the cursor position at the start of the IA, so we can
2058 * set length and adjust t1/t2 values later. We write a temporary
2059 * header out now just in case we decide to adjust the packet
2060 * within sub-process functions.
2062 ia_cursor
= reply
->cursor
;
2064 /* Initialize the IA_NA header. First the code. */
2065 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_NA
);
2068 /* Then option length. */
2069 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
2072 /* Then IA_NA header contents; IAID. */
2073 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2076 /* We store the client's t1 for now, and may over-ride it later. */
2077 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
2080 /* We store the client's t2 for now, and may over-ride it later. */
2081 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
2085 * For each address in this IA_NA, decide what to do about it.
2089 * The client leaves unchanged any information about addresses
2090 * it has recorded but are not included ("cancel/break" below).
2091 * A not included IA ("cleanup" below) could give a Renew/Rebind.
2093 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2094 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
2095 reply
->client_valid
= reply
->client_prefer
= 0;
2096 for (; oc
!= NULL
; oc
= oc
->next
) {
2097 status
= reply_process_addr(reply
, oc
);
2100 * Canceled means we did not allocate addresses to the
2101 * client, but we're "done" with this IA - we set a status
2102 * code. So transmit this reply, e.g., move on to the next
2105 if (status
== ISC_R_CANCELED
)
2108 if ((status
!= ISC_R_SUCCESS
) &&
2109 (status
!= ISC_R_ADDRINUSE
) &&
2110 (status
!= ISC_R_ADDRNOTAVAIL
))
2117 * If we fell through the above and never gave the client
2118 * an address, give it one now.
2120 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
2121 status
= find_client_address(reply
);
2123 if (status
== ISC_R_NORESOURCES
) {
2124 switch (reply
->packet
->dhcpv6_msg_type
) {
2125 case DHCPV6_SOLICIT
:
2127 * No address for any IA is handled
2132 case DHCPV6_REQUEST
:
2133 /* Section 18.2.1 (Request):
2135 * If the server cannot assign any addresses to
2136 * an IA in the message from the client, the
2137 * server MUST include the IA in the Reply
2138 * message with no addresses in the IA and a
2139 * Status Code option in the IA containing
2140 * status code NoAddrsAvail.
2142 option_state_dereference(&reply
->reply_ia
, MDL
);
2143 if (!option_state_allocate(&reply
->reply_ia
,
2146 log_error("reply_process_ia_na: No "
2147 "memory for option state "
2149 status
= ISC_R_NOMEMORY
;
2153 if (!set_status_code(STATUS_NoAddrsAvail
,
2154 "No addresses available "
2155 "for this interface.",
2157 log_error("reply_process_ia_na: Unable "
2158 "to set NoAddrsAvail status "
2160 status
= ISC_R_FAILURE
;
2164 status
= ISC_R_SUCCESS
;
2169 * RFC 3315 does not tell us to emit a status
2170 * code in this condition, or anything else.
2172 * If we included non-allocated addresses
2173 * (zeroed lifetimes) in an IA, then the client
2174 * will deconfigure them.
2176 * So we want to include the IA even if we
2177 * can't give it a new address if it includes
2178 * zeroed lifetime addresses.
2180 * We don't want to include the IA if we
2181 * provide zero addresses including zeroed
2184 if (reply
->resources_included
)
2185 status
= ISC_R_SUCCESS
;
2192 if (status
!= ISC_R_SUCCESS
)
2196 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2197 sizeof(reply
->buf
) - reply
->cursor
,
2198 reply
->reply_ia
, reply
->packet
,
2199 required_opts_IA
, NULL
);
2201 /* Reset the length of this IA to match what was just written. */
2202 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2203 reply
->cursor
- (ia_cursor
+ 4));
2205 /* Calculate T1/T2 and stuff them in the reply */
2206 set_reply_tee_times(reply
, ia_cursor
);
2209 * yes, goto's aren't the best but we also want to avoid extra
2212 if (status
== ISC_R_CANCELED
)
2216 * Handle static leases, we always log stuff and if it's
2217 * a hard binding we run any commit statements that we have
2219 if (reply
->static_lease
) {
2220 char tmp_addr
[INET6_ADDRSTRLEN
];
2221 log_info("%s NA: address %s to client with duid %s iaid = %d "
2223 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2224 inet_ntop(AF_INET6
, reply
->fixed
.data
, tmp_addr
,
2226 print_hex_1(reply
->client_id
.len
,
2227 reply
->client_id
.data
, 60),
2230 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
2231 (reply
->on_star
.on_commit
!= NULL
)) {
2232 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
2233 reply
->packet
->options
,
2234 reply
->opt_state
, NULL
,
2235 reply
->on_star
.on_commit
, NULL
);
2236 executable_statement_dereference
2237 (&reply
->on_star
.on_commit
, MDL
);
2243 * If we have any addresses log what we are doing.
2245 if (reply
->ia
->num_iasubopt
!= 0) {
2246 struct iasubopt
*tmp
;
2248 char tmp_addr
[INET6_ADDRSTRLEN
];
2250 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2251 tmp
= reply
->ia
->iasubopt
[i
];
2253 log_info("%s NA: address %s to client with duid %s "
2254 "iaid = %d valid for %u seconds",
2255 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2256 inet_ntop(AF_INET6
, &tmp
->addr
,
2257 tmp_addr
, sizeof(tmp_addr
)),
2258 print_hex_1(reply
->client_id
.len
,
2259 reply
->client_id
.data
, 60),
2265 * If this is not a 'soft' binding, consume the new changes into
2266 * the database (if any have been attached to the ia_na).
2268 * Loop through the assigned dynamic addresses, referencing the
2269 * leases onto this IA_NA rather than any old ones, and updating
2270 * pool timers for each (if any).
2273 if ((reply
->ia
->num_iasubopt
!= 0) &&
2274 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
2275 struct iasubopt
*tmp
;
2276 struct data_string
*ia_id
;
2279 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2280 tmp
= reply
->ia
->iasubopt
[i
];
2282 if (tmp
->ia
!= NULL
)
2283 ia_dereference(&tmp
->ia
, MDL
);
2284 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2286 /* Commit 'hard' bindings. */
2287 renew_lease6(tmp
->ipv6_pool
, tmp
);
2288 schedule_lease_timeout(tmp
->ipv6_pool
);
2290 /* If we have anything to do on commit do it now */
2291 if (tmp
->on_star
.on_commit
!= NULL
) {
2292 execute_statements(NULL
, reply
->packet
,
2294 reply
->packet
->options
,
2297 tmp
->on_star
.on_commit
,
2299 executable_statement_dereference
2300 (&tmp
->on_star
.on_commit
, MDL
);
2303 #if defined (NSUPDATE)
2305 * Perform ddns updates.
2307 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2310 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2312 reply
->packet
->options
,
2316 ddns_updates(reply
->packet
, NULL
, NULL
,
2317 tmp
, NULL
, reply
->opt_state
);
2320 /* Do our threshold check. */
2321 check_pool6_threshold(reply
, tmp
);
2324 /* Remove any old ia from the hash. */
2325 if (reply
->old_ia
!= NULL
) {
2326 if (!release_on_roam(reply
)) {
2327 ia_id
= &reply
->old_ia
->iaid_duid
;
2328 ia_hash_delete(ia_na_active
,
2329 (unsigned char *)ia_id
->data
,
2333 ia_dereference(&reply
->old_ia
, MDL
);
2336 /* Put new ia into the hash. */
2337 reply
->ia
->cltt
= cur_time
;
2338 ia_id
= &reply
->ia
->iaid_duid
;
2339 ia_hash_add(ia_na_active
, (unsigned char *)ia_id
->data
,
2340 ia_id
->len
, reply
->ia
, MDL
);
2342 write_ia(reply
->ia
);
2344 schedule_lease_timeout_reply(reply
);
2348 if (packet_ia
!= NULL
)
2349 option_state_dereference(&packet_ia
, MDL
);
2350 if (reply
->reply_ia
!= NULL
)
2351 option_state_dereference(&reply
->reply_ia
, MDL
);
2352 if (ia_data
.data
!= NULL
)
2353 data_string_forget(&ia_data
, MDL
);
2354 if (data
.data
!= NULL
)
2355 data_string_forget(&data
, MDL
);
2356 if (reply
->ia
!= NULL
)
2357 ia_dereference(&reply
->ia
, MDL
);
2358 if (reply
->old_ia
!= NULL
)
2359 ia_dereference(&reply
->old_ia
, MDL
);
2360 if (reply
->lease
!= NULL
)
2361 iasubopt_dereference(&reply
->lease
, MDL
);
2362 if (reply
->fixed
.data
!= NULL
)
2363 data_string_forget(&reply
->fixed
, MDL
);
2364 if (reply
->subnet
!= NULL
)
2365 subnet_dereference(&reply
->subnet
, MDL
);
2366 if (reply
->on_star
.on_expiry
!= NULL
)
2367 executable_statement_dereference
2368 (&reply
->on_star
.on_expiry
, MDL
);
2369 if (reply
->on_star
.on_release
!= NULL
)
2370 executable_statement_dereference
2371 (&reply
->on_star
.on_release
, MDL
);
2374 * ISC_R_CANCELED is a status code used by the addr processing to
2375 * indicate we're replying with a status code. This is still a
2376 * success at higher layers.
2378 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2382 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
2383 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
2384 * in the event we are replying with a status code and do not wish to process
2385 * more IAADDRs within this IA.
2388 reply_process_addr(struct reply_state
*reply
, struct option_cache
*addr
) {
2389 u_int32_t pref_life
, valid_life
;
2390 struct binding_scope
**scope
;
2391 struct group
*group
;
2392 struct subnet
*subnet
;
2393 struct iaddr tmp_addr
;
2394 struct option_cache
*oc
;
2395 struct data_string iaaddr
, data
;
2396 isc_result_t status
= ISC_R_SUCCESS
;
2398 int invalid_for_eui_64
= 0;
2401 /* Initializes values that will be cleaned up. */
2402 memset(&iaaddr
, 0, sizeof(iaaddr
));
2403 memset(&data
, 0, sizeof(data
));
2404 /* Note that reply->lease may be set by address_is_owned() */
2407 * There is no point trying to process an incoming address if there
2408 * is no room for an outgoing address.
2410 if ((reply
->cursor
+ 28) > sizeof(reply
->buf
)) {
2411 log_error("reply_process_addr: Out of room for address.");
2412 return ISC_R_NOSPACE
;
2415 /* Extract this IAADDR option. */
2416 if (!evaluate_option_cache(&iaaddr
, reply
->packet
, NULL
, NULL
,
2417 reply
->packet
->options
, NULL
, &global_scope
,
2419 (iaaddr
.len
< IAADDR_OFFSET
)) {
2420 log_error("reply_process_addr: error evaluating IAADDR.");
2421 status
= ISC_R_FAILURE
;
2425 /* The first 16 bytes are the IPv6 address. */
2426 pref_life
= getULong(iaaddr
.data
+ 16);
2427 valid_life
= getULong(iaaddr
.data
+ 20);
2429 if ((reply
->client_valid
== 0) ||
2430 (reply
->client_valid
> valid_life
))
2431 reply
->client_valid
= valid_life
;
2433 if ((reply
->client_prefer
== 0) ||
2434 (reply
->client_prefer
> pref_life
))
2435 reply
->client_prefer
= pref_life
;
2438 * Clients may choose to send :: as an address, with the idea to give
2439 * hints about preferred-lifetime or valid-lifetime.
2442 memset(tmp_addr
.iabuf
, 0, 16);
2443 if (!memcmp(iaaddr
.data
, tmp_addr
.iabuf
, 16)) {
2444 /* Status remains success; we just ignore this one. */
2448 /* tmp_addr len remains 16 */
2449 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2452 * Verify that this address is on the client's network.
2454 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
2455 subnet
= subnet
->next_sibling
) {
2456 if (addr_eq(subnet_number(tmp_addr
, subnet
->netmask
),
2463 /* If the requested address falls into an EUI-64 pool, then
2464 * we need to verify if it has EUI-64 duid AND the requested
2465 * address is correct for that duid. If not we treat it just
2466 * like an not-on-link request. */
2467 struct ipv6_pool
* pool
= NULL
;
2468 struct in6_addr
* addr
= (struct in6_addr
*)(iaaddr
.data
);
2469 if ((find_ipv6_pool(&pool
, D6O_IA_NA
, addr
) == ISC_R_SUCCESS
)
2470 && (pool
->ipv6_pond
->use_eui_64
) &&
2471 (!valid_for_eui_64_pool(pool
, &reply
->client_id
, 0, addr
))) {
2472 log_debug ("Requested address: %s,"
2473 " not valid for EUI-64 pool",
2475 invalid_for_eui_64
= 1;
2480 /* Address not found on shared network. */
2482 if ((subnet
== NULL
) || invalid_for_eui_64
) {
2484 if (subnet
== NULL
) {
2486 /* Ignore this address on 'soft' bindings. */
2487 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
2488 /* disable rapid commit */
2489 reply
->buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
2490 delete_option(&dhcpv6_universe
,
2493 /* status remains success */
2498 * RFC3315 section 18.2.1:
2500 * If the server finds that the prefix on one or more IP
2501 * addresses in any IA in the message from the client is not
2502 * appropriate for the link to which the client is connected,
2503 * the server MUST return the IA to the client with a Status
2504 * Code option with the value NotOnLink.
2506 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) {
2507 /* Rewind the IA_NA to empty. */
2508 option_state_dereference(&reply
->reply_ia
, MDL
);
2509 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2510 log_error("reply_process_addr: No memory for "
2511 "option state wipe.");
2512 status
= ISC_R_NOMEMORY
;
2516 /* Append a NotOnLink status code. */
2517 if (!set_status_code(STATUS_NotOnLink
,
2518 "Address not for use on this "
2519 "link.", reply
->reply_ia
)) {
2520 log_error("reply_process_addr: Failure "
2521 "setting status code.");
2522 status
= ISC_R_FAILURE
;
2526 /* Fin (no more IAADDRs). */
2527 status
= ISC_R_CANCELED
;
2532 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2534 * If the server finds that any of the addresses are not
2535 * appropriate for the link to which the client is attached,
2536 * the server returns the address to the client with lifetimes
2539 if ((reply
->packet
->dhcpv6_msg_type
!= DHCPV6_RENEW
) &&
2540 (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
2541 log_error("It is impossible to lease a client that is "
2542 "not sending a solicit, request, renew, or "
2544 status
= ISC_R_FAILURE
;
2548 reply
->send_prefer
= reply
->send_valid
= 0;
2553 /* Verify the address belongs to the client. */
2554 if (!address_is_owned(reply
, &tmp_addr
)) {
2556 * For solicit and request, any addresses included are
2557 * 'requested' addresses. For rebind, we actually have
2558 * no direction on what to do from 3315 section 18.2.4!
2559 * So I think the best bet is to try and give it out, and if
2560 * we can't, zero lifetimes.
2562 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
2563 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
2564 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
2565 status
= reply_process_try_addr(reply
, &tmp_addr
);
2568 * If the address is in use, or isn't in any dynamic
2569 * range, continue as normal. If any other error was
2572 if ((status
!= ISC_R_SUCCESS
) &&
2573 (status
!= ISC_R_ADDRINUSE
) &&
2574 (status
!= ISC_R_ADDRNOTAVAIL
))
2578 * If we didn't honor this lease, for solicit and
2579 * request we simply omit it from our answer. For
2580 * rebind, we send it with zeroed lifetimes.
2582 if (reply
->lease
== NULL
) {
2583 if (reply
->packet
->dhcpv6_msg_type
==
2585 reply
->send_prefer
= 0;
2586 reply
->send_valid
= 0;
2590 /* status remains success - ignore */
2594 * RFC3315 section 18.2.3:
2596 * If the server cannot find a client entry for the IA the
2597 * server returns the IA containing no addresses with a Status
2598 * Code option set to NoBinding in the Reply message.
2600 * On mismatch we (ab)use this pretending we have not the IA
2601 * as soon as we have not an address.
2603 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
2604 /* Rewind the IA_NA to empty. */
2605 option_state_dereference(&reply
->reply_ia
, MDL
);
2606 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2607 log_error("reply_process_addr: No memory for "
2608 "option state wipe.");
2609 status
= ISC_R_NOMEMORY
;
2613 /* Append a NoBinding status code. */
2614 if (!set_status_code(STATUS_NoBinding
,
2615 "Address not bound to this "
2616 "interface.", reply
->reply_ia
)) {
2617 log_error("reply_process_addr: Unable to "
2618 "attach status code.");
2619 status
= ISC_R_FAILURE
;
2623 /* Fin (no more IAADDRs). */
2624 status
= ISC_R_CANCELED
;
2627 log_error("It is impossible to lease a client that is "
2628 "not sending a solicit, request, renew, or "
2630 status
= ISC_R_FAILURE
;
2635 if (reply
->static_lease
) {
2636 if (reply
->host
== NULL
)
2637 log_fatal("Impossible condition at %s:%d.", MDL
);
2639 scope
= &global_scope
;
2640 group
= reply
->subnet
->group
;
2642 if (reply
->lease
== NULL
)
2643 log_fatal("Impossible condition at %s:%d.", MDL
);
2645 scope
= &reply
->lease
->scope
;
2646 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
2650 * If client_resources is nonzero, then the reply_process_is_addressed
2651 * function has executed configuration state into the reply option
2652 * cache. We will use that valid cache to derive configuration for
2653 * whether or not to engage in additional addresses, and similar.
2655 if (reply
->client_resources
!= 0) {
2659 * Does this client have "enough" addresses already? Default
2660 * to one. Everybody gets one, and one should be enough for
2663 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2664 SV_LIMIT_ADDRS_PER_IA
);
2666 if (!evaluate_option_cache(&data
, reply
->packet
,
2668 reply
->packet
->options
,
2672 log_error("reply_process_addr: unable to "
2673 "evaluate addrs-per-ia value.");
2674 status
= ISC_R_FAILURE
;
2678 limit
= getULong(data
.data
);
2679 data_string_forget(&data
, MDL
);
2683 * If we wish to limit the client to a certain number of
2684 * addresses, then omit the address from the reply.
2686 if (reply
->client_resources
>= limit
)
2690 status
= reply_process_is_addressed(reply
, scope
, group
);
2691 if (status
!= ISC_R_SUCCESS
)
2695 status
= reply_process_send_addr(reply
, &tmp_addr
);
2698 if (iaaddr
.data
!= NULL
)
2699 data_string_forget(&iaaddr
, MDL
);
2700 if (data
.data
!= NULL
)
2701 data_string_forget(&data
, MDL
);
2702 if (reply
->lease
!= NULL
)
2703 iasubopt_dereference(&reply
->lease
, MDL
);
2709 * Verify the address belongs to the client. If we've got a host
2710 * record with a fixed address, it has to be the assigned address
2711 * (fault out all else). Otherwise it's a dynamic address, so lookup
2712 * that address and make sure it belongs to this DUID:IAID pair.
2714 static isc_boolean_t
2715 address_is_owned(struct reply_state
*reply
, struct iaddr
*addr
) {
2717 struct ipv6_pond
*pond
;
2720 * This faults out addresses that don't match fixed addresses.
2722 if (reply
->static_lease
) {
2723 if (reply
->fixed
.data
== NULL
)
2724 log_fatal("Impossible condition at %s:%d.", MDL
);
2726 if (memcmp(addr
->iabuf
, reply
->fixed
.data
, 16) == 0)
2732 if ((reply
->old_ia
== NULL
) || (reply
->old_ia
->num_iasubopt
== 0))
2735 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2736 struct iasubopt
*tmp
;
2738 tmp
= reply
->old_ia
->iasubopt
[i
];
2740 if (memcmp(addr
->iabuf
, &tmp
->addr
, 16) == 0) {
2741 if (lease6_usable(tmp
) == ISC_FALSE
) {
2745 pond
= tmp
->ipv6_pool
->ipv6_pond
;
2746 if (((pond
->prohibit_list
!= NULL
) &&
2747 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
2748 ((pond
->permit_list
!= NULL
) &&
2749 (!permitted(reply
->packet
, pond
->permit_list
))))
2752 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
2761 /* Process a client-supplied IA_TA. This may append options to the tail of
2762 * the reply packet being built in the reply_state structure.
2765 reply_process_ia_ta(struct reply_state
*reply
, struct option_cache
*ia
) {
2766 isc_result_t status
= ISC_R_SUCCESS
;
2769 struct option_state
*packet_ia
;
2770 struct option_cache
*oc
;
2771 struct data_string ia_data
, data
;
2772 struct data_string iaaddr
;
2773 u_int32_t pref_life
, valid_life
;
2774 struct iaddr tmp_addr
;
2776 /* Initialize values that will get cleaned up on return. */
2778 memset(&ia_data
, 0, sizeof(ia_data
));
2779 memset(&data
, 0, sizeof(data
));
2780 memset(&iaaddr
, 0, sizeof(iaaddr
));
2782 /* Make sure there is at least room for the header. */
2783 if ((reply
->cursor
+ IA_TA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2784 log_error("reply_process_ia_ta: Reply too long for IA.");
2785 return ISC_R_NOSPACE
;
2789 /* Fetch the IA_TA contents. */
2790 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2791 ia
, IA_TA_OFFSET
)) {
2792 log_error("reply_process_ia_ta: error evaluating ia");
2793 status
= ISC_R_FAILURE
;
2797 /* Extract IA_TA header contents. */
2798 iaid
= getULong(ia_data
.data
);
2800 /* Create an IA_TA structure. */
2801 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2802 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2803 log_error("reply_process_ia_ta: no memory for ia.");
2804 status
= ISC_R_NOMEMORY
;
2807 reply
->ia
->ia_type
= D6O_IA_TA
;
2809 /* Cache pre-existing IA, if any. */
2810 ia_hash_lookup(&reply
->old_ia
, ia_ta_active
,
2811 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2812 reply
->ia
->iaid_duid
.len
, MDL
);
2815 * Create an option cache to carry the IA_TA option contents, and
2816 * execute any user-supplied values into it.
2818 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2819 status
= ISC_R_NOMEMORY
;
2824 * Temporary leases are dynamic by definition.
2826 reply
->static_lease
= ISC_FALSE
;
2829 * Save the cursor position at the start of the IA, so we can
2830 * set length later. We write a temporary
2831 * header out now just in case we decide to adjust the packet
2832 * within sub-process functions.
2834 ia_cursor
= reply
->cursor
;
2836 /* Initialize the IA_TA header. First the code. */
2837 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_TA
);
2840 /* Then option length. */
2841 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x04u
);
2844 /* Then IA_TA header contents; IAID. */
2845 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2849 * Deal with an IAADDR for lifetimes.
2850 * For all or none, process IAADDRs as hints.
2852 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
2853 reply
->client_valid
= reply
->client_prefer
= 0;
2854 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2855 for (; oc
!= NULL
; oc
= oc
->next
) {
2856 memset(&iaaddr
, 0, sizeof(iaaddr
));
2857 if (!evaluate_option_cache(&iaaddr
, reply
->packet
,
2859 reply
->packet
->options
, NULL
,
2860 &global_scope
, oc
, MDL
) ||
2861 (iaaddr
.len
< IAADDR_OFFSET
)) {
2862 log_error("reply_process_ia_ta: error "
2863 "evaluating IAADDR.");
2864 status
= ISC_R_FAILURE
;
2867 /* The first 16 bytes are the IPv6 address. */
2868 pref_life
= getULong(iaaddr
.data
+ 16);
2869 valid_life
= getULong(iaaddr
.data
+ 20);
2871 if ((reply
->client_valid
== 0) ||
2872 (reply
->client_valid
> valid_life
))
2873 reply
->client_valid
= valid_life
;
2875 if ((reply
->client_prefer
== 0) ||
2876 (reply
->client_prefer
> pref_life
))
2877 reply
->client_prefer
= pref_life
;
2879 /* Nothing more if something has failed. */
2880 if (status
== ISC_R_CANCELED
)
2884 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2885 if (!temporary_is_available(reply
, &tmp_addr
))
2887 status
= reply_process_is_addressed(reply
,
2888 &reply
->lease
->scope
,
2889 reply
->lease
->ipv6_pool
->ipv6_pond
->group
);
2890 if (status
!= ISC_R_SUCCESS
)
2892 status
= reply_process_send_addr(reply
, &tmp_addr
);
2893 if (status
!= ISC_R_SUCCESS
)
2895 if (reply
->lease
!= NULL
)
2896 iasubopt_dereference(&reply
->lease
, MDL
);
2900 /* Rewind the IA_TA to empty. */
2901 option_state_dereference(&reply
->reply_ia
, MDL
);
2902 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2903 status
= ISC_R_NOMEMORY
;
2906 status
= ISC_R_CANCELED
;
2907 reply
->client_resources
= 0;
2908 reply
->resources_included
= ISC_FALSE
;
2909 if (reply
->lease
!= NULL
)
2910 iasubopt_dereference(&reply
->lease
, MDL
);
2915 * Give the client temporary addresses.
2917 if (reply
->client_resources
!= 0)
2919 status
= find_client_temporaries(reply
);
2920 if (status
== ISC_R_NORESOURCES
) {
2921 switch (reply
->packet
->dhcpv6_msg_type
) {
2922 case DHCPV6_SOLICIT
:
2924 * No address for any IA is handled
2929 case DHCPV6_REQUEST
:
2930 /* Section 18.2.1 (Request):
2932 * If the server cannot assign any addresses to
2933 * an IA in the message from the client, the
2934 * server MUST include the IA in the Reply
2935 * message with no addresses in the IA and a
2936 * Status Code option in the IA containing
2937 * status code NoAddrsAvail.
2939 option_state_dereference(&reply
->reply_ia
, MDL
);
2940 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2941 log_error("reply_process_ia_ta: No "
2942 "memory for option state wipe.");
2943 status
= ISC_R_NOMEMORY
;
2947 if (!set_status_code(STATUS_NoAddrsAvail
,
2948 "No addresses available "
2949 "for this interface.",
2951 log_error("reply_process_ia_ta: Unable "
2952 "to set NoAddrsAvail status code.");
2953 status
= ISC_R_FAILURE
;
2957 status
= ISC_R_SUCCESS
;
2962 * We don't want to include the IA if we
2963 * provide zero addresses including zeroed
2966 if (reply
->resources_included
)
2967 status
= ISC_R_SUCCESS
;
2972 } else if (status
!= ISC_R_SUCCESS
)
2976 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2977 sizeof(reply
->buf
) - reply
->cursor
,
2978 reply
->reply_ia
, reply
->packet
,
2979 required_opts_IA
, NULL
);
2981 /* Reset the length of this IA to match what was just written. */
2982 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2983 reply
->cursor
- (ia_cursor
+ 4));
2986 * yes, goto's aren't the best but we also want to avoid extra
2989 if (status
== ISC_R_CANCELED
)
2993 * If we have any addresses log what we are doing.
2995 if (reply
->ia
->num_iasubopt
!= 0) {
2996 struct iasubopt
*tmp
;
2998 char tmp_addr
[INET6_ADDRSTRLEN
];
3000 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3001 tmp
= reply
->ia
->iasubopt
[i
];
3003 log_info("%s TA: address %s to client with duid %s "
3004 "iaid = %d valid for %u seconds",
3005 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
3006 inet_ntop(AF_INET6
, &tmp
->addr
,
3007 tmp_addr
, sizeof(tmp_addr
)),
3008 print_hex_1(reply
->client_id
.len
,
3009 reply
->client_id
.data
, 60),
3016 * For hard bindings we consume the new changes into
3017 * the database (if any have been attached to the ia_ta).
3019 * Loop through the assigned dynamic addresses, referencing the
3020 * leases onto this IA_TA rather than any old ones, and updating
3021 * pool timers for each (if any).
3023 if ((reply
->ia
->num_iasubopt
!= 0) &&
3024 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
3025 struct iasubopt
*tmp
;
3026 struct data_string
*ia_id
;
3029 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3030 tmp
= reply
->ia
->iasubopt
[i
];
3032 if (tmp
->ia
!= NULL
)
3033 ia_dereference(&tmp
->ia
, MDL
);
3034 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
3036 /* Commit 'hard' bindings. */
3037 renew_lease6(tmp
->ipv6_pool
, tmp
);
3038 schedule_lease_timeout(tmp
->ipv6_pool
);
3040 /* If we have anything to do on commit do it now */
3041 if (tmp
->on_star
.on_commit
!= NULL
) {
3042 execute_statements(NULL
, reply
->packet
,
3044 reply
->packet
->options
,
3047 tmp
->on_star
.on_commit
,
3049 executable_statement_dereference
3050 (&tmp
->on_star
.on_commit
, MDL
);
3053 #if defined (NSUPDATE)
3055 * Perform ddns updates.
3057 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3060 evaluate_boolean_option_cache(NULL
, reply
->packet
,
3062 reply
->packet
->options
,
3066 ddns_updates(reply
->packet
, NULL
, NULL
,
3067 tmp
, NULL
, reply
->opt_state
);
3070 /* Do our threshold check. */
3071 check_pool6_threshold(reply
, tmp
);
3074 /* Remove any old ia from the hash. */
3075 if (reply
->old_ia
!= NULL
) {
3076 if (!release_on_roam(reply
)) {
3077 ia_id
= &reply
->old_ia
->iaid_duid
;
3078 ia_hash_delete(ia_ta_active
,
3079 (unsigned char *)ia_id
->data
,
3083 ia_dereference(&reply
->old_ia
, MDL
);
3086 /* Put new ia into the hash. */
3087 reply
->ia
->cltt
= cur_time
;
3088 ia_id
= &reply
->ia
->iaid_duid
;
3089 ia_hash_add(ia_ta_active
, (unsigned char *)ia_id
->data
,
3090 ia_id
->len
, reply
->ia
, MDL
);
3092 write_ia(reply
->ia
);
3094 schedule_lease_timeout_reply(reply
);
3098 if (packet_ia
!= NULL
)
3099 option_state_dereference(&packet_ia
, MDL
);
3100 if (iaaddr
.data
!= NULL
)
3101 data_string_forget(&iaaddr
, MDL
);
3102 if (reply
->reply_ia
!= NULL
)
3103 option_state_dereference(&reply
->reply_ia
, MDL
);
3104 if (ia_data
.data
!= NULL
)
3105 data_string_forget(&ia_data
, MDL
);
3106 if (data
.data
!= NULL
)
3107 data_string_forget(&data
, MDL
);
3108 if (reply
->ia
!= NULL
)
3109 ia_dereference(&reply
->ia
, MDL
);
3110 if (reply
->old_ia
!= NULL
)
3111 ia_dereference(&reply
->old_ia
, MDL
);
3112 if (reply
->lease
!= NULL
)
3113 iasubopt_dereference(&reply
->lease
, MDL
);
3116 * ISC_R_CANCELED is a status code used by the addr processing to
3117 * indicate we're replying with other addresses. This is still a
3118 * success at higher layers.
3120 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
3124 * Verify the temporary address is available.
3126 static isc_boolean_t
3127 temporary_is_available(struct reply_state
*reply
, struct iaddr
*addr
) {
3128 struct in6_addr tmp_addr
;
3129 struct subnet
*subnet
;
3130 struct ipv6_pool
*pool
= NULL
;
3131 struct ipv6_pond
*pond
= NULL
;
3134 memcpy(&tmp_addr
, addr
->iabuf
, sizeof(tmp_addr
));
3136 * Clients may choose to send :: as an address, with the idea to give
3137 * hints about preferred-lifetime or valid-lifetime.
3138 * So this is not a request for this address.
3140 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
))
3144 * Verify that this address is on the client's network.
3146 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
3147 subnet
= subnet
->next_sibling
) {
3148 if (addr_eq(subnet_number(*addr
, subnet
->netmask
),
3153 /* Address not found on shared network. */
3158 * Check if this address is owned (must be before next step).
3160 if (address_is_owned(reply
, addr
))
3164 * Verify that this address is in a temporary pool and try to get it.
3166 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3167 if (((pond
->prohibit_list
!= NULL
) &&
3168 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3169 ((pond
->permit_list
!= NULL
) &&
3170 (!permitted(reply
->packet
, pond
->permit_list
))))
3173 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3174 if (pool
->pool_type
!= D6O_IA_TA
)
3177 if (ipv6_in_pool(&tmp_addr
, pool
))
3187 if (lease6_exists(pool
, &tmp_addr
))
3189 if (iasubopt_allocate(&reply
->lease
, MDL
) != ISC_R_SUCCESS
)
3191 reply
->lease
->addr
= tmp_addr
;
3192 reply
->lease
->plen
= 0;
3193 /* Default is soft binding for 2 minutes. */
3194 if (add_lease6(pool
, reply
->lease
, cur_time
+ 120) != ISC_R_SUCCESS
)
3201 * Get a temporary address per prefix.
3204 find_client_temporaries(struct reply_state
*reply
) {
3206 struct ipv6_pool
*p
= NULL
;
3207 struct ipv6_pond
*pond
;
3208 isc_result_t status
= ISC_R_NORESOURCES
;;
3209 unsigned int attempts
;
3210 struct iaddr send_addr
;
3213 * Do a quick walk through of the ponds and pools
3214 * to see if we have any prefix pools
3216 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3217 if (pond
->ipv6_pools
== NULL
)
3220 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3221 if (p
->pool_type
== D6O_IA_TA
)
3228 /* If we get here and p is NULL we have no useful pools */
3230 log_debug("Unable to get client addresses: "
3231 "no IPv6 pools on this shared network");
3232 return ISC_R_NORESOURCES
;
3236 * We have at least one pool that could provide an address
3237 * Now we walk through the ponds and pools again and check
3238 * to see if the client is permitted and if an address is
3242 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3243 if (((pond
->prohibit_list
!= NULL
) &&
3244 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3245 ((pond
->permit_list
!= NULL
) &&
3246 (!permitted(reply
->packet
, pond
->permit_list
))))
3249 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3250 if (p
->pool_type
!= D6O_IA_TA
) {
3255 * Get an address in this temporary pool.
3257 status
= create_lease6(p
, &reply
->lease
, &attempts
,
3261 if (status
!= ISC_R_SUCCESS
) {
3262 log_debug("Unable to get a temporary address.");
3266 status
= reply_process_is_addressed(reply
,
3267 &reply
->lease
->scope
,
3269 if (status
!= ISC_R_SUCCESS
) {
3273 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3274 status
= reply_process_send_addr(reply
, &send_addr
);
3275 if (status
!= ISC_R_SUCCESS
) {
3279 * reply->lease can't be null as we use it above
3280 * add check if that changes
3282 iasubopt_dereference(&reply
->lease
, MDL
);
3287 if (reply
->lease
!= NULL
) {
3288 iasubopt_dereference(&reply
->lease
, MDL
);
3294 * This function only returns failure on 'hard' failures. If it succeeds,
3295 * it will leave a lease structure behind.
3298 reply_process_try_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3299 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
3300 struct ipv6_pool
*pool
= NULL
;
3301 struct ipv6_pond
*pond
= NULL
;
3303 struct data_string data_addr
;
3305 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
3306 (addr
== NULL
) || (reply
->lease
!= NULL
))
3307 return (DHCP_R_INVALIDARG
);
3310 * Do a quick walk through of the ponds and pools
3311 * to see if we have any NA address pools
3313 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3314 if (pond
->ipv6_pools
== NULL
)
3317 for (i
= 0; ; i
++) {
3318 pool
= pond
->ipv6_pools
[i
];
3319 if ((pool
== NULL
) ||
3320 (pool
->pool_type
== D6O_IA_NA
))
3327 /* If we get here and p is NULL we have no useful pools */
3329 return (ISC_R_ADDRNOTAVAIL
);
3332 memset(&data_addr
, 0, sizeof(data_addr
));
3333 data_addr
.len
= addr
->len
;
3334 data_addr
.data
= addr
->iabuf
;
3337 * We have at least one pool that could provide an address
3338 * Now we walk through the ponds and pools again and check
3339 * to see if the client is permitted and if an address is
3342 * Within a given pond we start looking at the last pool we
3343 * allocated from, unless it had a collision trying to allocate
3344 * an address. This will tend to move us into less-filled pools.
3347 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3348 if (((pond
->prohibit_list
!= NULL
) &&
3349 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3350 ((pond
->permit_list
!= NULL
) &&
3351 (!permitted(reply
->packet
, pond
->permit_list
))))
3354 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3355 if (pool
->pool_type
!= D6O_IA_NA
)
3358 status
= try_client_v6_address(&reply
->lease
, pool
,
3360 if (status
== ISC_R_SUCCESS
)
3364 if (status
== ISC_R_SUCCESS
)
3368 /* Note that this is just pedantry. There is no allocation to free. */
3369 data_string_forget(&data_addr
, MDL
);
3370 /* Return just the most recent status... */
3374 /* Look around for an address to give the client. First, look through the
3375 * old IA for addresses we can extend. Second, try to allocate a new address.
3376 * Finally, actually add that address into the current reply IA.
3379 find_client_address(struct reply_state
*reply
) {
3380 struct iaddr send_addr
;
3381 isc_result_t status
= ISC_R_NORESOURCES
;
3382 struct iasubopt
*lease
, *best_lease
= NULL
;
3383 struct binding_scope
**scope
;
3384 struct group
*group
;
3387 if (reply
->static_lease
) {
3388 if (reply
->host
== NULL
)
3389 return DHCP_R_INVALIDARG
;
3392 memcpy(send_addr
.iabuf
, reply
->fixed
.data
, 16);
3394 scope
= &global_scope
;
3395 group
= reply
->subnet
->group
;
3399 if (reply
->old_ia
!= NULL
) {
3400 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3401 struct shared_network
*candidate_shared
;
3402 struct ipv6_pond
*pond
;
3404 lease
= reply
->old_ia
->iasubopt
[i
];
3405 candidate_shared
= lease
->ipv6_pool
->shared_network
;
3406 pond
= lease
->ipv6_pool
->ipv6_pond
;
3409 * Look for the best lease on the client's shared
3410 * network, that is still permitted
3413 if ((candidate_shared
!= reply
->shared
) ||
3414 (lease6_usable(lease
) != ISC_TRUE
))
3417 if (((pond
->prohibit_list
!= NULL
) &&
3418 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3419 ((pond
->permit_list
!= NULL
) &&
3420 (!permitted(reply
->packet
, pond
->permit_list
))))
3423 best_lease
= lease_compare(lease
, best_lease
);
3427 /* Try to pick a new address if we didn't find one, or if we found an
3430 if ((best_lease
== NULL
) || (best_lease
->state
== FTS_ABANDONED
)) {
3431 status
= pick_v6_address(reply
);
3432 } else if (best_lease
!= NULL
) {
3433 iasubopt_reference(&reply
->lease
, best_lease
, MDL
);
3434 status
= ISC_R_SUCCESS
;
3437 /* Pick the abandoned lease as a last resort. */
3438 if ((status
== ISC_R_NORESOURCES
) && (best_lease
!= NULL
)) {
3439 /* I don't see how this is supposed to be done right now. */
3440 log_error("Best match for DUID %s is an abandoned address,"
3441 " This may be a result of multiple clients attempting"
3442 " to use this DUID",
3443 print_hex_1(reply
->client_id
.len
,
3444 reply
->client_id
.data
, 60));
3445 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
3448 /* Give up now if we didn't find a lease. */
3449 if (status
!= ISC_R_SUCCESS
)
3452 if (reply
->lease
== NULL
)
3453 log_fatal("Impossible condition at %s:%d.", MDL
);
3455 /* Draw binding scopes from the lease's binding scope, and config
3456 * from the lease's containing subnet and higher. Note that it may
3457 * be desirable to place the group attachment directly in the pool.
3459 scope
= &reply
->lease
->scope
;
3460 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
3463 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3466 status
= reply_process_is_addressed(reply
, scope
, group
);
3467 if (status
!= ISC_R_SUCCESS
)
3470 status
= reply_process_send_addr(reply
, &send_addr
);
3474 /* Once an address is found for a client, perform several common functions;
3475 * Calculate and store valid and preferred lease times, draw client options
3476 * into the option state.
3479 reply_process_is_addressed(struct reply_state
*reply
,
3480 struct binding_scope
**scope
, struct group
*group
)
3482 isc_result_t status
= ISC_R_SUCCESS
;
3483 struct data_string data
;
3484 struct option_cache
*oc
;
3485 struct option_state
*tmp_options
= NULL
;
3486 struct on_star
*on_star
;
3489 /* Initialize values we will cleanup. */
3490 memset(&data
, 0, sizeof(data
));
3493 * Find the proper on_star block to use. We use the
3494 * one in the lease if we have a lease or the one in
3495 * the reply if we don't have a lease because this is
3499 on_star
= &reply
->lease
->on_star
;
3501 on_star
= &reply
->on_star
;
3505 * Bring in the root configuration. We only do this to bring
3506 * in the on * statements, as we didn't have the lease available
3507 * we did it the first time.
3509 option_state_allocate(&tmp_options
, MDL
);
3510 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3511 reply
->packet
->options
, tmp_options
,
3512 &global_scope
, root_group
, NULL
,
3514 if (tmp_options
!= NULL
) {
3515 option_state_dereference(&tmp_options
, MDL
);
3519 * Bring configured options into the root packet level cache - start
3520 * with the lease's closest enclosing group (passed in by the caller
3523 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3524 reply
->packet
->options
, reply
->opt_state
,
3525 scope
, group
, root_group
, on_star
);
3527 /* Execute statements from class scopes. */
3528 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3529 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3530 reply
->packet
->options
,
3531 reply
->opt_state
, scope
,
3532 reply
->packet
->classes
[i
- 1]->group
,
3537 * If there is a host record, over-ride with values configured there,
3538 * without re-evaluating configuration from the previously executed
3539 * group or its common enclosers.
3541 if (reply
->host
!= NULL
)
3542 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3543 reply
->packet
->options
,
3544 reply
->opt_state
, scope
,
3545 reply
->host
->group
, group
,
3548 /* Determine valid lifetime. */
3549 if (reply
->client_valid
== 0)
3550 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
3552 reply
->send_valid
= reply
->client_valid
;
3554 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3555 SV_DEFAULT_LEASE_TIME
);
3557 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3558 reply
->packet
->options
,
3562 log_error("reply_process_is_addressed: unable to "
3563 "evaluate default lease time");
3564 status
= ISC_R_FAILURE
;
3568 reply
->send_valid
= getULong(data
.data
);
3569 data_string_forget(&data
, MDL
);
3572 /* Check to see if the lease time would cause us to wrap
3573 * in which case we make it infinite.
3574 * The following doesn't work on at least some systems:
3575 * (cur_time + reply->send_valid < cur_time)
3577 if (reply
->send_valid
!= INFINITE_TIME
) {
3578 time_t test_time
= cur_time
+ reply
->send_valid
;
3579 if (test_time
< cur_time
)
3580 reply
->send_valid
= INFINITE_TIME
;
3583 if (reply
->client_prefer
== 0)
3584 reply
->send_prefer
= reply
->send_valid
;
3586 reply
->send_prefer
= reply
->client_prefer
;
3588 if ((reply
->send_prefer
>= reply
->send_valid
) &&
3589 (reply
->send_valid
!= INFINITE_TIME
))
3590 reply
->send_prefer
= (reply
->send_valid
/ 2) +
3591 (reply
->send_valid
/ 8);
3593 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3594 SV_PREFER_LIFETIME
);
3596 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3597 reply
->packet
->options
,
3601 log_error("reply_process_is_addressed: unable to "
3602 "evaluate preferred lease time");
3603 status
= ISC_R_FAILURE
;
3607 reply
->send_prefer
= getULong(data
.data
);
3608 data_string_forget(&data
, MDL
);
3611 /* Note lowest values for later calculation of renew/rebind times. */
3612 if (reply
->min_prefer
> reply
->send_prefer
)
3613 reply
->min_prefer
= reply
->send_prefer
;
3615 if (reply
->min_valid
> reply
->send_valid
)
3616 reply
->min_valid
= reply
->send_valid
;
3620 * XXX: Old 4.0.0 alpha code would change the host {} record
3621 * XXX: uid upon lease assignment. This was intended to cover the
3622 * XXX: case where a client first identifies itself using vendor
3623 * XXX: options in a solicit, or request, but later neglects to include
3624 * XXX: these options in a Renew or Rebind. It is not clear that this
3625 * XXX: is required, and has some startling ramifications (such as
3626 * XXX: how to recover this dynamic host {} state across restarts).
3628 if (reply
->host
!= NULL
)
3629 change_host_uid(host
, reply
->client_id
->data
,
3630 reply
->client_id
->len
);
3633 /* Perform dynamic lease related update work. */
3634 if (reply
->lease
!= NULL
) {
3635 /* Cached lifetimes */
3636 reply
->lease
->prefer
= reply
->send_prefer
;
3637 reply
->lease
->valid
= reply
->send_valid
;
3639 /* Advance (or rewind) the valid lifetime.
3640 * In the protocol 0xFFFFFFFF is infinite
3641 * when connecting to the lease file MAX_TIME is
3643 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
3644 if (reply
->send_valid
== INFINITE_TIME
) {
3645 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
3647 reply
->lease
->soft_lifetime_end_time
=
3648 cur_time
+ reply
->send_valid
;
3650 /* Wait before renew! */
3653 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
3654 if (status
!= ISC_R_SUCCESS
) {
3655 log_fatal("reply_process_is_addressed: Unable to "
3656 "attach lease to new IA: %s",
3657 isc_result_totext(status
));
3661 * If this is a new lease, make sure it is attached somewhere.
3663 if (reply
->lease
->ia
== NULL
) {
3664 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
3668 /* Bring a copy of the relevant options into the IA scope. */
3669 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3670 reply
->packet
->options
, reply
->reply_ia
,
3671 scope
, group
, root_group
, NULL
);
3673 /* Execute statements from class scopes. */
3674 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3675 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3676 reply
->packet
->options
,
3677 reply
->reply_ia
, scope
,
3678 reply
->packet
->classes
[i
- 1]->group
,
3683 * And bring in host record configuration, if any, but not to overlap
3684 * the previous group or its common enclosers.
3686 if (reply
->host
!= NULL
)
3687 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3688 reply
->packet
->options
,
3689 reply
->reply_ia
, scope
,
3690 reply
->host
->group
, group
, NULL
);
3693 if (data
.data
!= NULL
)
3694 data_string_forget(&data
, MDL
);
3696 if (status
== ISC_R_SUCCESS
)
3697 reply
->client_resources
++;
3702 /* Simply send an IAADDR within the IA scope as described. */
3704 reply_process_send_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3705 isc_result_t status
= ISC_R_SUCCESS
;
3706 struct data_string data
;
3708 memset(&data
, 0, sizeof(data
));
3710 /* Now append the lease. */
3711 data
.len
= IAADDR_OFFSET
;
3712 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
3713 log_error("reply_process_send_addr: out of memory"
3714 "allocating new IAADDR buffer.");
3715 status
= ISC_R_NOMEMORY
;
3718 data
.data
= data
.buffer
->data
;
3720 memcpy(data
.buffer
->data
, addr
->iabuf
, 16);
3721 putULong(data
.buffer
->data
+ 16, reply
->send_prefer
);
3722 putULong(data
.buffer
->data
+ 20, reply
->send_valid
);
3724 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
3725 data
.buffer
, data
.buffer
->data
,
3726 data
.len
, D6O_IAADDR
, 0)) {
3727 log_error("reply_process_send_addr: unable "
3728 "to save IAADDR option");
3729 status
= ISC_R_FAILURE
;
3733 reply
->resources_included
= ISC_TRUE
;
3736 if (data
.data
!= NULL
)
3737 data_string_forget(&data
, MDL
);
3742 /* Choose the better of two leases. */
3743 static struct iasubopt
*
3744 lease_compare(struct iasubopt
*alpha
, struct iasubopt
*beta
) {
3750 switch(alpha
->state
) {
3752 switch(beta
->state
) {
3754 /* Choose the lease with the longest lifetime (most
3755 * likely the most recently allocated).
3757 if (alpha
->hard_lifetime_end_time
<
3758 beta
->hard_lifetime_end_time
)
3768 log_fatal("Impossible condition at %s:%d.", MDL
);
3773 switch (beta
->state
) {
3778 /* Choose the most recently expired lease. */
3779 if (alpha
->hard_lifetime_end_time
<
3780 beta
->hard_lifetime_end_time
)
3782 else if ((alpha
->hard_lifetime_end_time
==
3783 beta
->hard_lifetime_end_time
) &&
3784 (alpha
->soft_lifetime_end_time
<
3785 beta
->soft_lifetime_end_time
))
3794 log_fatal("Impossible condition at %s:%d.", MDL
);
3799 switch (beta
->state
) {
3805 /* Choose the lease that was abandoned longest ago. */
3806 if (alpha
->hard_lifetime_end_time
<
3807 beta
->hard_lifetime_end_time
)
3813 log_fatal("Impossible condition at %s:%d.", MDL
);
3818 log_fatal("Impossible condition at %s:%d.", MDL
);
3821 log_fatal("Triple impossible condition at %s:%d.", MDL
);
3825 /* Process a client-supplied IA_PD. This may append options to the tail of
3826 * the reply packet being built in the reply_state structure.
3829 reply_process_ia_pd(struct reply_state
*reply
, struct option_cache
*ia
) {
3830 isc_result_t status
= ISC_R_SUCCESS
;
3833 struct option_state
*packet_ia
;
3834 struct option_cache
*oc
;
3835 struct data_string ia_data
, data
;
3837 /* Initialize values that will get cleaned up on return. */
3839 memset(&ia_data
, 0, sizeof(ia_data
));
3840 memset(&data
, 0, sizeof(data
));
3842 * Note that find_client_prefix() may set reply->lease.
3845 /* Make sure there is at least room for the header. */
3846 if ((reply
->cursor
+ IA_PD_OFFSET
+ 4) > sizeof(reply
->buf
)) {
3847 log_error("reply_process_ia_pd: Reply too long for IA.");
3848 return ISC_R_NOSPACE
;
3852 /* Fetch the IA_PD contents. */
3853 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
3854 ia
, IA_PD_OFFSET
)) {
3855 log_error("reply_process_ia_pd: error evaluating ia");
3856 status
= ISC_R_FAILURE
;
3860 /* Extract IA_PD header contents. */
3861 iaid
= getULong(ia_data
.data
);
3862 reply
->renew
= getULong(ia_data
.data
+ 4);
3863 reply
->rebind
= getULong(ia_data
.data
+ 8);
3865 /* Create an IA_PD structure. */
3866 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
3867 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
3868 log_error("reply_process_ia_pd: no memory for ia.");
3869 status
= ISC_R_NOMEMORY
;
3872 reply
->ia
->ia_type
= D6O_IA_PD
;
3874 /* Cache pre-existing IA_PD, if any. */
3875 ia_hash_lookup(&reply
->old_ia
, ia_pd_active
,
3876 (unsigned char *)reply
->ia
->iaid_duid
.data
,
3877 reply
->ia
->iaid_duid
.len
, MDL
);
3880 * Create an option cache to carry the IA_PD option contents, and
3881 * execute any user-supplied values into it.
3883 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
3884 status
= ISC_R_NOMEMORY
;
3888 /* Check & count the fixed prefix host records. */
3889 reply
->static_prefixes
= 0;
3890 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_prefix
!= NULL
)) {
3891 struct iaddrcidrnetlist
*fp
;
3893 for (fp
= reply
->host
->fixed_prefix
; fp
!= NULL
;
3895 reply
->static_prefixes
+= 1;
3900 * Save the cursor position at the start of the IA_PD, so we can
3901 * set length and adjust t1/t2 values later. We write a temporary
3902 * header out now just in case we decide to adjust the packet
3903 * within sub-process functions.
3905 ia_cursor
= reply
->cursor
;
3907 /* Initialize the IA_PD header. First the code. */
3908 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_PD
);
3911 /* Then option length. */
3912 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
3915 /* Then IA_PD header contents; IAID. */
3916 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
3919 /* We store the client's t1 for now, and may over-ride it later. */
3920 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
3923 /* We store the client's t2 for now, and may over-ride it later. */
3924 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
3928 * For each prefix in this IA_PD, decide what to do about it.
3930 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAPREFIX
);
3931 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
3932 reply
->client_valid
= reply
->client_prefer
= 0;
3933 reply
->preflen
= -1;
3934 for (; oc
!= NULL
; oc
= oc
->next
) {
3935 status
= reply_process_prefix(reply
, oc
);
3938 * Canceled means we did not allocate prefixes to the
3939 * client, but we're "done" with this IA - we set a status
3940 * code. So transmit this reply, e.g., move on to the next
3943 if (status
== ISC_R_CANCELED
)
3946 if ((status
!= ISC_R_SUCCESS
) &&
3947 (status
!= ISC_R_ADDRINUSE
) &&
3948 (status
!= ISC_R_ADDRNOTAVAIL
))
3955 * If we fell through the above and never gave the client
3956 * a prefix, give it one now.
3958 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
3959 status
= find_client_prefix(reply
);
3961 if (status
== ISC_R_NORESOURCES
) {
3962 switch (reply
->packet
->dhcpv6_msg_type
) {
3963 case DHCPV6_SOLICIT
:
3965 * No prefix for any IA is handled
3970 case DHCPV6_REQUEST
:
3971 /* Same than for addresses. */
3972 option_state_dereference(&reply
->reply_ia
, MDL
);
3973 if (!option_state_allocate(&reply
->reply_ia
,
3976 log_error("reply_process_ia_pd: No "
3977 "memory for option state "
3979 status
= ISC_R_NOMEMORY
;
3983 if (!set_status_code(STATUS_NoPrefixAvail
,
3984 "No prefixes available "
3985 "for this interface.",
3987 log_error("reply_process_ia_pd: "
3989 "NoPrefixAvail status "
3991 status
= ISC_R_FAILURE
;
3995 status
= ISC_R_SUCCESS
;
3999 if (reply
->resources_included
)
4000 status
= ISC_R_SUCCESS
;
4007 if (status
!= ISC_R_SUCCESS
)
4011 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
4012 sizeof(reply
->buf
) - reply
->cursor
,
4013 reply
->reply_ia
, reply
->packet
,
4014 required_opts_IA_PD
, NULL
);
4016 /* Reset the length of this IA_PD to match what was just written. */
4017 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
4018 reply
->cursor
- (ia_cursor
+ 4));
4020 /* Calculate T1/T2 and stuff them in the reply */
4021 set_reply_tee_times(reply
, ia_cursor
);
4024 * yes, goto's aren't the best but we also want to avoid extra
4027 if (status
== ISC_R_CANCELED
)
4031 * Handle static prefixes, we always log stuff and if it's
4032 * a hard binding we run any commit statements that we have
4034 if (reply
->static_prefixes
!= 0) {
4035 char tmp_addr
[INET6_ADDRSTRLEN
];
4036 log_info("%s PD: address %s/%d to client with duid %s "
4038 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
4039 inet_ntop(AF_INET6
, reply
->fixed_pref
.lo_addr
.iabuf
,
4040 tmp_addr
, sizeof(tmp_addr
)),
4041 reply
->fixed_pref
.bits
,
4042 print_hex_1(reply
->client_id
.len
,
4043 reply
->client_id
.data
, 60),
4045 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
4046 (reply
->on_star
.on_commit
!= NULL
)) {
4047 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
4048 reply
->packet
->options
,
4050 NULL
, reply
->on_star
.on_commit
,
4052 executable_statement_dereference
4053 (&reply
->on_star
.on_commit
, MDL
);
4059 * If we have any addresses log what we are doing.
4061 if (reply
->ia
->num_iasubopt
!= 0) {
4062 struct iasubopt
*tmp
;
4064 char tmp_addr
[INET6_ADDRSTRLEN
];
4066 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
4067 tmp
= reply
->ia
->iasubopt
[i
];
4069 log_info("%s PD: address %s/%d to client with duid %s"
4070 " iaid = %d valid for %u seconds",
4071 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
4072 inet_ntop(AF_INET6
, &tmp
->addr
,
4073 tmp_addr
, sizeof(tmp_addr
)),
4075 print_hex_1(reply
->client_id
.len
,
4076 reply
->client_id
.data
, 60),
4082 * If this is not a 'soft' binding, consume the new changes into
4083 * the database (if any have been attached to the ia_pd).
4085 * Loop through the assigned dynamic prefixes, referencing the
4086 * prefixes onto this IA_PD rather than any old ones, and updating
4087 * prefix pool timers for each (if any).
4089 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
4090 (reply
->ia
->num_iasubopt
!= 0)) {
4091 struct iasubopt
*tmp
;
4092 struct data_string
*ia_id
;
4095 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
4096 tmp
= reply
->ia
->iasubopt
[i
];
4098 if (tmp
->ia
!= NULL
)
4099 ia_dereference(&tmp
->ia
, MDL
);
4100 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
4102 /* Commit 'hard' bindings. */
4103 renew_lease6(tmp
->ipv6_pool
, tmp
);
4104 schedule_lease_timeout(tmp
->ipv6_pool
);
4106 /* If we have anything to do on commit do it now */
4107 if (tmp
->on_star
.on_commit
!= NULL
) {
4108 execute_statements(NULL
, reply
->packet
,
4110 reply
->packet
->options
,
4113 tmp
->on_star
.on_commit
,
4115 executable_statement_dereference
4116 (&tmp
->on_star
.on_commit
, MDL
);
4119 /* Do our threshold check. */
4120 check_pool6_threshold(reply
, tmp
);
4123 /* Remove any old ia from the hash. */
4124 if (reply
->old_ia
!= NULL
) {
4125 if (!release_on_roam(reply
)) {
4126 ia_id
= &reply
->old_ia
->iaid_duid
;
4127 ia_hash_delete(ia_pd_active
,
4128 (unsigned char *)ia_id
->data
,
4132 ia_dereference(&reply
->old_ia
, MDL
);
4135 /* Put new ia into the hash. */
4136 reply
->ia
->cltt
= cur_time
;
4137 ia_id
= &reply
->ia
->iaid_duid
;
4138 ia_hash_add(ia_pd_active
, (unsigned char *)ia_id
->data
,
4139 ia_id
->len
, reply
->ia
, MDL
);
4141 write_ia(reply
->ia
);
4143 schedule_lease_timeout_reply(reply
);
4147 if (packet_ia
!= NULL
)
4148 option_state_dereference(&packet_ia
, MDL
);
4149 if (reply
->reply_ia
!= NULL
)
4150 option_state_dereference(&reply
->reply_ia
, MDL
);
4151 if (ia_data
.data
!= NULL
)
4152 data_string_forget(&ia_data
, MDL
);
4153 if (data
.data
!= NULL
)
4154 data_string_forget(&data
, MDL
);
4155 if (reply
->ia
!= NULL
)
4156 ia_dereference(&reply
->ia
, MDL
);
4157 if (reply
->old_ia
!= NULL
)
4158 ia_dereference(&reply
->old_ia
, MDL
);
4159 if (reply
->lease
!= NULL
)
4160 iasubopt_dereference(&reply
->lease
, MDL
);
4161 if (reply
->on_star
.on_expiry
!= NULL
)
4162 executable_statement_dereference
4163 (&reply
->on_star
.on_expiry
, MDL
);
4164 if (reply
->on_star
.on_release
!= NULL
)
4165 executable_statement_dereference
4166 (&reply
->on_star
.on_release
, MDL
);
4169 * ISC_R_CANCELED is a status code used by the prefix processing to
4170 * indicate we're replying with a status code. This is still a
4171 * success at higher layers.
4173 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
4178 * \brief Find the proper scoping group for use with a v6 static prefix.
4180 * We start by trying to find a subnet based on the given prefix and
4181 * the shared network. If we don't find one then the prefix has been
4182 * declared outside of any subnets. If there is a static address
4183 * associated with the host we use it to try and find a subnet (this
4184 * should succeed). If there isn't a static address we fall back
4185 * to the shared subnet itself.
4186 * Once we have a subnet we extract the group from it and return it.
4188 * \param reply - the reply structure we use to collect information
4189 * we will use the fields shared, fixed_pref and host
4190 * from the structure
4192 * \return a pointer to the group structure to use for scoping
4195 static struct group
*
4196 find_group_by_prefix(struct reply_state
*reply
) {
4197 /* default group if we don't find anything better */
4198 struct group
*group
= reply
->shared
->group
;
4199 struct subnet
*subnet
= NULL
;
4200 struct iaddr tmp_addr
;
4201 struct data_string fixed_addr
;
4203 /* Try with the prefix first */
4204 if (find_grouped_subnet(&subnet
, reply
->shared
,
4205 reply
->fixed_pref
.lo_addr
, MDL
) != 0) {
4206 group
= subnet
->group
;
4207 subnet_dereference(&subnet
, MDL
);
4211 /* Didn't find a subnet via prefix, what about fixed address */
4212 /* The caller has already tested reply->host != NULL */
4214 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
4216 if ((reply
->host
->fixed_addr
!= NULL
) &&
4217 (evaluate_option_cache(&fixed_addr
, NULL
, NULL
, NULL
,
4218 NULL
, NULL
, &global_scope
,
4219 reply
->host
->fixed_addr
, MDL
))) {
4220 if (fixed_addr
.len
>= 16) {
4222 memcpy(tmp_addr
.iabuf
, fixed_addr
.data
, 16);
4223 if (find_grouped_subnet(&subnet
, reply
->shared
,
4224 tmp_addr
, MDL
) != 0) {
4225 group
= subnet
->group
;
4226 subnet_dereference(&subnet
, MDL
);
4229 data_string_forget(&fixed_addr
, MDL
);
4232 /* return whatever we got */
4237 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
4238 * contents into the reply's current ia_pd-scoped option cache. Returns
4239 * ISC_R_CANCELED in the event we are replying with a status code and do
4240 * not wish to process more IAPREFIXes within this IA_PD.
4243 reply_process_prefix(struct reply_state
*reply
, struct option_cache
*pref
) {
4244 u_int32_t pref_life
, valid_life
;
4245 struct binding_scope
**scope
;
4246 struct iaddrcidrnet tmp_pref
;
4247 struct option_cache
*oc
;
4248 struct data_string iapref
, data
;
4249 isc_result_t status
= ISC_R_SUCCESS
;
4250 struct group
*group
;
4252 /* Initializes values that will be cleaned up. */
4253 memset(&iapref
, 0, sizeof(iapref
));
4254 memset(&data
, 0, sizeof(data
));
4255 /* Note that reply->lease may be set by prefix_is_owned() */
4258 * There is no point trying to process an incoming prefix if there
4259 * is no room for an outgoing prefix.
4261 if ((reply
->cursor
+ 29) > sizeof(reply
->buf
)) {
4262 log_error("reply_process_prefix: Out of room for prefix.");
4263 return ISC_R_NOSPACE
;
4266 /* Extract this IAPREFIX option. */
4267 if (!evaluate_option_cache(&iapref
, reply
->packet
, NULL
, NULL
,
4268 reply
->packet
->options
, NULL
, &global_scope
,
4270 (iapref
.len
< IAPREFIX_OFFSET
)) {
4271 log_error("reply_process_prefix: error evaluating IAPREFIX.");
4272 status
= ISC_R_FAILURE
;
4277 * Layout: preferred and valid lifetimes followed by the prefix
4278 * length and the IPv6 address.
4280 pref_life
= getULong(iapref
.data
);
4281 valid_life
= getULong(iapref
.data
+ 4);
4283 if ((reply
->client_valid
== 0) ||
4284 (reply
->client_valid
> valid_life
))
4285 reply
->client_valid
= valid_life
;
4287 if ((reply
->client_prefer
== 0) ||
4288 (reply
->client_prefer
> pref_life
))
4289 reply
->client_prefer
= pref_life
;
4292 * Clients may choose to send ::/0 as a prefix, with the idea to give
4293 * hints about preferred-lifetime or valid-lifetime.
4295 tmp_pref
.lo_addr
.len
= 16;
4296 memset(tmp_pref
.lo_addr
.iabuf
, 0, 16);
4297 if ((iapref
.data
[8] == 0) &&
4298 (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0)) {
4299 /* Status remains success; we just ignore this one. */
4304 * Clients may choose to send ::/X as a prefix to specify a
4305 * preferred/requested prefix length. Note X is never zero here.
4307 tmp_pref
.bits
= (int) iapref
.data
[8];
4308 if (reply
->preflen
< 0) {
4309 /* Cache the first preferred prefix length. */
4310 reply
->preflen
= tmp_pref
.bits
;
4312 if (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0) {
4316 memcpy(tmp_pref
.lo_addr
.iabuf
, iapref
.data
+ 9, 16);
4318 /* Verify the prefix belongs to the client. */
4319 if (!prefix_is_owned(reply
, &tmp_pref
)) {
4320 /* Same than for addresses. */
4321 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
4322 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
4323 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
4324 status
= reply_process_try_prefix(reply
, &tmp_pref
);
4326 /* Either error out or skip this prefix. */
4327 if ((status
!= ISC_R_SUCCESS
) &&
4328 (status
!= ISC_R_ADDRINUSE
) &&
4329 (status
!= ISC_R_ADDRNOTAVAIL
))
4332 if (reply
->lease
== NULL
) {
4333 if (reply
->packet
->dhcpv6_msg_type
==
4335 reply
->send_prefer
= 0;
4336 reply
->send_valid
= 0;
4340 /* status remains success - ignore */
4344 * RFC3633 section 18.2.3:
4346 * If the delegating router cannot find a binding
4347 * for the requesting router's IA_PD the delegating
4348 * router returns the IA_PD containing no prefixes
4349 * with a Status Code option set to NoBinding in the
4352 * On mismatch we (ab)use this pretending we have not the IA
4353 * as soon as we have not a prefix.
4355 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
4356 /* Rewind the IA_PD to empty. */
4357 option_state_dereference(&reply
->reply_ia
, MDL
);
4358 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
4359 log_error("reply_process_prefix: No memory "
4360 "for option state wipe.");
4361 status
= ISC_R_NOMEMORY
;
4365 /* Append a NoBinding status code. */
4366 if (!set_status_code(STATUS_NoBinding
,
4367 "Prefix not bound to this "
4368 "interface.", reply
->reply_ia
)) {
4369 log_error("reply_process_prefix: Unable to "
4370 "attach status code.");
4371 status
= ISC_R_FAILURE
;
4375 /* Fin (no more IAPREFIXes). */
4376 status
= ISC_R_CANCELED
;
4379 log_error("It is impossible to lease a client that is "
4380 "not sending a solicit, request, renew, or "
4382 status
= ISC_R_FAILURE
;
4387 if (reply
->static_prefixes
> 0) {
4388 if (reply
->host
== NULL
)
4389 log_fatal("Impossible condition at %s:%d.", MDL
);
4391 scope
= &global_scope
;
4393 /* Copy the static prefix for logging and finding the group */
4394 memcpy(&reply
->fixed_pref
, &tmp_pref
, sizeof(tmp_pref
));
4396 /* Try to find a group for the static prefix */
4397 group
= find_group_by_prefix(reply
);
4399 if (reply
->lease
== NULL
)
4400 log_fatal("Impossible condition at %s:%d.", MDL
);
4402 scope
= &reply
->lease
->scope
;
4403 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4407 * If client_resources is nonzero, then the reply_process_is_prefixed
4408 * function has executed configuration state into the reply option
4409 * cache. We will use that valid cache to derive configuration for
4410 * whether or not to engage in additional prefixes, and similar.
4412 if (reply
->client_resources
!= 0) {
4416 * Does this client have "enough" prefixes already? Default
4417 * to one. Everybody gets one, and one should be enough for
4420 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4421 SV_LIMIT_PREFS_PER_IA
);
4423 if (!evaluate_option_cache(&data
, reply
->packet
,
4425 reply
->packet
->options
,
4429 log_error("reply_process_prefix: unable to "
4430 "evaluate prefs-per-ia value.");
4431 status
= ISC_R_FAILURE
;
4435 limit
= getULong(data
.data
);
4436 data_string_forget(&data
, MDL
);
4440 * If we wish to limit the client to a certain number of
4441 * prefixes, then omit the prefix from the reply.
4443 if (reply
->client_resources
>= limit
)
4447 status
= reply_process_is_prefixed(reply
, scope
, group
);
4448 if (status
!= ISC_R_SUCCESS
)
4452 status
= reply_process_send_prefix(reply
, &tmp_pref
);
4455 if (iapref
.data
!= NULL
)
4456 data_string_forget(&iapref
, MDL
);
4457 if (data
.data
!= NULL
)
4458 data_string_forget(&data
, MDL
);
4459 if (reply
->lease
!= NULL
)
4460 iasubopt_dereference(&reply
->lease
, MDL
);
4466 * Verify the prefix belongs to the client. If we've got a host
4467 * record with fixed prefixes, it has to be an assigned prefix
4468 * (fault out all else). Otherwise it's a dynamic prefix, so lookup
4469 * that prefix and make sure it belongs to this DUID:IAID pair.
4471 static isc_boolean_t
4472 prefix_is_owned(struct reply_state
*reply
, struct iaddrcidrnet
*pref
) {
4473 struct iaddrcidrnetlist
*l
;
4475 struct ipv6_pond
*pond
;
4478 * This faults out prefixes that don't match fixed prefixes.
4480 if (reply
->static_prefixes
> 0) {
4481 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4482 if ((pref
->bits
== l
->cidrnet
.bits
) &&
4483 (memcmp(pref
->lo_addr
.iabuf
,
4484 l
->cidrnet
.lo_addr
.iabuf
, 16) == 0))
4490 if ((reply
->old_ia
== NULL
) ||
4491 (reply
->old_ia
->num_iasubopt
== 0))
4494 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4495 struct iasubopt
*tmp
;
4497 tmp
= reply
->old_ia
->iasubopt
[i
];
4499 if ((pref
->bits
== (int) tmp
->plen
) &&
4500 (memcmp(pref
->lo_addr
.iabuf
, &tmp
->addr
, 16) == 0)) {
4501 if (lease6_usable(tmp
) == ISC_FALSE
) {
4505 pond
= tmp
->ipv6_pool
->ipv6_pond
;
4506 if (((pond
->prohibit_list
!= NULL
) &&
4507 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4508 ((pond
->permit_list
!= NULL
) &&
4509 (!permitted(reply
->packet
, pond
->permit_list
))))
4512 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
4521 * This function only returns failure on 'hard' failures. If it succeeds,
4522 * it will leave a prefix structure behind.
4525 reply_process_try_prefix(struct reply_state
*reply
,
4526 struct iaddrcidrnet
*pref
) {
4527 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
4528 struct ipv6_pool
*pool
= NULL
;
4529 struct ipv6_pond
*pond
= NULL
;
4531 struct data_string data_pref
;
4533 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
4534 (pref
== NULL
) || (reply
->lease
!= NULL
))
4535 return (DHCP_R_INVALIDARG
);
4538 * Do a quick walk through of the ponds and pools
4539 * to see if we have any prefix pools
4541 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4542 if (pond
->ipv6_pools
== NULL
)
4545 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4546 if (pool
->pool_type
== D6O_IA_PD
)
4553 /* If we get here and p is NULL we have no useful pools */
4555 return (ISC_R_ADDRNOTAVAIL
);
4558 memset(&data_pref
, 0, sizeof(data_pref
));
4560 if (!buffer_allocate(&data_pref
.buffer
, data_pref
.len
, MDL
)) {
4561 log_error("reply_process_try_prefix: out of memory.");
4562 return (ISC_R_NOMEMORY
);
4564 data_pref
.data
= data_pref
.buffer
->data
;
4565 data_pref
.buffer
->data
[0] = (u_int8_t
) pref
->bits
;
4566 memcpy(data_pref
.buffer
->data
+ 1, pref
->lo_addr
.iabuf
, 16);
4569 * We have at least one pool that could provide a prefix
4570 * Now we walk through the ponds and pools again and check
4571 * to see if the client is permitted and if an prefix is
4576 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4577 if (((pond
->prohibit_list
!= NULL
) &&
4578 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4579 ((pond
->permit_list
!= NULL
) &&
4580 (!permitted(reply
->packet
, pond
->permit_list
))))
4583 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4584 if (pool
->pool_type
!= D6O_IA_PD
) {
4588 status
= try_client_v6_prefix(&reply
->lease
, pool
,
4590 /* If we found it in this pool (either in use or available),
4591 there is no need to look further. */
4592 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4595 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4599 data_string_forget(&data_pref
, MDL
);
4600 /* Return just the most recent status... */
4604 /* Look around for a prefix to give the client. First, look through the old
4605 * IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
4606 * Finally, actually add that prefix into the current reply IA_PD.
4609 find_client_prefix(struct reply_state
*reply
) {
4610 struct iaddrcidrnet send_pref
;
4611 isc_result_t status
= ISC_R_NORESOURCES
;
4612 struct iasubopt
*prefix
, *best_prefix
= NULL
;
4613 struct binding_scope
**scope
;
4615 struct group
*group
;
4617 if (reply
->static_prefixes
> 0) {
4618 struct iaddrcidrnetlist
*l
;
4620 if (reply
->host
== NULL
)
4621 return DHCP_R_INVALIDARG
;
4623 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4624 if (l
->cidrnet
.bits
== reply
->preflen
)
4629 * If no fixed prefix has the preferred length,
4630 * get the first one.
4632 l
= reply
->host
->fixed_prefix
;
4634 memcpy(&send_pref
, &l
->cidrnet
, sizeof(send_pref
));
4636 scope
= &global_scope
;
4638 /* Copy the prefix for logging purposes */
4639 memcpy(&reply
->fixed_pref
, &l
->cidrnet
, sizeof(send_pref
));
4641 /* Try to find a group for the static prefix */
4642 group
= find_group_by_prefix(reply
);
4647 if (reply
->old_ia
!= NULL
) {
4648 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4649 struct shared_network
*candidate_shared
;
4650 struct ipv6_pond
*pond
;
4652 prefix
= reply
->old_ia
->iasubopt
[i
];
4653 candidate_shared
= prefix
->ipv6_pool
->shared_network
;
4654 pond
= prefix
->ipv6_pool
->ipv6_pond
;
4657 * Consider this prefix if it is in a global pool or
4658 * if it is scoped in a pool under the client's shared
4661 if (((candidate_shared
!= NULL
) &&
4662 (candidate_shared
!= reply
->shared
)) ||
4663 (lease6_usable(prefix
) != ISC_TRUE
))
4667 * And check if the prefix is still permitted
4670 if (((pond
->prohibit_list
!= NULL
) &&
4671 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4672 ((pond
->permit_list
!= NULL
) &&
4673 (!permitted(reply
->packet
, pond
->permit_list
))))
4676 best_prefix
= prefix_compare(reply
, prefix
,
4681 * If we have prefix length hint and we're not igoring them,
4682 * then toss the best match if it doesn't match the hint,
4683 * unless this is in response to a rebind. In the latter
4684 * case we're supposed to return it with zero lifetimes.
4686 if (best_prefix
&& (reply
->preflen
> 0)
4687 && (prefix_length_mode
!= PLM_IGNORE
)
4688 && (reply
->preflen
!= best_prefix
->plen
)
4689 && (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
4694 /* Try to pick a new prefix if we didn't find one, or if we found an
4697 if ((best_prefix
== NULL
) || (best_prefix
->state
== FTS_ABANDONED
)) {
4698 status
= pick_v6_prefix(reply
);
4699 } else if (best_prefix
!= NULL
) {
4700 iasubopt_reference(&reply
->lease
, best_prefix
, MDL
);
4701 status
= ISC_R_SUCCESS
;
4704 /* Pick the abandoned prefix as a last resort. */
4705 if ((status
== ISC_R_NORESOURCES
) && (best_prefix
!= NULL
)) {
4706 /* I don't see how this is supposed to be done right now. */
4707 log_error("Reclaiming abandoned prefixes is not yet "
4708 "supported. Treating this as an out of space "
4710 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
4713 /* Give up now if we didn't find a prefix. */
4714 if (status
!= ISC_R_SUCCESS
)
4717 if (reply
->lease
== NULL
)
4718 log_fatal("Impossible condition at %s:%d.", MDL
);
4720 scope
= &reply
->lease
->scope
;
4721 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4723 send_pref
.lo_addr
.len
= 16;
4724 memcpy(send_pref
.lo_addr
.iabuf
, &reply
->lease
->addr
, 16);
4725 send_pref
.bits
= (int) reply
->lease
->plen
;
4728 status
= reply_process_is_prefixed(reply
, scope
, group
);
4729 if (status
!= ISC_R_SUCCESS
)
4732 status
= reply_process_send_prefix(reply
, &send_pref
);
4736 /* Once a prefix is found for a client, perform several common functions;
4737 * Calculate and store valid and preferred prefix times, draw client options
4738 * into the option state.
4741 reply_process_is_prefixed(struct reply_state
*reply
,
4742 struct binding_scope
**scope
, struct group
*group
)
4744 isc_result_t status
= ISC_R_SUCCESS
;
4745 struct data_string data
;
4746 struct option_cache
*oc
;
4747 struct option_state
*tmp_options
= NULL
;
4748 struct on_star
*on_star
;
4751 /* Initialize values we will cleanup. */
4752 memset(&data
, 0, sizeof(data
));
4755 * Find the proper on_star block to use. We use the
4756 * one in the lease if we have a lease or the one in
4757 * the reply if we don't have a lease because this is
4761 on_star
= &reply
->lease
->on_star
;
4763 on_star
= &reply
->on_star
;
4767 * Bring in the root configuration. We only do this to bring
4768 * in the on * statements, as we didn't have the lease available
4769 * we we did it the first time.
4771 option_state_allocate(&tmp_options
, MDL
);
4772 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4773 reply
->packet
->options
, tmp_options
,
4774 &global_scope
, root_group
, NULL
,
4776 if (tmp_options
!= NULL
) {
4777 option_state_dereference(&tmp_options
, MDL
);
4781 * Bring configured options into the root packet level cache - start
4782 * with the lease's closest enclosing group (passed in by the caller
4785 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4786 reply
->packet
->options
, reply
->opt_state
,
4787 scope
, group
, root_group
, on_star
);
4789 /* Execute statements from class scopes. */
4790 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
4791 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4792 reply
->packet
->options
,
4793 reply
->opt_state
, scope
,
4794 reply
->packet
->classes
[i
- 1]->group
,
4799 * If there is a host record, over-ride with values configured there,
4800 * without re-evaluating configuration from the previously executed
4801 * group or its common enclosers.
4803 if (reply
->host
!= NULL
)
4804 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4805 reply
->packet
->options
,
4806 reply
->opt_state
, scope
,
4807 reply
->host
->group
, group
,
4810 /* Determine valid lifetime. */
4811 if (reply
->client_valid
== 0)
4812 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
4814 reply
->send_valid
= reply
->client_valid
;
4816 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4817 SV_DEFAULT_LEASE_TIME
);
4819 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4820 reply
->packet
->options
,
4824 log_error("reply_process_is_prefixed: unable to "
4825 "evaluate default prefix time");
4826 status
= ISC_R_FAILURE
;
4830 reply
->send_valid
= getULong(data
.data
);
4831 data_string_forget(&data
, MDL
);
4834 /* Check to see if the lease time would cause us to wrap
4835 * in which case we make it infinite.
4836 * The following doesn't work on at least some systems:
4837 * (cur_time + reply->send_valid < cur_time)
4839 if (reply
->send_valid
!= INFINITE_TIME
) {
4840 time_t test_time
= cur_time
+ reply
->send_valid
;
4841 if (test_time
< cur_time
)
4842 reply
->send_valid
= INFINITE_TIME
;
4845 if (reply
->client_prefer
== 0)
4846 reply
->send_prefer
= reply
->send_valid
;
4848 reply
->send_prefer
= reply
->client_prefer
;
4850 if ((reply
->send_prefer
>= reply
->send_valid
) &&
4851 (reply
->send_valid
!= INFINITE_TIME
))
4852 reply
->send_prefer
= (reply
->send_valid
/ 2) +
4853 (reply
->send_valid
/ 8);
4855 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4856 SV_PREFER_LIFETIME
);
4858 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4859 reply
->packet
->options
,
4863 log_error("reply_process_is_prefixed: unable to "
4864 "evaluate preferred prefix time");
4865 status
= ISC_R_FAILURE
;
4869 reply
->send_prefer
= getULong(data
.data
);
4870 data_string_forget(&data
, MDL
);
4873 /* Note lowest values for later calculation of renew/rebind times. */
4874 if (reply
->min_prefer
> reply
->send_prefer
)
4875 reply
->min_prefer
= reply
->send_prefer
;
4877 if (reply
->min_valid
> reply
->send_valid
)
4878 reply
->min_valid
= reply
->send_valid
;
4880 /* Perform dynamic prefix related update work. */
4881 if (reply
->lease
!= NULL
) {
4882 /* Cached lifetimes */
4883 reply
->lease
->prefer
= reply
->send_prefer
;
4884 reply
->lease
->valid
= reply
->send_valid
;
4886 /* Advance (or rewind) the valid lifetime.
4887 * In the protocol 0xFFFFFFFF is infinite
4888 * when connecting to the lease file MAX_TIME is
4890 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
4891 if (reply
->send_valid
== INFINITE_TIME
) {
4892 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
4894 reply
->lease
->soft_lifetime_end_time
=
4895 cur_time
+ reply
->send_valid
;
4897 /* Wait before renew! */
4900 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
4901 if (status
!= ISC_R_SUCCESS
) {
4902 log_fatal("reply_process_is_prefixed: Unable to "
4903 "attach prefix to new IA_PD: %s",
4904 isc_result_totext(status
));
4908 * If this is a new prefix, make sure it is attached somewhere.
4910 if (reply
->lease
->ia
== NULL
) {
4911 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
4915 /* Bring a copy of the relevant options into the IA_PD scope. */
4916 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4917 reply
->packet
->options
, reply
->reply_ia
,
4918 scope
, group
, root_group
, NULL
);
4920 /* Execute statements from class scopes. */
4921 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
4922 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4923 reply
->packet
->options
,
4924 reply
->reply_ia
, scope
,
4925 reply
->packet
->classes
[i
- 1]->group
,
4930 * And bring in host record configuration, if any, but not to overlap
4931 * the previous group or its common enclosers.
4933 if (reply
->host
!= NULL
)
4934 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4935 reply
->packet
->options
,
4936 reply
->reply_ia
, scope
,
4937 reply
->host
->group
, group
, NULL
);
4940 if (data
.data
!= NULL
)
4941 data_string_forget(&data
, MDL
);
4943 if (status
== ISC_R_SUCCESS
)
4944 reply
->client_resources
++;
4949 /* Simply send an IAPREFIX within the IA_PD scope as described. */
4951 reply_process_send_prefix(struct reply_state
*reply
,
4952 struct iaddrcidrnet
*pref
) {
4953 isc_result_t status
= ISC_R_SUCCESS
;
4954 struct data_string data
;
4956 memset(&data
, 0, sizeof(data
));
4958 /* Now append the prefix. */
4959 data
.len
= IAPREFIX_OFFSET
;
4960 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
4961 log_error("reply_process_send_prefix: out of memory"
4962 "allocating new IAPREFIX buffer.");
4963 status
= ISC_R_NOMEMORY
;
4966 data
.data
= data
.buffer
->data
;
4968 putULong(data
.buffer
->data
, reply
->send_prefer
);
4969 putULong(data
.buffer
->data
+ 4, reply
->send_valid
);
4970 data
.buffer
->data
[8] = pref
->bits
;
4971 memcpy(data
.buffer
->data
+ 9, pref
->lo_addr
.iabuf
, 16);
4973 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
4974 data
.buffer
, data
.buffer
->data
,
4975 data
.len
, D6O_IAPREFIX
, 0)) {
4976 log_error("reply_process_send_prefix: unable "
4977 "to save IAPREFIX option");
4978 status
= ISC_R_FAILURE
;
4982 reply
->resources_included
= ISC_TRUE
;
4985 if (data
.data
!= NULL
)
4986 data_string_forget(&data
, MDL
);
4991 /* Choose the better of two prefixes. */
4992 static struct iasubopt
*
4993 prefix_compare(struct reply_state
*reply
,
4994 struct iasubopt
*alpha
, struct iasubopt
*beta
) {
5000 if (reply
->preflen
>= 0) {
5001 if ((alpha
->plen
== reply
->preflen
) &&
5002 (beta
->plen
!= reply
->preflen
))
5004 if ((beta
->plen
== reply
->preflen
) &&
5005 (alpha
->plen
!= reply
->preflen
))
5009 switch(alpha
->state
) {
5011 switch(beta
->state
) {
5013 /* Choose the prefix with the longest lifetime (most
5014 * likely the most recently allocated).
5016 if (alpha
->hard_lifetime_end_time
<
5017 beta
->hard_lifetime_end_time
)
5027 log_fatal("Impossible condition at %s:%d.", MDL
);
5032 switch (beta
->state
) {
5037 /* Choose the most recently expired prefix. */
5038 if (alpha
->hard_lifetime_end_time
<
5039 beta
->hard_lifetime_end_time
)
5041 else if ((alpha
->hard_lifetime_end_time
==
5042 beta
->hard_lifetime_end_time
) &&
5043 (alpha
->soft_lifetime_end_time
<
5044 beta
->soft_lifetime_end_time
))
5053 log_fatal("Impossible condition at %s:%d.", MDL
);
5058 switch (beta
->state
) {
5064 /* Choose the prefix that was abandoned longest ago. */
5065 if (alpha
->hard_lifetime_end_time
<
5066 beta
->hard_lifetime_end_time
)
5072 log_fatal("Impossible condition at %s:%d.", MDL
);
5077 log_fatal("Impossible condition at %s:%d.", MDL
);
5080 log_fatal("Triple impossible condition at %s:%d.", MDL
);
5085 * Solicit is how a client starts requesting addresses.
5087 * If the client asks for rapid commit, and we support it, we will
5088 * allocate the addresses and reply.
5090 * Otherwise we will send an advertise message.
5094 dhcpv6_solicit(struct data_string
*reply_ret
, struct packet
*packet
) {
5095 struct data_string client_id
;
5098 * Validate our input.
5100 if (!valid_client_msg(packet
, &client_id
)) {
5104 lease_to_client(reply_ret
, packet
, &client_id
, NULL
);
5109 data_string_forget(&client_id
, MDL
);
5113 * Request is how a client actually requests addresses.
5115 * Very similar to Solicit handling, except the server DUID is required.
5119 dhcpv6_request(struct data_string
*reply_ret
, struct packet
*packet
) {
5120 struct data_string client_id
;
5121 struct data_string server_id
;
5124 * Validate our input.
5126 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5130 /* If the REQUEST arrived via unicast and unicast option isn't set,
5131 * reject it per RFC 3315, Sec 18.2.1 */
5132 if (packet
->unicast
== ISC_TRUE
&&
5133 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5134 unicast_reject(reply_ret
, packet
, &client_id
, &server_id
);
5139 lease_to_client(reply_ret
, packet
, &client_id
, &server_id
);
5145 data_string_forget(&client_id
, MDL
);
5146 data_string_forget(&server_id
, MDL
);
5149 /* Find a DHCPv6 packet's shared network from hints in the packet.
5152 shared_network_from_packet6(struct shared_network
**shared
,
5153 struct packet
*packet
)
5155 const struct packet
*chk_packet
;
5156 const struct in6_addr
*link_addr
, *first_link_addr
;
5157 struct iaddr tmp_addr
;
5158 struct subnet
*subnet
;
5159 isc_result_t status
;
5161 if ((shared
== NULL
) || (*shared
!= NULL
) || (packet
== NULL
))
5162 return DHCP_R_INVALIDARG
;
5165 * First, find the link address where the packet from the client
5166 * first appeared (if this packet was relayed).
5168 first_link_addr
= NULL
;
5169 chk_packet
= packet
->dhcpv6_container_packet
;
5170 while (chk_packet
!= NULL
) {
5171 link_addr
= &chk_packet
->dhcpv6_link_address
;
5172 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
5173 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
5174 first_link_addr
= link_addr
;
5177 chk_packet
= chk_packet
->dhcpv6_container_packet
;
5181 * If there is a relayed link address, find the subnet associated
5182 * with that, and use that to get the appropriate
5185 if (first_link_addr
!= NULL
) {
5186 tmp_addr
.len
= sizeof(*first_link_addr
);
5187 memcpy(tmp_addr
.iabuf
,
5188 first_link_addr
, sizeof(*first_link_addr
));
5190 if (!find_subnet(&subnet
, tmp_addr
, MDL
)) {
5191 log_debug("No subnet found for link-address %s.",
5193 return ISC_R_NOTFOUND
;
5195 status
= shared_network_reference(shared
,
5196 subnet
->shared_network
, MDL
);
5197 subnet_dereference(&subnet
, MDL
);
5200 * If there is no link address, we will use the interface
5201 * that this packet came in on to pick the shared_network.
5203 } else if (packet
->interface
!= NULL
) {
5204 status
= shared_network_reference(shared
,
5205 packet
->interface
->shared_network
,
5207 if (packet
->dhcpv6_container_packet
!= NULL
) {
5208 log_info("[L2 Relay] No link address in relay packet "
5209 "assuming L2 relay and using receiving "
5215 * We shouldn't be able to get here but if there is no link
5216 * address and no interface we don't know where to get the
5217 * pool from log an error and return an error.
5219 log_error("No interface and no link address "
5220 "can't determine pool");
5221 status
= DHCP_R_INVALIDARG
;
5228 * When a client thinks it might be on a new link, it sends a
5231 * From RFC3315 section 18.2.2:
5233 * When the server receives a Confirm message, the server determines
5234 * whether the addresses in the Confirm message are appropriate for the
5235 * link to which the client is attached. If all of the addresses in the
5236 * Confirm message pass this test, the server returns a status of
5237 * Success. If any of the addresses do not pass this test, the server
5238 * returns a status of NotOnLink. If the server is unable to perform
5239 * this test (for example, the server does not have information about
5240 * prefixes on the link to which the client is connected), or there were
5241 * no addresses in any of the IAs sent by the client, the server MUST
5242 * NOT send a reply to the client.
5246 dhcpv6_confirm(struct data_string
*reply_ret
, struct packet
*packet
) {
5247 struct shared_network
*shared
;
5248 struct subnet
*subnet
;
5249 struct option_cache
*ia
, *ta
, *oc
;
5250 struct data_string cli_enc_opt_data
, iaaddr
, client_id
, packet_oro
;
5251 struct option_state
*cli_enc_opt_state
, *opt_state
;
5252 struct iaddr cli_addr
;
5254 isc_boolean_t inappropriate
, has_addrs
;
5255 char reply_data
[65536];
5256 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5257 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5260 * Basic client message validation.
5262 memset(&client_id
, 0, sizeof(client_id
));
5263 if (!valid_client_msg(packet
, &client_id
)) {
5268 * Do not process Confirms that do not have IA's we do not recognize.
5270 ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5271 ta
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
5272 if ((ia
== NULL
) && (ta
== NULL
))
5276 * IA_PD's are simply ignored.
5278 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5281 * Bit of variable initialization.
5283 opt_state
= cli_enc_opt_state
= NULL
;
5284 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5285 memset(&iaaddr
, 0, sizeof(iaaddr
));
5286 memset(&packet_oro
, 0, sizeof(packet_oro
));
5288 /* Determine what shared network the client is connected to. We
5289 * must not respond if we don't have any information about the
5290 * network the client is on.
5293 if ((shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
) ||
5297 /* If there are no recorded subnets, then we have no
5298 * information about this subnet - ignore Confirms.
5300 subnet
= shared
->subnets
;
5304 /* Are the addresses in all the IA's appropriate for that link? */
5305 has_addrs
= inappropriate
= ISC_FALSE
;
5307 while(!inappropriate
) {
5308 /* If we've reached the end of the IA_NA pass, move to the
5311 if ((pass
== D6O_IA_NA
) && (ia
== NULL
)) {
5316 /* If we've reached the end of all passes, we're done. */
5320 if (((pass
== D6O_IA_NA
) &&
5321 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5323 packet
, ia
, IA_NA_OFFSET
)) ||
5324 ((pass
== D6O_IA_TA
) &&
5325 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5327 packet
, ia
, IA_TA_OFFSET
))) {
5331 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5334 for ( ; oc
!= NULL
; oc
= oc
->next
) {
5335 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5336 packet
->options
, NULL
,
5337 &global_scope
, oc
, MDL
) ||
5338 (iaaddr
.len
< IAADDR_OFFSET
)) {
5339 log_error("dhcpv6_confirm: "
5340 "error evaluating IAADDR.");
5344 /* Copy out the IPv6 address for processing. */
5346 memcpy(cli_addr
.iabuf
, iaaddr
.data
, 16);
5348 data_string_forget(&iaaddr
, MDL
);
5350 /* Record that we've processed at least one address. */
5351 has_addrs
= ISC_TRUE
;
5353 /* Find out if any subnets cover this address. */
5354 for (subnet
= shared
->subnets
; subnet
!= NULL
;
5355 subnet
= subnet
->next_sibling
) {
5356 if (addr_eq(subnet_number(cli_addr
,
5362 /* If we reach the end of the subnet list, and no
5363 * subnet matches the client address, then it must
5364 * be inappropriate to the link (so far as our
5365 * configuration says). Once we've found one
5366 * inappropriate address, there is no reason to
5367 * continue searching.
5369 if (subnet
== NULL
) {
5370 inappropriate
= ISC_TRUE
;
5375 option_state_dereference(&cli_enc_opt_state
, MDL
);
5376 data_string_forget(&cli_enc_opt_data
, MDL
);
5378 /* Advance to the next IA_*. */
5382 /* If the client supplied no addresses, do not reply. */
5389 if (!start_reply(packet
, &client_id
, NULL
, &opt_state
, reply
)) {
5396 if (inappropriate
) {
5397 if (!set_status_code(STATUS_NotOnLink
,
5398 "Some of the addresses are not on link.",
5403 if (!set_status_code(STATUS_Success
,
5404 "All addresses still on link.",
5411 * Only one option: add it.
5413 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5414 sizeof(reply_data
)-reply_ofs
,
5416 required_opts
, &packet_oro
);
5419 * Return our reply to the caller.
5421 reply_ret
->len
= reply_ofs
;
5422 reply_ret
->buffer
= NULL
;
5423 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5424 log_fatal("No memory to store reply.");
5426 reply_ret
->data
= reply_ret
->buffer
->data
;
5427 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5430 /* Cleanup any stale data strings. */
5431 if (cli_enc_opt_data
.buffer
!= NULL
)
5432 data_string_forget(&cli_enc_opt_data
, MDL
);
5433 if (iaaddr
.buffer
!= NULL
)
5434 data_string_forget(&iaaddr
, MDL
);
5435 if (client_id
.buffer
!= NULL
)
5436 data_string_forget(&client_id
, MDL
);
5437 if (packet_oro
.buffer
!= NULL
)
5438 data_string_forget(&packet_oro
, MDL
);
5440 /* Release any stale option states. */
5441 if (cli_enc_opt_state
!= NULL
)
5442 option_state_dereference(&cli_enc_opt_state
, MDL
);
5443 if (opt_state
!= NULL
)
5444 option_state_dereference(&opt_state
, MDL
);
5448 * Renew is when a client wants to extend its lease/prefix, at time T1.
5450 * We handle this the same as if the client wants a new lease/prefix,
5451 * except for the error code of when addresses don't match.
5455 dhcpv6_renew(struct data_string
*reply
, struct packet
*packet
) {
5456 struct data_string client_id
;
5457 struct data_string server_id
;
5460 * Validate the request.
5462 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5466 /* If the RENEW arrived via unicast and unicast option isn't set,
5467 * reject it per RFC 3315, Sec 18.2.3 */
5468 if (packet
->unicast
== ISC_TRUE
&&
5469 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5470 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5475 lease_to_client(reply
, packet
, &client_id
, &server_id
);
5481 data_string_forget(&server_id
, MDL
);
5482 data_string_forget(&client_id
, MDL
);
5486 * Rebind is when a client wants to extend its lease, at time T2.
5488 * We handle this the same as if the client wants a new lease, except
5489 * for the error code of when addresses don't match.
5493 dhcpv6_rebind(struct data_string
*reply
, struct packet
*packet
) {
5494 struct data_string client_id
;
5496 if (!valid_client_msg(packet
, &client_id
)) {
5500 lease_to_client(reply
, packet
, &client_id
, NULL
);
5502 data_string_forget(&client_id
, MDL
);
5506 ia_na_match_decline(const struct data_string
*client_id
,
5507 const struct data_string
*iaaddr
,
5508 struct iasubopt
*lease
)
5510 char tmp_addr
[INET6_ADDRSTRLEN
];
5512 log_error("Client %s reports address %s is "
5513 "already in use by another host!",
5514 print_hex_1(client_id
->len
, client_id
->data
, 60),
5515 inet_ntop(AF_INET6
, iaaddr
->data
,
5516 tmp_addr
, sizeof(tmp_addr
)));
5517 if (lease
!= NULL
) {
5518 decline_lease6(lease
->ipv6_pool
, lease
);
5519 lease
->ia
->cltt
= cur_time
;
5520 write_ia(lease
->ia
);
5525 ia_na_nomatch_decline(const struct data_string
*client_id
,
5526 const struct data_string
*iaaddr
,
5527 u_int32_t
*ia_na_id
,
5528 struct packet
*packet
,
5533 char tmp_addr
[INET6_ADDRSTRLEN
];
5534 struct option_state
*host_opt_state
;
5537 log_info("Client %s declines address %s, which is not offered to it.",
5538 print_hex_1(client_id
->len
, client_id
->data
, 60),
5539 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5542 * Create state for this IA_NA.
5544 host_opt_state
= NULL
;
5545 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5546 log_error("ia_na_nomatch_decline: out of memory "
5547 "allocating option_state.");
5551 if (!set_status_code(STATUS_NoBinding
, "Decline for unknown address.",
5557 * Insure we have enough space
5559 if (reply_len
< (*reply_ofs
+ 16)) {
5560 log_error("ia_na_nomatch_decline: "
5561 "out of space for reply packet.");
5566 * Put our status code into the reply packet.
5568 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5569 reply_len
-(*reply_ofs
)-16,
5570 host_opt_state
, packet
,
5571 required_opts_STATUS_CODE
, NULL
);
5574 * Store the non-encapsulated option data for this
5575 * IA_NA into our reply packet. Defined in RFC 3315,
5579 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5581 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5582 /* IA_NA, copied from the client */
5583 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5584 /* t1 and t2, odd that we need them, but here it is */
5585 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5586 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5589 * Get ready for next IA_NA.
5591 *reply_ofs
+= (len
+ 16);
5594 option_state_dereference(&host_opt_state
, MDL
);
5598 iterate_over_ia_na(struct data_string
*reply_ret
,
5599 struct packet
*packet
,
5600 const struct data_string
*client_id
,
5601 const struct data_string
*server_id
,
5602 const char *packet_type
,
5603 void (*ia_na_match
)(),
5604 void (*ia_na_nomatch
)())
5606 struct option_state
*opt_state
;
5607 struct host_decl
*packet_host
;
5608 struct option_cache
*ia
;
5609 struct option_cache
*oc
;
5610 /* cli_enc_... variables come from the IA_NA/IA_TA options */
5611 struct data_string cli_enc_opt_data
;
5612 struct option_state
*cli_enc_opt_state
;
5613 struct host_decl
*host
;
5614 struct data_string iaaddr
;
5615 struct data_string fixed_addr
;
5616 char reply_data
[65536];
5617 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5618 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5619 char status_msg
[32];
5620 struct iasubopt
*lease
;
5621 struct ia_xx
*existing_ia_na
;
5623 struct data_string key
;
5627 * Initialize to empty values, in case we have to exit early.
5630 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5631 cli_enc_opt_state
= NULL
;
5632 memset(&iaaddr
, 0, sizeof(iaaddr
));
5633 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
5637 * Find the host record that matches from the packet, if any.
5640 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
5643 * Set our reply information.
5645 reply
->msg_type
= DHCPV6_REPLY
;
5646 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
5647 sizeof(reply
->transaction_id
));
5650 * Build our option state for reply.
5653 if (!option_state_allocate(&opt_state
, MDL
)) {
5654 log_error("iterate_over_ia_na: no memory for option_state.");
5657 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5658 packet
->options
, opt_state
,
5659 &global_scope
, root_group
, NULL
, NULL
);
5662 * RFC 3315, section 18.2.7 tells us which options to include.
5664 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
5666 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5667 (unsigned char *)server_duid
.data
,
5668 server_duid
.len
, D6O_SERVERID
, 0)) {
5669 log_error("iterate_over_ia_na: "
5670 "error saving server identifier.");
5675 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
5677 (unsigned char *)client_id
->data
,
5680 log_error("iterate_over_ia_na: "
5681 "error saving client identifier.");
5685 snprintf(status_msg
, sizeof(status_msg
), "%s received.", packet_type
);
5686 if (!set_status_code(STATUS_Success
, status_msg
, opt_state
)) {
5691 * Add our options that are not associated with any IA_NA or IA_TA.
5693 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5694 sizeof(reply_data
)-reply_ofs
,
5696 required_opts
, NULL
);
5699 * Loop through the IA_NA reported by the client, and deal with
5700 * addresses reported as already in use.
5702 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5703 ia
!= NULL
; ia
= ia
->next
) {
5705 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
5707 packet
, ia
, IA_NA_OFFSET
)) {
5711 iaid
= getULong(cli_enc_opt_data
.data
);
5714 * XXX: It is possible that we can get multiple addresses
5715 * sent by the client. We don't send multiple
5716 * addresses, so this indicates a client error.
5717 * We should check for multiple IAADDR options, log
5718 * if found, and set as an error.
5720 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5723 /* no address given for this IA, ignore */
5724 option_state_dereference(&cli_enc_opt_state
, MDL
);
5725 data_string_forget(&cli_enc_opt_data
, MDL
);
5729 memset(&iaaddr
, 0, sizeof(iaaddr
));
5730 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5731 packet
->options
, NULL
,
5732 &global_scope
, oc
, MDL
)) {
5733 log_error("iterate_over_ia_na: "
5734 "error evaluating IAADDR.");
5739 * Now we need to figure out which host record matches
5740 * this IA_NA and IAADDR (encapsulated option contents
5741 * matching a host record by option).
5743 * XXX: We don't currently track IA_NA separately, but
5744 * we will need to do this!
5747 if (!find_hosts_by_option(&host
, packet
,
5748 cli_enc_opt_state
, MDL
)) {
5749 if (packet_host
!= NULL
) {
5755 while (host
!= NULL
) {
5756 if (host
->fixed_addr
!= NULL
) {
5757 if (!evaluate_option_cache(&fixed_addr
, NULL
,
5759 NULL
, &global_scope
,
5762 log_error("iterate_over_ia_na: error "
5763 "evaluating host address.");
5766 if ((iaaddr
.len
>= 16) &&
5767 !memcmp(fixed_addr
.data
, iaaddr
.data
, 16)) {
5768 data_string_forget(&fixed_addr
, MDL
);
5771 data_string_forget(&fixed_addr
, MDL
);
5773 host
= host
->n_ipaddr
;
5776 if ((host
== NULL
) && (iaaddr
.len
>= IAADDR_OFFSET
)) {
5778 * Find existing IA_NA.
5780 if (ia_make_key(&key
, iaid
,
5781 (char *)client_id
->data
,
5783 MDL
) != ISC_R_SUCCESS
) {
5784 log_fatal("iterate_over_ia_na: no memory for "
5788 existing_ia_na
= NULL
;
5789 if (ia_hash_lookup(&existing_ia_na
, ia_na_active
,
5790 (unsigned char *)key
.data
,
5793 * Make sure this address is in the IA_NA.
5795 for (i
=0; i
<existing_ia_na
->num_iasubopt
; i
++) {
5796 struct iasubopt
*tmp
;
5797 struct in6_addr
*in6_addr
;
5799 tmp
= existing_ia_na
->iasubopt
[i
];
5800 in6_addr
= &tmp
->addr
;
5801 if (memcmp(in6_addr
,
5802 iaaddr
.data
, 16) == 0) {
5803 iasubopt_reference(&lease
,
5810 data_string_forget(&key
, MDL
);
5813 if ((host
!= NULL
) || (lease
!= NULL
)) {
5814 ia_na_match(client_id
, &iaaddr
, lease
);
5816 ia_na_nomatch(client_id
, &iaaddr
,
5817 (u_int32_t
*)cli_enc_opt_data
.data
,
5818 packet
, reply_data
, &reply_ofs
,
5819 sizeof(reply_data
));
5822 if (lease
!= NULL
) {
5823 iasubopt_dereference(&lease
, MDL
);
5826 data_string_forget(&iaaddr
, MDL
);
5827 option_state_dereference(&cli_enc_opt_state
, MDL
);
5828 data_string_forget(&cli_enc_opt_data
, MDL
);
5832 * Return our reply to the caller.
5834 reply_ret
->len
= reply_ofs
;
5835 reply_ret
->buffer
= NULL
;
5836 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5837 log_fatal("No memory to store reply.");
5839 reply_ret
->data
= reply_ret
->buffer
->data
;
5840 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5843 if (lease
!= NULL
) {
5844 iasubopt_dereference(&lease
, MDL
);
5846 if (fixed_addr
.buffer
!= NULL
) {
5847 data_string_forget(&fixed_addr
, MDL
);
5849 if (iaaddr
.buffer
!= NULL
) {
5850 data_string_forget(&iaaddr
, MDL
);
5852 if (cli_enc_opt_state
!= NULL
) {
5853 option_state_dereference(&cli_enc_opt_state
, MDL
);
5855 if (cli_enc_opt_data
.buffer
!= NULL
) {
5856 data_string_forget(&cli_enc_opt_data
, MDL
);
5858 if (opt_state
!= NULL
) {
5859 option_state_dereference(&opt_state
, MDL
);
5864 * Decline means a client has detected that something else is using an
5865 * address we gave it.
5867 * Since we're only dealing with fixed leases for now, there's not
5868 * much we can do, other that log the occurrence.
5870 * When we start issuing addresses from pools, then we will have to
5871 * record our declined addresses and issue another. In general with
5872 * IPv6 there is no worry about DoS by clients exhausting space, but
5873 * we still need to be aware of this possibility.
5878 dhcpv6_decline(struct data_string
*reply
, struct packet
*packet
) {
5879 struct data_string client_id
;
5880 struct data_string server_id
;
5883 * Validate our input.
5885 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5889 /* If the DECLINE arrived via unicast and unicast option isn't set,
5890 * reject it per RFC 3315, Sec 18.2.7 */
5891 if (packet
->unicast
== ISC_TRUE
&&
5892 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5893 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5896 * Undefined for IA_PD.
5898 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5901 * And operate on each IA_NA in this packet.
5903 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
5904 "Decline", ia_na_match_decline
,
5905 ia_na_nomatch_decline
);
5909 data_string_forget(&server_id
, MDL
);
5910 data_string_forget(&client_id
, MDL
);
5914 ia_na_match_release(const struct data_string
*client_id
,
5915 const struct data_string
*iaaddr
,
5916 struct iasubopt
*lease
)
5918 char tmp_addr
[INET6_ADDRSTRLEN
];
5920 log_info("Client %s releases address %s",
5921 print_hex_1(client_id
->len
, client_id
->data
, 60),
5922 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5923 if (lease
!= NULL
) {
5924 release_lease6(lease
->ipv6_pool
, lease
);
5925 lease
->ia
->cltt
= cur_time
;
5926 write_ia(lease
->ia
);
5931 ia_na_nomatch_release(const struct data_string
*client_id
,
5932 const struct data_string
*iaaddr
,
5933 u_int32_t
*ia_na_id
,
5934 struct packet
*packet
,
5939 char tmp_addr
[INET6_ADDRSTRLEN
];
5940 struct option_state
*host_opt_state
;
5943 log_info("Client %s releases address %s, which is not leased to it.",
5944 print_hex_1(client_id
->len
, client_id
->data
, 60),
5945 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5948 * Create state for this IA_NA.
5950 host_opt_state
= NULL
;
5951 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5952 log_error("ia_na_nomatch_release: out of memory "
5953 "allocating option_state.");
5957 if (!set_status_code(STATUS_NoBinding
,
5958 "Release for non-leased address.",
5964 * Insure we have enough space
5966 if (reply_len
< (*reply_ofs
+ 16)) {
5967 log_error("ia_na_nomatch_release: "
5968 "out of space for reply packet.");
5973 * Put our status code into the reply packet.
5975 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5976 reply_len
-(*reply_ofs
)-16,
5977 host_opt_state
, packet
,
5978 required_opts_STATUS_CODE
, NULL
);
5981 * Store the non-encapsulated option data for this
5982 * IA_NA into our reply packet. Defined in RFC 3315,
5986 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5988 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5989 /* IA_NA, copied from the client */
5990 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5991 /* t1 and t2, odd that we need them, but here it is */
5992 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5993 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5996 * Get ready for next IA_NA.
5998 *reply_ofs
+= (len
+ 16);
6001 option_state_dereference(&host_opt_state
, MDL
);
6005 ia_pd_match_release(const struct data_string
*client_id
,
6006 const struct data_string
*iapref
,
6007 struct iasubopt
*prefix
)
6009 char tmp_addr
[INET6_ADDRSTRLEN
];
6011 log_info("Client %s releases prefix %s/%u",
6012 print_hex_1(client_id
->len
, client_id
->data
, 60),
6013 inet_ntop(AF_INET6
, iapref
->data
+ 9,
6014 tmp_addr
, sizeof(tmp_addr
)),
6015 (unsigned) getUChar(iapref
->data
+ 8));
6016 if (prefix
!= NULL
) {
6017 release_lease6(prefix
->ipv6_pool
, prefix
);
6018 prefix
->ia
->cltt
= cur_time
;
6019 write_ia(prefix
->ia
);
6024 ia_pd_nomatch_release(const struct data_string
*client_id
,
6025 const struct data_string
*iapref
,
6026 u_int32_t
*ia_pd_id
,
6027 struct packet
*packet
,
6032 char tmp_addr
[INET6_ADDRSTRLEN
];
6033 struct option_state
*host_opt_state
;
6036 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
6037 print_hex_1(client_id
->len
, client_id
->data
, 60),
6038 inet_ntop(AF_INET6
, iapref
->data
+ 9,
6039 tmp_addr
, sizeof(tmp_addr
)),
6040 (unsigned) getUChar(iapref
->data
+ 8));
6043 * Create state for this IA_PD.
6045 host_opt_state
= NULL
;
6046 if (!option_state_allocate(&host_opt_state
, MDL
)) {
6047 log_error("ia_pd_nomatch_release: out of memory "
6048 "allocating option_state.");
6052 if (!set_status_code(STATUS_NoBinding
,
6053 "Release for non-leased prefix.",
6059 * Insure we have enough space
6061 if (reply_len
< (*reply_ofs
+ 16)) {
6062 log_error("ia_pd_nomatch_release: "
6063 "out of space for reply packet.");
6068 * Put our status code into the reply packet.
6070 len
= store_options6(reply_data
+(*reply_ofs
)+16,
6071 reply_len
-(*reply_ofs
)-16,
6072 host_opt_state
, packet
,
6073 required_opts_STATUS_CODE
, NULL
);
6076 * Store the non-encapsulated option data for this
6077 * IA_PD into our reply packet. Defined in RFC 3315,
6081 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_PD
);
6083 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
6084 /* IA_PD, copied from the client */
6085 memcpy(reply_data
+(*reply_ofs
)+4, ia_pd_id
, 4);
6086 /* t1 and t2, odd that we need them, but here it is */
6087 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
6088 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
6091 * Get ready for next IA_PD.
6093 *reply_ofs
+= (len
+ 16);
6096 option_state_dereference(&host_opt_state
, MDL
);
6100 iterate_over_ia_pd(struct data_string
*reply_ret
,
6101 struct packet
*packet
,
6102 const struct data_string
*client_id
,
6103 const struct data_string
*server_id
,
6104 const char *packet_type
,
6105 void (*ia_pd_match
)(),
6106 void (*ia_pd_nomatch
)())
6108 struct data_string reply_new
;
6110 struct option_state
*opt_state
;
6111 struct host_decl
*packet_host
;
6112 struct option_cache
*ia
;
6113 struct option_cache
*oc
;
6114 /* cli_enc_... variables come from the IA_PD options */
6115 struct data_string cli_enc_opt_data
;
6116 struct option_state
*cli_enc_opt_state
;
6117 struct host_decl
*host
;
6118 struct data_string iaprefix
;
6119 char reply_data
[65536];
6121 struct iasubopt
*prefix
;
6122 struct ia_xx
*existing_ia_pd
;
6124 struct data_string key
;
6128 * Initialize to empty values, in case we have to exit early.
6130 memset(&reply_new
, 0, sizeof(reply_new
));
6132 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
6133 cli_enc_opt_state
= NULL
;
6134 memset(&iaprefix
, 0, sizeof(iaprefix
));
6138 * Compute the available length for the reply.
6140 reply_len
= sizeof(reply_data
) - reply_ret
->len
;
6144 * Find the host record that matches from the packet, if any.
6147 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
6150 * Build our option state for reply.
6153 if (!option_state_allocate(&opt_state
, MDL
)) {
6154 log_error("iterate_over_ia_pd: no memory for option_state.");
6157 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
6158 packet
->options
, opt_state
,
6159 &global_scope
, root_group
, NULL
, NULL
);
6162 * Loop through the IA_PD reported by the client, and deal with
6163 * prefixes reported as already in use.
6165 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
6166 ia
!= NULL
; ia
= ia
->next
) {
6168 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
6170 packet
, ia
, IA_PD_OFFSET
)) {
6174 iaid
= getULong(cli_enc_opt_data
.data
);
6176 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
6179 /* no prefix given for this IA_PD, ignore */
6180 option_state_dereference(&cli_enc_opt_state
, MDL
);
6181 data_string_forget(&cli_enc_opt_data
, MDL
);
6185 for (; oc
!= NULL
; oc
= oc
->next
) {
6186 memset(&iaprefix
, 0, sizeof(iaprefix
));
6187 if (!evaluate_option_cache(&iaprefix
, packet
, NULL
, NULL
,
6188 packet
->options
, NULL
,
6189 &global_scope
, oc
, MDL
)) {
6190 log_error("iterate_over_ia_pd: "
6191 "error evaluating IAPREFIX.");
6196 * Now we need to figure out which host record matches
6197 * this IA_PD and IAPREFIX (encapsulated option contents
6198 * matching a host record by option).
6200 * XXX: We don't currently track IA_PD separately, but
6201 * we will need to do this!
6204 if (!find_hosts_by_option(&host
, packet
,
6205 cli_enc_opt_state
, MDL
)) {
6206 if (packet_host
!= NULL
) {
6212 while (host
!= NULL
) {
6213 if (host
->fixed_prefix
!= NULL
) {
6214 struct iaddrcidrnetlist
*l
;
6215 int plen
= (int) getUChar(iaprefix
.data
+ 8);
6217 for (l
= host
->fixed_prefix
; l
!= NULL
;
6219 if (plen
!= l
->cidrnet
.bits
)
6221 if (memcmp(iaprefix
.data
+ 9,
6222 l
->cidrnet
.lo_addr
.iabuf
,
6226 if ((l
!= NULL
) && (iaprefix
.len
>= 17))
6229 host
= host
->n_ipaddr
;
6232 if ((host
== NULL
) && (iaprefix
.len
>= IAPREFIX_OFFSET
)) {
6234 * Find existing IA_PD.
6236 if (ia_make_key(&key
, iaid
,
6237 (char *)client_id
->data
,
6239 MDL
) != ISC_R_SUCCESS
) {
6240 log_fatal("iterate_over_ia_pd: no memory for "
6244 existing_ia_pd
= NULL
;
6245 if (ia_hash_lookup(&existing_ia_pd
, ia_pd_active
,
6246 (unsigned char *)key
.data
,
6249 * Make sure this prefix is in the IA_PD.
6252 i
< existing_ia_pd
->num_iasubopt
;
6254 struct iasubopt
*tmp
;
6257 plen
= getUChar(iaprefix
.data
+ 8);
6258 tmp
= existing_ia_pd
->iasubopt
[i
];
6259 if ((tmp
->plen
== plen
) &&
6263 iasubopt_reference(&prefix
,
6270 data_string_forget(&key
, MDL
);
6273 if ((host
!= NULL
) || (prefix
!= NULL
)) {
6274 ia_pd_match(client_id
, &iaprefix
, prefix
);
6276 ia_pd_nomatch(client_id
, &iaprefix
,
6277 (u_int32_t
*)cli_enc_opt_data
.data
,
6278 packet
, reply_data
, &reply_ofs
,
6279 reply_len
- reply_ofs
);
6282 if (prefix
!= NULL
) {
6283 iasubopt_dereference(&prefix
, MDL
);
6286 data_string_forget(&iaprefix
, MDL
);
6289 option_state_dereference(&cli_enc_opt_state
, MDL
);
6290 data_string_forget(&cli_enc_opt_data
, MDL
);
6294 * Return our reply to the caller.
6295 * The IA_NA routine has already filled at least the header.
6297 reply_new
.len
= reply_ret
->len
+ reply_ofs
;
6298 if (!buffer_allocate(&reply_new
.buffer
, reply_new
.len
, MDL
)) {
6299 log_fatal("No memory to store reply.");
6301 reply_new
.data
= reply_new
.buffer
->data
;
6302 memcpy(reply_new
.buffer
->data
,
6303 reply_ret
->buffer
->data
, reply_ret
->len
);
6304 memcpy(reply_new
.buffer
->data
+ reply_ret
->len
,
6305 reply_data
, reply_ofs
);
6306 data_string_forget(reply_ret
, MDL
);
6307 data_string_copy(reply_ret
, &reply_new
, MDL
);
6308 data_string_forget(&reply_new
, MDL
);
6311 if (prefix
!= NULL
) {
6312 iasubopt_dereference(&prefix
, MDL
);
6314 if (iaprefix
.buffer
!= NULL
) {
6315 data_string_forget(&iaprefix
, MDL
);
6317 if (cli_enc_opt_state
!= NULL
) {
6318 option_state_dereference(&cli_enc_opt_state
, MDL
);
6320 if (cli_enc_opt_data
.buffer
!= NULL
) {
6321 data_string_forget(&cli_enc_opt_data
, MDL
);
6323 if (opt_state
!= NULL
) {
6324 option_state_dereference(&opt_state
, MDL
);
6329 * Release means a client is done with the leases.
6333 dhcpv6_release(struct data_string
*reply
, struct packet
*packet
) {
6334 struct data_string client_id
;
6335 struct data_string server_id
;
6338 * Validate our input.
6340 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
6344 /* If the RELEASE arrived via unicast and unicast option isn't set,
6345 * reject it per RFC 3315, Sec 18.2.6 */
6346 if (packet
->unicast
== ISC_TRUE
&&
6347 is_unicast_option_defined(packet
) == ISC_FALSE
) {
6348 unicast_reject(reply
, packet
, &client_id
, &server_id
);
6351 * And operate on each IA_NA in this packet.
6353 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
6354 "Release", ia_na_match_release
,
6355 ia_na_nomatch_release
);
6358 * And operate on each IA_PD in this packet.
6360 iterate_over_ia_pd(reply
, packet
, &client_id
, &server_id
,
6361 "Release", ia_pd_match_release
,
6362 ia_pd_nomatch_release
);
6365 data_string_forget(&server_id
, MDL
);
6366 data_string_forget(&client_id
, MDL
);
6370 * Information-Request is used by clients who have obtained an address
6371 * from other means, but want configuration information from the server.
6375 dhcpv6_information_request(struct data_string
*reply
, struct packet
*packet
) {
6376 struct data_string client_id
;
6377 struct data_string server_id
;
6380 * Validate our input.
6382 if (!valid_client_info_req(packet
, &server_id
)) {
6387 * Get our client ID, if there is one.
6389 memset(&client_id
, 0, sizeof(client_id
));
6390 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
) {
6391 data_string_forget(&client_id
, MDL
);
6395 * Use the lease_to_client() function. This will work fine,
6396 * because the valid_client_info_req() insures that we
6397 * don't have any IA that would cause us to allocate
6398 * resources to the client.
6400 lease_to_client(reply
, packet
, &client_id
,
6401 server_id
.data
!= NULL
? &server_id
: NULL
);
6406 if (client_id
.data
!= NULL
) {
6407 data_string_forget(&client_id
, MDL
);
6409 data_string_forget(&server_id
, MDL
);
6413 * The Relay-forw message is sent by relays. It typically contains a
6414 * single option, which encapsulates an entire packet.
6416 * We need to build an encapsulated reply.
6419 /* XXX: this is very, very similar to do_packet6(), and should probably
6420 be combined in a clever way */
6421 /* DHCPv6 server side */
6423 dhcpv6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
6424 struct option_cache
*oc
;
6425 struct data_string enc_opt_data
;
6426 struct packet
*enc_packet
;
6427 unsigned char msg_type
;
6428 const struct dhcpv6_packet
*msg
;
6429 const struct dhcpv6_relay_packet
*relay
;
6430 struct data_string enc_reply
;
6431 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6432 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6433 struct data_string a_opt
, packet_ero
;
6434 struct option_state
*opt_state
;
6435 static char reply_data
[65536];
6436 struct dhcpv6_relay_packet
*reply
;
6440 * Initialize variables for early exit.
6443 memset(&a_opt
, 0, sizeof(a_opt
));
6444 memset(&packet_ero
, 0, sizeof(packet_ero
));
6445 memset(&enc_reply
, 0, sizeof(enc_reply
));
6446 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6450 * Get our encapsulated relay message.
6452 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
6454 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
6455 link_addr
, sizeof(link_addr
));
6456 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
6457 peer_addr
, sizeof(peer_addr
));
6458 log_info("Relay-forward from %s with link address=%s and "
6459 "peer address=%s missing Relay Message option.",
6460 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
6464 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
6465 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
6466 /* should be dhcpv6_relay_forw */
6467 log_error("dhcpv6_forw_relay: error evaluating "
6468 "relayed message.");
6472 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
6473 /* should be dhcpv6_relay_forw */
6474 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
6479 * Build a packet structure from this encapsulated packet.
6482 if (!packet_allocate(&enc_packet
, MDL
)) {
6483 /* should be dhcpv6_relay_forw */
6484 log_error("dhcpv6_forw_relay: "
6485 "no memory for encapsulated packet.");
6489 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
6490 /* should be dhcpv6_relay_forw */
6491 log_error("dhcpv6_forw_relay: "
6492 "no memory for encapsulated packet's options.");
6496 enc_packet
->client_port
= packet
->client_port
;
6497 enc_packet
->client_addr
= packet
->client_addr
;
6498 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
6499 enc_packet
->dhcpv6_container_packet
= packet
;
6501 msg_type
= enc_opt_data
.data
[0];
6502 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
6503 (msg_type
== DHCPV6_RELAY_REPL
)) {
6504 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6505 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
6506 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
6508 /* relay-specific data */
6509 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
6510 memcpy(&enc_packet
->dhcpv6_link_address
,
6511 relay
->link_address
, sizeof(relay
->link_address
));
6512 memcpy(&enc_packet
->dhcpv6_peer_address
,
6513 relay
->peer_address
, sizeof(relay
->peer_address
));
6515 if (!parse_option_buffer(enc_packet
->options
,
6517 enc_opt_data
.len
- relaylen
,
6518 &dhcpv6_universe
)) {
6519 /* no logging here, as parse_option_buffer() logs all
6520 cases where it fails */
6523 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
6524 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6526 if (!dhcpv4_over_dhcpv6
||
6527 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6528 log_error("dhcpv6_relay_forw: "
6529 "unsupported %s message type.",
6530 dhcpv6_type_names
[msg_type
]);
6533 forw_dhcpv4_query(packet
);
6536 log_error("dhcpv6_relay_forw: unsupported %s message type.",
6537 dhcpv6_type_names
[msg_type
]);
6539 #endif /* DHCP4o6 */
6541 int msglen
= (int)(offsetof(struct dhcpv6_packet
, options
));
6542 msg
= (struct dhcpv6_packet
*)enc_opt_data
.data
;
6543 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
6545 /* message-specific data */
6546 memcpy(enc_packet
->dhcpv6_transaction_id
,
6547 msg
->transaction_id
,
6548 sizeof(enc_packet
->dhcpv6_transaction_id
));
6550 if (!parse_option_buffer(enc_packet
->options
,
6552 enc_opt_data
.len
- msglen
,
6553 &dhcpv6_universe
)) {
6554 /* no logging here, as parse_option_buffer() logs all
6555 cases where it fails */
6561 * This is recursive. It is possible to exceed maximum packet size.
6562 * XXX: This will cause the packet send to fail.
6564 build_dhcpv6_reply(&enc_reply
, enc_packet
);
6567 * If we got no encapsulated data, then it is discarded, and
6568 * our reply-forw is also discarded.
6570 if (enc_reply
.data
== NULL
) {
6575 * Now we can use the reply_data buffer.
6576 * Packet header stuff all comes from the forward message.
6578 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
6579 reply
->msg_type
= DHCPV6_RELAY_REPL
;
6580 reply
->hop_count
= packet
->dhcpv6_hop_count
;
6581 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
6582 sizeof(reply
->link_address
));
6583 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
6584 sizeof(reply
->peer_address
));
6585 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6588 * Get the reply option state.
6591 if (!option_state_allocate(&opt_state
, MDL
)) {
6592 log_error("dhcpv6_relay_forw: no memory for option state.");
6597 * Append the interface-id if present.
6599 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6602 if (!evaluate_option_cache(&a_opt
, packet
,
6604 packet
->options
, NULL
,
6605 &global_scope
, oc
, MDL
)) {
6606 log_error("dhcpv6_relay_forw: error evaluating "
6610 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6611 (unsigned char *)a_opt
.data
,
6613 D6O_INTERFACE_ID
, 0)) {
6614 log_error("dhcpv6_relay_forw: error saving "
6618 data_string_forget(&a_opt
, MDL
);
6622 * Append our encapsulated stuff for caller.
6624 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6625 (unsigned char *)enc_reply
.data
,
6627 D6O_RELAY_MSG
, 0)) {
6628 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
6633 * Get the ERO if any.
6635 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
6640 if (!evaluate_option_cache(&packet_ero
, packet
,
6642 packet
->options
, NULL
,
6643 &global_scope
, oc
, MDL
) ||
6644 (packet_ero
.len
& 1)) {
6645 log_error("dhcpv6_relay_forw: error evaluating ERO.");
6649 /* Decode and apply the ERO. */
6650 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
6651 req
= getUShort(packet_ero
.data
+ i
);
6652 /* Already in the reply? */
6653 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
6656 /* Get it from the packet if present. */
6657 oc
= lookup_option(&dhcpv6_universe
,
6662 if (!evaluate_option_cache(&a_opt
, packet
,
6664 packet
->options
, NULL
,
6665 &global_scope
, oc
, MDL
)) {
6666 log_error("dhcpv6_relay_forw: error "
6667 "evaluating option %u.", req
);
6670 if (!save_option_buffer(&dhcpv6_universe
,
6673 (unsigned char *)a_opt
.data
,
6677 log_error("dhcpv6_relay_forw: error saving "
6681 data_string_forget(&a_opt
, MDL
);
6685 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
6686 sizeof(reply_data
) - reply_ofs
,
6688 required_opts_agent
, &packet_ero
);
6691 * Return our reply to the caller.
6693 reply_ret
->len
= reply_ofs
;
6694 reply_ret
->buffer
= NULL
;
6695 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
6696 log_fatal("No memory to store reply.");
6698 reply_ret
->data
= reply_ret
->buffer
->data
;
6699 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
6702 if (opt_state
!= NULL
)
6703 option_state_dereference(&opt_state
, MDL
);
6704 if (a_opt
.data
!= NULL
) {
6705 data_string_forget(&a_opt
, MDL
);
6707 if (packet_ero
.data
!= NULL
) {
6708 data_string_forget(&packet_ero
, MDL
);
6710 if (enc_reply
.data
!= NULL
) {
6711 data_string_forget(&enc_reply
, MDL
);
6713 if (enc_opt_data
.data
!= NULL
) {
6714 data_string_forget(&enc_opt_data
, MDL
);
6716 if (enc_packet
!= NULL
) {
6717 packet_dereference(&enc_packet
, MDL
);
6722 /* \brief Internal processing of a relayed DHCPv4-query
6723 * (DHCPv4 server side)
6725 * Code copied from \ref dhcpv6_relay_forw() which itself is
6726 * from \ref do_packet6().
6728 * \param reply_ret pointer to the response
6729 * \param packet the query
6732 dhcp4o6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
6733 struct option_cache
*oc
;
6734 struct data_string enc_opt_data
;
6735 struct packet
*enc_packet
;
6736 unsigned char msg_type
;
6737 const struct dhcpv6_relay_packet
*relay
;
6738 const struct dhcpv4_over_dhcpv6_packet
*msg
;
6739 struct data_string enc_reply
;
6740 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6741 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6742 struct data_string a_opt
, packet_ero
;
6743 struct option_state
*opt_state
;
6744 static char reply_data
[65536];
6745 struct dhcpv6_relay_packet
*reply
;
6749 * Initialize variables for early exit.
6752 memset(&a_opt
, 0, sizeof(a_opt
));
6753 memset(&packet_ero
, 0, sizeof(packet_ero
));
6754 memset(&enc_reply
, 0, sizeof(enc_reply
));
6755 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6759 * Get our encapsulated relay message.
6761 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
6763 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
6764 link_addr
, sizeof(link_addr
));
6765 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
6766 peer_addr
, sizeof(peer_addr
));
6767 log_info("Relay-forward from %s with link address=%s and "
6768 "peer address=%s missing Relay Message option.",
6769 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
6773 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
6774 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
6775 log_error("dhcp4o6_relay_forw: error evaluating "
6776 "relayed message.");
6780 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
6781 log_error("dhcp4o6_relay_forw: "
6782 "encapsulated packet too short.");
6787 * Build a packet structure from this encapsulated packet.
6789 if (!packet_allocate(&enc_packet
, MDL
)) {
6790 log_error("dhcp4o6_relay_forw: "
6791 "no memory for encapsulated packet.");
6795 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
6796 log_error("dhcp4o6_relay_forw: "
6797 "no memory for encapsulated packet's options.");
6801 enc_packet
->client_port
= packet
->client_port
;
6802 enc_packet
->client_addr
= packet
->client_addr
;
6803 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
6804 enc_packet
->dhcpv6_container_packet
= packet
;
6806 msg_type
= enc_opt_data
.data
[0];
6807 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
6808 (msg_type
== DHCPV6_RELAY_REPL
)) {
6809 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6810 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
6811 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
6813 /* relay-specific data */
6814 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
6815 memcpy(&enc_packet
->dhcpv6_link_address
,
6816 relay
->link_address
, sizeof(relay
->link_address
));
6817 memcpy(&enc_packet
->dhcpv6_peer_address
,
6818 relay
->peer_address
, sizeof(relay
->peer_address
));
6820 if (!parse_option_buffer(enc_packet
->options
,
6822 enc_opt_data
.len
- relaylen
,
6823 &dhcpv6_universe
)) {
6824 /* no logging here, as parse_option_buffer() logs all
6825 cases where it fails */
6828 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
6829 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6831 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
6832 msg
= (struct dhcpv4_over_dhcpv6_packet
*)enc_opt_data
.data
;
6833 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
6835 /* message-specific data */
6836 memcpy(enc_packet
->dhcp4o6_flags
,
6838 sizeof(enc_packet
->dhcp4o6_flags
));
6840 if (!parse_option_buffer(enc_packet
->options
,
6842 enc_opt_data
.len
- msglen
,
6843 &dhcpv6_universe
)) {
6844 /* no logging here, as parse_option_buffer() logs all
6845 cases where it fails */
6849 log_error("dhcp4o6_relay_forw: unexpected message of type %d.",
6855 * This is recursive. It is possible to exceed maximum packet size.
6856 * XXX: This will cause the packet send to fail.
6858 build_dhcpv6_reply(&enc_reply
, enc_packet
);
6861 * If we got no encapsulated data, then it is discarded, and
6862 * our reply-forw is also discarded.
6864 if (enc_reply
.data
== NULL
) {
6869 * Now we can use the reply_data buffer.
6870 * Packet header stuff all comes from the forward message.
6872 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
6873 reply
->msg_type
= DHCPV6_RELAY_REPL
;
6874 reply
->hop_count
= packet
->dhcpv6_hop_count
;
6875 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
6876 sizeof(reply
->link_address
));
6877 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
6878 sizeof(reply
->peer_address
));
6879 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6882 * Get the reply option state.
6884 if (!option_state_allocate(&opt_state
, MDL
)) {
6885 log_error("dhcp4o6_relay_forw: no memory for option state.");
6890 * Append the interface-id if present.
6892 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6895 if (!evaluate_option_cache(&a_opt
, packet
,
6897 packet
->options
, NULL
,
6898 &global_scope
, oc
, MDL
)) {
6899 log_error("dhcp4o6_relay_forw: error evaluating "
6903 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6904 (unsigned char *)a_opt
.data
,
6906 D6O_INTERFACE_ID
, 0)) {
6907 log_error("dhcp4o6_relay_forw: error saving "
6911 data_string_forget(&a_opt
, MDL
);
6915 * Append our encapsulated stuff for caller.
6917 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6918 (unsigned char *)enc_reply
.data
,
6920 D6O_RELAY_MSG
, 0)) {
6921 log_error("dhcp4o6_relay_forw: error saving Relay MSG.");
6926 * Get the ERO if any.
6928 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
6933 if (!evaluate_option_cache(&packet_ero
, packet
,
6935 packet
->options
, NULL
,
6936 &global_scope
, oc
, MDL
) ||
6937 (packet_ero
.len
& 1)) {
6938 log_error("dhcp4o6_relay_forw: error evaluating ERO.");
6942 /* Decode and apply the ERO. */
6943 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
6944 req
= getUShort(packet_ero
.data
+ i
);
6945 /* Already in the reply? */
6946 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
6949 /* Get it from the packet if present. */
6950 oc
= lookup_option(&dhcpv6_universe
,
6955 if (!evaluate_option_cache(&a_opt
, packet
,
6957 packet
->options
, NULL
,
6958 &global_scope
, oc
, MDL
)) {
6959 log_error("dhcp4o6_relay_forw: error "
6960 "evaluating option %u.", req
);
6963 if (!save_option_buffer(&dhcpv6_universe
,
6966 (unsigned char *)a_opt
.data
,
6970 log_error("dhcp4o6_relay_forw: error saving "
6974 data_string_forget(&a_opt
, MDL
);
6978 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
6979 sizeof(reply_data
) - reply_ofs
,
6981 required_opts_agent
, &packet_ero
);
6984 * Return our reply to the caller.
6986 reply_ret
->len
= reply_ofs
;
6987 reply_ret
->buffer
= NULL
;
6988 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
6989 log_fatal("No memory to store reply.");
6991 reply_ret
->data
= reply_ret
->buffer
->data
;
6992 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
6995 if (opt_state
!= NULL
)
6996 option_state_dereference(&opt_state
, MDL
);
6997 if (a_opt
.data
!= NULL
) {
6998 data_string_forget(&a_opt
, MDL
);
7000 if (packet_ero
.data
!= NULL
) {
7001 data_string_forget(&packet_ero
, MDL
);
7003 if (enc_reply
.data
!= NULL
) {
7004 data_string_forget(&enc_reply
, MDL
);
7006 if (enc_opt_data
.data
!= NULL
) {
7007 data_string_forget(&enc_opt_data
, MDL
);
7009 if (enc_packet
!= NULL
) {
7010 packet_dereference(&enc_packet
, MDL
);
7015 * \brief Internal processing of a DHCPv4-query
7016 * (DHCPv4 server function)
7018 * Code copied from \ref do_packet().
7020 * \param reply_ret pointer to the response
7021 * \param packet the query
7024 dhcp4o6_dhcpv4_query(struct data_string
*reply_ret
, struct packet
*packet
) {
7025 struct option_cache
*oc
;
7026 struct data_string enc_opt_data
;
7027 struct packet
*enc_packet
;
7028 struct data_string enc_response
;
7029 struct option_state
*opt_state
;
7030 static char response_data
[65536];
7031 struct dhcpv4_over_dhcpv6_packet
*response
;
7035 * Initialize variables for early exit.
7038 memset(&enc_response
, 0, sizeof(enc_response
));
7039 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
7043 * Get our encapsulated relay message.
7045 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_DHCPV4_MSG
);
7047 log_info("DHCPv4-query from %s missing DHCPv4 Message option.",
7048 piaddr(packet
->client_addr
));
7052 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
7053 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
7054 log_error("dhcp4o6_dhcpv4_query: error evaluating "
7059 if (enc_opt_data
.len
< DHCP_FIXED_NON_UDP
) {
7060 log_error("dhcp4o6_dhcpv4_query: DHCPv4 packet too short.");
7065 * Build a packet structure from this encapsulated packet.
7067 if (!packet_allocate(&enc_packet
, MDL
)) {
7068 log_error("dhcp4o6_dhcpv4_query: "
7069 "no memory for encapsulated packet.");
7073 enc_packet
->raw
= (struct dhcp_packet
*)enc_opt_data
.data
;
7074 enc_packet
->packet_length
= enc_opt_data
.len
;
7075 enc_packet
->dhcp4o6_response
= &enc_response
;
7076 enc_packet
->client_port
= packet
->client_port
;
7077 enc_packet
->client_addr
= packet
->client_addr
;
7078 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
7079 enc_packet
->dhcpv6_container_packet
= packet
;
7080 if (packet
->dhcp4o6_flags
[0] & DHCP4O6_QUERY_UNICAST
)
7081 enc_packet
->unicast
= 1;
7083 if (enc_packet
->raw
->hlen
> sizeof(enc_packet
->raw
->chaddr
)) {
7084 log_info("dhcp4o6_dhcpv4_query: "
7085 "discarding packet with bogus hlen.");
7089 /* Allocate packet->options now so it is non-null for all packets */
7090 if (!option_state_allocate (&enc_packet
->options
, MDL
)) {
7091 log_error("dhcp4o6_dhcpv4_query: no memory for options.");
7095 /* If there's an option buffer, try to parse it. */
7096 if (enc_packet
->packet_length
>= DHCP_FIXED_NON_UDP
+ 4) {
7097 struct option_cache
*op
;
7098 if (!parse_options(enc_packet
)) {
7099 if (enc_packet
->options
)
7100 option_state_dereference
7101 (&enc_packet
->options
, MDL
);
7102 packet_dereference (&enc_packet
, MDL
);
7106 if (enc_packet
->options_valid
&&
7107 (op
= lookup_option(&dhcp_universe
,
7108 enc_packet
->options
,
7109 DHO_DHCP_MESSAGE_TYPE
))) {
7110 struct data_string dp
;
7111 memset(&dp
, 0, sizeof dp
);
7112 evaluate_option_cache(&dp
, enc_packet
, NULL
, NULL
,
7113 enc_packet
->options
, NULL
,
7116 enc_packet
->packet_type
= dp
.data
[0];
7118 enc_packet
->packet_type
= 0;
7119 data_string_forget(&dp
, MDL
);
7123 if (validate_packet(enc_packet
) != 0) {
7124 if (enc_packet
->packet_type
)
7130 /* If the caller kept the packet, they'll have upped the refcnt. */
7131 packet_dereference(&enc_packet
, MDL
);
7134 * If we got no response data, then it is discarded, and
7135 * our DHCPv4-response is also discarded.
7137 if (enc_response
.data
== NULL
) {
7142 * Now we can use the response_data buffer.
7144 response
= (struct dhcpv4_over_dhcpv6_packet
*)response_data
;
7145 response
->msg_type
= DHCPV6_DHCPV4_RESPONSE
;
7146 response
->flags
[0] = response
->flags
[1] = response
->flags
[2] = 0;
7148 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7151 * Get the response option state.
7153 if (!option_state_allocate(&opt_state
, MDL
)) {
7154 log_error("dhcp4o6_dhcpv4_query: no memory for option state.");
7159 * Append our encapsulated stuff for caller.
7161 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7162 (unsigned char *)enc_response
.data
,
7164 D6O_DHCPV4_MSG
, 0)) {
7165 log_error("dhcp4o6_dhcpv4_query: error saving DHCPv4 MSG.");
7169 response_ofs
+= store_options6(response_data
+ response_ofs
,
7170 sizeof(response_data
) - response_ofs
,
7172 required_opts_4o6
, NULL
);
7175 * Return our response to the caller.
7177 reply_ret
->len
= response_ofs
;
7178 reply_ret
->buffer
= NULL
;
7179 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
7180 log_fatal("dhcp4o6_dhcpv4_query: no memory to store reply.");
7182 reply_ret
->data
= reply_ret
->buffer
->data
;
7183 memcpy(reply_ret
->buffer
->data
, response_data
, response_ofs
);
7186 if (opt_state
!= NULL
)
7187 option_state_dereference(&opt_state
, MDL
);
7188 if (enc_response
.data
!= NULL
) {
7189 data_string_forget(&enc_response
, MDL
);
7191 if (enc_opt_data
.data
!= NULL
) {
7192 data_string_forget(&enc_opt_data
, MDL
);
7194 if (enc_packet
!= NULL
) {
7195 packet_dereference(&enc_packet
, MDL
);
7200 * \brief Forward a DHCPv4-query message to the DHCPv4 side
7201 * (DHCPv6 server function)
7203 * Format: interface:16 + address:16 + DHCPv6 DHCPv4-query message
7205 * \brief packet the DHCPv6 DHCPv4-query message
7207 static void forw_dhcpv4_query(struct packet
*packet
) {
7208 struct data_string ds
;
7212 /* Get the initial message. */
7213 while (packet
->dhcpv6_container_packet
!= NULL
)
7214 packet
= packet
->dhcpv6_container_packet
;
7216 /* Check the initial message. */
7217 if ((packet
->raw
== NULL
) ||
7218 (packet
->client_addr
.len
!= 16) ||
7219 (packet
->interface
== NULL
)) {
7220 log_error("forw_dhcpv4_query: can't find initial message.");
7225 len
= packet
->packet_length
+ 32;
7226 memset(&ds
, 0, sizeof(ds
));
7227 if (!buffer_allocate(&ds
.buffer
, len
, MDL
)) {
7228 log_error("forw_dhcpv4_query: "
7229 "no memory for encapsulating packet.");
7232 ds
.data
= ds
.buffer
->data
;
7235 /* Fill the buffer. */
7236 strncpy((char *)ds
.buffer
->data
, packet
->interface
->name
, 16);
7237 memcpy(ds
.buffer
->data
+ 16,
7238 packet
->client_addr
.iabuf
, 16);
7239 memcpy(ds
.buffer
->data
+ 32,
7240 (unsigned char *)packet
->raw
,
7241 packet
->packet_length
);
7243 /* Forward to the DHCPv4 server. */
7244 cc
= send(dhcp4o6_fd
, ds
.data
, ds
.len
, 0);
7246 log_error("forw_dhcpv4_query: send(): %m");
7247 data_string_forget(&ds
, MDL
);
7252 dhcpv6_discard(struct packet
*packet
) {
7253 /* INSIST(packet->msg_type > 0); */
7254 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
7256 log_debug("Discarding %s from %s; message type not handled by server",
7257 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7258 piaddr(packet
->client_addr
));
7262 build_dhcpv6_reply(struct data_string
*reply
, struct packet
*packet
) {
7263 memset(reply
, 0, sizeof(*reply
));
7265 /* I would like to classify the client once here, but
7266 * as I don't want to classify all of the incoming packets
7267 * I need to do it before handling specific types.
7268 * We don't need to classify if we are tossing the packet
7269 * or if it is a relay - the classification step will get
7270 * done when we process the inner client packet.
7273 switch (packet
->dhcpv6_msg_type
) {
7274 case DHCPV6_SOLICIT
:
7275 classify_client(packet
);
7276 dhcpv6_solicit(reply
, packet
);
7278 case DHCPV6_ADVERTISE
:
7279 dhcpv6_discard(packet
);
7281 case DHCPV6_REQUEST
:
7282 classify_client(packet
);
7283 dhcpv6_request(reply
, packet
);
7285 case DHCPV6_CONFIRM
:
7286 classify_client(packet
);
7287 dhcpv6_confirm(reply
, packet
);
7290 classify_client(packet
);
7291 dhcpv6_renew(reply
, packet
);
7294 classify_client(packet
);
7295 dhcpv6_rebind(reply
, packet
);
7298 dhcpv6_discard(packet
);
7300 case DHCPV6_RELEASE
:
7301 classify_client(packet
);
7302 dhcpv6_release(reply
, packet
);
7304 case DHCPV6_DECLINE
:
7305 classify_client(packet
);
7306 dhcpv6_decline(reply
, packet
);
7308 case DHCPV6_RECONFIGURE
:
7309 dhcpv6_discard(packet
);
7311 case DHCPV6_INFORMATION_REQUEST
:
7312 classify_client(packet
);
7313 dhcpv6_information_request(reply
, packet
);
7315 case DHCPV6_RELAY_FORW
:
7317 if (dhcpv4_over_dhcpv6
&& (local_family
== AF_INET
))
7318 dhcp4o6_relay_forw(reply
, packet
);
7320 #endif /* DHCP4o6 */
7321 dhcpv6_relay_forw(reply
, packet
);
7323 case DHCPV6_RELAY_REPL
:
7324 dhcpv6_discard(packet
);
7326 case DHCPV6_LEASEQUERY
:
7327 classify_client(packet
);
7328 dhcpv6_leasequery(reply
, packet
);
7330 case DHCPV6_LEASEQUERY_REPLY
:
7331 dhcpv6_discard(packet
);
7333 case DHCPV6_DHCPV4_QUERY
:
7335 if (dhcpv4_over_dhcpv6
) {
7336 if (local_family
== AF_INET6
) {
7337 forw_dhcpv4_query(packet
);
7339 dhcp4o6_dhcpv4_query(reply
, packet
);
7342 #endif /* DHCP4o6 */
7343 dhcpv6_discard(packet
);
7345 case DHCPV6_DHCPV4_RESPONSE
:
7346 dhcpv6_discard(packet
);
7349 /* XXX: would be nice if we had "notice" level,
7350 as syslog, for this */
7351 log_info("Discarding unknown DHCPv6 message type %d "
7352 "from %s", packet
->dhcpv6_msg_type
,
7353 piaddr(packet
->client_addr
));
7358 log_packet_in(const struct packet
*packet
) {
7359 struct data_string s
;
7361 char tmp_addr
[INET6_ADDRSTRLEN
];
7364 memset(&s
, 0, sizeof(s
));
7366 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
7367 data_string_sprintfa(&s
, "%s message from %s port %d",
7368 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7369 piaddr(packet
->client_addr
),
7370 ntohs(packet
->client_port
));
7372 data_string_sprintfa(&s
,
7373 "Unknown message type %d from %s port %d",
7374 packet
->dhcpv6_msg_type
,
7375 piaddr(packet
->client_addr
),
7376 ntohs(packet
->client_port
));
7378 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7379 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7380 addr
= &packet
->dhcpv6_link_address
;
7381 data_string_sprintfa(&s
, ", link address %s",
7382 inet_ntop(AF_INET6
, addr
,
7383 tmp_addr
, sizeof(tmp_addr
)));
7384 addr
= &packet
->dhcpv6_peer_address
;
7385 data_string_sprintfa(&s
, ", peer address %s",
7386 inet_ntop(AF_INET6
, addr
,
7387 tmp_addr
, sizeof(tmp_addr
)));
7388 } else if ((packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_QUERY
) &&
7389 (packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_RESPONSE
)) {
7391 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
7392 data_string_sprintfa(&s
, ", transaction ID 0x%06X", tid
);
7395 oc = lookup_option(&dhcpv6_universe, packet->options,
7398 memset(&tmp_ds, 0, sizeof(tmp_ds_));
7399 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
7400 packet->options, NULL,
7401 &global_scope, oc, MDL)) {
7402 log_error("Error evaluating Client Identifier");
7404 data_strint_sprintf(&s, ", client ID %s",
7406 data_string_forget(&tmp_ds, MDL);
7412 log_info("%s", s
.data
);
7414 data_string_forget(&s
, MDL
);
7418 dhcpv6(struct packet
*packet
) {
7419 struct data_string reply
;
7420 struct sockaddr_in6 to_addr
;
7424 * Log a message that we received this packet.
7426 log_packet_in(packet
);
7429 * Build our reply packet.
7431 build_dhcpv6_reply(&reply
, packet
);
7433 if (reply
.data
!= NULL
) {
7435 * Send our reply, if we have one.
7437 memset(&to_addr
, 0, sizeof(to_addr
));
7438 to_addr
.sin6_family
= AF_INET6
;
7439 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7440 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7441 to_addr
.sin6_port
= local_port
;
7443 to_addr
.sin6_port
= remote_port
;
7446 #if defined (REPLY_TO_SOURCE_PORT)
7448 * This appears to have been included for testing so we would
7449 * not need a root client, but was accidently left in the
7450 * final code. We continue to include it in case
7451 * some users have come to rely upon it, but leave
7452 * it off by default as it's a bad idea.
7454 to_addr
.sin6_port
= packet
->client_port
;
7457 memcpy(&to_addr
.sin6_addr
, packet
->client_addr
.iabuf
,
7458 sizeof(to_addr
.sin6_addr
));
7460 log_info("Sending %s to %s port %d",
7461 dhcpv6_type_names
[reply
.data
[0]],
7462 piaddr(packet
->client_addr
),
7463 ntohs(to_addr
.sin6_port
));
7465 send_ret
= send_packet6(packet
->interface
,
7466 reply
.data
, reply
.len
, &to_addr
);
7467 if (send_ret
!= reply
.len
) {
7468 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
7469 send_ret
, reply
.len
);
7471 data_string_forget(&reply
, MDL
);
7477 * \brief Receive a DHCPv4-query message from the DHCPv6 side
7478 * (DHCPv4 server function)
7480 * Receive a message with a DHCPv4-query inside from the DHCPv6 server.
7481 * (code copied from \ref do_packet6() \ref and dhcpv6())
7483 * Format: interface:16 + address:16 + DHCPv6 DHCPv4-query message
7485 * \param raw the DHCPv6 DHCPv4-query message raw content
7487 static void recv_dhcpv4_query(struct data_string
*raw
) {
7488 struct interface_info
*ip
;
7491 struct packet
*packet
;
7492 unsigned char msg_type
;
7493 const struct dhcpv6_relay_packet
*relay
;
7494 const struct dhcpv4_over_dhcpv6_packet
*msg
;
7495 struct data_string reply
;
7496 struct data_string ds
;
7500 memset(name
, 0, sizeof(name
));
7501 memcpy(name
, raw
->data
, 16);
7502 for (ip
= interfaces
; ip
!= NULL
; ip
= ip
->next
) {
7503 if (!strcmp(name
, ip
->name
))
7507 log_error("recv_dhcpv4_query: can't find interface %s.",
7513 memcpy(iaddr
.iabuf
, raw
->data
+ 16, 16);
7516 * From do_packet6().
7519 if (!packet6_len_okay((char *)raw
->data
+ 32, raw
->len
- 32)) {
7520 log_error("recv_dhcpv4_query: "
7521 "short packet from %s, len %d, dropped",
7522 piaddr(iaddr
), raw
->len
- 32);
7527 * Build a packet structure.
7530 if (!packet_allocate(&packet
, MDL
)) {
7531 log_error("recv_dhcpv4_query: no memory for packet.");
7535 if (!option_state_allocate(&packet
->options
, MDL
)) {
7536 log_error("recv_dhcpv4_query: no memory for options.");
7537 packet_dereference(&packet
, MDL
);
7541 packet
->raw
= (struct dhcp_packet
*)(raw
->data
+ 32);
7542 packet
->packet_length
= raw
->len
- 32;
7543 packet
->client_port
= remote_port
;
7544 packet
->client_addr
= iaddr
;
7545 interface_reference(&packet
->interface
, ip
, MDL
);
7547 msg_type
= raw
->data
[32];
7548 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
7549 (msg_type
== DHCPV6_RELAY_REPL
)) {
7551 (int)(offsetof(struct dhcpv6_relay_packet
, options
));
7552 relay
= (const struct dhcpv6_relay_packet
*)(raw
->data
+ 32);
7553 packet
->dhcpv6_msg_type
= relay
->msg_type
;
7555 /* relay-specific data */
7556 packet
->dhcpv6_hop_count
= relay
->hop_count
;
7557 memcpy(&packet
->dhcpv6_link_address
,
7558 relay
->link_address
, sizeof(relay
->link_address
));
7559 memcpy(&packet
->dhcpv6_peer_address
,
7560 relay
->peer_address
, sizeof(relay
->peer_address
));
7562 if (!parse_option_buffer(packet
->options
,
7564 raw
->len
- 32 - relaylen
,
7565 &dhcpv6_universe
)) {
7566 /* no logging here, as parse_option_buffer() logs all
7567 cases where it fails */
7568 packet_dereference(&packet
, MDL
);
7571 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
7572 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
7574 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7575 msg
= (struct dhcpv4_over_dhcpv6_packet
*)(raw
->data
+ 32);
7576 packet
->dhcpv6_msg_type
= msg
->msg_type
;
7578 /* message-specific data */
7579 memcpy(packet
->dhcp4o6_flags
, msg
->flags
,
7580 sizeof(packet
->dhcp4o6_flags
));
7582 if (!parse_option_buffer(packet
->options
,
7584 raw
->len
- 32 - msglen
,
7585 &dhcpv6_universe
)) {
7586 /* no logging here, as parse_option_buffer() logs all
7587 cases where it fails */
7588 packet_dereference(&packet
, MDL
);
7592 log_error("recv_dhcpv4_query: unexpected message of type %d.",
7594 packet_dereference(&packet
, MDL
);
7603 * Log a message that we received this packet.
7605 /* log_packet_in(packet); */
7606 memset(&ds
, 0, sizeof(ds
));
7607 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
7608 data_string_sprintfa(&ds
, "%s message from %s",
7609 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7610 piaddr(packet
->client_addr
));
7612 data_string_sprintfa(&ds
,
7613 "Unknown message type %d from %s",
7614 packet
->dhcpv6_msg_type
,
7615 piaddr(packet
->client_addr
));
7617 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7618 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7619 char tmp_addr
[INET6_ADDRSTRLEN
];
7622 addr
= &packet
->dhcpv6_link_address
;
7623 data_string_sprintfa(&ds
, ", link address %s",
7624 inet_ntop(AF_INET6
, addr
,
7625 tmp_addr
, sizeof(tmp_addr
)));
7626 addr
= &packet
->dhcpv6_peer_address
;
7627 data_string_sprintfa(&ds
, ", peer address %s",
7628 inet_ntop(AF_INET6
, addr
,
7629 tmp_addr
, sizeof(tmp_addr
)));
7630 } else if ((packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_QUERY
) &&
7631 (packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_RESPONSE
)) {
7634 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
7635 data_string_sprintfa(&ds
, ", transaction ID 0x%06X", tid
);
7637 log_info("%s", ds
.data
);
7638 data_string_forget(&ds
, MDL
);
7641 * Build our reply packet.
7643 build_dhcpv6_reply(&reply
, packet
);
7645 packet_dereference(&packet
, MDL
);
7647 if (reply
.data
== NULL
)
7651 * Forward the response.
7653 len
= reply
.len
+ 32;
7654 memset(&ds
, 0, sizeof(ds
));
7655 if (!buffer_allocate(&ds
.buffer
, len
, MDL
)) {
7656 log_error("recv_dhcpv4_query: no memory.");
7659 ds
.data
= ds
.buffer
->data
;
7662 memcpy(ds
.buffer
->data
, name
, 16);
7663 memcpy(ds
.buffer
->data
+ 16, iaddr
.iabuf
, 16);
7664 memcpy(ds
.buffer
->data
+ 32, reply
.data
, reply
.len
);
7665 cc
= send(dhcp4o6_fd
, ds
.data
, ds
.len
, 0);
7667 log_error("recv_dhcpv4_query: send(): %m");
7668 data_string_forget(&ds
, MDL
);
7670 #endif /* DHCP4o6 */
7673 seek_shared_host(struct host_decl
**hp
, struct shared_network
*shared
) {
7674 struct host_decl
*nofixed
= NULL
;
7675 struct host_decl
*seek
, *hold
= NULL
;
7678 * Seek forward through fixed addresses for the right link.
7680 * Note: how to do this for fixed prefixes???
7682 host_reference(&hold
, *hp
, MDL
);
7683 host_dereference(hp
, MDL
);
7685 while (seek
!= NULL
) {
7686 if (seek
->fixed_addr
== NULL
)
7688 else if (fixed_matches_shared(seek
, shared
))
7691 seek
= seek
->n_ipaddr
;
7694 if ((seek
== NULL
) && (nofixed
!= NULL
))
7698 host_reference(hp
, seek
, MDL
);
7701 static isc_boolean_t
7702 fixed_matches_shared(struct host_decl
*host
, struct shared_network
*shared
) {
7703 struct subnet
*subnet
;
7704 struct data_string addr
;
7705 isc_boolean_t matched
;
7708 if (host
->fixed_addr
== NULL
)
7711 memset(&addr
, 0, sizeof(addr
));
7712 if (!evaluate_option_cache(&addr
, NULL
, NULL
, NULL
, NULL
, NULL
,
7713 &global_scope
, host
->fixed_addr
, MDL
))
7716 if (addr
.len
< 16) {
7717 data_string_forget(&addr
, MDL
);
7722 memcpy(fixed
.iabuf
, addr
.data
, 16);
7724 matched
= ISC_FALSE
;
7725 for (subnet
= shared
->subnets
; subnet
!= NULL
;
7726 subnet
= subnet
->next_sibling
) {
7727 if (addr_eq(subnet_number(fixed
, subnet
->netmask
),
7734 data_string_forget(&addr
, MDL
);
7740 * \brief Constructs a REPLY with status of UseMulticast to a given packet
7742 * Per RFC 3315 Secs 18.2.1,3,6 & 7, when a server rejects a client's
7743 * unicast-sent packet, the response must only contain the client id,
7744 * server id, and a status code option of 5 (UseMulticast). This function
7745 * constructs such a packet and returns it as a data_string.
7747 * \param reply_ret = data_string which will receive the newly constructed
7749 * \param packet = client request which is being rejected
7750 * \param client_id = data_string which contains the client id
7751 * \param server_id = data_string which which contains the server id
7755 unicast_reject(struct data_string
*reply_ret
,
7756 struct packet
*packet
,
7757 const struct data_string
*client_id
,
7758 const struct data_string
*server_id
)
7760 struct reply_state reply
;
7761 memset(&reply
, 0x0, sizeof(struct reply_state
));
7763 /* Locate the client. */
7764 if (shared_network_from_packet6(&reply
.shared
, packet
)
7766 log_error("unicast_reject: could not locate client.");
7770 /* Initialize the reply. */
7771 packet_reference(&reply
.packet
, packet
, MDL
);
7772 data_string_copy(&reply
.client_id
, client_id
, MDL
);
7774 if (start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
7775 &reply
.buf
.reply
)) {
7776 /* Set the UseMulticast status code. */
7777 if (!set_status_code(STATUS_UseMulticast
,
7778 "Unicast not allowed by server.",
7780 log_error("unicast_reject: Unable to set status code.");
7782 /* Set write cursor to just past the reply header. */
7783 reply
.cursor
= REPLY_OPTIONS_INDEX
;
7784 reply
.cursor
+= store_options6(((char *)reply
.buf
.data
7790 unicast_reject_opts
,
7793 /* Return our reply to the caller. */
7794 reply_ret
->len
= reply
.cursor
;
7795 reply_ret
->buffer
= NULL
;
7796 if (!buffer_allocate(&reply_ret
->buffer
,
7797 reply
.cursor
, MDL
)) {
7798 log_fatal("unicast_reject:"
7799 "No memory to store Reply.");
7802 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
,
7804 reply_ret
->data
= reply_ret
->buffer
->data
;
7810 if (reply
.shared
!= NULL
)
7811 shared_network_dereference(&reply
.shared
, MDL
);
7812 if (reply
.opt_state
!= NULL
)
7813 option_state_dereference(&reply
.opt_state
, MDL
);
7814 if (reply
.packet
!= NULL
)
7815 packet_dereference(&reply
.packet
, MDL
);
7816 if (reply
.client_id
.data
!= NULL
)
7817 data_string_forget(&reply
.client_id
, MDL
);
7822 * \brief Checks if the dhcp6.unicast option has been defined
7824 * Scans the option space for the presence of the dhcp6.unicast option. The
7825 * function attempts to map the inbound packet to a shared network first
7826 * by an ip address specified via an D6O_IA_XX option and if that fails then
7827 * by the packet's source information (e.g. relay link, link, or interace).
7828 * Once the packet is mapped to a shared network, the function executes all
7829 * statements from the network's group outward into a local option cache.
7830 * The option cache is then scanned for the presence of unicast option. If
7831 * the packet cannot be mapped to a shared network, the function returns
7833 * \param packet inbound packet from the client
7835 * \return ISC_TRUE if the dhcp6.unicast option is defined, false otherwise.
7839 is_unicast_option_defined(struct packet
*packet
) {
7840 isc_boolean_t is_defined
= ISC_FALSE
;
7841 struct option_state
*opt_state
= NULL
;
7842 struct option_cache
*oc
= NULL
;
7843 struct shared_network
*shared
= NULL
;
7845 if (!option_state_allocate(&opt_state
, MDL
)) {
7846 log_fatal("is_unicast_option_defined:"
7847 "No memory for option state.");
7850 /* We try to map the packet to a network first by an IA_XX value.
7851 * If that fails, we try by packet source. */
7852 if (((shared_network_from_requested_addr(&shared
, packet
)
7853 != ISC_R_SUCCESS
) &&
7854 (shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
))
7855 || (shared
== NULL
)) {
7856 /* @todo what would this really mean? I think wrong network
7857 * logic will catch it */
7858 log_error("is_unicast_option_defined:"
7859 "cannot attribute packet to a network.");
7863 /* Now that we've mapped it to a network, execute statments to that
7864 * scope, looking for the unicast option. We don't care about the
7865 * value of the option, only whether or not it is defined. */
7866 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
, opt_state
,
7867 &global_scope
, shared
->group
, NULL
, NULL
);
7869 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_UNICAST
);
7870 is_defined
= (oc
!= NULL
? ISC_TRUE
: ISC_FALSE
);
7871 log_debug("is_unicast_option_defined: option found : %d", is_defined
);
7873 if (shared
!= NULL
) {
7874 shared_network_dereference(&shared
, MDL
);
7877 if (opt_state
!= NULL
) {
7878 option_state_dereference(&opt_state
, MDL
);
7881 return (is_defined
);
7886 * \brief Maps a packet to a shared network based on the requested IP address
7888 * The function attempts to find a subnet that matches the first requested IP
7889 * address contained within the given packet. Note that it looks first for
7890 * D6O_IA_NAs, then D6O_IA_PDs and lastly D6O_IA_TAs. If a matching network is
7891 * found, a reference to it is returned in the parameter, shared.
7893 * \param shared shared_network pointer which will receive the matching network
7894 * \param packet inbound packet from the client
7896 * \return ISC_R_SUCCESS if the packet can be mapped to a shared_network.
7900 shared_network_from_requested_addr (struct shared_network
**shared
,
7901 struct packet
* packet
) {
7903 struct subnet
* subnet
= NULL
;
7904 isc_result_t status
= ISC_R_FAILURE
;
7906 /* Try to match first IA_ address or prefix we find to a subnet. In
7907 * theory all IA_ values in a given request are supposed to be in the
7908 * same subnet so we only need to try one right? */
7909 if ((get_first_ia_addr_val(packet
, D6O_IA_NA
, &iaddr
) != ISC_R_SUCCESS
)
7910 && (get_first_ia_addr_val(packet
, D6O_IA_PD
, &iaddr
)
7912 && (get_first_ia_addr_val(packet
, D6O_IA_TA
, &iaddr
)
7913 != ISC_R_SUCCESS
)) {
7914 /* we found nothing to match against */
7915 log_debug("share_network_from_request_addr: nothing to match");
7916 return (ISC_R_FAILURE
);
7919 if (!find_subnet(&subnet
, iaddr
, MDL
)) {
7920 log_debug("shared_network_from_requested_addr:"
7921 "No subnet found for addr %s.", piaddr(iaddr
));
7923 status
= shared_network_reference(shared
,
7924 subnet
->shared_network
, MDL
);
7925 subnet_dereference(&subnet
, MDL
);
7926 log_debug("shared_network_from_requested_addr:"
7927 " found shared network %s for address %s.",
7928 ((*shared
)->name
? (*shared
)->name
: "unnamed"),
7933 return (ISC_R_FAILURE
);
7938 * \brief Retrieves the first IP address from a given packet of a given type
7940 * Search a packet for options of a given type (D6O_IA_AN, D6O_IA_PD, or
7941 * D6O_IA_TA) for the first non-blank IA_XX value and return its IP address
7944 * \param packet packet received from the client
7945 * \param addr_type the address option type (D6O_IA_NA , D6O_IA_PD, or
7946 * D6O_IP_TA) to look for within the packet.
7947 * \param iaddr pointer to the iaddr structure which will receive the extracted
7950 * \return ISC_R_SUCCESS if an address was succesfully extracted, ISC_R_FALURE
7955 get_first_ia_addr_val (struct packet
* packet
, int addr_type
,
7956 struct iaddr
* iaddr
) {
7957 struct option_cache
*ia
;
7958 struct option_cache
*oc
= NULL
;
7959 struct data_string cli_enc_opt_data
;
7960 struct option_state
*cli_enc_opt_state
;
7961 int addr_opt_offset
;
7963 int addr_opt_data_len
;
7966 isc_result_t status
= ISC_R_FAILURE
;
7967 memset(iaddr
, 0, sizeof(struct iaddr
));
7969 /* Set up address type specifics */
7970 switch (addr_type
) {
7972 addr_opt_offset
= IA_NA_OFFSET
;
7973 addr_opt
= D6O_IAADDR
;
7974 addr_opt_data_len
= 24;
7978 addr_opt_offset
= IA_TA_OFFSET
;
7979 addr_opt
= D6O_IAADDR
;
7980 addr_opt_data_len
= 24;
7984 addr_opt_offset
= IA_PD_OFFSET
;
7985 addr_opt
= D6O_IAPREFIX
;
7986 addr_opt_data_len
= 25;
7990 /* shouldn't be here */
7991 log_error ("get_first_ia_addr_val: invalid opt type %d",
7993 return (ISC_R_FAILURE
);
7996 /* Find the first, non-blank IA_XX value within an D6O_IA_XX option. */
7997 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, addr_type
);
7998 ia
!= NULL
&& oc
== NULL
; ia
= ia
->next
) {
7999 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
8001 packet
, ia
, addr_opt_offset
)) {
8002 log_debug ("get_first_ia_addr_val:"
8003 " couldn't unroll enclosing option");
8004 return (ISC_R_FAILURE
);
8007 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
8010 /* no address given for this IA, ignore */
8011 option_state_dereference(&cli_enc_opt_state
, MDL
);
8012 data_string_forget(&cli_enc_opt_data
, MDL
);
8016 /* If we found a non-blank IA_XX then extract its ip address. */
8018 struct data_string iaddr_str
;
8020 memset(&iaddr_str
, 0, sizeof(iaddr_str
));
8021 if (!evaluate_option_cache(&iaddr_str
, packet
, NULL
, NULL
,
8022 packet
->options
, NULL
, &global_scope
,
8024 log_error("get_first_ia_addr_val: "
8025 "error evaluating IA_XX option.");
8027 if (iaddr_str
.len
!= addr_opt_data_len
) {
8028 log_error("shared_network_from_requested_addr:"
8029 " invalid length %d, expected %d",
8030 iaddr_str
.len
, addr_opt_data_len
);
8033 memcpy (iaddr
->iabuf
,
8034 iaddr_str
.data
+ ip_addr_offset
, 16);
8035 status
= ISC_R_SUCCESS
;
8037 data_string_forget(&iaddr_str
, MDL
);
8040 option_state_dereference(&cli_enc_opt_state
, MDL
);
8041 data_string_forget(&cli_enc_opt_data
, MDL
);
8048 * \brief Calculates the reply T1/T2 times and stuffs them in outbound buffer
8050 * T1/T2 time selection is kind of weird. We actually use DHCP * (v4) scoped
8051 * options, dhcp-renewal-time and dhcp-rebinding-time, as handy existing places
8052 * where these can be configured by an administrator. A value of zero tells the
8053 * client it may choose its own value.
8055 * When those options are not defined, the values will be set to zero unless
8056 * the global option, dhcpv6-set-tee-times is enabled. When this option is
8057 * enabled the values are calculated as recommended by RFC 3315, Section 22.4:
8059 * T1 will be set to 0.5 times the shortest preferred lifetime
8060 * in the IA_XX option. If the "shortest" preferred lifetime is
8061 * 0xFFFFFFFF, T1 will set to 0xFFFFFFFF.
8063 * T2 will be set to 0.8 times the shortest preferred lifetime
8064 * in the IA_XX option. If the "shortest" preferred lifetime is
8065 * 0xFFFFFFFF, T2 will set to 0xFFFFFFFF.
8067 * Note that dhcpv6-set-tee-times is intended to be transitional and will
8068 * likely be removed in 4.4.0, leaving the behavior as getting the values
8069 * either from the configured parameters (if you want zeros, define them as
8070 * zeros) or by calculating them per the RFC.
8072 * \param reply - pointer to the reply_state structure
8073 * \param ia_cursor - offset of the beginning of the IA_XX option within the
8074 * reply's outbound data buffer
8077 set_reply_tee_times(struct reply_state
* reply
, unsigned ia_cursor
)
8079 struct option_cache
*oc
;
8082 /* Found out if calculated values are enabled. */
8083 oc
= lookup_option(&server_universe
, reply
->opt_state
,
8084 SV_DHCPV6_SET_TEE_TIMES
);
8085 set_tee_times
= (oc
&&
8086 evaluate_boolean_option_cache(NULL
, reply
->packet
,
8088 reply
->packet
->options
,
8090 &global_scope
, oc
, MDL
));
8092 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
8093 DHO_DHCP_RENEWAL_TIME
);
8095 /* dhcp-renewal-time is defined, use it */
8096 struct data_string data
;
8097 memset(&data
, 0x00, sizeof(data
));
8099 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
8100 reply
->packet
->options
,
8101 reply
->opt_state
, &global_scope
,
8104 log_error("Invalid renewal time.");
8107 reply
->renew
= getULong(data
.data
);
8110 if (data
.data
!= NULL
)
8111 data_string_forget(&data
, MDL
);
8112 } else if (set_tee_times
) {
8113 /* Setting them is enabled so T1 is either infinite or
8114 * 0.5 * the shortest preferred lifetime in the IA_XX */
8115 if (reply
->min_prefer
== INFINITE_TIME
)
8116 reply
->renew
= INFINITE_TIME
;
8118 reply
->renew
= reply
->min_prefer
/ 2;
8120 /* Default is to let the client choose */
8124 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
8127 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
8128 DHO_DHCP_REBINDING_TIME
);
8130 /* dhcp-rebinding-time is defined, use it */
8131 struct data_string data
;
8132 memset(&data
, 0x00, sizeof(data
));
8134 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
8135 reply
->packet
->options
,
8136 reply
->opt_state
, &global_scope
,
8139 log_error("Invalid rebinding time.");
8142 reply
->rebind
= getULong(data
.data
);
8145 if (data
.data
!= NULL
)
8146 data_string_forget(&data
, MDL
);
8147 } else if (set_tee_times
) {
8148 /* Setting them is enabled so T2 is either infinite or
8149 * 0.8 * the shortest preferred lifetime in the reply */
8150 if (reply
->min_prefer
== INFINITE_TIME
)
8151 reply
->rebind
= INFINITE_TIME
;
8153 reply
->rebind
= (reply
->min_prefer
/ 5) * 4;
8155 /* Default is to let the client choose */
8159 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
8163 * Releases the iasubopts in the pre-existing IA, if they are not in
8164 * the same shared-network as the new IA.
8166 * returns 1 if the release was done, 0 otherwise
8169 release_on_roam(struct reply_state
* reply
) {
8170 struct ia_xx
* old_ia
= reply
->old_ia
;
8171 struct iasubopt
*lease
= NULL
;
8174 if (old_ia
== NULL
|| old_ia
->num_iasubopt
<= 0) {
8178 /* If the old shared-network and new are the same, client hasn't
8179 * roamed, nothing to do. We only check the first one because you
8180 * cannot have iasubopts on different shared-networks within a
8182 lease
= old_ia
->iasubopt
[0];
8183 if (lease
->ipv6_pool
->shared_network
== reply
->shared
) {
8187 /* Old and new are on different shared networks so the client must
8188 * roamed. Release the old leases. */
8189 for (i
= 0; i
< old_ia
->num_iasubopt
; i
++) {
8190 lease
= old_ia
->iasubopt
[i
];
8192 log_info("Client: %s roamed to new network,"
8193 " releasing lease: %s%s",
8194 print_hex_1(reply
->client_id
.len
,
8195 reply
->client_id
.data
, 60),
8196 pin6_addr(&lease
->addr
), iasubopt_plen_str(lease
));
8198 release_lease6(lease
->ipv6_pool
, lease
);
8199 lease
->ia
->cltt
= cur_time
;
8200 write_ia(lease
->ia
);
8207 * Convenience function which returns a string (static buffer)
8208 * containing either a "/" followed by the prefix length or an
8209 * empty string depending on the lease type
8211 const char *iasubopt_plen_str(struct iasubopt
*lease
) {
8212 static char prefix_buf
[16];
8214 if ((lease
->ia
) && (lease
->ia
->ia_type
== D6O_IA_PD
)) {
8215 sprintf(prefix_buf
, "/%-d", lease
->plen
);
8218 return (prefix_buf
);