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
);
182 static int reuse_lease6(struct reply_state
*reply
, struct iasubopt
*lease
);
183 static void shorten_lifetimes(struct reply_state
*reply
, struct iasubopt
*lease
,
184 time_t age
, int threshold
);
185 static void write_to_packet(struct reply_state
*reply
, unsigned ia_cursor
);
186 static const char *iasubopt_plen_str(struct iasubopt
*lease
);
189 static void ddns_update_static6(struct reply_state
* reply
);
194 * \brief Omapi I/O handler
196 * The inter-process communication receive handler.
197 * Get the message, put it into the raw data_string
198 * and call \ref send_dhcpv4_response() (DHCPv6 side) or
199 * \ref recv_dhcpv4_query() (DHCPv4 side)
201 * \param h the OMAPI object
202 * \return a result for I/O success or error (used by the I/O subsystem)
204 isc_result_t
dhcpv4o6_handler(omapi_object_t
*h
) {
206 struct data_string raw
;
209 if (h
->type
!= dhcp4o6_type
)
210 return DHCP_R_INVALIDARG
;
212 cc
= recv(dhcp4o6_fd
, buf
, sizeof(buf
), 0);
214 if (cc
< DHCP_FIXED_NON_UDP
+ 32)
215 return ISC_R_UNEXPECTED
;
216 memset(&raw
, 0, sizeof(raw
));
217 if (!buffer_allocate(&raw
.buffer
, cc
, MDL
)) {
218 log_error("dhcpv4o6_handler: no memory buffer.");
219 return ISC_R_NOMEMORY
;
221 raw
.data
= raw
.buffer
->data
;
223 memcpy(raw
.buffer
->data
, buf
, cc
);
225 if (local_family
== AF_INET6
) {
226 send_dhcpv4_response(&raw
);
228 recv_dhcpv4_query(&raw
);
231 data_string_forget(&raw
, MDL
);
233 return ISC_R_SUCCESS
;
237 * \brief Send the DHCPv4-response back to the DHCPv6 side
238 * (DHCPv6 server function)
240 * Format: interface:16 + address:16 + DHCPv6 DHCPv4-response message
242 * \param raw the IPC message content
244 static void send_dhcpv4_response(struct data_string
*raw
) {
245 struct interface_info
*ip
;
247 struct sockaddr_in6 to_addr
;
248 char pbuf
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
251 memset(name
, 0, sizeof(name
));
252 memcpy(name
, raw
->data
, 16);
253 for (ip
= interfaces
; ip
!= NULL
; ip
= ip
->next
) {
254 if (!strcmp(name
, ip
->name
))
258 log_error("send_dhcpv4_response: can't find interface %s.",
263 memset(&to_addr
, 0, sizeof(to_addr
));
264 to_addr
.sin6_family
= AF_INET6
;
265 memcpy(&to_addr
.sin6_addr
, raw
->data
+ 16, 16);
266 if ((raw
->data
[32] == DHCPV6_RELAY_FORW
) ||
267 (raw
->data
[32] == DHCPV6_RELAY_REPL
)) {
268 to_addr
.sin6_port
= local_port
;
270 to_addr
.sin6_port
= remote_port
;
273 log_info("send_dhcpv4_response(): sending %s on %s to %s port %d",
274 dhcpv6_type_names
[raw
->data
[32]],
276 inet_ntop(AF_INET6
, raw
->data
+ 16, pbuf
, sizeof(pbuf
)),
277 ntohs(to_addr
.sin6_port
));
279 send_ret
= send_packet6(ip
, raw
->data
+ 32, raw
->len
- 32, &to_addr
);
281 log_error("send_dhcpv4_response: send_packet6(): %m");
282 } else if (send_ret
!= raw
->len
- 32) {
283 log_error("send_dhcpv4_response: send_packet6() "
284 "sent %d of %d bytes",
285 send_ret
, raw
->len
- 32);
291 * Schedule lease timeouts for all of the iasubopts in the reply.
292 * This is currently used to schedule timeouts for soft leases.
296 schedule_lease_timeout_reply(struct reply_state
*reply
) {
297 struct iasubopt
*tmp
;
300 /* sanity check the reply */
301 if ((reply
== NULL
) || (reply
->ia
== NULL
) || (reply
->ia
->iasubopt
== NULL
))
304 /* walk through the list, scheduling as we go */
305 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
306 tmp
= reply
->ia
->iasubopt
[i
];
307 schedule_lease_timeout(tmp
->ipv6_pool
);
312 * This function returns the time since DUID time start for the
313 * given time_t value.
316 duid_time(time_t when
) {
318 * This time is modulo 2^32.
320 while ((when
- DUID_TIME_EPOCH
) > 4294967295u) {
321 /* use 2^31 to avoid spurious compiler warnings */
326 return when
- DUID_TIME_EPOCH
;
333 * This must remain the same for the lifetime of this server, because
334 * clients return the server DUID that we sent them in Request packets.
336 * We pick the server DUID like this:
338 * 1. Check dhcpd.conf - any value the administrator has configured
339 * overrides any possible values.
340 * 2. Check the leases.txt - we want to use the previous value if
342 * 3. Check if dhcpd.conf specifies a type of server DUID to use,
343 * and generate that type.
344 * 4. Generate a type 1 (time + hardware address) DUID.
346 static struct data_string server_duid
;
349 * Check if the server_duid has been set.
352 server_duid_isset(void) {
353 return (server_duid
.data
!= NULL
);
357 * Return the server_duid.
360 copy_server_duid(struct data_string
*ds
, const char *file
, int line
) {
361 data_string_copy(ds
, &server_duid
, file
, line
);
365 * Set the server DUID to a specified value. This is used when
366 * the server DUID is stored in persistent memory (basically the
370 set_server_duid(struct data_string
*new_duid
) {
371 /* INSIST(new_duid != NULL); */
372 /* INSIST(new_duid->data != NULL); */
374 if (server_duid_isset()) {
375 data_string_forget(&server_duid
, MDL
);
377 data_string_copy(&server_duid
, new_duid
, MDL
);
382 * Set the server DUID based on the D6O_SERVERID option. This handles
383 * the case where the administrator explicitly put it in the dhcpd.conf
387 set_server_duid_from_option(void) {
388 struct option_state
*opt_state
;
389 struct option_cache
*oc
;
390 struct data_string option_duid
;
391 isc_result_t ret_val
;
394 if (!option_state_allocate(&opt_state
, MDL
)) {
395 log_fatal("No memory for server DUID.");
398 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
,
399 opt_state
, &global_scope
, root_group
,
402 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
404 ret_val
= ISC_R_NOTFOUND
;
406 memset(&option_duid
, 0, sizeof(option_duid
));
407 if (!evaluate_option_cache(&option_duid
, NULL
, NULL
, NULL
,
408 opt_state
, NULL
, &global_scope
,
410 ret_val
= ISC_R_UNEXPECTED
;
412 set_server_duid(&option_duid
);
413 data_string_forget(&option_duid
, MDL
);
414 ret_val
= ISC_R_SUCCESS
;
418 option_state_dereference(&opt_state
, MDL
);
424 * DUID layout, as defined in RFC 3315, section 9.
426 * We support type 1 (hardware address plus time) and type 3 (hardware
429 * We can support type 2 for specific vendors in the future, if they
430 * publish the specification. And of course there may be additional
433 static int server_duid_type
= DUID_LLT
;
439 set_server_duid_type(int type
) {
440 server_duid_type
= type
;
444 * Generate a new server DUID. This is done if there was no DUID in
445 * the leases.txt or in the dhcpd.conf file.
448 generate_new_server_duid(void) {
449 struct interface_info
*p
;
451 struct data_string generated_duid
;
454 * Verify we have a type that we support.
456 if ((server_duid_type
!= DUID_LL
) && (server_duid_type
!= DUID_LLT
)) {
457 log_error("Invalid DUID type %d specified, "
458 "only LL and LLT types supported", server_duid_type
);
459 return DHCP_R_INVALIDARG
;
463 * Find an interface with a hardware address.
466 for (p
= interfaces
; p
!= NULL
; p
= p
->next
) {
467 if (p
->hw_address
.hlen
> 0) {
472 return ISC_R_UNEXPECTED
;
478 memset(&generated_duid
, 0, sizeof(generated_duid
));
479 if (server_duid_type
== DUID_LLT
) {
480 time_val
= duid_time(time(NULL
));
481 generated_duid
.len
= 8 + p
->hw_address
.hlen
- 1;
482 if (!buffer_allocate(&generated_duid
.buffer
,
483 generated_duid
.len
, MDL
)) {
484 log_fatal("No memory for server DUID.");
486 generated_duid
.data
= generated_duid
.buffer
->data
;
487 putUShort(generated_duid
.buffer
->data
, DUID_LLT
);
488 putUShort(generated_duid
.buffer
->data
+ 2,
489 p
->hw_address
.hbuf
[0]);
490 putULong(generated_duid
.buffer
->data
+ 4, time_val
);
491 memcpy(generated_duid
.buffer
->data
+ 8,
492 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
493 } else if (server_duid_type
== DUID_LL
) {
494 generated_duid
.len
= 4 + p
->hw_address
.hlen
- 1;
495 if (!buffer_allocate(&generated_duid
.buffer
,
496 generated_duid
.len
, MDL
)) {
497 log_fatal("No memory for server DUID.");
499 generated_duid
.data
= generated_duid
.buffer
->data
;
500 putUShort(generated_duid
.buffer
->data
, DUID_LL
);
501 putUShort(generated_duid
.buffer
->data
+ 2,
502 p
->hw_address
.hbuf
[0]);
503 memcpy(generated_duid
.buffer
->data
+ 4,
504 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
506 log_fatal("Unsupported server DUID type %d.", server_duid_type
);
509 set_server_duid(&generated_duid
);
510 data_string_forget(&generated_duid
, MDL
);
512 return ISC_R_SUCCESS
;
516 * Get the client identifier from the packet.
519 get_client_id(struct packet
*packet
, struct data_string
*client_id
) {
520 struct option_cache
*oc
;
523 * Verify our client_id structure is empty.
525 if ((client_id
->data
!= NULL
) || (client_id
->len
!= 0)) {
526 return DHCP_R_INVALIDARG
;
529 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_CLIENTID
);
531 return ISC_R_NOTFOUND
;
534 if (!evaluate_option_cache(client_id
, packet
, NULL
, NULL
,
535 packet
->options
, NULL
,
536 &global_scope
, oc
, MDL
)) {
537 return ISC_R_FAILURE
;
540 return ISC_R_SUCCESS
;
544 * Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
546 * Servers MUST discard any Solicit messages that do not include a
547 * Client Identifier option or that do include a Server Identifier
551 valid_client_msg(struct packet
*packet
, struct data_string
*client_id
) {
553 struct option_cache
*oc
;
554 struct data_string data
;
557 memset(client_id
, 0, sizeof(*client_id
));
558 memset(&data
, 0, sizeof(data
));
560 switch (get_client_id(packet
, client_id
)) {
564 log_debug("Discarding %s from %s; "
565 "client identifier missing",
566 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
567 piaddr(packet
->client_addr
));
570 log_error("Error processing %s from %s; "
571 "unable to evaluate Client Identifier",
572 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
573 piaddr(packet
->client_addr
));
578 * Required by RFC 3315, section 15.
580 if (packet
->unicast
) {
581 log_debug("Discarding %s from %s; packet sent unicast "
583 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
584 piaddr(packet
->client_addr
),
585 print_hex_1(client_id
->len
, client_id
->data
, 60));
590 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
592 if (evaluate_option_cache(&data
, packet
, NULL
, NULL
,
593 packet
->options
, NULL
,
594 &global_scope
, oc
, MDL
)) {
595 log_debug("Discarding %s from %s; "
596 "server identifier found "
597 "(CLIENTID %s, SERVERID %s)",
598 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
599 piaddr(packet
->client_addr
),
600 print_hex_1(client_id
->len
,
601 client_id
->data
, 60),
602 print_hex_2(data
.len
,
605 log_debug("Discarding %s from %s; "
606 "server identifier found "
608 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
609 print_hex_1(client_id
->len
,
610 client_id
->data
, 60),
611 piaddr(packet
->client_addr
));
621 data_string_forget(&data
, MDL
);
624 if (client_id
->len
> 0) {
625 data_string_forget(client_id
, MDL
);
632 * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
633 * 15.9 (slightly different wording, but same meaning):
635 * Servers MUST discard any received Request message that meet any of
636 * the following conditions:
638 * - the message does not include a Server Identifier option.
639 * - the contents of the Server Identifier option do not match the
641 * - the message does not include a Client Identifier option.
644 valid_client_resp(struct packet
*packet
,
645 struct data_string
*client_id
,
646 struct data_string
*server_id
)
649 struct option_cache
*oc
;
651 /* INSIST((duid.data != NULL) && (duid.len > 0)); */
654 memset(client_id
, 0, sizeof(*client_id
));
655 memset(server_id
, 0, sizeof(*server_id
));
657 switch (get_client_id(packet
, client_id
)) {
661 log_debug("Discarding %s from %s; "
662 "client identifier missing",
663 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
664 piaddr(packet
->client_addr
));
667 log_error("Error processing %s from %s; "
668 "unable to evaluate Client Identifier",
669 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
670 piaddr(packet
->client_addr
));
674 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
676 log_debug("Discarding %s from %s: "
677 "server identifier missing (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 (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
684 packet
->options
, NULL
,
685 &global_scope
, oc
, MDL
)) {
686 log_error("Error processing %s from %s; "
687 "unable to evaluate Server Identifier (CLIENTID %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));
693 if ((server_duid
.len
!= server_id
->len
) ||
694 (memcmp(server_duid
.data
, server_id
->data
, server_duid
.len
) != 0)) {
695 log_debug("Discarding %s from %s; "
696 "not our server identifier "
697 "(CLIENTID %s, SERVERID %s, server DUID %s)",
698 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
699 piaddr(packet
->client_addr
),
700 print_hex_1(client_id
->len
, client_id
->data
, 60),
701 print_hex_2(server_id
->len
, server_id
->data
, 60),
702 print_hex_3(server_duid
.len
, server_duid
.data
, 60));
711 if (server_id
->len
> 0) {
712 data_string_forget(server_id
, MDL
);
714 if (client_id
->len
> 0) {
715 data_string_forget(client_id
, MDL
);
722 * Information request validation, defined in RFC 3315, section 15.12:
724 * Servers MUST discard any received Information-request message that
725 * meets any of the following conditions:
727 * - The message includes a Server Identifier option and the DUID in
728 * the option does not match the server's DUID.
730 * - The message includes an IA option.
733 valid_client_info_req(struct packet
*packet
, struct data_string
*server_id
) {
735 struct option_cache
*oc
;
736 struct data_string client_id
;
737 char client_id_str
[80]; /* print_hex_1() uses maximum 60 characters,
738 plus a few more for extra information */
741 memset(server_id
, 0, sizeof(*server_id
));
742 memset(&client_id
, 0, sizeof(client_id
));
745 * Make a string that we can print out to give more
746 * information about the client if we need to.
748 * By RFC 3315, Section 18.1.5 clients SHOULD have a
749 * client-id on an Information-request packet, but it
750 * is not strictly necessary.
752 if (get_client_id(packet
, &client_id
) == ISC_R_SUCCESS
) {
753 snprintf(client_id_str
, sizeof(client_id_str
), " (CLIENTID %s)",
754 print_hex_1(client_id
.len
, client_id
.data
, 60));
755 data_string_forget(&client_id
, MDL
);
757 client_id_str
[0] = '\0';
761 * Required by RFC 3315, section 15.
763 if (packet
->unicast
) {
764 log_debug("Discarding %s from %s; packet sent unicast%s",
765 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
766 piaddr(packet
->client_addr
), client_id_str
);
770 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
772 log_debug("Discarding %s from %s; "
773 "IA_NA option present%s",
774 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
775 piaddr(packet
->client_addr
), client_id_str
);
778 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
780 log_debug("Discarding %s from %s; "
781 "IA_TA option present%s",
782 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
783 piaddr(packet
->client_addr
), client_id_str
);
786 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
788 log_debug("Discarding %s from %s; "
789 "IA_PD option present%s",
790 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
791 piaddr(packet
->client_addr
), client_id_str
);
795 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
797 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
798 packet
->options
, NULL
,
799 &global_scope
, oc
, MDL
)) {
800 log_error("Error processing %s from %s; "
801 "unable to evaluate Server Identifier%s",
802 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
803 piaddr(packet
->client_addr
), client_id_str
);
806 if ((server_duid
.len
!= server_id
->len
) ||
807 (memcmp(server_duid
.data
, server_id
->data
,
808 server_duid
.len
) != 0)) {
809 log_debug("Discarding %s from %s; "
810 "not our server identifier "
811 "(SERVERID %s, server DUID %s)%s",
812 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
813 piaddr(packet
->client_addr
),
814 print_hex_1(server_id
->len
,
815 server_id
->data
, 60),
816 print_hex_2(server_duid
.len
,
817 server_duid
.data
, 60),
828 if (server_id
->len
> 0) {
829 data_string_forget(server_id
, MDL
);
836 * Options that we want to send, in addition to what was requested
839 static const int required_opts
[] = {
846 static const int required_opts_solicit
[] = {
858 static const int required_opts_agent
[] = {
863 static const int required_opts_IA
[] = {
868 static const int required_opts_IA_PD
[] = {
873 static const int required_opts_STATUS_CODE
[] = {
878 static const int required_opts_4o6
[] = {
884 static const int unicast_reject_opts
[] = {
893 * Extracts from packet contents an IA_* option, storing the IA structure
894 * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
895 * in enc_opt_state for later lookup and evaluation. The 'offset' indicates
896 * where in the IA_* the DHCPv6 options commence.
899 get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
900 struct data_string
*enc_opt_data
,
901 struct packet
*packet
,
902 struct option_cache
*oc
,
906 * Get the raw data for the encapsulated options.
908 memset(enc_opt_data
, 0, sizeof(*enc_opt_data
));
909 if (!evaluate_option_cache(enc_opt_data
, packet
,
910 NULL
, NULL
, packet
->options
, NULL
,
911 &global_scope
, oc
, MDL
)) {
912 log_error("get_encapsulated_IA_state: "
913 "error evaluating raw option.");
916 if (enc_opt_data
->len
< offset
) {
917 log_error("get_encapsulated_IA_state: raw option too small.");
918 data_string_forget(enc_opt_data
, MDL
);
923 * Now create the option state structure, and pass it to the
924 * function that parses options.
926 *enc_opt_state
= NULL
;
927 if (!option_state_allocate(enc_opt_state
, MDL
)) {
928 log_error("get_encapsulated_IA_state: no memory for options.");
929 data_string_forget(enc_opt_data
, MDL
);
932 if (!parse_option_buffer(*enc_opt_state
,
933 enc_opt_data
->data
+ offset
,
934 enc_opt_data
->len
- offset
,
936 log_error("get_encapsulated_IA_state: error parsing options.");
937 option_state_dereference(enc_opt_state
, MDL
);
938 data_string_forget(enc_opt_data
, MDL
);
946 set_status_code(u_int16_t status_code
, const char *status_message
,
947 struct option_state
*opt_state
)
949 struct data_string d
;
952 memset(&d
, 0, sizeof(d
));
953 d
.len
= sizeof(status_code
) + strlen(status_message
);
954 if (!buffer_allocate(&d
.buffer
, d
.len
, MDL
)) {
955 log_fatal("set_status_code: no memory for status code.");
957 d
.data
= d
.buffer
->data
;
958 putUShort(d
.buffer
->data
, status_code
);
959 memcpy(d
.buffer
->data
+ sizeof(status_code
),
960 status_message
, d
.len
- sizeof(status_code
));
961 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
962 d
.buffer
, (unsigned char *)d
.data
, d
.len
,
963 D6O_STATUS_CODE
, 0)) {
964 log_error("set_status_code: error saving status code.");
969 data_string_forget(&d
, MDL
);
973 void check_pool6_threshold(struct reply_state
*reply
,
974 struct iasubopt
*lease
)
976 struct ipv6_pond
*pond
;
977 isc_uint64_t used
, count
, high_threshold
;
978 int poolhigh
= 0, poollow
= 0;
979 char *shared_name
= "no name";
980 char tmp_addr
[INET6_ADDRSTRLEN
];
982 if ((lease
->ipv6_pool
== NULL
) || (lease
->ipv6_pool
->ipv6_pond
== NULL
))
984 pond
= lease
->ipv6_pool
->ipv6_pond
;
986 /* If the address range is too large to track, just skip all this. */
987 if (pond
->jumbo_range
== 1) {
991 count
= pond
->num_total
;
992 used
= pond
->num_active
;
994 /* get network name for logging */
995 if ((pond
->shared_network
!= NULL
) &&
996 (pond
->shared_network
->name
!= NULL
)) {
997 shared_name
= pond
->shared_network
->name
;
1000 /* The logged flag indicates if we have already crossed the high
1001 * threshold and emitted a log message. If it is set we check to
1002 * see if we have re-crossed the low threshold and need to reset
1003 * things. When we cross the high threshold we determine what
1004 * the low threshold is and save it into the low_threshold value.
1005 * When we cross that threshold we reset the logged flag and
1006 * the low_threshold to 0 which allows the high threshold message
1007 * to be emitted once again.
1008 * if we haven't recrossed the boundry we don't need to do anything.
1010 if (pond
->logged
!=0) {
1011 if (used
<= pond
->low_threshold
) {
1012 pond
->low_threshold
= 0;
1014 log_error("Pool threshold reset - shared subnet: %s; "
1015 "address: %s; low threshold %llu/%llu.",
1017 inet_ntop(AF_INET6
, &lease
->addr
,
1018 tmp_addr
, sizeof(tmp_addr
)),
1024 /* find the high threshold */
1025 if (get_option_int(&poolhigh
, &server_universe
, reply
->packet
, NULL
,
1026 NULL
, reply
->packet
->options
, reply
->opt_state
,
1027 reply
->opt_state
, &lease
->scope
,
1028 SV_LOG_THRESHOLD_HIGH
, MDL
) == 0) {
1029 /* no threshold bail out */
1033 /* We do have a threshold for this pool, see if its valid */
1034 if ((poolhigh
<= 0) || (poolhigh
> 100)) {
1039 /* we have a valid value, have we exceeded it */
1040 high_threshold
= FIND_POND6_PERCENT(count
, poolhigh
);
1041 if (used
< high_threshold
) {
1042 /* nope, no more to do */
1046 /* we've exceeded it, output a message */
1047 log_error("Pool threshold exceeded - shared subnet: %s; "
1048 "address: %s; high threshold %d%% %llu/%llu.",
1050 inet_ntop(AF_INET6
, &lease
->addr
, tmp_addr
, sizeof(tmp_addr
)),
1051 poolhigh
, used
, count
);
1053 /* handle the low threshold now, if we don't
1054 * have one we default to 0. */
1055 if ((get_option_int(&poollow
, &server_universe
, reply
->packet
, NULL
,
1056 NULL
, reply
->packet
->options
, reply
->opt_state
,
1057 reply
->opt_state
, &lease
->scope
,
1058 SV_LOG_THRESHOLD_LOW
, MDL
) == 0) ||
1064 * If the low theshold is higher than the high threshold we continue to log
1065 * If it isn't then we set the flag saying we already logged and determine
1066 * what the reset threshold is.
1068 if (poollow
< poolhigh
) {
1070 pond
->low_threshold
= FIND_POND6_PERCENT(count
, poollow
);
1075 * We have a set of operations we do to set up the reply packet, which
1076 * is the same for many message types.
1079 start_reply(struct packet
*packet
,
1080 const struct data_string
*client_id
,
1081 const struct data_string
*server_id
,
1082 struct option_state
**opt_state
,
1083 struct dhcpv6_packet
*reply
)
1085 struct option_cache
*oc
;
1086 const unsigned char *server_id_data
;
1090 * Build our option state for reply.
1093 if (!option_state_allocate(opt_state
, MDL
)) {
1094 log_error("start_reply: no memory for option_state.");
1097 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1098 packet
->options
, *opt_state
,
1099 &global_scope
, root_group
, NULL
, NULL
);
1102 * A small bit of special handling for Solicit messages.
1104 * We could move the logic into a flag, but for now just check
1107 if (packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
1108 reply
->msg_type
= DHCPV6_ADVERTISE
;
1112 * - this message type supports rapid commit (Solicit), and
1113 * - the server is configured to supply a rapid commit, and
1114 * - the client requests a rapid commit,
1115 * Then we add a rapid commit option, and send Reply (instead
1118 oc
= lookup_option(&dhcpv6_universe
,
1119 *opt_state
, D6O_RAPID_COMMIT
);
1121 oc
= lookup_option(&dhcpv6_universe
,
1122 packet
->options
, D6O_RAPID_COMMIT
);
1124 /* Rapid-commit in action. */
1125 reply
->msg_type
= DHCPV6_REPLY
;
1127 /* Don't want a rapid-commit in advertise. */
1128 delete_option(&dhcpv6_universe
,
1129 *opt_state
, D6O_RAPID_COMMIT
);
1133 reply
->msg_type
= DHCPV6_REPLY
;
1134 /* Delete the rapid-commit from the sent options. */
1135 oc
= lookup_option(&dhcpv6_universe
,
1136 *opt_state
, D6O_RAPID_COMMIT
);
1138 delete_option(&dhcpv6_universe
,
1139 *opt_state
, D6O_RAPID_COMMIT
);
1144 * Use the client's transaction identifier for the reply.
1146 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
1147 sizeof(reply
->transaction_id
));
1150 * RFC 3315, section 18.2 says we need server identifier and
1151 * client identifier.
1153 * If the server ID is defined via the configuration file, then
1154 * it will already be present in the option state at this point,
1155 * so we don't need to set it.
1157 * If we have a server ID passed in from the caller,
1158 * use that, otherwise use the global DUID.
1160 oc
= lookup_option(&dhcpv6_universe
, *opt_state
, D6O_SERVERID
);
1162 if (server_id
== NULL
) {
1163 server_id_data
= server_duid
.data
;
1164 server_id_len
= server_duid
.len
;
1166 server_id_data
= server_id
->data
;
1167 server_id_len
= server_id
->len
;
1169 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1170 NULL
, (unsigned char *)server_id_data
,
1171 server_id_len
, D6O_SERVERID
, 0)) {
1172 log_error("start_reply: "
1173 "error saving server identifier.");
1178 if (client_id
->buffer
!= NULL
) {
1179 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1181 (unsigned char *)client_id
->data
,
1184 log_error("start_reply: error saving "
1185 "client identifier.");
1191 * If the client accepts reconfiguration, let it know that we
1194 * Note: we don't actually do this yet, but DOCSIS requires we
1197 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
1200 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1201 NULL
, (unsigned char *)"", 0,
1202 D6O_RECONF_ACCEPT
, 0)) {
1203 log_error("start_reply: "
1204 "error saving RECONF_ACCEPT option.");
1205 option_state_dereference(opt_state
, MDL
);
1214 * Try to get the IPv6 address the client asked for from the
1217 * addr is the result (should be a pointer to NULL on entry)
1218 * pool is the pool to search in
1219 * requested_addr is the address the client wants
1222 try_client_v6_address(struct iasubopt
**addr
,
1223 struct ipv6_pool
*pool
,
1224 const struct data_string
*requested_addr
)
1226 struct in6_addr tmp_addr
;
1227 isc_result_t result
;
1229 if (requested_addr
->len
< sizeof(tmp_addr
)) {
1230 return DHCP_R_INVALIDARG
;
1232 memcpy(&tmp_addr
, requested_addr
->data
, sizeof(tmp_addr
));
1233 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
)) {
1234 return ISC_R_FAILURE
;
1238 * The address is not covered by this (or possibly any) dynamic
1241 if (!ipv6_in_pool(&tmp_addr
, pool
)) {
1242 return ISC_R_ADDRNOTAVAIL
;
1245 if (lease6_exists(pool
, &tmp_addr
)) {
1246 return ISC_R_ADDRINUSE
;
1249 result
= iasubopt_allocate(addr
, MDL
);
1250 if (result
!= ISC_R_SUCCESS
) {
1253 (*addr
)->addr
= tmp_addr
;
1256 /* Default is soft binding for 2 minutes. */
1257 result
= add_lease6(pool
, *addr
, cur_time
+ 120);
1258 if (result
!= ISC_R_SUCCESS
) {
1259 iasubopt_dereference(addr
, MDL
);
1266 * \brief Get an IPv6 address for the client.
1268 * Attempt to find a usable address for the client. We walk through
1269 * the ponds checking for permit and deny then through the pools
1270 * seeing if they have an available address.
1272 * \param reply = the state structure for the current work on this request
1273 * if we create a lease we return it using reply->lease
1276 * ISC_R_SUCCESS = we were able to find an address and are returning a
1277 * pointer to the lease
1278 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1279 * is probabalistic. We don't exhaustively try the
1280 * address range, instead we hash the duid and if
1281 * the address derived from the hash is in use we
1282 * hash the address. After a number of failures we
1283 * conclude the pool is basically full.
1286 pick_v6_address(struct reply_state
*reply
)
1288 struct ipv6_pool
*p
= NULL
;
1289 struct ipv6_pond
*pond
;
1292 unsigned int attempts
;
1293 char tmp_buf
[INET6_ADDRSTRLEN
];
1294 struct iasubopt
**addr
= &reply
->lease
;
1295 isc_uint64_t total
= 0;
1296 isc_uint64_t active
= 0;
1297 isc_uint64_t abandoned
= 0;
1298 int jumbo_range
= 0;
1299 char *shared_name
= (reply
->shared
->name
?
1300 reply
->shared
->name
: "(no name)");
1303 * Do a quick walk through of the ponds and pools
1304 * to see if we have any NA address pools
1306 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1307 if (pond
->ipv6_pools
== NULL
)
1310 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1311 if (p
->pool_type
== D6O_IA_NA
)
1318 /* If we get here and p is NULL we have no useful pools */
1320 log_debug("Unable to pick client address: "
1321 "no IPv6 pools on this shared network");
1322 return ISC_R_NORESOURCES
;
1326 * We have at least one pool that could provide an address
1327 * Now we walk through the ponds and pools again and check
1328 * to see if the client is permitted and if an address is
1331 * Within a given pond we start looking at the last pool we
1332 * allocated from, unless it had a collision trying to allocate
1333 * an address. This will tend to move us into less-filled pools.
1336 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1337 isc_result_t result
= ISC_R_FAILURE
;
1339 if (((pond
->prohibit_list
!= NULL
) &&
1340 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1341 ((pond
->permit_list
!= NULL
) &&
1342 (!permitted(reply
->packet
, pond
->permit_list
))))
1346 /* If pond is EUI-64 but client duid isn't a valid EUI-64
1347 * id, then skip this pond */
1348 if (pond
->use_eui_64
&&
1349 !valid_eui_64_duid(&reply
->ia
->iaid_duid
, IAID_LEN
)) {
1354 start_pool
= pond
->last_ipv6_pool
;
1357 p
= pond
->ipv6_pools
[i
];
1358 if (p
->pool_type
== D6O_IA_NA
) {
1360 if (pond
->use_eui_64
) {
1362 create_lease6_eui_64(p
, addr
,
1363 &reply
->ia
->iaid_duid
,
1370 create_lease6(p
, addr
, &attempts
,
1371 &reply
->ia
->iaid_duid
,
1376 if (result
== ISC_R_SUCCESS
) {
1378 * Record the pool used (or next one if
1379 * there was a collision).
1383 if (pond
->ipv6_pools
[i
]
1389 pond
->last_ipv6_pool
= i
;
1391 log_debug("Picking pool address %s",
1394 tmp_buf
, sizeof(tmp_buf
)));
1395 return (ISC_R_SUCCESS
);
1400 if (pond
->ipv6_pools
[i
] == NULL
) {
1403 } while (i
!= start_pool
);
1405 if (result
== ISC_R_NORESOURCES
) {
1406 jumbo_range
+= pond
->jumbo_range
;
1407 total
+= pond
->num_total
;
1408 active
+= pond
->num_active
;
1409 abandoned
+= pond
->num_abandoned
;
1414 * If we failed to pick an IPv6 address from any of the subnets.
1415 * Presumably that means we have no addresses for the client.
1417 if (jumbo_range
!= 0) {
1418 log_debug("Unable to pick client address: "
1419 "no addresses available - shared network %s: "
1420 " 2^64-1 < total, %llu active, %llu abandoned",
1421 shared_name
, active
- abandoned
, abandoned
);
1423 log_debug("Unable to pick client address: "
1424 "no addresses available - shared network %s: "
1425 "%llu total, %llu active, %llu abandoned",
1426 shared_name
, total
, active
- abandoned
, abandoned
);
1429 return ISC_R_NORESOURCES
;
1433 * Try to get the IPv6 prefix the client asked for from the
1436 * pref is the result (should be a pointer to NULL on entry)
1437 * pool is the prefix pool to search in
1438 * requested_pref is the address the client wants
1441 try_client_v6_prefix(struct iasubopt
**pref
,
1442 struct ipv6_pool
*pool
,
1443 const struct data_string
*requested_pref
)
1446 struct in6_addr tmp_pref
;
1448 isc_result_t result
;
1450 if (requested_pref
->len
< sizeof(tmp_plen
) + sizeof(tmp_pref
)) {
1451 return DHCP_R_INVALIDARG
;
1454 tmp_plen
= (int) requested_pref
->data
[0];
1455 if ((tmp_plen
< 3) || (tmp_plen
> 128)) {
1456 return ISC_R_FAILURE
;
1459 memcpy(&tmp_pref
, requested_pref
->data
+ 1, sizeof(tmp_pref
));
1460 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref
)) {
1461 return ISC_R_FAILURE
;
1465 memcpy(&ia
.iabuf
, &tmp_pref
, 16);
1466 if (!is_cidr_mask_valid(&ia
, (int) tmp_plen
)) {
1467 return ISC_R_FAILURE
;
1470 if (!ipv6_in_pool(&tmp_pref
, pool
) ||
1471 ((int)tmp_plen
!= pool
->units
)) {
1472 return ISC_R_ADDRNOTAVAIL
;
1475 if (prefix6_exists(pool
, &tmp_pref
, tmp_plen
)) {
1476 return ISC_R_ADDRINUSE
;
1479 result
= iasubopt_allocate(pref
, MDL
);
1480 if (result
!= ISC_R_SUCCESS
) {
1484 (*pref
)->addr
= tmp_pref
;
1485 (*pref
)->plen
= tmp_plen
;
1487 /* Default is soft binding for 2 minutes. */
1488 result
= add_lease6(pool
, *pref
, cur_time
+ 120);
1489 if (result
!= ISC_R_SUCCESS
) {
1490 iasubopt_dereference(pref
, MDL
);
1498 * \brief Get an IPv6 prefix for the client.
1500 * Attempt to find a usable prefix for the client. Based upon the prefix
1501 * length mode and the plen supplied by the client (if one), we make one
1502 * or more calls to pick_v6_prefix_helper() to find a prefix as follows:
1504 * PLM_IGNORE or client specifies a plen of zero, use the first available
1505 * prefix regardless of it's length.
1507 * PLM_PREFER – look for an exact match to client's plen first, if none
1508 * found, use the first available prefix of any length
1510 * PLM_EXACT – look for an exact match first, if none found then fail. This
1511 * is the default behavior.
1513 * PLM_MAXIMUM - look for an exact match first, then the first available whose
1514 * prefix length is less than client's plen, otherwise fail.
1516 * PLM_MINIMUM - look for an exact match first, then the first available whose
1517 * prefix length is greater than client's plen, otherwise fail.
1519 * Note that the selection mode is configurable at the global scope only via
1522 * \param reply = the state structure for the current work on this request
1523 * if we create a lease we return it using reply->lease
1526 * ISC_R_SUCCESS = we were able to find an prefix and are returning a
1527 * pointer to the lease
1528 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1529 * is probabalistic. We don't exhaustively try the
1530 * address range, instead we hash the duid and if
1531 * the address derived from the hash is in use we
1532 * hash the address. After a number of failures we
1533 * conclude the pool is basically full.
1536 pick_v6_prefix(struct reply_state
*reply
) {
1537 struct ipv6_pool
*p
= NULL
;
1538 struct ipv6_pond
*pond
;
1540 isc_result_t result
;
1543 * Do a quick walk through of the ponds and pools
1544 * to see if we have any prefix pools
1546 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1547 if (pond
->ipv6_pools
== NULL
)
1550 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1551 if (p
->pool_type
== D6O_IA_PD
)
1558 /* If we get here and p is NULL we have no useful pools */
1560 log_debug("Unable to pick client prefix: "
1561 "no IPv6 pools on this shared network");
1562 return ISC_R_NORESOURCES
;
1565 if (reply
->preflen
<= 0) {
1566 /* If we didn't get a plen (-1) or client plen is 0, then just
1567 * select first available (same as PLM_INGORE) */
1568 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1570 switch (prefix_length_mode
) {
1572 /* First we look for an exact match, if not found
1573 * then first available */
1574 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1575 if (result
!= ISC_R_SUCCESS
) {
1576 result
= pick_v6_prefix_helper(reply
,
1582 /* Match exactly or fail */
1583 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1588 /* First we look for an exact match, if not found
1589 * then first available by mode */
1590 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1591 if (result
!= ISC_R_SUCCESS
) {
1592 result
= pick_v6_prefix_helper(reply
,
1593 prefix_length_mode
);
1598 /* First available */
1599 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1604 if (result
== ISC_R_SUCCESS
) {
1605 char tmp_buf
[INET6_ADDRSTRLEN
];
1607 log_debug("Picking pool prefix %s/%u",
1608 inet_ntop(AF_INET6
, &(reply
->lease
->addr
),
1609 tmp_buf
, sizeof(tmp_buf
)),
1610 (unsigned)(reply
->lease
->plen
));
1611 return (ISC_R_SUCCESS
);
1615 * If we failed to pick an IPv6 prefix
1616 * Presumably that means we have no prefixes for the client.
1618 log_debug("Unable to pick client prefix: no prefixes available");
1619 return ISC_R_NORESOURCES
;
1624 * \brief Get an IPv6 prefix for the client based upon selection mode.
1626 * We walk through the ponds checking for permit and deny. If a pond is
1627 * permissable to use, loop through its PD pools checking prefix lengths
1628 * against the client plen based on the prefix length mode, looking for
1629 * available prefixes.
1631 * \param reply = the state structure for the current work on this request
1632 * if we create a lease we return it using reply->lease
1633 * \prefix_mode = selection mode to use
1636 * ISC_R_SUCCESS = we were able to find a prefix and are returning a
1637 * pointer to the lease
1638 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1639 * is probabalistic. We don't exhaustively try the
1640 * address range, instead we hash the duid and if
1641 * the address derived from the hash is in use we
1642 * hash the address. After a number of failures we
1643 * conclude the pool is basically full.
1646 pick_v6_prefix_helper(struct reply_state
*reply
, int prefix_mode
) {
1647 struct ipv6_pool
*p
= NULL
;
1648 struct ipv6_pond
*pond
;
1650 unsigned int attempts
;
1651 struct iasubopt
**pref
= &reply
->lease
;
1653 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1654 if (((pond
->prohibit_list
!= NULL
) &&
1655 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1656 ((pond
->permit_list
!= NULL
) &&
1657 (!permitted(reply
->packet
, pond
->permit_list
))))
1660 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1661 if ((p
->pool_type
== D6O_IA_PD
) &&
1662 (eval_prefix_mode(p
->units
, reply
->preflen
,
1663 prefix_mode
) == 1) &&
1664 (create_prefix6(p
, pref
, &attempts
,
1665 &reply
->ia
->iaid_duid
,
1666 cur_time
+ 120) == ISC_R_SUCCESS
)) {
1667 return (ISC_R_SUCCESS
);
1672 return ISC_R_NORESOURCES
;
1677 * \brief Test a prefix length against another based on prefix length mode
1679 * \param len - prefix length to test
1680 * \param preflen - preferred prefix length against which to test
1681 * \param prefix_mode - prefix selection mode with which to test
1683 * Note that the case of preferred length of 0 is not short-cut here as it
1684 * is assumed to be done at a higher level.
1686 * \return 1 if the given length is usable based upon mode and a preferred
1690 eval_prefix_mode(int len
, int preflen
, int prefix_mode
) {
1692 switch (prefix_mode
) {
1694 use_it
= (len
== preflen
);
1697 /* they asked for a prefix length no "shorter" than preflen */
1698 use_it
= (len
>= preflen
);
1701 /* they asked for a prefix length no "longer" than preflen */
1702 use_it
= (len
<= preflen
);
1705 /* otherwise use it */
1713 *! \file server/dhcpv6.c
1715 * \brief construct a reply containing information about a client's lease
1717 * lease_to_client() is called from several messages to construct a
1718 * reply that contains all that we know about the client's correct lease
1719 * (or projected lease).
1721 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1722 * send what we "may" give them on a request.
1724 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1725 * the client should really use).
1727 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1728 * Rebind out any "wrong" addresses the client sends. This means we send
1729 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1730 * possibly send the address with zeroed lifetimes.
1732 * Information-Request - No binding.
1734 * The basic structure is to traverse the client-supplied data first, and
1735 * validate and echo back any contents that can be. If the client-supplied
1736 * data does not error out (on renew/rebind as above), but we did not send
1737 * any addresses, attempt to allocate one.
1739 * At the end of the this function we call commit_leases_timed() to
1740 * fsync and rotate the file as necessary. commit_leases_timed() will
1741 * check that we have written at least one lease to the file and that
1742 * some time has passed before doing any fsync or file rewrite so we
1743 * don't bother tracking if we did a write_ia during this function.
1745 /* TODO: look at client hints for lease times */
1748 lease_to_client(struct data_string
*reply_ret
,
1749 struct packet
*packet
,
1750 const struct data_string
*client_id
,
1751 const struct data_string
*server_id
)
1753 static struct reply_state reply
;
1754 struct option_cache
*oc
;
1755 struct data_string packet_oro
;
1758 memset(&packet_oro
, 0, sizeof(packet_oro
));
1760 /* Locate the client. */
1761 if (shared_network_from_packet6(&reply
.shared
,
1762 packet
) != ISC_R_SUCCESS
)
1766 * Initialize the reply.
1768 packet_reference(&reply
.packet
, packet
, MDL
);
1769 data_string_copy(&reply
.client_id
, client_id
, MDL
);
1771 if (!start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
1775 /* Set the write cursor to just past the reply header. */
1776 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1779 * Get the ORO from the packet, if any.
1781 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ORO
);
1783 if (!evaluate_option_cache(&packet_oro
, packet
,
1785 packet
->options
, NULL
,
1786 &global_scope
, oc
, MDL
)) {
1787 log_error("lease_to_client: error evaluating ORO.");
1793 * Find a host record that matches the packet, if any, and is
1794 * valid for the shared network the client is on.
1796 if (find_hosts6(&reply
.host
, packet
, client_id
, MDL
)) {
1798 seek_shared_host(&reply
.host
, reply
.shared
);
1801 /* Process the client supplied IA's onto the reply buffer. */
1803 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
1805 for (; oc
!= NULL
; oc
= oc
->next
) {
1806 isc_result_t status
;
1808 /* Start counting resources (addresses) offered. */
1809 reply
.client_resources
= 0;
1810 reply
.resources_included
= ISC_FALSE
;
1812 status
= reply_process_ia_na(&reply
, oc
);
1815 * We continue to try other IA's whether we can address
1816 * this one or not. Any other result is an immediate fail.
1818 if ((status
!= ISC_R_SUCCESS
) &&
1819 (status
!= ISC_R_NORESOURCES
))
1822 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
1823 for (; oc
!= NULL
; oc
= oc
->next
) {
1824 isc_result_t status
;
1826 /* Start counting resources (addresses) offered. */
1827 reply
.client_resources
= 0;
1828 reply
.resources_included
= ISC_FALSE
;
1830 status
= reply_process_ia_ta(&reply
, oc
);
1833 * We continue to try other IA's whether we can address
1834 * this one or not. Any other result is an immediate fail.
1836 if ((status
!= ISC_R_SUCCESS
) &&
1837 (status
!= ISC_R_NORESOURCES
))
1841 /* Same for IA_PD's. */
1843 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
1844 for (; oc
!= NULL
; oc
= oc
->next
) {
1845 isc_result_t status
;
1847 /* Start counting resources (prefixes) offered. */
1848 reply
.client_resources
= 0;
1849 reply
.resources_included
= ISC_FALSE
;
1851 status
= reply_process_ia_pd(&reply
, oc
);
1854 * We continue to try other IA_PD's whether we can address
1855 * this one or not. Any other result is an immediate fail.
1857 if ((status
!= ISC_R_SUCCESS
) &&
1858 (status
!= ISC_R_NORESOURCES
))
1863 * Make no reply if we gave no resources and is not
1864 * for Information-Request.
1866 if ((reply
.ia_count
== 0) && (reply
.pd_count
== 0)) {
1867 if (reply
.packet
->dhcpv6_msg_type
!=
1868 DHCPV6_INFORMATION_REQUEST
)
1872 * Because we only execute statements on a per-IA basis,
1873 * we need to execute statements in any non-IA reply to
1874 * source configuration.
1876 execute_statements_in_scope(NULL
, reply
.packet
, NULL
, NULL
,
1877 reply
.packet
->options
,
1878 reply
.opt_state
, &global_scope
,
1879 reply
.shared
->group
, root_group
,
1882 /* Execute statements from class scopes. */
1883 for (i
= reply
.packet
->class_count
; i
> 0; i
--) {
1884 execute_statements_in_scope(NULL
, reply
.packet
,
1886 reply
.packet
->options
,
1889 reply
.packet
->classes
[i
- 1]->group
,
1890 reply
.shared
->group
, NULL
);
1893 /* Bring in any configuration from a host record. */
1894 if (reply
.host
!= NULL
)
1895 execute_statements_in_scope(NULL
, reply
.packet
,
1897 reply
.packet
->options
,
1901 reply
.shared
->group
, NULL
);
1905 * RFC3315 section 17.2.2 (Solicit):
1907 * If the server will not assign any addresses to any IAs in a
1908 * subsequent Request from the client, the server MUST send an
1909 * Advertise message to the client that includes only a Status
1910 * Code option with code NoAddrsAvail and a status message for
1911 * the user, a Server Identifier option with the server's DUID,
1912 * and a Client Identifier option with the client's DUID.
1914 * This has been updated by an errata such that the server
1915 * can always send an IA.
1917 * Section 18.2.1 (Request):
1919 * If the server cannot assign any addresses to an IA in the
1920 * message from the client, the server MUST include the IA in
1921 * the Reply message with no addresses in the IA and a Status
1922 * Code option in the IA containing status code NoAddrsAvail.
1924 * Section 18.1.8 (Client Behavior):
1926 * Leave unchanged any information about addresses the client has
1927 * recorded in the IA but that were not included in the IA from
1929 * Sends a Renew/Rebind if the IA is not in the Reply message.
1933 * Having stored the client's IA's, store any options that
1934 * will fit in the remaining space.
1936 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+ reply
.cursor
,
1937 sizeof(reply
.buf
) - reply
.cursor
,
1938 reply
.opt_state
, reply
.packet
,
1939 required_opts_solicit
,
1942 /* Return our reply to the caller. */
1943 reply_ret
->len
= reply
.cursor
;
1944 reply_ret
->buffer
= NULL
;
1945 if (!buffer_allocate(&reply_ret
->buffer
, reply
.cursor
, MDL
)) {
1946 log_fatal("No memory to store Reply.");
1948 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
, reply
.cursor
);
1949 reply_ret
->data
= reply_ret
->buffer
->data
;
1951 /* If appropriate commit and rotate the lease file */
1952 (void) commit_leases_timed();
1956 if (reply
.shared
!= NULL
)
1957 shared_network_dereference(&reply
.shared
, MDL
);
1958 if (reply
.host
!= NULL
)
1959 host_dereference(&reply
.host
, MDL
);
1960 if (reply
.opt_state
!= NULL
)
1961 option_state_dereference(&reply
.opt_state
, MDL
);
1962 if (reply
.packet
!= NULL
)
1963 packet_dereference(&reply
.packet
, MDL
);
1964 if (reply
.client_id
.data
!= NULL
)
1965 data_string_forget(&reply
.client_id
, MDL
);
1966 if (packet_oro
.buffer
!= NULL
)
1967 data_string_forget(&packet_oro
, MDL
);
1968 reply
.renew
= reply
.rebind
= reply
.min_prefer
= reply
.min_valid
= 0;
1972 /* Process a client-supplied IA_NA. This may append options to the tail of
1973 * the reply packet being built in the reply_state structure.
1976 reply_process_ia_na(struct reply_state
*reply
, struct option_cache
*ia
) {
1977 isc_result_t status
= ISC_R_SUCCESS
;
1980 struct option_state
*packet_ia
;
1981 struct option_cache
*oc
;
1982 struct data_string ia_data
, data
;
1984 /* Initialize values that will get cleaned up on return. */
1986 memset(&ia_data
, 0, sizeof(ia_data
));
1987 memset(&data
, 0, sizeof(data
));
1989 * Note that find_client_address() may set reply->lease.
1992 /* Make sure there is at least room for the header. */
1993 if ((reply
->cursor
+ IA_NA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
1994 log_error("reply_process_ia_na: Reply too long for IA.");
1995 return ISC_R_NOSPACE
;
1999 /* Fetch the IA_NA contents. */
2000 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2001 ia
, IA_NA_OFFSET
)) {
2002 log_error("reply_process_ia_na: error evaluating ia");
2003 status
= ISC_R_FAILURE
;
2007 /* Extract IA_NA header contents. */
2008 iaid
= getULong(ia_data
.data
);
2009 reply
->renew
= getULong(ia_data
.data
+ 4);
2010 reply
->rebind
= getULong(ia_data
.data
+ 8);
2012 /* Create an IA_NA structure. */
2013 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2014 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2015 log_error("reply_process_ia_na: no memory for ia.");
2016 status
= ISC_R_NOMEMORY
;
2019 reply
->ia
->ia_type
= D6O_IA_NA
;
2021 /* Cache pre-existing IA, if any. */
2022 ia_hash_lookup(&reply
->old_ia
, ia_na_active
,
2023 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2024 reply
->ia
->iaid_duid
.len
, MDL
);
2027 * Create an option cache to carry the IA_NA option contents, and
2028 * execute any user-supplied values into it.
2030 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2031 status
= ISC_R_NOMEMORY
;
2035 /* Check & cache the fixed host record. */
2036 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_addr
!= NULL
)) {
2037 struct iaddr tmp_addr
;
2039 if (!evaluate_option_cache(&reply
->fixed
, NULL
, NULL
, NULL
,
2040 NULL
, NULL
, &global_scope
,
2041 reply
->host
->fixed_addr
, MDL
)) {
2042 log_error("reply_process_ia_na: unable to evaluate "
2044 status
= ISC_R_FAILURE
;
2048 if (reply
->fixed
.len
< 16) {
2049 log_error("reply_process_ia_na: invalid fixed address.");
2050 status
= DHCP_R_INVALIDARG
;
2054 /* Find the static lease's subnet. */
2056 memcpy(tmp_addr
.iabuf
, reply
->fixed
.data
, 16);
2058 if (find_grouped_subnet(&reply
->subnet
, reply
->shared
,
2059 tmp_addr
, MDL
) == 0)
2060 log_fatal("Impossible condition at %s:%d.", MDL
);
2062 reply
->static_lease
= ISC_TRUE
;
2064 reply
->static_lease
= ISC_FALSE
;
2067 * Save the cursor position at the start of the IA, so we can
2068 * set length and adjust t1/t2 values later. We write a temporary
2069 * header out now just in case we decide to adjust the packet
2070 * within sub-process functions.
2072 ia_cursor
= reply
->cursor
;
2074 /* Initialize the IA_NA header. First the code. */
2075 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_NA
);
2078 /* Then option length. */
2079 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
2082 /* Then IA_NA header contents; IAID. */
2083 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2086 /* We store the client's t1 for now, and may over-ride it later. */
2087 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
2090 /* We store the client's t2 for now, and may over-ride it later. */
2091 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
2095 * For each address in this IA_NA, decide what to do about it.
2099 * The client leaves unchanged any information about addresses
2100 * it has recorded but are not included ("cancel/break" below).
2101 * A not included IA ("cleanup" below) could give a Renew/Rebind.
2103 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2104 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
2105 reply
->client_valid
= reply
->client_prefer
= 0;
2106 for (; oc
!= NULL
; oc
= oc
->next
) {
2107 status
= reply_process_addr(reply
, oc
);
2110 * Canceled means we did not allocate addresses to the
2111 * client, but we're "done" with this IA - we set a status
2112 * code. So transmit this reply, e.g., move on to the next
2115 if (status
== ISC_R_CANCELED
)
2118 if ((status
!= ISC_R_SUCCESS
) &&
2119 (status
!= ISC_R_ADDRINUSE
) &&
2120 (status
!= ISC_R_ADDRNOTAVAIL
))
2127 * If we fell through the above and never gave the client
2128 * an address, give it one now.
2130 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
2131 status
= find_client_address(reply
);
2133 if (status
== ISC_R_NORESOURCES
) {
2134 switch (reply
->packet
->dhcpv6_msg_type
) {
2135 case DHCPV6_SOLICIT
:
2137 * No address for any IA is handled
2142 case DHCPV6_REQUEST
:
2143 /* Section 18.2.1 (Request):
2145 * If the server cannot assign any addresses to
2146 * an IA in the message from the client, the
2147 * server MUST include the IA in the Reply
2148 * message with no addresses in the IA and a
2149 * Status Code option in the IA containing
2150 * status code NoAddrsAvail.
2152 option_state_dereference(&reply
->reply_ia
, MDL
);
2153 if (!option_state_allocate(&reply
->reply_ia
,
2156 log_error("reply_process_ia_na: No "
2157 "memory for option state "
2159 status
= ISC_R_NOMEMORY
;
2163 if (!set_status_code(STATUS_NoAddrsAvail
,
2164 "No addresses available "
2165 "for this interface.",
2167 log_error("reply_process_ia_na: Unable "
2168 "to set NoAddrsAvail status "
2170 status
= ISC_R_FAILURE
;
2174 status
= ISC_R_SUCCESS
;
2179 * RFC 3315 does not tell us to emit a status
2180 * code in this condition, or anything else.
2182 * If we included non-allocated addresses
2183 * (zeroed lifetimes) in an IA, then the client
2184 * will deconfigure them.
2186 * So we want to include the IA even if we
2187 * can't give it a new address if it includes
2188 * zeroed lifetime addresses.
2190 * We don't want to include the IA if we
2191 * provide zero addresses including zeroed
2194 if (reply
->resources_included
)
2195 status
= ISC_R_SUCCESS
;
2202 if (status
!= ISC_R_SUCCESS
)
2207 * yes, goto's aren't the best but we also want to avoid extra
2210 if (status
== ISC_R_CANCELED
) {
2211 /* We're replying with a status code so we still need to
2212 * write it out in wire-format to the outbound buffer */
2213 write_to_packet(reply
, ia_cursor
);
2218 * Handle static leases, we always log stuff and if it's
2219 * a hard binding we run any commit statements that we have
2221 if (reply
->static_lease
) {
2222 char tmp_addr
[INET6_ADDRSTRLEN
];
2223 log_info("%s NA: address %s to client with duid %s iaid = %d "
2225 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2226 inet_ntop(AF_INET6
, reply
->fixed
.data
, tmp_addr
,
2228 print_hex_1(reply
->client_id
.len
,
2229 reply
->client_id
.data
, 60),
2232 /* Write the lease out in wire-format to the outbound buffer */
2233 write_to_packet(reply
, ia_cursor
);
2235 /* Performs DDNS updates if we're configured to do them */
2236 ddns_update_static6(reply
);
2238 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
2239 (reply
->on_star
.on_commit
!= NULL
)) {
2240 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
2241 reply
->packet
->options
,
2242 reply
->opt_state
, NULL
,
2243 reply
->on_star
.on_commit
, NULL
);
2244 executable_statement_dereference
2245 (&reply
->on_star
.on_commit
, MDL
);
2251 * If we have any addresses log what we are doing.
2253 if (reply
->ia
->num_iasubopt
!= 0) {
2254 struct iasubopt
*tmp
;
2256 char tmp_addr
[INET6_ADDRSTRLEN
];
2258 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2259 tmp
= reply
->ia
->iasubopt
[i
];
2261 log_info("%s NA: address %s to client with duid %s "
2262 "iaid = %d valid for %u seconds",
2263 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2264 inet_ntop(AF_INET6
, &tmp
->addr
,
2265 tmp_addr
, sizeof(tmp_addr
)),
2266 print_hex_1(reply
->client_id
.len
,
2267 reply
->client_id
.data
, 60),
2273 * If this is not a 'soft' binding, consume the new changes into
2274 * the database (if any have been attached to the ia_na).
2276 * Loop through the assigned dynamic addresses, referencing the
2277 * leases onto this IA_NA rather than any old ones, and updating
2278 * pool timers for each (if any).
2280 * Note that we must do ddns_updates() before we test for lease
2281 * reuse (so we'll know if DNS entries are different). To ensure
2282 * we don't break any configs, we run on_commit statements before
2283 * we do ddns_updates() just in case the former affects the later.
2284 * This is symetrical with v4 logic. We always run on_commit and
2285 * ddns_udpates() whether a lease is reused or renewed.
2287 if ((reply
->ia
->num_iasubopt
!= 0) &&
2288 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
2289 int must_commit
= 0;
2290 struct iasubopt
*tmp
;
2291 struct data_string
*ia_id
;
2294 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2295 tmp
= reply
->ia
->iasubopt
[i
];
2296 if (tmp
->ia
!= NULL
) {
2297 ia_dereference(&tmp
->ia
, MDL
);
2300 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2302 /* If we have anything to do on commit do it now */
2303 if (tmp
->on_star
.on_commit
!= NULL
) {
2304 execute_statements(NULL
, reply
->packet
,
2306 reply
->packet
->options
,
2309 tmp
->on_star
.on_commit
,
2311 executable_statement_dereference
2312 (&tmp
->on_star
.on_commit
, MDL
);
2315 #if defined (NSUPDATE)
2317 /* Perform ddns updates */
2318 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2321 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2323 reply
->packet
->options
,
2327 ddns_updates(reply
->packet
, NULL
, NULL
,
2328 tmp
, NULL
, reply
->opt_state
);
2331 if (!reuse_lease6(reply
, tmp
)) {
2332 /* Commit 'hard' bindings. */
2334 renew_lease6(tmp
->ipv6_pool
, tmp
);
2335 schedule_lease_timeout(tmp
->ipv6_pool
);
2337 /* Do our threshold check. */
2338 check_pool6_threshold(reply
, tmp
);
2342 /* write the IA_NA in wire-format to the outbound buffer */
2343 write_to_packet(reply
, ia_cursor
);
2345 /* Remove any old ia from the hash. */
2346 if (reply
->old_ia
!= NULL
) {
2347 if (!release_on_roam(reply
)) {
2348 ia_id
= &reply
->old_ia
->iaid_duid
;
2349 ia_hash_delete(ia_na_active
,
2350 (unsigned char *)ia_id
->data
,
2354 ia_dereference(&reply
->old_ia
, MDL
);
2357 /* Put new ia into the hash. */
2358 reply
->ia
->cltt
= cur_time
;
2359 ia_id
= &reply
->ia
->iaid_duid
;
2360 ia_hash_add(ia_na_active
, (unsigned char *)ia_id
->data
,
2361 ia_id
->len
, reply
->ia
, MDL
);
2363 /* If we couldn't reuse all of the iasubopts, we
2364 * must update udpate the lease db */
2366 write_ia(reply
->ia
);
2369 /* write the IA_NA in wire-format to the outbound buffer */
2370 write_to_packet(reply
, ia_cursor
);
2371 schedule_lease_timeout_reply(reply
);
2375 if (packet_ia
!= NULL
)
2376 option_state_dereference(&packet_ia
, MDL
);
2377 if (reply
->reply_ia
!= NULL
)
2378 option_state_dereference(&reply
->reply_ia
, MDL
);
2379 if (ia_data
.data
!= NULL
)
2380 data_string_forget(&ia_data
, MDL
);
2381 if (data
.data
!= NULL
)
2382 data_string_forget(&data
, MDL
);
2383 if (reply
->ia
!= NULL
)
2384 ia_dereference(&reply
->ia
, MDL
);
2385 if (reply
->old_ia
!= NULL
)
2386 ia_dereference(&reply
->old_ia
, MDL
);
2387 if (reply
->lease
!= NULL
)
2388 iasubopt_dereference(&reply
->lease
, MDL
);
2389 if (reply
->fixed
.data
!= NULL
)
2390 data_string_forget(&reply
->fixed
, MDL
);
2391 if (reply
->subnet
!= NULL
)
2392 subnet_dereference(&reply
->subnet
, MDL
);
2393 if (reply
->on_star
.on_expiry
!= NULL
)
2394 executable_statement_dereference
2395 (&reply
->on_star
.on_expiry
, MDL
);
2396 if (reply
->on_star
.on_release
!= NULL
)
2397 executable_statement_dereference
2398 (&reply
->on_star
.on_release
, MDL
);
2401 * ISC_R_CANCELED is a status code used by the addr processing to
2402 * indicate we're replying with a status code. This is still a
2403 * success at higher layers.
2405 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2409 * Writes the populated IA_xx in wire format to the reply buffer
2412 write_to_packet(struct reply_state
*reply
, unsigned ia_cursor
) {
2413 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2414 sizeof(reply
->buf
) - reply
->cursor
,
2415 reply
->reply_ia
, reply
->packet
,
2416 (reply
->ia
->ia_type
!= D6O_IA_PD
?
2417 required_opts_IA
: required_opts_IA_PD
),
2420 /* Reset the length of this IA to match what was just written. */
2421 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2422 reply
->cursor
- (ia_cursor
+ 4));
2424 if (reply
->ia
->ia_type
!= D6O_IA_TA
) {
2425 /* Calculate T1/T2 and stuff them in the reply */
2426 set_reply_tee_times(reply
, ia_cursor
);
2431 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
2432 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
2433 * in the event we are replying with a status code and do not wish to process
2434 * more IAADDRs within this IA.
2437 reply_process_addr(struct reply_state
*reply
, struct option_cache
*addr
) {
2438 u_int32_t pref_life
, valid_life
;
2439 struct binding_scope
**scope
;
2440 struct group
*group
;
2441 struct subnet
*subnet
;
2442 struct iaddr tmp_addr
;
2443 struct option_cache
*oc
;
2444 struct data_string iaaddr
, data
;
2445 isc_result_t status
= ISC_R_SUCCESS
;
2447 int invalid_for_eui_64
= 0;
2450 /* Initializes values that will be cleaned up. */
2451 memset(&iaaddr
, 0, sizeof(iaaddr
));
2452 memset(&data
, 0, sizeof(data
));
2453 /* Note that reply->lease may be set by address_is_owned() */
2456 * There is no point trying to process an incoming address if there
2457 * is no room for an outgoing address.
2459 if ((reply
->cursor
+ 28) > sizeof(reply
->buf
)) {
2460 log_error("reply_process_addr: Out of room for address.");
2461 return ISC_R_NOSPACE
;
2464 /* Extract this IAADDR option. */
2465 if (!evaluate_option_cache(&iaaddr
, reply
->packet
, NULL
, NULL
,
2466 reply
->packet
->options
, NULL
, &global_scope
,
2468 (iaaddr
.len
< IAADDR_OFFSET
)) {
2469 log_error("reply_process_addr: error evaluating IAADDR.");
2470 status
= ISC_R_FAILURE
;
2474 /* The first 16 bytes are the IPv6 address. */
2475 pref_life
= getULong(iaaddr
.data
+ 16);
2476 valid_life
= getULong(iaaddr
.data
+ 20);
2478 if ((reply
->client_valid
== 0) ||
2479 (reply
->client_valid
> valid_life
))
2480 reply
->client_valid
= valid_life
;
2482 if ((reply
->client_prefer
== 0) ||
2483 (reply
->client_prefer
> pref_life
))
2484 reply
->client_prefer
= pref_life
;
2487 * Clients may choose to send :: as an address, with the idea to give
2488 * hints about preferred-lifetime or valid-lifetime.
2491 memset(tmp_addr
.iabuf
, 0, 16);
2492 if (!memcmp(iaaddr
.data
, tmp_addr
.iabuf
, 16)) {
2493 /* Status remains success; we just ignore this one. */
2497 /* tmp_addr len remains 16 */
2498 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2501 * Verify that this address is on the client's network.
2503 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
2504 subnet
= subnet
->next_sibling
) {
2505 if (addr_eq(subnet_number(tmp_addr
, subnet
->netmask
),
2512 /* If the requested address falls into an EUI-64 pool, then
2513 * we need to verify if it has EUI-64 duid AND the requested
2514 * address is correct for that duid. If not we treat it just
2515 * like an not-on-link request. */
2516 struct ipv6_pool
* pool
= NULL
;
2517 struct in6_addr
* addr
= (struct in6_addr
*)(iaaddr
.data
);
2518 if ((find_ipv6_pool(&pool
, D6O_IA_NA
, addr
) == ISC_R_SUCCESS
)
2519 && (pool
->ipv6_pond
->use_eui_64
) &&
2520 (!valid_for_eui_64_pool(pool
, &reply
->client_id
, 0, addr
))) {
2521 log_debug ("Requested address: %s,"
2522 " not valid for EUI-64 pool",
2524 invalid_for_eui_64
= 1;
2529 /* Address not found on shared network. */
2531 if ((subnet
== NULL
) || invalid_for_eui_64
) {
2533 if (subnet
== NULL
) {
2535 /* Ignore this address on 'soft' bindings. */
2536 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
2537 /* disable rapid commit */
2538 reply
->buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
2539 delete_option(&dhcpv6_universe
,
2542 /* status remains success */
2547 * RFC3315 section 18.2.1:
2549 * If the server finds that the prefix on one or more IP
2550 * addresses in any IA in the message from the client is not
2551 * appropriate for the link to which the client is connected,
2552 * the server MUST return the IA to the client with a Status
2553 * Code option with the value NotOnLink.
2555 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) {
2556 /* Rewind the IA_NA to empty. */
2557 option_state_dereference(&reply
->reply_ia
, MDL
);
2558 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2559 log_error("reply_process_addr: No memory for "
2560 "option state wipe.");
2561 status
= ISC_R_NOMEMORY
;
2565 /* Append a NotOnLink status code. */
2566 if (!set_status_code(STATUS_NotOnLink
,
2567 "Address not for use on this "
2568 "link.", reply
->reply_ia
)) {
2569 log_error("reply_process_addr: Failure "
2570 "setting status code.");
2571 status
= ISC_R_FAILURE
;
2575 /* Fin (no more IAADDRs). */
2576 status
= ISC_R_CANCELED
;
2581 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2583 * If the server finds that any of the addresses are not
2584 * appropriate for the link to which the client is attached,
2585 * the server returns the address to the client with lifetimes
2588 if ((reply
->packet
->dhcpv6_msg_type
!= DHCPV6_RENEW
) &&
2589 (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
2590 log_error("It is impossible to lease a client that is "
2591 "not sending a solicit, request, renew, or "
2593 status
= ISC_R_FAILURE
;
2597 reply
->send_prefer
= reply
->send_valid
= 0;
2602 /* Verify the address belongs to the client. */
2603 if (!address_is_owned(reply
, &tmp_addr
)) {
2605 * For solicit and request, any addresses included are
2606 * 'requested' addresses. For rebind, we actually have
2607 * no direction on what to do from 3315 section 18.2.4!
2608 * So I think the best bet is to try and give it out, and if
2609 * we can't, zero lifetimes.
2611 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
2612 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
2613 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
2614 status
= reply_process_try_addr(reply
, &tmp_addr
);
2617 * If the address is in use, or isn't in any dynamic
2618 * range, continue as normal. If any other error was
2621 if ((status
!= ISC_R_SUCCESS
) &&
2622 (status
!= ISC_R_ADDRINUSE
) &&
2623 (status
!= ISC_R_ADDRNOTAVAIL
))
2627 * If we didn't honor this lease, for solicit and
2628 * request we simply omit it from our answer. For
2629 * rebind, we send it with zeroed lifetimes.
2631 if (reply
->lease
== NULL
) {
2632 if (reply
->packet
->dhcpv6_msg_type
==
2634 reply
->send_prefer
= 0;
2635 reply
->send_valid
= 0;
2639 /* status remains success - ignore */
2643 * RFC3315 section 18.2.3:
2645 * If the server cannot find a client entry for the IA the
2646 * server returns the IA containing no addresses with a Status
2647 * Code option set to NoBinding in the Reply message.
2649 * On mismatch we (ab)use this pretending we have not the IA
2650 * as soon as we have not an address.
2652 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
2653 /* Rewind the IA_NA to empty. */
2654 option_state_dereference(&reply
->reply_ia
, MDL
);
2655 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2656 log_error("reply_process_addr: No memory for "
2657 "option state wipe.");
2658 status
= ISC_R_NOMEMORY
;
2662 /* Append a NoBinding status code. */
2663 if (!set_status_code(STATUS_NoBinding
,
2664 "Address not bound to this "
2665 "interface.", reply
->reply_ia
)) {
2666 log_error("reply_process_addr: Unable to "
2667 "attach status code.");
2668 status
= ISC_R_FAILURE
;
2672 /* Fin (no more IAADDRs). */
2673 status
= ISC_R_CANCELED
;
2676 log_error("It is impossible to lease a client that is "
2677 "not sending a solicit, request, renew, or "
2679 status
= ISC_R_FAILURE
;
2684 if (reply
->static_lease
) {
2685 if (reply
->host
== NULL
)
2686 log_fatal("Impossible condition at %s:%d.", MDL
);
2688 scope
= &global_scope
;
2689 group
= reply
->subnet
->group
;
2691 if (reply
->lease
== NULL
)
2692 log_fatal("Impossible condition at %s:%d.", MDL
);
2694 scope
= &reply
->lease
->scope
;
2695 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
2699 * If client_resources is nonzero, then the reply_process_is_addressed
2700 * function has executed configuration state into the reply option
2701 * cache. We will use that valid cache to derive configuration for
2702 * whether or not to engage in additional addresses, and similar.
2704 if (reply
->client_resources
!= 0) {
2708 * Does this client have "enough" addresses already? Default
2709 * to one. Everybody gets one, and one should be enough for
2712 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2713 SV_LIMIT_ADDRS_PER_IA
);
2715 if (!evaluate_option_cache(&data
, reply
->packet
,
2717 reply
->packet
->options
,
2721 log_error("reply_process_addr: unable to "
2722 "evaluate addrs-per-ia value.");
2723 status
= ISC_R_FAILURE
;
2727 limit
= getULong(data
.data
);
2728 data_string_forget(&data
, MDL
);
2732 * If we wish to limit the client to a certain number of
2733 * addresses, then omit the address from the reply.
2735 if (reply
->client_resources
>= limit
)
2739 status
= reply_process_is_addressed(reply
, scope
, group
);
2740 if (status
!= ISC_R_SUCCESS
)
2744 status
= reply_process_send_addr(reply
, &tmp_addr
);
2747 if (iaaddr
.data
!= NULL
)
2748 data_string_forget(&iaaddr
, MDL
);
2749 if (data
.data
!= NULL
)
2750 data_string_forget(&data
, MDL
);
2751 if (reply
->lease
!= NULL
)
2752 iasubopt_dereference(&reply
->lease
, MDL
);
2758 * Verify the address belongs to the client. If we've got a host
2759 * record with a fixed address, it has to be the assigned address
2760 * (fault out all else). Otherwise it's a dynamic address, so lookup
2761 * that address and make sure it belongs to this DUID:IAID pair.
2763 static isc_boolean_t
2764 address_is_owned(struct reply_state
*reply
, struct iaddr
*addr
) {
2766 struct ipv6_pond
*pond
;
2769 * This faults out addresses that don't match fixed addresses.
2771 if (reply
->static_lease
) {
2772 if (reply
->fixed
.data
== NULL
)
2773 log_fatal("Impossible condition at %s:%d.", MDL
);
2775 if (memcmp(addr
->iabuf
, reply
->fixed
.data
, 16) == 0)
2781 if ((reply
->old_ia
== NULL
) || (reply
->old_ia
->num_iasubopt
== 0))
2784 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2785 struct iasubopt
*tmp
;
2787 tmp
= reply
->old_ia
->iasubopt
[i
];
2789 if (memcmp(addr
->iabuf
, &tmp
->addr
, 16) == 0) {
2790 if (lease6_usable(tmp
) == ISC_FALSE
) {
2794 pond
= tmp
->ipv6_pool
->ipv6_pond
;
2795 if (((pond
->prohibit_list
!= NULL
) &&
2796 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
2797 ((pond
->permit_list
!= NULL
) &&
2798 (!permitted(reply
->packet
, pond
->permit_list
))))
2801 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
2810 /* Process a client-supplied IA_TA. This may append options to the tail of
2811 * the reply packet being built in the reply_state structure.
2814 reply_process_ia_ta(struct reply_state
*reply
, struct option_cache
*ia
) {
2815 isc_result_t status
= ISC_R_SUCCESS
;
2818 struct option_state
*packet_ia
;
2819 struct option_cache
*oc
;
2820 struct data_string ia_data
, data
;
2821 struct data_string iaaddr
;
2822 u_int32_t pref_life
, valid_life
;
2823 struct iaddr tmp_addr
;
2825 /* Initialize values that will get cleaned up on return. */
2827 memset(&ia_data
, 0, sizeof(ia_data
));
2828 memset(&data
, 0, sizeof(data
));
2829 memset(&iaaddr
, 0, sizeof(iaaddr
));
2831 /* Make sure there is at least room for the header. */
2832 if ((reply
->cursor
+ IA_TA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2833 log_error("reply_process_ia_ta: Reply too long for IA.");
2834 return ISC_R_NOSPACE
;
2838 /* Fetch the IA_TA contents. */
2839 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2840 ia
, IA_TA_OFFSET
)) {
2841 log_error("reply_process_ia_ta: error evaluating ia");
2842 status
= ISC_R_FAILURE
;
2846 /* Extract IA_TA header contents. */
2847 iaid
= getULong(ia_data
.data
);
2849 /* Create an IA_TA structure. */
2850 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2851 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2852 log_error("reply_process_ia_ta: no memory for ia.");
2853 status
= ISC_R_NOMEMORY
;
2856 reply
->ia
->ia_type
= D6O_IA_TA
;
2858 /* Cache pre-existing IA, if any. */
2859 ia_hash_lookup(&reply
->old_ia
, ia_ta_active
,
2860 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2861 reply
->ia
->iaid_duid
.len
, MDL
);
2864 * Create an option cache to carry the IA_TA option contents, and
2865 * execute any user-supplied values into it.
2867 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2868 status
= ISC_R_NOMEMORY
;
2873 * Temporary leases are dynamic by definition.
2875 reply
->static_lease
= ISC_FALSE
;
2878 * Save the cursor position at the start of the IA, so we can
2879 * set length later. We write a temporary
2880 * header out now just in case we decide to adjust the packet
2881 * within sub-process functions.
2883 ia_cursor
= reply
->cursor
;
2885 /* Initialize the IA_TA header. First the code. */
2886 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_TA
);
2889 /* Then option length. */
2890 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x04u
);
2893 /* Then IA_TA header contents; IAID. */
2894 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2898 * Deal with an IAADDR for lifetimes.
2899 * For all or none, process IAADDRs as hints.
2901 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
2902 reply
->client_valid
= reply
->client_prefer
= 0;
2903 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2904 for (; oc
!= NULL
; oc
= oc
->next
) {
2905 memset(&iaaddr
, 0, sizeof(iaaddr
));
2906 if (!evaluate_option_cache(&iaaddr
, reply
->packet
,
2908 reply
->packet
->options
, NULL
,
2909 &global_scope
, oc
, MDL
) ||
2910 (iaaddr
.len
< IAADDR_OFFSET
)) {
2911 log_error("reply_process_ia_ta: error "
2912 "evaluating IAADDR.");
2913 status
= ISC_R_FAILURE
;
2916 /* The first 16 bytes are the IPv6 address. */
2917 pref_life
= getULong(iaaddr
.data
+ 16);
2918 valid_life
= getULong(iaaddr
.data
+ 20);
2920 if ((reply
->client_valid
== 0) ||
2921 (reply
->client_valid
> valid_life
))
2922 reply
->client_valid
= valid_life
;
2924 if ((reply
->client_prefer
== 0) ||
2925 (reply
->client_prefer
> pref_life
))
2926 reply
->client_prefer
= pref_life
;
2928 /* Nothing more if something has failed. */
2929 if (status
== ISC_R_CANCELED
)
2933 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2934 if (!temporary_is_available(reply
, &tmp_addr
))
2936 status
= reply_process_is_addressed(reply
,
2937 &reply
->lease
->scope
,
2938 reply
->lease
->ipv6_pool
->ipv6_pond
->group
);
2939 if (status
!= ISC_R_SUCCESS
)
2941 status
= reply_process_send_addr(reply
, &tmp_addr
);
2942 if (status
!= ISC_R_SUCCESS
)
2944 if (reply
->lease
!= NULL
)
2945 iasubopt_dereference(&reply
->lease
, MDL
);
2949 /* Rewind the IA_TA to empty. */
2950 option_state_dereference(&reply
->reply_ia
, MDL
);
2951 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2952 status
= ISC_R_NOMEMORY
;
2955 status
= ISC_R_CANCELED
;
2956 reply
->client_resources
= 0;
2957 reply
->resources_included
= ISC_FALSE
;
2958 if (reply
->lease
!= NULL
)
2959 iasubopt_dereference(&reply
->lease
, MDL
);
2964 * Give the client temporary addresses.
2966 if (reply
->client_resources
!= 0)
2968 status
= find_client_temporaries(reply
);
2969 if (status
== ISC_R_NORESOURCES
) {
2970 switch (reply
->packet
->dhcpv6_msg_type
) {
2971 case DHCPV6_SOLICIT
:
2973 * No address for any IA is handled
2978 case DHCPV6_REQUEST
:
2979 /* Section 18.2.1 (Request):
2981 * If the server cannot assign any addresses to
2982 * an IA in the message from the client, the
2983 * server MUST include the IA in the Reply
2984 * message with no addresses in the IA and a
2985 * Status Code option in the IA containing
2986 * status code NoAddrsAvail.
2988 option_state_dereference(&reply
->reply_ia
, MDL
);
2989 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2990 log_error("reply_process_ia_ta: No "
2991 "memory for option state wipe.");
2992 status
= ISC_R_NOMEMORY
;
2996 if (!set_status_code(STATUS_NoAddrsAvail
,
2997 "No addresses available "
2998 "for this interface.",
3000 log_error("reply_process_ia_ta: Unable "
3001 "to set NoAddrsAvail status code.");
3002 status
= ISC_R_FAILURE
;
3006 status
= ISC_R_SUCCESS
;
3011 * We don't want to include the IA if we
3012 * provide zero addresses including zeroed
3015 if (reply
->resources_included
)
3016 status
= ISC_R_SUCCESS
;
3021 } else if (status
!= ISC_R_SUCCESS
)
3027 * yes, goto's aren't the best but we also want to avoid extra
3030 if (status
== ISC_R_CANCELED
) {
3031 /* We're replying with a status code so we still need to
3032 * write it out in wire-format to the outbound buffer */
3033 write_to_packet(reply
, ia_cursor
);
3038 * If we have any addresses log what we are doing.
3040 if (reply
->ia
->num_iasubopt
!= 0) {
3041 struct iasubopt
*tmp
;
3043 char tmp_addr
[INET6_ADDRSTRLEN
];
3045 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3046 tmp
= reply
->ia
->iasubopt
[i
];
3048 log_info("%s TA: address %s to client with duid %s "
3049 "iaid = %d valid for %u seconds",
3050 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
3051 inet_ntop(AF_INET6
, &tmp
->addr
,
3052 tmp_addr
, sizeof(tmp_addr
)),
3053 print_hex_1(reply
->client_id
.len
,
3054 reply
->client_id
.data
, 60),
3061 * For hard bindings we consume the new changes into
3062 * the database (if any have been attached to the ia_ta).
3064 * Loop through the assigned dynamic addresses, referencing the
3065 * leases onto this IA_TA rather than any old ones, and updating
3066 * pool timers for each (if any).
3068 if ((reply
->ia
->num_iasubopt
!= 0) &&
3069 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
3070 int must_commit
= 0;
3071 struct iasubopt
*tmp
;
3072 struct data_string
*ia_id
;
3075 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3076 tmp
= reply
->ia
->iasubopt
[i
];
3078 if (tmp
->ia
!= NULL
)
3079 ia_dereference(&tmp
->ia
, MDL
);
3080 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
3082 /* If we have anything to do on commit do it now */
3083 if (tmp
->on_star
.on_commit
!= NULL
) {
3084 execute_statements(NULL
, reply
->packet
,
3086 reply
->packet
->options
,
3089 tmp
->on_star
.on_commit
,
3091 executable_statement_dereference
3092 (&tmp
->on_star
.on_commit
, MDL
);
3095 #if defined (NSUPDATE)
3097 * Perform ddns updates.
3099 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3102 evaluate_boolean_option_cache(NULL
, reply
->packet
,
3104 reply
->packet
->options
,
3108 ddns_updates(reply
->packet
, NULL
, NULL
,
3109 tmp
, NULL
, reply
->opt_state
);
3113 if (!reuse_lease6(reply
, tmp
)) {
3114 /* Commit 'hard' bindings. */
3116 renew_lease6(tmp
->ipv6_pool
, tmp
);
3117 schedule_lease_timeout(tmp
->ipv6_pool
);
3119 /* Do our threshold check. */
3120 check_pool6_threshold(reply
, tmp
);
3124 /* write the IA_TA in wire-format to the outbound buffer */
3125 write_to_packet(reply
, ia_cursor
);
3127 /* Remove any old ia from the hash. */
3128 if (reply
->old_ia
!= NULL
) {
3129 if (!release_on_roam(reply
)) {
3130 ia_id
= &reply
->old_ia
->iaid_duid
;
3131 ia_hash_delete(ia_ta_active
,
3132 (unsigned char *)ia_id
->data
,
3136 ia_dereference(&reply
->old_ia
, MDL
);
3139 /* Put new ia into the hash. */
3140 reply
->ia
->cltt
= cur_time
;
3141 ia_id
= &reply
->ia
->iaid_duid
;
3142 ia_hash_add(ia_ta_active
, (unsigned char *)ia_id
->data
,
3143 ia_id
->len
, reply
->ia
, MDL
);
3145 /* If we couldn't reuse all of the iasubopts, we
3146 * must update udpate the lease db */
3148 write_ia(reply
->ia
);
3151 /* write the IA_TA in wire-format to the outbound buffer */
3152 write_to_packet(reply
, ia_cursor
);
3153 schedule_lease_timeout_reply(reply
);
3157 if (packet_ia
!= NULL
)
3158 option_state_dereference(&packet_ia
, MDL
);
3159 if (iaaddr
.data
!= NULL
)
3160 data_string_forget(&iaaddr
, MDL
);
3161 if (reply
->reply_ia
!= NULL
)
3162 option_state_dereference(&reply
->reply_ia
, MDL
);
3163 if (ia_data
.data
!= NULL
)
3164 data_string_forget(&ia_data
, MDL
);
3165 if (data
.data
!= NULL
)
3166 data_string_forget(&data
, MDL
);
3167 if (reply
->ia
!= NULL
)
3168 ia_dereference(&reply
->ia
, MDL
);
3169 if (reply
->old_ia
!= NULL
)
3170 ia_dereference(&reply
->old_ia
, MDL
);
3171 if (reply
->lease
!= NULL
)
3172 iasubopt_dereference(&reply
->lease
, MDL
);
3175 * ISC_R_CANCELED is a status code used by the addr processing to
3176 * indicate we're replying with other addresses. This is still a
3177 * success at higher layers.
3179 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
3182 * Determines if a lease (iasubopt) can be reused without extending it.
3183 * If dhcp-cache-threshold is greater than zero (i.e enabled) then
3184 * a lease may be reused without going through a full renewal if
3185 * it meets all the requirements. In short it must be active, younger
3186 * than the threshold, and not have DNS changes.
3188 * If it is determined that it can be reused, that a call to
3189 * shorten_lifetimes() is made to reduce the valid and preferred lifetimes
3190 * sent to the client by the age of the lease.
3192 * Returns 1 if lease can be reused, 0 otherwise
3195 reuse_lease6(struct reply_state
*reply
, struct iasubopt
*lease
) {
3196 int threshold
= DEFAULT_CACHE_THRESHOLD
;
3197 struct option_cache
* oc
= NULL
;
3198 struct data_string d1
;
3203 /* In order to even qualify for reuse consideration:
3204 * 1. Lease must be active
3205 * 2. It must have been accepted at least once
3206 * 3. DNS info must not have changed */
3207 if ((lease
->state
!= FTS_ACTIVE
) ||
3208 (lease
->hard_lifetime_end_time
== 0) ||
3209 (lease
->ddns_cb
!= NULL
)) {
3213 /* Look up threshold value */
3214 memset(&d1
, 0, sizeof(struct data_string
));
3215 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3216 SV_CACHE_THRESHOLD
);
3218 evaluate_option_cache(&d1
, reply
->packet
, NULL
, NULL
,
3219 reply
->packet
->options
, reply
->opt_state
,
3220 &lease
->scope
, oc
, MDL
)) {
3221 if (d1
.len
== 1 && (d1
.data
[0] < 100)) {
3222 threshold
= d1
.data
[0];
3225 data_string_forget(&d1
, MDL
);
3228 if (threshold
<= 0) {
3232 if (lease
->valid
>= MAX_TIME
) {
3233 /* Infinite leases are always reused. We have to make
3234 * a choice because we cannot determine when they actually
3235 * began, so we either always reuse them or we never do. */
3236 log_debug ("reusing infinite lease for: %s%s",
3237 pin6_addr(&lease
->addr
), iasubopt_plen_str(lease
));
3241 age
= cur_tv
.tv_sec
- (lease
->hard_lifetime_end_time
- lease
->valid
);
3242 if (lease
->valid
<= (INT_MAX
/ threshold
))
3243 limit
= lease
->valid
* threshold
/ 100;
3245 limit
= lease
->valid
/ 100 * threshold
;
3248 /* Reduce valid/preferred going to the client by age */
3249 shorten_lifetimes(reply
, lease
, age
, threshold
);
3257 * Reduces the valid and preferred lifetimes for a given lease (iasubopt)
3259 * We cannot determine until after a iasubopt has been added to
3260 * the reply if the lease can be reused. Therefore, when we do reuse a
3261 * lease we need a way to alter the lifetimes that will be sent to the client.
3262 * That's where this function comes in handy:
3264 * Locate the iasubopt by it's address within the reply the reduce both
3265 * the preferred and valid lifetimes by the given number of seconds.
3267 * Note that this function, by necessity, works directly with the
3268 * option_cache data. Sort of a no-no but I don't have any better ideas.
3270 void shorten_lifetimes(struct reply_state
*reply
, struct iasubopt
*lease
,
3271 time_t age
, int threshold
) {
3272 struct option_cache
* oc
= NULL
;
3279 if (reply
->ia
->ia_type
!= D6O_IA_PD
) {
3280 subopt_type
= D6O_IAADDR
;
3281 addr_offset
= IASUBOPT_NA_ADDR_OFFSET
;
3282 pref_offset
= IASUBOPT_NA_PREF_OFFSET
;
3283 val_offset
= IASUBOPT_NA_VALID_OFFSET
;
3284 exp_length
= IASUBOPT_NA_LEN
;
3287 subopt_type
= D6O_IAPREFIX
;
3288 addr_offset
= IASUBOPT_PD_PREFIX_OFFSET
;
3289 pref_offset
= IASUBOPT_PD_PREF_OFFSET
;
3290 val_offset
= IASUBOPT_PD_VALID_OFFSET
;
3291 exp_length
= IASUBOPT_PD_LEN
;
3294 // loop through the iasubopts for the one that matches this lease
3295 oc
= lookup_option(&dhcpv6_universe
, reply
->reply_ia
, subopt_type
);
3296 for (; oc
!= NULL
; oc
= oc
->next
) {
3297 if (oc
->data
.data
== NULL
|| oc
->data
.len
!= exp_length
) {
3298 /* shouldn't happen */
3302 /* If address matches (and for PDs the prefix len matches)
3303 * we assume this is our subopt, so update the lifetimes */
3304 if (!memcmp(oc
->data
.data
+ addr_offset
, &lease
->addr
, 16) &&
3305 (subopt_type
!= D6O_IAPREFIX
||
3306 (oc
->data
.data
[IASUBOPT_PD_PREFLEN_OFFSET
] ==
3308 u_int32_t pref_life
= getULong(oc
->data
.data
+
3310 u_int32_t valid_life
= getULong(oc
->data
.data
+
3313 if (pref_life
< MAX_TIME
&& pref_life
> age
) {
3315 putULong((unsigned char*)(oc
->data
.data
) +
3316 pref_offset
, pref_life
);
3318 if (reply
->min_prefer
> pref_life
) {
3319 reply
->min_prefer
= pref_life
;
3323 if (valid_life
< MAX_TIME
&& valid_life
> age
) {
3325 putULong((unsigned char*)(oc
->data
.data
) +
3326 val_offset
, valid_life
);
3328 if (reply
->min_valid
> reply
->send_valid
) {
3329 reply
->min_valid
= valid_life
;
3333 log_debug ("Reusing lease for: %s%s, "
3334 "age %ld secs < %d%%,"
3335 " sending shortened lifetimes -"
3336 " preferred: %u, valid %u",
3337 pin6_addr(&lease
->addr
),
3338 iasubopt_plen_str(lease
),
3339 (long)age
, threshold
,
3340 pref_life
, valid_life
);
3347 * Verify the temporary address is available.
3349 static isc_boolean_t
3350 temporary_is_available(struct reply_state
*reply
, struct iaddr
*addr
) {
3351 struct in6_addr tmp_addr
;
3352 struct subnet
*subnet
;
3353 struct ipv6_pool
*pool
= NULL
;
3354 struct ipv6_pond
*pond
= NULL
;
3357 memcpy(&tmp_addr
, addr
->iabuf
, sizeof(tmp_addr
));
3359 * Clients may choose to send :: as an address, with the idea to give
3360 * hints about preferred-lifetime or valid-lifetime.
3361 * So this is not a request for this address.
3363 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
))
3367 * Verify that this address is on the client's network.
3369 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
3370 subnet
= subnet
->next_sibling
) {
3371 if (addr_eq(subnet_number(*addr
, subnet
->netmask
),
3376 /* Address not found on shared network. */
3381 * Check if this address is owned (must be before next step).
3383 if (address_is_owned(reply
, addr
))
3387 * Verify that this address is in a temporary pool and try to get it.
3389 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3390 if (((pond
->prohibit_list
!= NULL
) &&
3391 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3392 ((pond
->permit_list
!= NULL
) &&
3393 (!permitted(reply
->packet
, pond
->permit_list
))))
3396 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3397 if (pool
->pool_type
!= D6O_IA_TA
)
3400 if (ipv6_in_pool(&tmp_addr
, pool
))
3410 if (lease6_exists(pool
, &tmp_addr
))
3412 if (iasubopt_allocate(&reply
->lease
, MDL
) != ISC_R_SUCCESS
)
3414 reply
->lease
->addr
= tmp_addr
;
3415 reply
->lease
->plen
= 0;
3416 /* Default is soft binding for 2 minutes. */
3417 if (add_lease6(pool
, reply
->lease
, cur_time
+ 120) != ISC_R_SUCCESS
)
3424 * Get a temporary address per prefix.
3427 find_client_temporaries(struct reply_state
*reply
) {
3429 struct ipv6_pool
*p
= NULL
;
3430 struct ipv6_pond
*pond
;
3431 isc_result_t status
= ISC_R_NORESOURCES
;;
3432 unsigned int attempts
;
3433 struct iaddr send_addr
;
3436 * Do a quick walk through of the ponds and pools
3437 * to see if we have any prefix pools
3439 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3440 if (pond
->ipv6_pools
== NULL
)
3443 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3444 if (p
->pool_type
== D6O_IA_TA
)
3451 /* If we get here and p is NULL we have no useful pools */
3453 log_debug("Unable to get client addresses: "
3454 "no IPv6 pools on this shared network");
3455 return ISC_R_NORESOURCES
;
3459 * We have at least one pool that could provide an address
3460 * Now we walk through the ponds and pools again and check
3461 * to see if the client is permitted and if an address is
3465 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3466 if (((pond
->prohibit_list
!= NULL
) &&
3467 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3468 ((pond
->permit_list
!= NULL
) &&
3469 (!permitted(reply
->packet
, pond
->permit_list
))))
3472 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3473 if (p
->pool_type
!= D6O_IA_TA
) {
3478 * Get an address in this temporary pool.
3480 status
= create_lease6(p
, &reply
->lease
, &attempts
,
3484 if (status
!= ISC_R_SUCCESS
) {
3485 log_debug("Unable to get a temporary address.");
3489 status
= reply_process_is_addressed(reply
,
3490 &reply
->lease
->scope
,
3492 if (status
!= ISC_R_SUCCESS
) {
3496 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3497 status
= reply_process_send_addr(reply
, &send_addr
);
3498 if (status
!= ISC_R_SUCCESS
) {
3502 * reply->lease can't be null as we use it above
3503 * add check if that changes
3505 iasubopt_dereference(&reply
->lease
, MDL
);
3510 if (reply
->lease
!= NULL
) {
3511 iasubopt_dereference(&reply
->lease
, MDL
);
3517 * This function only returns failure on 'hard' failures. If it succeeds,
3518 * it will leave a lease structure behind.
3521 reply_process_try_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3522 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
3523 struct ipv6_pool
*pool
= NULL
;
3524 struct ipv6_pond
*pond
= NULL
;
3526 struct data_string data_addr
;
3528 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
3529 (addr
== NULL
) || (reply
->lease
!= NULL
))
3530 return (DHCP_R_INVALIDARG
);
3533 * Do a quick walk through of the ponds and pools
3534 * to see if we have any NA address pools
3536 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3537 if (pond
->ipv6_pools
== NULL
)
3540 for (i
= 0; ; i
++) {
3541 pool
= pond
->ipv6_pools
[i
];
3542 if ((pool
== NULL
) ||
3543 (pool
->pool_type
== D6O_IA_NA
))
3550 /* If we get here and p is NULL we have no useful pools */
3552 return (ISC_R_ADDRNOTAVAIL
);
3555 memset(&data_addr
, 0, sizeof(data_addr
));
3556 data_addr
.len
= addr
->len
;
3557 data_addr
.data
= addr
->iabuf
;
3560 * We have at least one pool that could provide an address
3561 * Now we walk through the ponds and pools again and check
3562 * to see if the client is permitted and if an address is
3565 * Within a given pond we start looking at the last pool we
3566 * allocated from, unless it had a collision trying to allocate
3567 * an address. This will tend to move us into less-filled pools.
3570 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3571 if (((pond
->prohibit_list
!= NULL
) &&
3572 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3573 ((pond
->permit_list
!= NULL
) &&
3574 (!permitted(reply
->packet
, pond
->permit_list
))))
3577 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3578 if (pool
->pool_type
!= D6O_IA_NA
)
3581 status
= try_client_v6_address(&reply
->lease
, pool
,
3583 if (status
== ISC_R_SUCCESS
)
3587 if (status
== ISC_R_SUCCESS
)
3591 /* Note that this is just pedantry. There is no allocation to free. */
3592 data_string_forget(&data_addr
, MDL
);
3593 /* Return just the most recent status... */
3597 /* Look around for an address to give the client. First, look through the
3598 * old IA for addresses we can extend. Second, try to allocate a new address.
3599 * Finally, actually add that address into the current reply IA.
3602 find_client_address(struct reply_state
*reply
) {
3603 struct iaddr send_addr
;
3604 isc_result_t status
= ISC_R_NORESOURCES
;
3605 struct iasubopt
*lease
, *best_lease
= NULL
;
3606 struct binding_scope
**scope
;
3607 struct group
*group
;
3610 if (reply
->static_lease
) {
3611 if (reply
->host
== NULL
)
3612 return DHCP_R_INVALIDARG
;
3615 memcpy(send_addr
.iabuf
, reply
->fixed
.data
, 16);
3617 scope
= &global_scope
;
3618 group
= reply
->subnet
->group
;
3622 if (reply
->old_ia
!= NULL
) {
3623 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3624 struct shared_network
*candidate_shared
;
3625 struct ipv6_pond
*pond
;
3627 lease
= reply
->old_ia
->iasubopt
[i
];
3628 candidate_shared
= lease
->ipv6_pool
->shared_network
;
3629 pond
= lease
->ipv6_pool
->ipv6_pond
;
3632 * Look for the best lease on the client's shared
3633 * network, that is still permitted
3636 if ((candidate_shared
!= reply
->shared
) ||
3637 (lease6_usable(lease
) != ISC_TRUE
))
3640 if (((pond
->prohibit_list
!= NULL
) &&
3641 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3642 ((pond
->permit_list
!= NULL
) &&
3643 (!permitted(reply
->packet
, pond
->permit_list
))))
3646 best_lease
= lease_compare(lease
, best_lease
);
3650 /* Try to pick a new address if we didn't find one, or if we found an
3653 if ((best_lease
== NULL
) || (best_lease
->state
== FTS_ABANDONED
)) {
3654 status
= pick_v6_address(reply
);
3655 } else if (best_lease
!= NULL
) {
3656 iasubopt_reference(&reply
->lease
, best_lease
, MDL
);
3657 status
= ISC_R_SUCCESS
;
3660 /* Pick the abandoned lease as a last resort. */
3661 if ((status
== ISC_R_NORESOURCES
) && (best_lease
!= NULL
)) {
3662 /* I don't see how this is supposed to be done right now. */
3663 log_error("Best match for DUID %s is an abandoned address,"
3664 " This may be a result of multiple clients attempting"
3665 " to use this DUID",
3666 print_hex_1(reply
->client_id
.len
,
3667 reply
->client_id
.data
, 60));
3668 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
3671 /* Give up now if we didn't find a lease. */
3672 if (status
!= ISC_R_SUCCESS
)
3675 if (reply
->lease
== NULL
)
3676 log_fatal("Impossible condition at %s:%d.", MDL
);
3678 /* Draw binding scopes from the lease's binding scope, and config
3679 * from the lease's containing subnet and higher. Note that it may
3680 * be desirable to place the group attachment directly in the pool.
3682 scope
= &reply
->lease
->scope
;
3683 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
3686 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3689 status
= reply_process_is_addressed(reply
, scope
, group
);
3690 if (status
!= ISC_R_SUCCESS
)
3693 status
= reply_process_send_addr(reply
, &send_addr
);
3697 /* Once an address is found for a client, perform several common functions;
3698 * Calculate and store valid and preferred lease times, draw client options
3699 * into the option state.
3702 reply_process_is_addressed(struct reply_state
*reply
,
3703 struct binding_scope
**scope
, struct group
*group
)
3705 isc_result_t status
= ISC_R_SUCCESS
;
3706 struct data_string data
;
3707 struct option_cache
*oc
;
3708 struct option_state
*tmp_options
= NULL
;
3709 struct on_star
*on_star
;
3712 /* Initialize values we will cleanup. */
3713 memset(&data
, 0, sizeof(data
));
3716 * Find the proper on_star block to use. We use the
3717 * one in the lease if we have a lease or the one in
3718 * the reply if we don't have a lease because this is
3722 on_star
= &reply
->lease
->on_star
;
3724 on_star
= &reply
->on_star
;
3728 * Bring in the root configuration. We only do this to bring
3729 * in the on * statements, as we didn't have the lease available
3730 * we did it the first time.
3732 option_state_allocate(&tmp_options
, MDL
);
3733 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3734 reply
->packet
->options
, tmp_options
,
3735 &global_scope
, root_group
, NULL
,
3737 if (tmp_options
!= NULL
) {
3738 option_state_dereference(&tmp_options
, MDL
);
3742 * Bring configured options into the root packet level cache - start
3743 * with the lease's closest enclosing group (passed in by the caller
3746 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3747 reply
->packet
->options
, reply
->opt_state
,
3748 scope
, group
, root_group
, on_star
);
3750 /* Execute statements from class scopes. */
3751 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3752 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3753 reply
->packet
->options
,
3754 reply
->opt_state
, scope
,
3755 reply
->packet
->classes
[i
- 1]->group
,
3760 * If there is a host record, over-ride with values configured there,
3761 * without re-evaluating configuration from the previously executed
3762 * group or its common enclosers.
3764 if (reply
->host
!= NULL
)
3765 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3766 reply
->packet
->options
,
3767 reply
->opt_state
, scope
,
3768 reply
->host
->group
, group
,
3771 /* Determine valid lifetime. */
3772 if (reply
->client_valid
== 0)
3773 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
3775 reply
->send_valid
= reply
->client_valid
;
3777 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3778 SV_DEFAULT_LEASE_TIME
);
3780 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3781 reply
->packet
->options
,
3785 log_error("reply_process_is_addressed: unable to "
3786 "evaluate default lease time");
3787 status
= ISC_R_FAILURE
;
3791 reply
->send_valid
= getULong(data
.data
);
3792 data_string_forget(&data
, MDL
);
3795 /* Check to see if the lease time would cause us to wrap
3796 * in which case we make it infinite.
3797 * The following doesn't work on at least some systems:
3798 * (cur_time + reply->send_valid < cur_time)
3800 if (reply
->send_valid
!= INFINITE_TIME
) {
3801 time_t test_time
= cur_time
+ reply
->send_valid
;
3802 if (test_time
< cur_time
)
3803 reply
->send_valid
= INFINITE_TIME
;
3806 if (reply
->client_prefer
== 0)
3807 reply
->send_prefer
= reply
->send_valid
;
3809 reply
->send_prefer
= reply
->client_prefer
;
3811 if ((reply
->send_prefer
>= reply
->send_valid
) &&
3812 (reply
->send_valid
!= INFINITE_TIME
))
3813 reply
->send_prefer
= (reply
->send_valid
/ 2) +
3814 (reply
->send_valid
/ 8);
3816 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3817 SV_PREFER_LIFETIME
);
3819 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3820 reply
->packet
->options
,
3824 log_error("reply_process_is_addressed: unable to "
3825 "evaluate preferred lease time");
3826 status
= ISC_R_FAILURE
;
3830 reply
->send_prefer
= getULong(data
.data
);
3831 data_string_forget(&data
, MDL
);
3834 /* Note lowest values for later calculation of renew/rebind times. */
3835 if (reply
->min_prefer
> reply
->send_prefer
)
3836 reply
->min_prefer
= reply
->send_prefer
;
3838 if (reply
->min_valid
> reply
->send_valid
)
3839 reply
->min_valid
= reply
->send_valid
;
3843 * XXX: Old 4.0.0 alpha code would change the host {} record
3844 * XXX: uid upon lease assignment. This was intended to cover the
3845 * XXX: case where a client first identifies itself using vendor
3846 * XXX: options in a solicit, or request, but later neglects to include
3847 * XXX: these options in a Renew or Rebind. It is not clear that this
3848 * XXX: is required, and has some startling ramifications (such as
3849 * XXX: how to recover this dynamic host {} state across restarts).
3851 if (reply
->host
!= NULL
)
3852 change_host_uid(host
, reply
->client_id
->data
,
3853 reply
->client_id
->len
);
3856 /* Perform dynamic lease related update work. */
3857 if (reply
->lease
!= NULL
) {
3858 /* Cached lifetimes */
3859 reply
->lease
->prefer
= reply
->send_prefer
;
3860 reply
->lease
->valid
= reply
->send_valid
;
3862 /* Advance (or rewind) the valid lifetime.
3863 * In the protocol 0xFFFFFFFF is infinite
3864 * when connecting to the lease file MAX_TIME is
3866 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
3867 if (reply
->send_valid
== INFINITE_TIME
) {
3868 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
3870 reply
->lease
->soft_lifetime_end_time
=
3871 cur_time
+ reply
->send_valid
;
3873 /* Wait before renew! */
3876 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
3877 if (status
!= ISC_R_SUCCESS
) {
3878 log_fatal("reply_process_is_addressed: Unable to "
3879 "attach lease to new IA: %s",
3880 isc_result_totext(status
));
3884 * If this is a new lease, make sure it is attached somewhere.
3886 if (reply
->lease
->ia
== NULL
) {
3887 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
3891 /* Bring a copy of the relevant options into the IA scope. */
3892 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3893 reply
->packet
->options
, reply
->reply_ia
,
3894 scope
, group
, root_group
, NULL
);
3896 /* Execute statements from class scopes. */
3897 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3898 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3899 reply
->packet
->options
,
3900 reply
->reply_ia
, scope
,
3901 reply
->packet
->classes
[i
- 1]->group
,
3906 * And bring in host record configuration, if any, but not to overlap
3907 * the previous group or its common enclosers.
3909 if (reply
->host
!= NULL
)
3910 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3911 reply
->packet
->options
,
3912 reply
->reply_ia
, scope
,
3913 reply
->host
->group
, group
, NULL
);
3916 if (data
.data
!= NULL
)
3917 data_string_forget(&data
, MDL
);
3919 if (status
== ISC_R_SUCCESS
)
3920 reply
->client_resources
++;
3925 /* Simply send an IAADDR within the IA scope as described. */
3927 reply_process_send_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3928 isc_result_t status
= ISC_R_SUCCESS
;
3929 struct data_string data
;
3931 memset(&data
, 0, sizeof(data
));
3933 /* Now append the lease. */
3934 data
.len
= IAADDR_OFFSET
;
3935 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
3936 log_error("reply_process_send_addr: out of memory"
3937 "allocating new IAADDR buffer.");
3938 status
= ISC_R_NOMEMORY
;
3941 data
.data
= data
.buffer
->data
;
3943 memcpy(data
.buffer
->data
, addr
->iabuf
, 16);
3944 putULong(data
.buffer
->data
+ 16, reply
->send_prefer
);
3945 putULong(data
.buffer
->data
+ 20, reply
->send_valid
);
3947 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
3948 data
.buffer
, data
.buffer
->data
,
3949 data
.len
, D6O_IAADDR
, 0)) {
3950 log_error("reply_process_send_addr: unable "
3951 "to save IAADDR option");
3952 status
= ISC_R_FAILURE
;
3956 reply
->resources_included
= ISC_TRUE
;
3959 if (data
.data
!= NULL
)
3960 data_string_forget(&data
, MDL
);
3965 /* Choose the better of two leases. */
3966 static struct iasubopt
*
3967 lease_compare(struct iasubopt
*alpha
, struct iasubopt
*beta
) {
3973 switch(alpha
->state
) {
3975 switch(beta
->state
) {
3977 /* Choose the lease with the longest lifetime (most
3978 * likely the most recently allocated).
3980 if (alpha
->hard_lifetime_end_time
<
3981 beta
->hard_lifetime_end_time
)
3991 log_fatal("Impossible condition at %s:%d.", MDL
);
3996 switch (beta
->state
) {
4001 /* Choose the most recently expired lease. */
4002 if (alpha
->hard_lifetime_end_time
<
4003 beta
->hard_lifetime_end_time
)
4005 else if ((alpha
->hard_lifetime_end_time
==
4006 beta
->hard_lifetime_end_time
) &&
4007 (alpha
->soft_lifetime_end_time
<
4008 beta
->soft_lifetime_end_time
))
4017 log_fatal("Impossible condition at %s:%d.", MDL
);
4022 switch (beta
->state
) {
4028 /* Choose the lease that was abandoned longest ago. */
4029 if (alpha
->hard_lifetime_end_time
<
4030 beta
->hard_lifetime_end_time
)
4036 log_fatal("Impossible condition at %s:%d.", MDL
);
4041 log_fatal("Impossible condition at %s:%d.", MDL
);
4044 log_fatal("Triple impossible condition at %s:%d.", MDL
);
4048 /* Process a client-supplied IA_PD. This may append options to the tail of
4049 * the reply packet being built in the reply_state structure.
4052 reply_process_ia_pd(struct reply_state
*reply
, struct option_cache
*ia
) {
4053 isc_result_t status
= ISC_R_SUCCESS
;
4056 struct option_state
*packet_ia
;
4057 struct option_cache
*oc
;
4058 struct data_string ia_data
, data
;
4060 /* Initialize values that will get cleaned up on return. */
4062 memset(&ia_data
, 0, sizeof(ia_data
));
4063 memset(&data
, 0, sizeof(data
));
4065 * Note that find_client_prefix() may set reply->lease.
4068 /* Make sure there is at least room for the header. */
4069 if ((reply
->cursor
+ IA_PD_OFFSET
+ 4) > sizeof(reply
->buf
)) {
4070 log_error("reply_process_ia_pd: Reply too long for IA.");
4071 return ISC_R_NOSPACE
;
4075 /* Fetch the IA_PD contents. */
4076 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
4077 ia
, IA_PD_OFFSET
)) {
4078 log_error("reply_process_ia_pd: error evaluating ia");
4079 status
= ISC_R_FAILURE
;
4083 /* Extract IA_PD header contents. */
4084 iaid
= getULong(ia_data
.data
);
4085 reply
->renew
= getULong(ia_data
.data
+ 4);
4086 reply
->rebind
= getULong(ia_data
.data
+ 8);
4088 /* Create an IA_PD structure. */
4089 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
4090 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
4091 log_error("reply_process_ia_pd: no memory for ia.");
4092 status
= ISC_R_NOMEMORY
;
4095 reply
->ia
->ia_type
= D6O_IA_PD
;
4097 /* Cache pre-existing IA_PD, if any. */
4098 ia_hash_lookup(&reply
->old_ia
, ia_pd_active
,
4099 (unsigned char *)reply
->ia
->iaid_duid
.data
,
4100 reply
->ia
->iaid_duid
.len
, MDL
);
4103 * Create an option cache to carry the IA_PD option contents, and
4104 * execute any user-supplied values into it.
4106 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
4107 status
= ISC_R_NOMEMORY
;
4111 /* Check & count the fixed prefix host records. */
4112 reply
->static_prefixes
= 0;
4113 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_prefix
!= NULL
)) {
4114 struct iaddrcidrnetlist
*fp
;
4116 for (fp
= reply
->host
->fixed_prefix
; fp
!= NULL
;
4118 reply
->static_prefixes
+= 1;
4123 * Save the cursor position at the start of the IA_PD, so we can
4124 * set length and adjust t1/t2 values later. We write a temporary
4125 * header out now just in case we decide to adjust the packet
4126 * within sub-process functions.
4128 ia_cursor
= reply
->cursor
;
4130 /* Initialize the IA_PD header. First the code. */
4131 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_PD
);
4134 /* Then option length. */
4135 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
4138 /* Then IA_PD header contents; IAID. */
4139 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
4142 /* We store the client's t1 for now, and may over-ride it later. */
4143 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
4146 /* We store the client's t2 for now, and may over-ride it later. */
4147 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
4151 * For each prefix in this IA_PD, decide what to do about it.
4153 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAPREFIX
);
4154 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
4155 reply
->client_valid
= reply
->client_prefer
= 0;
4156 reply
->preflen
= -1;
4157 for (; oc
!= NULL
; oc
= oc
->next
) {
4158 status
= reply_process_prefix(reply
, oc
);
4161 * Canceled means we did not allocate prefixes to the
4162 * client, but we're "done" with this IA - we set a status
4163 * code. So transmit this reply, e.g., move on to the next
4166 if (status
== ISC_R_CANCELED
)
4169 if ((status
!= ISC_R_SUCCESS
) &&
4170 (status
!= ISC_R_ADDRINUSE
) &&
4171 (status
!= ISC_R_ADDRNOTAVAIL
))
4178 * If we fell through the above and never gave the client
4179 * a prefix, give it one now.
4181 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
4182 status
= find_client_prefix(reply
);
4184 if (status
== ISC_R_NORESOURCES
) {
4185 switch (reply
->packet
->dhcpv6_msg_type
) {
4186 case DHCPV6_SOLICIT
:
4188 * No prefix for any IA is handled
4193 case DHCPV6_REQUEST
:
4194 /* Same than for addresses. */
4195 option_state_dereference(&reply
->reply_ia
, MDL
);
4196 if (!option_state_allocate(&reply
->reply_ia
,
4199 log_error("reply_process_ia_pd: No "
4200 "memory for option state "
4202 status
= ISC_R_NOMEMORY
;
4206 if (!set_status_code(STATUS_NoPrefixAvail
,
4207 "No prefixes available "
4208 "for this interface.",
4210 log_error("reply_process_ia_pd: "
4212 "NoPrefixAvail status "
4214 status
= ISC_R_FAILURE
;
4218 status
= ISC_R_SUCCESS
;
4222 if (reply
->resources_included
)
4223 status
= ISC_R_SUCCESS
;
4230 if (status
!= ISC_R_SUCCESS
)
4235 * yes, goto's aren't the best but we also want to avoid extra
4238 if (status
== ISC_R_CANCELED
) {
4239 /* We're replying with a status code so we still need to
4240 * write it out in wire-format to the outbound buffer */
4241 write_to_packet(reply
, ia_cursor
);
4246 * Handle static prefixes, we always log stuff and if it's
4247 * a hard binding we run any commit statements that we have
4249 if (reply
->static_prefixes
!= 0) {
4250 char tmp_addr
[INET6_ADDRSTRLEN
];
4251 log_info("%s PD: address %s/%d to client with duid %s "
4253 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
4254 inet_ntop(AF_INET6
, reply
->fixed_pref
.lo_addr
.iabuf
,
4255 tmp_addr
, sizeof(tmp_addr
)),
4256 reply
->fixed_pref
.bits
,
4257 print_hex_1(reply
->client_id
.len
,
4258 reply
->client_id
.data
, 60),
4261 /* Write the lease out in wire-format to the outbound buffer */
4262 write_to_packet(reply
, ia_cursor
);
4264 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
4265 (reply
->on_star
.on_commit
!= NULL
)) {
4266 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
4267 reply
->packet
->options
,
4269 NULL
, reply
->on_star
.on_commit
,
4271 executable_statement_dereference
4272 (&reply
->on_star
.on_commit
, MDL
);
4278 * If we have any addresses log what we are doing.
4280 if (reply
->ia
->num_iasubopt
!= 0) {
4281 struct iasubopt
*tmp
;
4283 char tmp_addr
[INET6_ADDRSTRLEN
];
4285 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
4286 tmp
= reply
->ia
->iasubopt
[i
];
4288 log_info("%s PD: address %s/%d to client with duid %s"
4289 " iaid = %d valid for %u seconds",
4290 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
4291 inet_ntop(AF_INET6
, &tmp
->addr
,
4292 tmp_addr
, sizeof(tmp_addr
)),
4294 print_hex_1(reply
->client_id
.len
,
4295 reply
->client_id
.data
, 60),
4301 * If this is not a 'soft' binding, consume the new changes into
4302 * the database (if any have been attached to the ia_pd).
4304 * Loop through the assigned dynamic prefixes, referencing the
4305 * prefixes onto this IA_PD rather than any old ones, and updating
4306 * prefix pool timers for each (if any).
4308 * If a lease can be reused we skip renewing it or checking the
4309 * pool threshold. If it can't we flag that the IA must be commited
4310 * to the db and do the renewal and pool check.
4312 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
4313 (reply
->ia
->num_iasubopt
!= 0)) {
4314 int must_commit
= 0;
4315 struct iasubopt
*tmp
;
4316 struct data_string
*ia_id
;
4319 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
4320 tmp
= reply
->ia
->iasubopt
[i
];
4322 if (tmp
->ia
!= NULL
)
4323 ia_dereference(&tmp
->ia
, MDL
);
4324 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
4326 /* If we have anything to do on commit do it now */
4327 if (tmp
->on_star
.on_commit
!= NULL
) {
4328 execute_statements(NULL
, reply
->packet
,
4330 reply
->packet
->options
,
4333 tmp
->on_star
.on_commit
,
4335 executable_statement_dereference
4336 (&tmp
->on_star
.on_commit
, MDL
);
4339 if (!reuse_lease6(reply
, tmp
)) {
4340 /* Commit 'hard' bindings. */
4342 renew_lease6(tmp
->ipv6_pool
, tmp
);
4343 schedule_lease_timeout(tmp
->ipv6_pool
);
4345 /* Do our threshold check. */
4346 check_pool6_threshold(reply
, tmp
);
4350 /* write the IA_PD in wire-format to the outbound buffer */
4351 write_to_packet(reply
, ia_cursor
);
4353 /* Remove any old ia from the hash. */
4354 if (reply
->old_ia
!= NULL
) {
4355 if (!release_on_roam(reply
)) {
4356 ia_id
= &reply
->old_ia
->iaid_duid
;
4357 ia_hash_delete(ia_pd_active
,
4358 (unsigned char *)ia_id
->data
,
4362 ia_dereference(&reply
->old_ia
, MDL
);
4365 /* Put new ia into the hash. */
4366 reply
->ia
->cltt
= cur_time
;
4367 ia_id
= &reply
->ia
->iaid_duid
;
4368 ia_hash_add(ia_pd_active
, (unsigned char *)ia_id
->data
,
4369 ia_id
->len
, reply
->ia
, MDL
);
4371 /* If we couldn't reuse all of the iasubopts, we
4372 * must udpate the lease db */
4374 write_ia(reply
->ia
);
4377 /* write the IA_PD in wire-format to the outbound buffer */
4378 write_to_packet(reply
, ia_cursor
);
4379 schedule_lease_timeout_reply(reply
);
4383 if (packet_ia
!= NULL
)
4384 option_state_dereference(&packet_ia
, MDL
);
4385 if (reply
->reply_ia
!= NULL
)
4386 option_state_dereference(&reply
->reply_ia
, MDL
);
4387 if (ia_data
.data
!= NULL
)
4388 data_string_forget(&ia_data
, MDL
);
4389 if (data
.data
!= NULL
)
4390 data_string_forget(&data
, MDL
);
4391 if (reply
->ia
!= NULL
)
4392 ia_dereference(&reply
->ia
, MDL
);
4393 if (reply
->old_ia
!= NULL
)
4394 ia_dereference(&reply
->old_ia
, MDL
);
4395 if (reply
->lease
!= NULL
)
4396 iasubopt_dereference(&reply
->lease
, MDL
);
4397 if (reply
->on_star
.on_expiry
!= NULL
)
4398 executable_statement_dereference
4399 (&reply
->on_star
.on_expiry
, MDL
);
4400 if (reply
->on_star
.on_release
!= NULL
)
4401 executable_statement_dereference
4402 (&reply
->on_star
.on_release
, MDL
);
4405 * ISC_R_CANCELED is a status code used by the prefix processing to
4406 * indicate we're replying with a status code. This is still a
4407 * success at higher layers.
4409 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
4414 * \brief Find the proper scoping group for use with a v6 static prefix.
4416 * We start by trying to find a subnet based on the given prefix and
4417 * the shared network. If we don't find one then the prefix has been
4418 * declared outside of any subnets. If there is a static address
4419 * associated with the host we use it to try and find a subnet (this
4420 * should succeed). If there isn't a static address we fall back
4421 * to the shared subnet itself.
4422 * Once we have a subnet we extract the group from it and return it.
4424 * \param reply - the reply structure we use to collect information
4425 * we will use the fields shared, fixed_pref and host
4426 * from the structure
4428 * \return a pointer to the group structure to use for scoping
4431 static struct group
*
4432 find_group_by_prefix(struct reply_state
*reply
) {
4433 /* default group if we don't find anything better */
4434 struct group
*group
= reply
->shared
->group
;
4435 struct subnet
*subnet
= NULL
;
4436 struct iaddr tmp_addr
;
4437 struct data_string fixed_addr
;
4439 /* Try with the prefix first */
4440 if (find_grouped_subnet(&subnet
, reply
->shared
,
4441 reply
->fixed_pref
.lo_addr
, MDL
) != 0) {
4442 group
= subnet
->group
;
4443 subnet_dereference(&subnet
, MDL
);
4447 /* Didn't find a subnet via prefix, what about fixed address */
4448 /* The caller has already tested reply->host != NULL */
4450 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
4452 if ((reply
->host
->fixed_addr
!= NULL
) &&
4453 (evaluate_option_cache(&fixed_addr
, NULL
, NULL
, NULL
,
4454 NULL
, NULL
, &global_scope
,
4455 reply
->host
->fixed_addr
, MDL
))) {
4456 if (fixed_addr
.len
>= 16) {
4458 memcpy(tmp_addr
.iabuf
, fixed_addr
.data
, 16);
4459 if (find_grouped_subnet(&subnet
, reply
->shared
,
4460 tmp_addr
, MDL
) != 0) {
4461 group
= subnet
->group
;
4462 subnet_dereference(&subnet
, MDL
);
4465 data_string_forget(&fixed_addr
, MDL
);
4468 /* return whatever we got */
4473 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
4474 * contents into the reply's current ia_pd-scoped option cache. Returns
4475 * ISC_R_CANCELED in the event we are replying with a status code and do
4476 * not wish to process more IAPREFIXes within this IA_PD.
4479 reply_process_prefix(struct reply_state
*reply
, struct option_cache
*pref
) {
4480 u_int32_t pref_life
, valid_life
;
4481 struct binding_scope
**scope
;
4482 struct iaddrcidrnet tmp_pref
;
4483 struct option_cache
*oc
;
4484 struct data_string iapref
, data
;
4485 isc_result_t status
= ISC_R_SUCCESS
;
4486 struct group
*group
;
4488 /* Initializes values that will be cleaned up. */
4489 memset(&iapref
, 0, sizeof(iapref
));
4490 memset(&data
, 0, sizeof(data
));
4491 /* Note that reply->lease may be set by prefix_is_owned() */
4494 * There is no point trying to process an incoming prefix if there
4495 * is no room for an outgoing prefix.
4497 if ((reply
->cursor
+ 29) > sizeof(reply
->buf
)) {
4498 log_error("reply_process_prefix: Out of room for prefix.");
4499 return ISC_R_NOSPACE
;
4502 /* Extract this IAPREFIX option. */
4503 if (!evaluate_option_cache(&iapref
, reply
->packet
, NULL
, NULL
,
4504 reply
->packet
->options
, NULL
, &global_scope
,
4506 (iapref
.len
< IAPREFIX_OFFSET
)) {
4507 log_error("reply_process_prefix: error evaluating IAPREFIX.");
4508 status
= ISC_R_FAILURE
;
4513 * Layout: preferred and valid lifetimes followed by the prefix
4514 * length and the IPv6 address.
4516 pref_life
= getULong(iapref
.data
);
4517 valid_life
= getULong(iapref
.data
+ 4);
4519 if ((reply
->client_valid
== 0) ||
4520 (reply
->client_valid
> valid_life
))
4521 reply
->client_valid
= valid_life
;
4523 if ((reply
->client_prefer
== 0) ||
4524 (reply
->client_prefer
> pref_life
))
4525 reply
->client_prefer
= pref_life
;
4528 * Clients may choose to send ::/0 as a prefix, with the idea to give
4529 * hints about preferred-lifetime or valid-lifetime.
4531 tmp_pref
.lo_addr
.len
= 16;
4532 memset(tmp_pref
.lo_addr
.iabuf
, 0, 16);
4533 if ((iapref
.data
[8] == 0) &&
4534 (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0)) {
4535 /* Status remains success; we just ignore this one. */
4540 * Clients may choose to send ::/X as a prefix to specify a
4541 * preferred/requested prefix length. Note X is never zero here.
4543 tmp_pref
.bits
= (int) iapref
.data
[8];
4544 if (reply
->preflen
< 0) {
4545 /* Cache the first preferred prefix length. */
4546 reply
->preflen
= tmp_pref
.bits
;
4548 if (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0) {
4552 memcpy(tmp_pref
.lo_addr
.iabuf
, iapref
.data
+ 9, 16);
4554 /* Verify the prefix belongs to the client. */
4555 if (!prefix_is_owned(reply
, &tmp_pref
)) {
4556 /* Same than for addresses. */
4557 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
4558 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
4559 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
4560 status
= reply_process_try_prefix(reply
, &tmp_pref
);
4562 /* Either error out or skip this prefix. */
4563 if ((status
!= ISC_R_SUCCESS
) &&
4564 (status
!= ISC_R_ADDRINUSE
) &&
4565 (status
!= ISC_R_ADDRNOTAVAIL
))
4568 if (reply
->lease
== NULL
) {
4569 if (reply
->packet
->dhcpv6_msg_type
==
4571 reply
->send_prefer
= 0;
4572 reply
->send_valid
= 0;
4576 /* status remains success - ignore */
4580 * RFC3633 section 18.2.3:
4582 * If the delegating router cannot find a binding
4583 * for the requesting router's IA_PD the delegating
4584 * router returns the IA_PD containing no prefixes
4585 * with a Status Code option set to NoBinding in the
4588 * On mismatch we (ab)use this pretending we have not the IA
4589 * as soon as we have not a prefix.
4591 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
4592 /* Rewind the IA_PD to empty. */
4593 option_state_dereference(&reply
->reply_ia
, MDL
);
4594 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
4595 log_error("reply_process_prefix: No memory "
4596 "for option state wipe.");
4597 status
= ISC_R_NOMEMORY
;
4601 /* Append a NoBinding status code. */
4602 if (!set_status_code(STATUS_NoBinding
,
4603 "Prefix not bound to this "
4604 "interface.", reply
->reply_ia
)) {
4605 log_error("reply_process_prefix: Unable to "
4606 "attach status code.");
4607 status
= ISC_R_FAILURE
;
4611 /* Fin (no more IAPREFIXes). */
4612 status
= ISC_R_CANCELED
;
4615 log_error("It is impossible to lease a client that is "
4616 "not sending a solicit, request, renew, or "
4618 status
= ISC_R_FAILURE
;
4623 if (reply
->static_prefixes
> 0) {
4624 if (reply
->host
== NULL
)
4625 log_fatal("Impossible condition at %s:%d.", MDL
);
4627 scope
= &global_scope
;
4629 /* Copy the static prefix for logging and finding the group */
4630 memcpy(&reply
->fixed_pref
, &tmp_pref
, sizeof(tmp_pref
));
4632 /* Try to find a group for the static prefix */
4633 group
= find_group_by_prefix(reply
);
4635 if (reply
->lease
== NULL
)
4636 log_fatal("Impossible condition at %s:%d.", MDL
);
4638 scope
= &reply
->lease
->scope
;
4639 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4643 * If client_resources is nonzero, then the reply_process_is_prefixed
4644 * function has executed configuration state into the reply option
4645 * cache. We will use that valid cache to derive configuration for
4646 * whether or not to engage in additional prefixes, and similar.
4648 if (reply
->client_resources
!= 0) {
4652 * Does this client have "enough" prefixes already? Default
4653 * to one. Everybody gets one, and one should be enough for
4656 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4657 SV_LIMIT_PREFS_PER_IA
);
4659 if (!evaluate_option_cache(&data
, reply
->packet
,
4661 reply
->packet
->options
,
4665 log_error("reply_process_prefix: unable to "
4666 "evaluate prefs-per-ia value.");
4667 status
= ISC_R_FAILURE
;
4671 limit
= getULong(data
.data
);
4672 data_string_forget(&data
, MDL
);
4676 * If we wish to limit the client to a certain number of
4677 * prefixes, then omit the prefix from the reply.
4679 if (reply
->client_resources
>= limit
)
4683 status
= reply_process_is_prefixed(reply
, scope
, group
);
4684 if (status
!= ISC_R_SUCCESS
)
4688 status
= reply_process_send_prefix(reply
, &tmp_pref
);
4691 if (iapref
.data
!= NULL
)
4692 data_string_forget(&iapref
, MDL
);
4693 if (data
.data
!= NULL
)
4694 data_string_forget(&data
, MDL
);
4695 if (reply
->lease
!= NULL
)
4696 iasubopt_dereference(&reply
->lease
, MDL
);
4702 * Verify the prefix belongs to the client. If we've got a host
4703 * record with fixed prefixes, it has to be an assigned prefix
4704 * (fault out all else). Otherwise it's a dynamic prefix, so lookup
4705 * that prefix and make sure it belongs to this DUID:IAID pair.
4707 static isc_boolean_t
4708 prefix_is_owned(struct reply_state
*reply
, struct iaddrcidrnet
*pref
) {
4709 struct iaddrcidrnetlist
*l
;
4711 struct ipv6_pond
*pond
;
4714 * This faults out prefixes that don't match fixed prefixes.
4716 if (reply
->static_prefixes
> 0) {
4717 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4718 if ((pref
->bits
== l
->cidrnet
.bits
) &&
4719 (memcmp(pref
->lo_addr
.iabuf
,
4720 l
->cidrnet
.lo_addr
.iabuf
, 16) == 0))
4726 if ((reply
->old_ia
== NULL
) ||
4727 (reply
->old_ia
->num_iasubopt
== 0))
4730 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4731 struct iasubopt
*tmp
;
4733 tmp
= reply
->old_ia
->iasubopt
[i
];
4735 if ((pref
->bits
== (int) tmp
->plen
) &&
4736 (memcmp(pref
->lo_addr
.iabuf
, &tmp
->addr
, 16) == 0)) {
4737 if (lease6_usable(tmp
) == ISC_FALSE
) {
4741 pond
= tmp
->ipv6_pool
->ipv6_pond
;
4742 if (((pond
->prohibit_list
!= NULL
) &&
4743 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4744 ((pond
->permit_list
!= NULL
) &&
4745 (!permitted(reply
->packet
, pond
->permit_list
))))
4748 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
4757 * This function only returns failure on 'hard' failures. If it succeeds,
4758 * it will leave a prefix structure behind.
4761 reply_process_try_prefix(struct reply_state
*reply
,
4762 struct iaddrcidrnet
*pref
) {
4763 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
4764 struct ipv6_pool
*pool
= NULL
;
4765 struct ipv6_pond
*pond
= NULL
;
4767 struct data_string data_pref
;
4769 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
4770 (pref
== NULL
) || (reply
->lease
!= NULL
))
4771 return (DHCP_R_INVALIDARG
);
4774 * Do a quick walk through of the ponds and pools
4775 * to see if we have any prefix pools
4777 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4778 if (pond
->ipv6_pools
== NULL
)
4781 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4782 if (pool
->pool_type
== D6O_IA_PD
)
4789 /* If we get here and p is NULL we have no useful pools */
4791 return (ISC_R_ADDRNOTAVAIL
);
4794 memset(&data_pref
, 0, sizeof(data_pref
));
4796 if (!buffer_allocate(&data_pref
.buffer
, data_pref
.len
, MDL
)) {
4797 log_error("reply_process_try_prefix: out of memory.");
4798 return (ISC_R_NOMEMORY
);
4800 data_pref
.data
= data_pref
.buffer
->data
;
4801 data_pref
.buffer
->data
[0] = (u_int8_t
) pref
->bits
;
4802 memcpy(data_pref
.buffer
->data
+ 1, pref
->lo_addr
.iabuf
, 16);
4805 * We have at least one pool that could provide a prefix
4806 * Now we walk through the ponds and pools again and check
4807 * to see if the client is permitted and if an prefix is
4812 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4813 if (((pond
->prohibit_list
!= NULL
) &&
4814 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4815 ((pond
->permit_list
!= NULL
) &&
4816 (!permitted(reply
->packet
, pond
->permit_list
))))
4819 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4820 if (pool
->pool_type
!= D6O_IA_PD
) {
4824 status
= try_client_v6_prefix(&reply
->lease
, pool
,
4826 /* If we found it in this pool (either in use or available),
4827 there is no need to look further. */
4828 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4831 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4835 data_string_forget(&data_pref
, MDL
);
4836 /* Return just the most recent status... */
4840 /* Look around for a prefix to give the client. First, look through the old
4841 * IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
4842 * Finally, actually add that prefix into the current reply IA_PD.
4845 find_client_prefix(struct reply_state
*reply
) {
4846 struct iaddrcidrnet send_pref
;
4847 isc_result_t status
= ISC_R_NORESOURCES
;
4848 struct iasubopt
*prefix
, *best_prefix
= NULL
;
4849 struct binding_scope
**scope
;
4851 struct group
*group
;
4853 if (reply
->static_prefixes
> 0) {
4854 struct iaddrcidrnetlist
*l
;
4856 if (reply
->host
== NULL
)
4857 return DHCP_R_INVALIDARG
;
4859 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4860 if (l
->cidrnet
.bits
== reply
->preflen
)
4865 * If no fixed prefix has the preferred length,
4866 * get the first one.
4868 l
= reply
->host
->fixed_prefix
;
4870 memcpy(&send_pref
, &l
->cidrnet
, sizeof(send_pref
));
4872 scope
= &global_scope
;
4874 /* Copy the prefix for logging purposes */
4875 memcpy(&reply
->fixed_pref
, &l
->cidrnet
, sizeof(send_pref
));
4877 /* Try to find a group for the static prefix */
4878 group
= find_group_by_prefix(reply
);
4883 if (reply
->old_ia
!= NULL
) {
4884 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4885 struct shared_network
*candidate_shared
;
4886 struct ipv6_pond
*pond
;
4888 prefix
= reply
->old_ia
->iasubopt
[i
];
4889 candidate_shared
= prefix
->ipv6_pool
->shared_network
;
4890 pond
= prefix
->ipv6_pool
->ipv6_pond
;
4893 * Consider this prefix if it is in a global pool or
4894 * if it is scoped in a pool under the client's shared
4897 if (((candidate_shared
!= NULL
) &&
4898 (candidate_shared
!= reply
->shared
)) ||
4899 (lease6_usable(prefix
) != ISC_TRUE
))
4903 * And check if the prefix is still permitted
4906 if (((pond
->prohibit_list
!= NULL
) &&
4907 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4908 ((pond
->permit_list
!= NULL
) &&
4909 (!permitted(reply
->packet
, pond
->permit_list
))))
4912 best_prefix
= prefix_compare(reply
, prefix
,
4917 * If we have prefix length hint and we're not igoring them,
4918 * then toss the best match if it doesn't match the hint,
4919 * unless this is in response to a rebind. In the latter
4920 * case we're supposed to return it with zero lifetimes.
4922 if (best_prefix
&& (reply
->preflen
> 0)
4923 && (prefix_length_mode
!= PLM_IGNORE
)
4924 && (reply
->preflen
!= best_prefix
->plen
)
4925 && (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
4930 /* Try to pick a new prefix if we didn't find one, or if we found an
4933 if ((best_prefix
== NULL
) || (best_prefix
->state
== FTS_ABANDONED
)) {
4934 status
= pick_v6_prefix(reply
);
4935 } else if (best_prefix
!= NULL
) {
4936 iasubopt_reference(&reply
->lease
, best_prefix
, MDL
);
4937 status
= ISC_R_SUCCESS
;
4940 /* Pick the abandoned prefix as a last resort. */
4941 if ((status
== ISC_R_NORESOURCES
) && (best_prefix
!= NULL
)) {
4942 /* I don't see how this is supposed to be done right now. */
4943 log_error("Reclaiming abandoned prefixes is not yet "
4944 "supported. Treating this as an out of space "
4946 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
4949 /* Give up now if we didn't find a prefix. */
4950 if (status
!= ISC_R_SUCCESS
)
4953 if (reply
->lease
== NULL
)
4954 log_fatal("Impossible condition at %s:%d.", MDL
);
4956 scope
= &reply
->lease
->scope
;
4957 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4959 send_pref
.lo_addr
.len
= 16;
4960 memcpy(send_pref
.lo_addr
.iabuf
, &reply
->lease
->addr
, 16);
4961 send_pref
.bits
= (int) reply
->lease
->plen
;
4964 status
= reply_process_is_prefixed(reply
, scope
, group
);
4965 if (status
!= ISC_R_SUCCESS
)
4968 status
= reply_process_send_prefix(reply
, &send_pref
);
4972 /* Once a prefix is found for a client, perform several common functions;
4973 * Calculate and store valid and preferred prefix times, draw client options
4974 * into the option state.
4977 reply_process_is_prefixed(struct reply_state
*reply
,
4978 struct binding_scope
**scope
, struct group
*group
)
4980 isc_result_t status
= ISC_R_SUCCESS
;
4981 struct data_string data
;
4982 struct option_cache
*oc
;
4983 struct option_state
*tmp_options
= NULL
;
4984 struct on_star
*on_star
;
4987 /* Initialize values we will cleanup. */
4988 memset(&data
, 0, sizeof(data
));
4991 * Find the proper on_star block to use. We use the
4992 * one in the lease if we have a lease or the one in
4993 * the reply if we don't have a lease because this is
4997 on_star
= &reply
->lease
->on_star
;
4999 on_star
= &reply
->on_star
;
5003 * Bring in the root configuration. We only do this to bring
5004 * in the on * statements, as we didn't have the lease available
5005 * we we did it the first time.
5007 option_state_allocate(&tmp_options
, MDL
);
5008 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5009 reply
->packet
->options
, tmp_options
,
5010 &global_scope
, root_group
, NULL
,
5012 if (tmp_options
!= NULL
) {
5013 option_state_dereference(&tmp_options
, MDL
);
5017 * Bring configured options into the root packet level cache - start
5018 * with the lease's closest enclosing group (passed in by the caller
5021 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5022 reply
->packet
->options
, reply
->opt_state
,
5023 scope
, group
, root_group
, on_star
);
5025 /* Execute statements from class scopes. */
5026 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
5027 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5028 reply
->packet
->options
,
5029 reply
->opt_state
, scope
,
5030 reply
->packet
->classes
[i
- 1]->group
,
5035 * If there is a host record, over-ride with values configured there,
5036 * without re-evaluating configuration from the previously executed
5037 * group or its common enclosers.
5039 if (reply
->host
!= NULL
)
5040 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5041 reply
->packet
->options
,
5042 reply
->opt_state
, scope
,
5043 reply
->host
->group
, group
,
5046 /* Determine valid lifetime. */
5047 if (reply
->client_valid
== 0)
5048 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
5050 reply
->send_valid
= reply
->client_valid
;
5052 oc
= lookup_option(&server_universe
, reply
->opt_state
,
5053 SV_DEFAULT_LEASE_TIME
);
5055 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
5056 reply
->packet
->options
,
5060 log_error("reply_process_is_prefixed: unable to "
5061 "evaluate default prefix time");
5062 status
= ISC_R_FAILURE
;
5066 reply
->send_valid
= getULong(data
.data
);
5067 data_string_forget(&data
, MDL
);
5070 /* Check to see if the lease time would cause us to wrap
5071 * in which case we make it infinite.
5072 * The following doesn't work on at least some systems:
5073 * (cur_time + reply->send_valid < cur_time)
5075 if (reply
->send_valid
!= INFINITE_TIME
) {
5076 time_t test_time
= cur_time
+ reply
->send_valid
;
5077 if (test_time
< cur_time
)
5078 reply
->send_valid
= INFINITE_TIME
;
5081 if (reply
->client_prefer
== 0)
5082 reply
->send_prefer
= reply
->send_valid
;
5084 reply
->send_prefer
= reply
->client_prefer
;
5086 if ((reply
->send_prefer
>= reply
->send_valid
) &&
5087 (reply
->send_valid
!= INFINITE_TIME
))
5088 reply
->send_prefer
= (reply
->send_valid
/ 2) +
5089 (reply
->send_valid
/ 8);
5091 oc
= lookup_option(&server_universe
, reply
->opt_state
,
5092 SV_PREFER_LIFETIME
);
5094 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
5095 reply
->packet
->options
,
5099 log_error("reply_process_is_prefixed: unable to "
5100 "evaluate preferred prefix time");
5101 status
= ISC_R_FAILURE
;
5105 reply
->send_prefer
= getULong(data
.data
);
5106 data_string_forget(&data
, MDL
);
5109 /* Note lowest values for later calculation of renew/rebind times. */
5110 if (reply
->min_prefer
> reply
->send_prefer
)
5111 reply
->min_prefer
= reply
->send_prefer
;
5113 if (reply
->min_valid
> reply
->send_valid
)
5114 reply
->min_valid
= reply
->send_valid
;
5116 /* Perform dynamic prefix related update work. */
5117 if (reply
->lease
!= NULL
) {
5118 /* Cached lifetimes */
5119 reply
->lease
->prefer
= reply
->send_prefer
;
5120 reply
->lease
->valid
= reply
->send_valid
;
5122 /* Advance (or rewind) the valid lifetime.
5123 * In the protocol 0xFFFFFFFF is infinite
5124 * when connecting to the lease file MAX_TIME is
5126 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
5127 if (reply
->send_valid
== INFINITE_TIME
) {
5128 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
5130 reply
->lease
->soft_lifetime_end_time
=
5131 cur_time
+ reply
->send_valid
;
5133 /* Wait before renew! */
5136 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
5137 if (status
!= ISC_R_SUCCESS
) {
5138 log_fatal("reply_process_is_prefixed: Unable to "
5139 "attach prefix to new IA_PD: %s",
5140 isc_result_totext(status
));
5144 * If this is a new prefix, make sure it is attached somewhere.
5146 if (reply
->lease
->ia
== NULL
) {
5147 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
5151 /* Bring a copy of the relevant options into the IA_PD scope. */
5152 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5153 reply
->packet
->options
, reply
->reply_ia
,
5154 scope
, group
, root_group
, NULL
);
5156 /* Execute statements from class scopes. */
5157 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
5158 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5159 reply
->packet
->options
,
5160 reply
->reply_ia
, scope
,
5161 reply
->packet
->classes
[i
- 1]->group
,
5166 * And bring in host record configuration, if any, but not to overlap
5167 * the previous group or its common enclosers.
5169 if (reply
->host
!= NULL
)
5170 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5171 reply
->packet
->options
,
5172 reply
->reply_ia
, scope
,
5173 reply
->host
->group
, group
, NULL
);
5176 if (data
.data
!= NULL
)
5177 data_string_forget(&data
, MDL
);
5179 if (status
== ISC_R_SUCCESS
)
5180 reply
->client_resources
++;
5185 /* Simply send an IAPREFIX within the IA_PD scope as described. */
5187 reply_process_send_prefix(struct reply_state
*reply
,
5188 struct iaddrcidrnet
*pref
) {
5189 isc_result_t status
= ISC_R_SUCCESS
;
5190 struct data_string data
;
5192 memset(&data
, 0, sizeof(data
));
5194 /* Now append the prefix. */
5195 data
.len
= IAPREFIX_OFFSET
;
5196 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
5197 log_error("reply_process_send_prefix: out of memory"
5198 "allocating new IAPREFIX buffer.");
5199 status
= ISC_R_NOMEMORY
;
5202 data
.data
= data
.buffer
->data
;
5204 putULong(data
.buffer
->data
, reply
->send_prefer
);
5205 putULong(data
.buffer
->data
+ 4, reply
->send_valid
);
5206 data
.buffer
->data
[8] = pref
->bits
;
5207 memcpy(data
.buffer
->data
+ 9, pref
->lo_addr
.iabuf
, 16);
5209 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
5210 data
.buffer
, data
.buffer
->data
,
5211 data
.len
, D6O_IAPREFIX
, 0)) {
5212 log_error("reply_process_send_prefix: unable "
5213 "to save IAPREFIX option");
5214 status
= ISC_R_FAILURE
;
5218 reply
->resources_included
= ISC_TRUE
;
5221 if (data
.data
!= NULL
)
5222 data_string_forget(&data
, MDL
);
5227 /* Choose the better of two prefixes. */
5228 static struct iasubopt
*
5229 prefix_compare(struct reply_state
*reply
,
5230 struct iasubopt
*alpha
, struct iasubopt
*beta
) {
5236 if (reply
->preflen
>= 0) {
5237 if ((alpha
->plen
== reply
->preflen
) &&
5238 (beta
->plen
!= reply
->preflen
))
5240 if ((beta
->plen
== reply
->preflen
) &&
5241 (alpha
->plen
!= reply
->preflen
))
5245 switch(alpha
->state
) {
5247 switch(beta
->state
) {
5249 /* Choose the prefix with the longest lifetime (most
5250 * likely the most recently allocated).
5252 if (alpha
->hard_lifetime_end_time
<
5253 beta
->hard_lifetime_end_time
)
5263 log_fatal("Impossible condition at %s:%d.", MDL
);
5268 switch (beta
->state
) {
5273 /* Choose the most recently expired prefix. */
5274 if (alpha
->hard_lifetime_end_time
<
5275 beta
->hard_lifetime_end_time
)
5277 else if ((alpha
->hard_lifetime_end_time
==
5278 beta
->hard_lifetime_end_time
) &&
5279 (alpha
->soft_lifetime_end_time
<
5280 beta
->soft_lifetime_end_time
))
5289 log_fatal("Impossible condition at %s:%d.", MDL
);
5294 switch (beta
->state
) {
5300 /* Choose the prefix that was abandoned longest ago. */
5301 if (alpha
->hard_lifetime_end_time
<
5302 beta
->hard_lifetime_end_time
)
5308 log_fatal("Impossible condition at %s:%d.", MDL
);
5313 log_fatal("Impossible condition at %s:%d.", MDL
);
5316 log_fatal("Triple impossible condition at %s:%d.", MDL
);
5321 * Solicit is how a client starts requesting addresses.
5323 * If the client asks for rapid commit, and we support it, we will
5324 * allocate the addresses and reply.
5326 * Otherwise we will send an advertise message.
5330 dhcpv6_solicit(struct data_string
*reply_ret
, struct packet
*packet
) {
5331 struct data_string client_id
;
5334 * Validate our input.
5336 if (!valid_client_msg(packet
, &client_id
)) {
5340 lease_to_client(reply_ret
, packet
, &client_id
, NULL
);
5345 data_string_forget(&client_id
, MDL
);
5349 * Request is how a client actually requests addresses.
5351 * Very similar to Solicit handling, except the server DUID is required.
5355 dhcpv6_request(struct data_string
*reply_ret
, struct packet
*packet
) {
5356 struct data_string client_id
;
5357 struct data_string server_id
;
5360 * Validate our input.
5362 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5366 /* If the REQUEST arrived via unicast and unicast option isn't set,
5367 * reject it per RFC 3315, Sec 18.2.1 */
5368 if (packet
->unicast
== ISC_TRUE
&&
5369 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5370 unicast_reject(reply_ret
, packet
, &client_id
, &server_id
);
5375 lease_to_client(reply_ret
, packet
, &client_id
, &server_id
);
5381 data_string_forget(&client_id
, MDL
);
5382 data_string_forget(&server_id
, MDL
);
5385 /* Find a DHCPv6 packet's shared network from hints in the packet.
5388 shared_network_from_packet6(struct shared_network
**shared
,
5389 struct packet
*packet
)
5391 const struct packet
*chk_packet
;
5392 const struct in6_addr
*link_addr
, *first_link_addr
;
5393 struct iaddr tmp_addr
;
5394 struct subnet
*subnet
;
5395 isc_result_t status
;
5397 if ((shared
== NULL
) || (*shared
!= NULL
) || (packet
== NULL
))
5398 return DHCP_R_INVALIDARG
;
5401 * First, find the link address where the packet from the client
5402 * first appeared (if this packet was relayed).
5404 first_link_addr
= NULL
;
5405 chk_packet
= packet
->dhcpv6_container_packet
;
5406 while (chk_packet
!= NULL
) {
5407 link_addr
= &chk_packet
->dhcpv6_link_address
;
5408 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
5409 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
5410 first_link_addr
= link_addr
;
5413 chk_packet
= chk_packet
->dhcpv6_container_packet
;
5417 * If there is a relayed link address, find the subnet associated
5418 * with that, and use that to get the appropriate
5421 if (first_link_addr
!= NULL
) {
5422 tmp_addr
.len
= sizeof(*first_link_addr
);
5423 memcpy(tmp_addr
.iabuf
,
5424 first_link_addr
, sizeof(*first_link_addr
));
5426 if (!find_subnet(&subnet
, tmp_addr
, MDL
)) {
5427 log_debug("No subnet found for link-address %s.",
5429 return ISC_R_NOTFOUND
;
5431 status
= shared_network_reference(shared
,
5432 subnet
->shared_network
, MDL
);
5433 subnet_dereference(&subnet
, MDL
);
5436 * If there is no link address, we will use the interface
5437 * that this packet came in on to pick the shared_network.
5439 } else if (packet
->interface
!= NULL
) {
5440 status
= shared_network_reference(shared
,
5441 packet
->interface
->shared_network
,
5443 if (packet
->dhcpv6_container_packet
!= NULL
) {
5444 log_info("[L2 Relay] No link address in relay packet "
5445 "assuming L2 relay and using receiving "
5451 * We shouldn't be able to get here but if there is no link
5452 * address and no interface we don't know where to get the
5453 * pool from log an error and return an error.
5455 log_error("No interface and no link address "
5456 "can't determine pool");
5457 status
= DHCP_R_INVALIDARG
;
5464 * When a client thinks it might be on a new link, it sends a
5467 * From RFC3315 section 18.2.2:
5469 * When the server receives a Confirm message, the server determines
5470 * whether the addresses in the Confirm message are appropriate for the
5471 * link to which the client is attached. If all of the addresses in the
5472 * Confirm message pass this test, the server returns a status of
5473 * Success. If any of the addresses do not pass this test, the server
5474 * returns a status of NotOnLink. If the server is unable to perform
5475 * this test (for example, the server does not have information about
5476 * prefixes on the link to which the client is connected), or there were
5477 * no addresses in any of the IAs sent by the client, the server MUST
5478 * NOT send a reply to the client.
5482 dhcpv6_confirm(struct data_string
*reply_ret
, struct packet
*packet
) {
5483 struct shared_network
*shared
;
5484 struct subnet
*subnet
;
5485 struct option_cache
*ia
, *ta
, *oc
;
5486 struct data_string cli_enc_opt_data
, iaaddr
, client_id
, packet_oro
;
5487 struct option_state
*cli_enc_opt_state
, *opt_state
;
5488 struct iaddr cli_addr
;
5490 isc_boolean_t inappropriate
, has_addrs
;
5491 char reply_data
[65536];
5492 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5493 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5496 * Basic client message validation.
5498 memset(&client_id
, 0, sizeof(client_id
));
5499 if (!valid_client_msg(packet
, &client_id
)) {
5504 * Do not process Confirms that do not have IA's we do not recognize.
5506 ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5507 ta
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
5508 if ((ia
== NULL
) && (ta
== NULL
))
5512 * IA_PD's are simply ignored.
5514 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5517 * Bit of variable initialization.
5519 opt_state
= cli_enc_opt_state
= NULL
;
5520 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5521 memset(&iaaddr
, 0, sizeof(iaaddr
));
5522 memset(&packet_oro
, 0, sizeof(packet_oro
));
5524 /* Determine what shared network the client is connected to. We
5525 * must not respond if we don't have any information about the
5526 * network the client is on.
5529 if ((shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
) ||
5533 /* If there are no recorded subnets, then we have no
5534 * information about this subnet - ignore Confirms.
5536 subnet
= shared
->subnets
;
5540 /* Are the addresses in all the IA's appropriate for that link? */
5541 has_addrs
= inappropriate
= ISC_FALSE
;
5543 while(!inappropriate
) {
5544 /* If we've reached the end of the IA_NA pass, move to the
5547 if ((pass
== D6O_IA_NA
) && (ia
== NULL
)) {
5552 /* If we've reached the end of all passes, we're done. */
5556 if (((pass
== D6O_IA_NA
) &&
5557 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5559 packet
, ia
, IA_NA_OFFSET
)) ||
5560 ((pass
== D6O_IA_TA
) &&
5561 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5563 packet
, ia
, IA_TA_OFFSET
))) {
5567 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5570 for ( ; oc
!= NULL
; oc
= oc
->next
) {
5571 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5572 packet
->options
, NULL
,
5573 &global_scope
, oc
, MDL
) ||
5574 (iaaddr
.len
< IAADDR_OFFSET
)) {
5575 log_error("dhcpv6_confirm: "
5576 "error evaluating IAADDR.");
5580 /* Copy out the IPv6 address for processing. */
5582 memcpy(cli_addr
.iabuf
, iaaddr
.data
, 16);
5584 data_string_forget(&iaaddr
, MDL
);
5586 /* Record that we've processed at least one address. */
5587 has_addrs
= ISC_TRUE
;
5589 /* Find out if any subnets cover this address. */
5590 for (subnet
= shared
->subnets
; subnet
!= NULL
;
5591 subnet
= subnet
->next_sibling
) {
5592 if (addr_eq(subnet_number(cli_addr
,
5598 /* If we reach the end of the subnet list, and no
5599 * subnet matches the client address, then it must
5600 * be inappropriate to the link (so far as our
5601 * configuration says). Once we've found one
5602 * inappropriate address, there is no reason to
5603 * continue searching.
5605 if (subnet
== NULL
) {
5606 inappropriate
= ISC_TRUE
;
5611 option_state_dereference(&cli_enc_opt_state
, MDL
);
5612 data_string_forget(&cli_enc_opt_data
, MDL
);
5614 /* Advance to the next IA_*. */
5618 /* If the client supplied no addresses, do not reply. */
5625 if (!start_reply(packet
, &client_id
, NULL
, &opt_state
, reply
)) {
5632 if (inappropriate
) {
5633 if (!set_status_code(STATUS_NotOnLink
,
5634 "Some of the addresses are not on link.",
5639 if (!set_status_code(STATUS_Success
,
5640 "All addresses still on link.",
5647 * Only one option: add it.
5649 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5650 sizeof(reply_data
)-reply_ofs
,
5652 required_opts
, &packet_oro
);
5655 * Return our reply to the caller.
5657 reply_ret
->len
= reply_ofs
;
5658 reply_ret
->buffer
= NULL
;
5659 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5660 log_fatal("No memory to store reply.");
5662 reply_ret
->data
= reply_ret
->buffer
->data
;
5663 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5666 /* Cleanup any stale data strings. */
5667 if (cli_enc_opt_data
.buffer
!= NULL
)
5668 data_string_forget(&cli_enc_opt_data
, MDL
);
5669 if (iaaddr
.buffer
!= NULL
)
5670 data_string_forget(&iaaddr
, MDL
);
5671 if (client_id
.buffer
!= NULL
)
5672 data_string_forget(&client_id
, MDL
);
5673 if (packet_oro
.buffer
!= NULL
)
5674 data_string_forget(&packet_oro
, MDL
);
5676 /* Release any stale option states. */
5677 if (cli_enc_opt_state
!= NULL
)
5678 option_state_dereference(&cli_enc_opt_state
, MDL
);
5679 if (opt_state
!= NULL
)
5680 option_state_dereference(&opt_state
, MDL
);
5684 * Renew is when a client wants to extend its lease/prefix, at time T1.
5686 * We handle this the same as if the client wants a new lease/prefix,
5687 * except for the error code of when addresses don't match.
5691 dhcpv6_renew(struct data_string
*reply
, struct packet
*packet
) {
5692 struct data_string client_id
;
5693 struct data_string server_id
;
5696 * Validate the request.
5698 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5702 /* If the RENEW arrived via unicast and unicast option isn't set,
5703 * reject it per RFC 3315, Sec 18.2.3 */
5704 if (packet
->unicast
== ISC_TRUE
&&
5705 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5706 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5711 lease_to_client(reply
, packet
, &client_id
, &server_id
);
5717 data_string_forget(&server_id
, MDL
);
5718 data_string_forget(&client_id
, MDL
);
5722 * Rebind is when a client wants to extend its lease, at time T2.
5724 * We handle this the same as if the client wants a new lease, except
5725 * for the error code of when addresses don't match.
5729 dhcpv6_rebind(struct data_string
*reply
, struct packet
*packet
) {
5730 struct data_string client_id
;
5732 if (!valid_client_msg(packet
, &client_id
)) {
5736 lease_to_client(reply
, packet
, &client_id
, NULL
);
5738 data_string_forget(&client_id
, MDL
);
5742 ia_na_match_decline(const struct data_string
*client_id
,
5743 const struct data_string
*iaaddr
,
5744 struct iasubopt
*lease
)
5746 char tmp_addr
[INET6_ADDRSTRLEN
];
5748 log_error("Client %s reports address %s is "
5749 "already in use by another host!",
5750 print_hex_1(client_id
->len
, client_id
->data
, 60),
5751 inet_ntop(AF_INET6
, iaaddr
->data
,
5752 tmp_addr
, sizeof(tmp_addr
)));
5753 if (lease
!= NULL
) {
5754 decline_lease6(lease
->ipv6_pool
, lease
);
5755 lease
->ia
->cltt
= cur_time
;
5756 write_ia(lease
->ia
);
5761 ia_na_nomatch_decline(const struct data_string
*client_id
,
5762 const struct data_string
*iaaddr
,
5763 u_int32_t
*ia_na_id
,
5764 struct packet
*packet
,
5769 char tmp_addr
[INET6_ADDRSTRLEN
];
5770 struct option_state
*host_opt_state
;
5773 log_info("Client %s declines address %s, which is not offered to it.",
5774 print_hex_1(client_id
->len
, client_id
->data
, 60),
5775 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5778 * Create state for this IA_NA.
5780 host_opt_state
= NULL
;
5781 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5782 log_error("ia_na_nomatch_decline: out of memory "
5783 "allocating option_state.");
5787 if (!set_status_code(STATUS_NoBinding
, "Decline for unknown address.",
5793 * Insure we have enough space
5795 if (reply_len
< (*reply_ofs
+ 16)) {
5796 log_error("ia_na_nomatch_decline: "
5797 "out of space for reply packet.");
5802 * Put our status code into the reply packet.
5804 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5805 reply_len
-(*reply_ofs
)-16,
5806 host_opt_state
, packet
,
5807 required_opts_STATUS_CODE
, NULL
);
5810 * Store the non-encapsulated option data for this
5811 * IA_NA into our reply packet. Defined in RFC 3315,
5815 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5817 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5818 /* IA_NA, copied from the client */
5819 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5820 /* t1 and t2, odd that we need them, but here it is */
5821 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5822 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5825 * Get ready for next IA_NA.
5827 *reply_ofs
+= (len
+ 16);
5830 option_state_dereference(&host_opt_state
, MDL
);
5834 iterate_over_ia_na(struct data_string
*reply_ret
,
5835 struct packet
*packet
,
5836 const struct data_string
*client_id
,
5837 const struct data_string
*server_id
,
5838 const char *packet_type
,
5839 void (*ia_na_match
)(),
5840 void (*ia_na_nomatch
)())
5842 struct option_state
*opt_state
;
5843 struct host_decl
*packet_host
;
5844 struct option_cache
*ia
;
5845 struct option_cache
*oc
;
5846 /* cli_enc_... variables come from the IA_NA/IA_TA options */
5847 struct data_string cli_enc_opt_data
;
5848 struct option_state
*cli_enc_opt_state
;
5849 struct host_decl
*host
;
5850 struct data_string iaaddr
;
5851 struct data_string fixed_addr
;
5852 char reply_data
[65536];
5853 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5854 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5855 char status_msg
[32];
5856 struct iasubopt
*lease
;
5857 struct ia_xx
*existing_ia_na
;
5859 struct data_string key
;
5863 * Initialize to empty values, in case we have to exit early.
5866 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5867 cli_enc_opt_state
= NULL
;
5868 memset(&iaaddr
, 0, sizeof(iaaddr
));
5869 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
5873 * Find the host record that matches from the packet, if any.
5876 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
5879 * Set our reply information.
5881 reply
->msg_type
= DHCPV6_REPLY
;
5882 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
5883 sizeof(reply
->transaction_id
));
5886 * Build our option state for reply.
5889 if (!option_state_allocate(&opt_state
, MDL
)) {
5890 log_error("iterate_over_ia_na: no memory for option_state.");
5893 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5894 packet
->options
, opt_state
,
5895 &global_scope
, root_group
, NULL
, NULL
);
5898 * RFC 3315, section 18.2.7 tells us which options to include.
5900 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
5902 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5903 (unsigned char *)server_duid
.data
,
5904 server_duid
.len
, D6O_SERVERID
, 0)) {
5905 log_error("iterate_over_ia_na: "
5906 "error saving server identifier.");
5911 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
5913 (unsigned char *)client_id
->data
,
5916 log_error("iterate_over_ia_na: "
5917 "error saving client identifier.");
5921 snprintf(status_msg
, sizeof(status_msg
), "%s received.", packet_type
);
5922 if (!set_status_code(STATUS_Success
, status_msg
, opt_state
)) {
5927 * Add our options that are not associated with any IA_NA or IA_TA.
5929 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5930 sizeof(reply_data
)-reply_ofs
,
5932 required_opts
, NULL
);
5935 * Loop through the IA_NA reported by the client, and deal with
5936 * addresses reported as already in use.
5938 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5939 ia
!= NULL
; ia
= ia
->next
) {
5941 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
5943 packet
, ia
, IA_NA_OFFSET
)) {
5947 iaid
= getULong(cli_enc_opt_data
.data
);
5950 * XXX: It is possible that we can get multiple addresses
5951 * sent by the client. We don't send multiple
5952 * addresses, so this indicates a client error.
5953 * We should check for multiple IAADDR options, log
5954 * if found, and set as an error.
5956 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5959 /* no address given for this IA, ignore */
5960 option_state_dereference(&cli_enc_opt_state
, MDL
);
5961 data_string_forget(&cli_enc_opt_data
, MDL
);
5965 memset(&iaaddr
, 0, sizeof(iaaddr
));
5966 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5967 packet
->options
, NULL
,
5968 &global_scope
, oc
, MDL
)) {
5969 log_error("iterate_over_ia_na: "
5970 "error evaluating IAADDR.");
5975 * Now we need to figure out which host record matches
5976 * this IA_NA and IAADDR (encapsulated option contents
5977 * matching a host record by option).
5979 * XXX: We don't currently track IA_NA separately, but
5980 * we will need to do this!
5983 if (!find_hosts_by_option(&host
, packet
,
5984 cli_enc_opt_state
, MDL
)) {
5985 if (packet_host
!= NULL
) {
5991 while (host
!= NULL
) {
5992 if (host
->fixed_addr
!= NULL
) {
5993 if (!evaluate_option_cache(&fixed_addr
, NULL
,
5995 NULL
, &global_scope
,
5998 log_error("iterate_over_ia_na: error "
5999 "evaluating host address.");
6002 if ((iaaddr
.len
>= 16) &&
6003 !memcmp(fixed_addr
.data
, iaaddr
.data
, 16)) {
6004 data_string_forget(&fixed_addr
, MDL
);
6007 data_string_forget(&fixed_addr
, MDL
);
6009 host
= host
->n_ipaddr
;
6012 if ((host
== NULL
) && (iaaddr
.len
>= IAADDR_OFFSET
)) {
6014 * Find existing IA_NA.
6016 if (ia_make_key(&key
, iaid
,
6017 (char *)client_id
->data
,
6019 MDL
) != ISC_R_SUCCESS
) {
6020 log_fatal("iterate_over_ia_na: no memory for "
6024 existing_ia_na
= NULL
;
6025 if (ia_hash_lookup(&existing_ia_na
, ia_na_active
,
6026 (unsigned char *)key
.data
,
6029 * Make sure this address is in the IA_NA.
6031 for (i
=0; i
<existing_ia_na
->num_iasubopt
; i
++) {
6032 struct iasubopt
*tmp
;
6033 struct in6_addr
*in6_addr
;
6035 tmp
= existing_ia_na
->iasubopt
[i
];
6036 in6_addr
= &tmp
->addr
;
6037 if (memcmp(in6_addr
,
6038 iaaddr
.data
, 16) == 0) {
6039 iasubopt_reference(&lease
,
6046 data_string_forget(&key
, MDL
);
6049 if ((host
!= NULL
) || (lease
!= NULL
)) {
6050 ia_na_match(client_id
, &iaaddr
, lease
);
6052 ia_na_nomatch(client_id
, &iaaddr
,
6053 (u_int32_t
*)cli_enc_opt_data
.data
,
6054 packet
, reply_data
, &reply_ofs
,
6055 sizeof(reply_data
));
6058 if (lease
!= NULL
) {
6059 iasubopt_dereference(&lease
, MDL
);
6062 data_string_forget(&iaaddr
, MDL
);
6063 option_state_dereference(&cli_enc_opt_state
, MDL
);
6064 data_string_forget(&cli_enc_opt_data
, MDL
);
6068 * Return our reply to the caller.
6070 reply_ret
->len
= reply_ofs
;
6071 reply_ret
->buffer
= NULL
;
6072 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
6073 log_fatal("No memory to store reply.");
6075 reply_ret
->data
= reply_ret
->buffer
->data
;
6076 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
6079 if (lease
!= NULL
) {
6080 iasubopt_dereference(&lease
, MDL
);
6082 if (fixed_addr
.buffer
!= NULL
) {
6083 data_string_forget(&fixed_addr
, MDL
);
6085 if (iaaddr
.buffer
!= NULL
) {
6086 data_string_forget(&iaaddr
, MDL
);
6088 if (cli_enc_opt_state
!= NULL
) {
6089 option_state_dereference(&cli_enc_opt_state
, MDL
);
6091 if (cli_enc_opt_data
.buffer
!= NULL
) {
6092 data_string_forget(&cli_enc_opt_data
, MDL
);
6094 if (opt_state
!= NULL
) {
6095 option_state_dereference(&opt_state
, MDL
);
6100 * Decline means a client has detected that something else is using an
6101 * address we gave it.
6103 * Since we're only dealing with fixed leases for now, there's not
6104 * much we can do, other that log the occurrence.
6106 * When we start issuing addresses from pools, then we will have to
6107 * record our declined addresses and issue another. In general with
6108 * IPv6 there is no worry about DoS by clients exhausting space, but
6109 * we still need to be aware of this possibility.
6114 dhcpv6_decline(struct data_string
*reply
, struct packet
*packet
) {
6115 struct data_string client_id
;
6116 struct data_string server_id
;
6119 * Validate our input.
6121 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
6125 /* If the DECLINE arrived via unicast and unicast option isn't set,
6126 * reject it per RFC 3315, Sec 18.2.7 */
6127 if (packet
->unicast
== ISC_TRUE
&&
6128 is_unicast_option_defined(packet
) == ISC_FALSE
) {
6129 unicast_reject(reply
, packet
, &client_id
, &server_id
);
6132 * Undefined for IA_PD.
6134 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
6137 * And operate on each IA_NA in this packet.
6139 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
6140 "Decline", ia_na_match_decline
,
6141 ia_na_nomatch_decline
);
6145 data_string_forget(&server_id
, MDL
);
6146 data_string_forget(&client_id
, MDL
);
6150 ia_na_match_release(const struct data_string
*client_id
,
6151 const struct data_string
*iaaddr
,
6152 struct iasubopt
*lease
)
6154 char tmp_addr
[INET6_ADDRSTRLEN
];
6156 log_info("Client %s releases address %s",
6157 print_hex_1(client_id
->len
, client_id
->data
, 60),
6158 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
6159 if (lease
!= NULL
) {
6160 release_lease6(lease
->ipv6_pool
, lease
);
6161 lease
->ia
->cltt
= cur_time
;
6162 write_ia(lease
->ia
);
6167 ia_na_nomatch_release(const struct data_string
*client_id
,
6168 const struct data_string
*iaaddr
,
6169 u_int32_t
*ia_na_id
,
6170 struct packet
*packet
,
6175 char tmp_addr
[INET6_ADDRSTRLEN
];
6176 struct option_state
*host_opt_state
;
6179 log_info("Client %s releases address %s, which is not leased to it.",
6180 print_hex_1(client_id
->len
, client_id
->data
, 60),
6181 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
6184 * Create state for this IA_NA.
6186 host_opt_state
= NULL
;
6187 if (!option_state_allocate(&host_opt_state
, MDL
)) {
6188 log_error("ia_na_nomatch_release: out of memory "
6189 "allocating option_state.");
6193 if (!set_status_code(STATUS_NoBinding
,
6194 "Release for non-leased address.",
6200 * Insure we have enough space
6202 if (reply_len
< (*reply_ofs
+ 16)) {
6203 log_error("ia_na_nomatch_release: "
6204 "out of space for reply packet.");
6209 * Put our status code into the reply packet.
6211 len
= store_options6(reply_data
+(*reply_ofs
)+16,
6212 reply_len
-(*reply_ofs
)-16,
6213 host_opt_state
, packet
,
6214 required_opts_STATUS_CODE
, NULL
);
6217 * Store the non-encapsulated option data for this
6218 * IA_NA into our reply packet. Defined in RFC 3315,
6222 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
6224 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
6225 /* IA_NA, copied from the client */
6226 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
6227 /* t1 and t2, odd that we need them, but here it is */
6228 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
6229 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
6232 * Get ready for next IA_NA.
6234 *reply_ofs
+= (len
+ 16);
6237 option_state_dereference(&host_opt_state
, MDL
);
6241 ia_pd_match_release(const struct data_string
*client_id
,
6242 const struct data_string
*iapref
,
6243 struct iasubopt
*prefix
)
6245 char tmp_addr
[INET6_ADDRSTRLEN
];
6247 log_info("Client %s releases prefix %s/%u",
6248 print_hex_1(client_id
->len
, client_id
->data
, 60),
6249 inet_ntop(AF_INET6
, iapref
->data
+ 9,
6250 tmp_addr
, sizeof(tmp_addr
)),
6251 (unsigned) getUChar(iapref
->data
+ 8));
6252 if (prefix
!= NULL
) {
6253 release_lease6(prefix
->ipv6_pool
, prefix
);
6254 prefix
->ia
->cltt
= cur_time
;
6255 write_ia(prefix
->ia
);
6260 ia_pd_nomatch_release(const struct data_string
*client_id
,
6261 const struct data_string
*iapref
,
6262 u_int32_t
*ia_pd_id
,
6263 struct packet
*packet
,
6268 char tmp_addr
[INET6_ADDRSTRLEN
];
6269 struct option_state
*host_opt_state
;
6272 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
6273 print_hex_1(client_id
->len
, client_id
->data
, 60),
6274 inet_ntop(AF_INET6
, iapref
->data
+ 9,
6275 tmp_addr
, sizeof(tmp_addr
)),
6276 (unsigned) getUChar(iapref
->data
+ 8));
6279 * Create state for this IA_PD.
6281 host_opt_state
= NULL
;
6282 if (!option_state_allocate(&host_opt_state
, MDL
)) {
6283 log_error("ia_pd_nomatch_release: out of memory "
6284 "allocating option_state.");
6288 if (!set_status_code(STATUS_NoBinding
,
6289 "Release for non-leased prefix.",
6295 * Insure we have enough space
6297 if (reply_len
< (*reply_ofs
+ 16)) {
6298 log_error("ia_pd_nomatch_release: "
6299 "out of space for reply packet.");
6304 * Put our status code into the reply packet.
6306 len
= store_options6(reply_data
+(*reply_ofs
)+16,
6307 reply_len
-(*reply_ofs
)-16,
6308 host_opt_state
, packet
,
6309 required_opts_STATUS_CODE
, NULL
);
6312 * Store the non-encapsulated option data for this
6313 * IA_PD into our reply packet. Defined in RFC 3315,
6317 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_PD
);
6319 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
6320 /* IA_PD, copied from the client */
6321 memcpy(reply_data
+(*reply_ofs
)+4, ia_pd_id
, 4);
6322 /* t1 and t2, odd that we need them, but here it is */
6323 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
6324 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
6327 * Get ready for next IA_PD.
6329 *reply_ofs
+= (len
+ 16);
6332 option_state_dereference(&host_opt_state
, MDL
);
6336 iterate_over_ia_pd(struct data_string
*reply_ret
,
6337 struct packet
*packet
,
6338 const struct data_string
*client_id
,
6339 const struct data_string
*server_id
,
6340 const char *packet_type
,
6341 void (*ia_pd_match
)(),
6342 void (*ia_pd_nomatch
)())
6344 struct data_string reply_new
;
6346 struct option_state
*opt_state
;
6347 struct host_decl
*packet_host
;
6348 struct option_cache
*ia
;
6349 struct option_cache
*oc
;
6350 /* cli_enc_... variables come from the IA_PD options */
6351 struct data_string cli_enc_opt_data
;
6352 struct option_state
*cli_enc_opt_state
;
6353 struct host_decl
*host
;
6354 struct data_string iaprefix
;
6355 char reply_data
[65536];
6357 struct iasubopt
*prefix
;
6358 struct ia_xx
*existing_ia_pd
;
6360 struct data_string key
;
6364 * Initialize to empty values, in case we have to exit early.
6366 memset(&reply_new
, 0, sizeof(reply_new
));
6368 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
6369 cli_enc_opt_state
= NULL
;
6370 memset(&iaprefix
, 0, sizeof(iaprefix
));
6374 * Compute the available length for the reply.
6376 reply_len
= sizeof(reply_data
) - reply_ret
->len
;
6380 * Find the host record that matches from the packet, if any.
6383 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
6386 * Build our option state for reply.
6389 if (!option_state_allocate(&opt_state
, MDL
)) {
6390 log_error("iterate_over_ia_pd: no memory for option_state.");
6393 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
6394 packet
->options
, opt_state
,
6395 &global_scope
, root_group
, NULL
, NULL
);
6398 * Loop through the IA_PD reported by the client, and deal with
6399 * prefixes reported as already in use.
6401 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
6402 ia
!= NULL
; ia
= ia
->next
) {
6404 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
6406 packet
, ia
, IA_PD_OFFSET
)) {
6410 iaid
= getULong(cli_enc_opt_data
.data
);
6412 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
6415 /* no prefix given for this IA_PD, ignore */
6416 option_state_dereference(&cli_enc_opt_state
, MDL
);
6417 data_string_forget(&cli_enc_opt_data
, MDL
);
6421 for (; oc
!= NULL
; oc
= oc
->next
) {
6422 memset(&iaprefix
, 0, sizeof(iaprefix
));
6423 if (!evaluate_option_cache(&iaprefix
, packet
, NULL
, NULL
,
6424 packet
->options
, NULL
,
6425 &global_scope
, oc
, MDL
)) {
6426 log_error("iterate_over_ia_pd: "
6427 "error evaluating IAPREFIX.");
6432 * Now we need to figure out which host record matches
6433 * this IA_PD and IAPREFIX (encapsulated option contents
6434 * matching a host record by option).
6436 * XXX: We don't currently track IA_PD separately, but
6437 * we will need to do this!
6440 if (!find_hosts_by_option(&host
, packet
,
6441 cli_enc_opt_state
, MDL
)) {
6442 if (packet_host
!= NULL
) {
6448 while (host
!= NULL
) {
6449 if (host
->fixed_prefix
!= NULL
) {
6450 struct iaddrcidrnetlist
*l
;
6451 int plen
= (int) getUChar(iaprefix
.data
+ 8);
6453 for (l
= host
->fixed_prefix
; l
!= NULL
;
6455 if (plen
!= l
->cidrnet
.bits
)
6457 if (memcmp(iaprefix
.data
+ 9,
6458 l
->cidrnet
.lo_addr
.iabuf
,
6462 if ((l
!= NULL
) && (iaprefix
.len
>= 17))
6465 host
= host
->n_ipaddr
;
6468 if ((host
== NULL
) && (iaprefix
.len
>= IAPREFIX_OFFSET
)) {
6470 * Find existing IA_PD.
6472 if (ia_make_key(&key
, iaid
,
6473 (char *)client_id
->data
,
6475 MDL
) != ISC_R_SUCCESS
) {
6476 log_fatal("iterate_over_ia_pd: no memory for "
6480 existing_ia_pd
= NULL
;
6481 if (ia_hash_lookup(&existing_ia_pd
, ia_pd_active
,
6482 (unsigned char *)key
.data
,
6485 * Make sure this prefix is in the IA_PD.
6488 i
< existing_ia_pd
->num_iasubopt
;
6490 struct iasubopt
*tmp
;
6493 plen
= getUChar(iaprefix
.data
+ 8);
6494 tmp
= existing_ia_pd
->iasubopt
[i
];
6495 if ((tmp
->plen
== plen
) &&
6499 iasubopt_reference(&prefix
,
6506 data_string_forget(&key
, MDL
);
6509 if ((host
!= NULL
) || (prefix
!= NULL
)) {
6510 ia_pd_match(client_id
, &iaprefix
, prefix
);
6512 ia_pd_nomatch(client_id
, &iaprefix
,
6513 (u_int32_t
*)cli_enc_opt_data
.data
,
6514 packet
, reply_data
, &reply_ofs
,
6515 reply_len
- reply_ofs
);
6518 if (prefix
!= NULL
) {
6519 iasubopt_dereference(&prefix
, MDL
);
6522 data_string_forget(&iaprefix
, MDL
);
6525 option_state_dereference(&cli_enc_opt_state
, MDL
);
6526 data_string_forget(&cli_enc_opt_data
, MDL
);
6530 * Return our reply to the caller.
6531 * The IA_NA routine has already filled at least the header.
6533 reply_new
.len
= reply_ret
->len
+ reply_ofs
;
6534 if (!buffer_allocate(&reply_new
.buffer
, reply_new
.len
, MDL
)) {
6535 log_fatal("No memory to store reply.");
6537 reply_new
.data
= reply_new
.buffer
->data
;
6538 memcpy(reply_new
.buffer
->data
,
6539 reply_ret
->buffer
->data
, reply_ret
->len
);
6540 memcpy(reply_new
.buffer
->data
+ reply_ret
->len
,
6541 reply_data
, reply_ofs
);
6542 data_string_forget(reply_ret
, MDL
);
6543 data_string_copy(reply_ret
, &reply_new
, MDL
);
6544 data_string_forget(&reply_new
, MDL
);
6547 if (prefix
!= NULL
) {
6548 iasubopt_dereference(&prefix
, MDL
);
6550 if (iaprefix
.buffer
!= NULL
) {
6551 data_string_forget(&iaprefix
, MDL
);
6553 if (cli_enc_opt_state
!= NULL
) {
6554 option_state_dereference(&cli_enc_opt_state
, MDL
);
6556 if (cli_enc_opt_data
.buffer
!= NULL
) {
6557 data_string_forget(&cli_enc_opt_data
, MDL
);
6559 if (opt_state
!= NULL
) {
6560 option_state_dereference(&opt_state
, MDL
);
6565 * Release means a client is done with the leases.
6569 dhcpv6_release(struct data_string
*reply
, struct packet
*packet
) {
6570 struct data_string client_id
;
6571 struct data_string server_id
;
6574 * Validate our input.
6576 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
6580 /* If the RELEASE arrived via unicast and unicast option isn't set,
6581 * reject it per RFC 3315, Sec 18.2.6 */
6582 if (packet
->unicast
== ISC_TRUE
&&
6583 is_unicast_option_defined(packet
) == ISC_FALSE
) {
6584 unicast_reject(reply
, packet
, &client_id
, &server_id
);
6587 * And operate on each IA_NA in this packet.
6589 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
6590 "Release", ia_na_match_release
,
6591 ia_na_nomatch_release
);
6594 * And operate on each IA_PD in this packet.
6596 iterate_over_ia_pd(reply
, packet
, &client_id
, &server_id
,
6597 "Release", ia_pd_match_release
,
6598 ia_pd_nomatch_release
);
6601 data_string_forget(&server_id
, MDL
);
6602 data_string_forget(&client_id
, MDL
);
6606 * Information-Request is used by clients who have obtained an address
6607 * from other means, but want configuration information from the server.
6611 dhcpv6_information_request(struct data_string
*reply
, struct packet
*packet
) {
6612 struct data_string client_id
;
6613 struct data_string server_id
;
6616 * Validate our input.
6618 if (!valid_client_info_req(packet
, &server_id
)) {
6623 * Get our client ID, if there is one.
6625 memset(&client_id
, 0, sizeof(client_id
));
6626 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
) {
6627 data_string_forget(&client_id
, MDL
);
6631 * Use the lease_to_client() function. This will work fine,
6632 * because the valid_client_info_req() insures that we
6633 * don't have any IA that would cause us to allocate
6634 * resources to the client.
6636 lease_to_client(reply
, packet
, &client_id
,
6637 server_id
.data
!= NULL
? &server_id
: NULL
);
6642 if (client_id
.data
!= NULL
) {
6643 data_string_forget(&client_id
, MDL
);
6645 data_string_forget(&server_id
, MDL
);
6649 * The Relay-forw message is sent by relays. It typically contains a
6650 * single option, which encapsulates an entire packet.
6652 * We need to build an encapsulated reply.
6655 /* XXX: this is very, very similar to do_packet6(), and should probably
6656 be combined in a clever way */
6657 /* DHCPv6 server side */
6659 dhcpv6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
6660 struct option_cache
*oc
;
6661 struct data_string enc_opt_data
;
6662 struct packet
*enc_packet
;
6663 unsigned char msg_type
;
6664 const struct dhcpv6_packet
*msg
;
6665 const struct dhcpv6_relay_packet
*relay
;
6666 struct data_string enc_reply
;
6667 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6668 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6669 struct data_string a_opt
, packet_ero
;
6670 struct option_state
*opt_state
;
6671 static char reply_data
[65536];
6672 struct dhcpv6_relay_packet
*reply
;
6676 * Initialize variables for early exit.
6679 memset(&a_opt
, 0, sizeof(a_opt
));
6680 memset(&packet_ero
, 0, sizeof(packet_ero
));
6681 memset(&enc_reply
, 0, sizeof(enc_reply
));
6682 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6686 * Get our encapsulated relay message.
6688 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
6690 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
6691 link_addr
, sizeof(link_addr
));
6692 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
6693 peer_addr
, sizeof(peer_addr
));
6694 log_info("Relay-forward from %s with link address=%s and "
6695 "peer address=%s missing Relay Message option.",
6696 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
6700 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
6701 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
6702 /* should be dhcpv6_relay_forw */
6703 log_error("dhcpv6_forw_relay: error evaluating "
6704 "relayed message.");
6708 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
6709 /* should be dhcpv6_relay_forw */
6710 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
6715 * Build a packet structure from this encapsulated packet.
6718 if (!packet_allocate(&enc_packet
, MDL
)) {
6719 /* should be dhcpv6_relay_forw */
6720 log_error("dhcpv6_forw_relay: "
6721 "no memory for encapsulated packet.");
6725 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
6726 /* should be dhcpv6_relay_forw */
6727 log_error("dhcpv6_forw_relay: "
6728 "no memory for encapsulated packet's options.");
6732 enc_packet
->client_port
= packet
->client_port
;
6733 enc_packet
->client_addr
= packet
->client_addr
;
6734 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
6735 enc_packet
->dhcpv6_container_packet
= packet
;
6737 msg_type
= enc_opt_data
.data
[0];
6738 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
6739 (msg_type
== DHCPV6_RELAY_REPL
)) {
6740 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6741 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
6742 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
6744 /* relay-specific data */
6745 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
6746 memcpy(&enc_packet
->dhcpv6_link_address
,
6747 relay
->link_address
, sizeof(relay
->link_address
));
6748 memcpy(&enc_packet
->dhcpv6_peer_address
,
6749 relay
->peer_address
, sizeof(relay
->peer_address
));
6751 if (!parse_option_buffer(enc_packet
->options
,
6753 enc_opt_data
.len
- relaylen
,
6754 &dhcpv6_universe
)) {
6755 /* no logging here, as parse_option_buffer() logs all
6756 cases where it fails */
6759 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
6760 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6762 if (!dhcpv4_over_dhcpv6
||
6763 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6764 log_error("dhcpv6_relay_forw: "
6765 "unsupported %s message type.",
6766 dhcpv6_type_names
[msg_type
]);
6769 forw_dhcpv4_query(packet
);
6772 log_error("dhcpv6_relay_forw: unsupported %s message type.",
6773 dhcpv6_type_names
[msg_type
]);
6775 #endif /* DHCP4o6 */
6777 int msglen
= (int)(offsetof(struct dhcpv6_packet
, options
));
6778 msg
= (struct dhcpv6_packet
*)enc_opt_data
.data
;
6779 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
6781 /* message-specific data */
6782 memcpy(enc_packet
->dhcpv6_transaction_id
,
6783 msg
->transaction_id
,
6784 sizeof(enc_packet
->dhcpv6_transaction_id
));
6786 if (!parse_option_buffer(enc_packet
->options
,
6788 enc_opt_data
.len
- msglen
,
6789 &dhcpv6_universe
)) {
6790 /* no logging here, as parse_option_buffer() logs all
6791 cases where it fails */
6797 * This is recursive. It is possible to exceed maximum packet size.
6798 * XXX: This will cause the packet send to fail.
6800 build_dhcpv6_reply(&enc_reply
, enc_packet
);
6803 * If we got no encapsulated data, then it is discarded, and
6804 * our reply-forw is also discarded.
6806 if (enc_reply
.data
== NULL
) {
6811 * Now we can use the reply_data buffer.
6812 * Packet header stuff all comes from the forward message.
6814 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
6815 reply
->msg_type
= DHCPV6_RELAY_REPL
;
6816 reply
->hop_count
= packet
->dhcpv6_hop_count
;
6817 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
6818 sizeof(reply
->link_address
));
6819 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
6820 sizeof(reply
->peer_address
));
6821 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6824 * Get the reply option state.
6827 if (!option_state_allocate(&opt_state
, MDL
)) {
6828 log_error("dhcpv6_relay_forw: no memory for option state.");
6833 * Append the interface-id if present.
6835 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6838 if (!evaluate_option_cache(&a_opt
, packet
,
6840 packet
->options
, NULL
,
6841 &global_scope
, oc
, MDL
)) {
6842 log_error("dhcpv6_relay_forw: error evaluating "
6846 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6847 (unsigned char *)a_opt
.data
,
6849 D6O_INTERFACE_ID
, 0)) {
6850 log_error("dhcpv6_relay_forw: error saving "
6854 data_string_forget(&a_opt
, MDL
);
6858 * Append our encapsulated stuff for caller.
6860 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6861 (unsigned char *)enc_reply
.data
,
6863 D6O_RELAY_MSG
, 0)) {
6864 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
6869 * Get the ERO if any.
6871 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
6876 if (!evaluate_option_cache(&packet_ero
, packet
,
6878 packet
->options
, NULL
,
6879 &global_scope
, oc
, MDL
) ||
6880 (packet_ero
.len
& 1)) {
6881 log_error("dhcpv6_relay_forw: error evaluating ERO.");
6885 /* Decode and apply the ERO. */
6886 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
6887 req
= getUShort(packet_ero
.data
+ i
);
6888 /* Already in the reply? */
6889 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
6892 /* Get it from the packet if present. */
6893 oc
= lookup_option(&dhcpv6_universe
,
6898 if (!evaluate_option_cache(&a_opt
, packet
,
6900 packet
->options
, NULL
,
6901 &global_scope
, oc
, MDL
)) {
6902 log_error("dhcpv6_relay_forw: error "
6903 "evaluating option %u.", req
);
6906 if (!save_option_buffer(&dhcpv6_universe
,
6909 (unsigned char *)a_opt
.data
,
6913 log_error("dhcpv6_relay_forw: error saving "
6917 data_string_forget(&a_opt
, MDL
);
6921 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
6922 sizeof(reply_data
) - reply_ofs
,
6924 required_opts_agent
, &packet_ero
);
6927 * Return our reply to the caller.
6929 reply_ret
->len
= reply_ofs
;
6930 reply_ret
->buffer
= NULL
;
6931 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
6932 log_fatal("No memory to store reply.");
6934 reply_ret
->data
= reply_ret
->buffer
->data
;
6935 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
6938 if (opt_state
!= NULL
)
6939 option_state_dereference(&opt_state
, MDL
);
6940 if (a_opt
.data
!= NULL
) {
6941 data_string_forget(&a_opt
, MDL
);
6943 if (packet_ero
.data
!= NULL
) {
6944 data_string_forget(&packet_ero
, MDL
);
6946 if (enc_reply
.data
!= NULL
) {
6947 data_string_forget(&enc_reply
, MDL
);
6949 if (enc_opt_data
.data
!= NULL
) {
6950 data_string_forget(&enc_opt_data
, MDL
);
6952 if (enc_packet
!= NULL
) {
6953 packet_dereference(&enc_packet
, MDL
);
6958 /* \brief Internal processing of a relayed DHCPv4-query
6959 * (DHCPv4 server side)
6961 * Code copied from \ref dhcpv6_relay_forw() which itself is
6962 * from \ref do_packet6().
6964 * \param reply_ret pointer to the response
6965 * \param packet the query
6968 dhcp4o6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
6969 struct option_cache
*oc
;
6970 struct data_string enc_opt_data
;
6971 struct packet
*enc_packet
;
6972 unsigned char msg_type
;
6973 const struct dhcpv6_relay_packet
*relay
;
6974 const struct dhcpv4_over_dhcpv6_packet
*msg
;
6975 struct data_string enc_reply
;
6976 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6977 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6978 struct data_string a_opt
, packet_ero
;
6979 struct option_state
*opt_state
;
6980 static char reply_data
[65536];
6981 struct dhcpv6_relay_packet
*reply
;
6985 * Initialize variables for early exit.
6988 memset(&a_opt
, 0, sizeof(a_opt
));
6989 memset(&packet_ero
, 0, sizeof(packet_ero
));
6990 memset(&enc_reply
, 0, sizeof(enc_reply
));
6991 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6995 * Get our encapsulated relay message.
6997 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
6999 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
7000 link_addr
, sizeof(link_addr
));
7001 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
7002 peer_addr
, sizeof(peer_addr
));
7003 log_info("Relay-forward from %s with link address=%s and "
7004 "peer address=%s missing Relay Message option.",
7005 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
7009 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
7010 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
7011 log_error("dhcp4o6_relay_forw: error evaluating "
7012 "relayed message.");
7016 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
7017 log_error("dhcp4o6_relay_forw: "
7018 "encapsulated packet too short.");
7023 * Build a packet structure from this encapsulated packet.
7025 if (!packet_allocate(&enc_packet
, MDL
)) {
7026 log_error("dhcp4o6_relay_forw: "
7027 "no memory for encapsulated packet.");
7031 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
7032 log_error("dhcp4o6_relay_forw: "
7033 "no memory for encapsulated packet's options.");
7037 enc_packet
->client_port
= packet
->client_port
;
7038 enc_packet
->client_addr
= packet
->client_addr
;
7039 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
7040 enc_packet
->dhcpv6_container_packet
= packet
;
7042 msg_type
= enc_opt_data
.data
[0];
7043 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
7044 (msg_type
== DHCPV6_RELAY_REPL
)) {
7045 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
7046 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
7047 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
7049 /* relay-specific data */
7050 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
7051 memcpy(&enc_packet
->dhcpv6_link_address
,
7052 relay
->link_address
, sizeof(relay
->link_address
));
7053 memcpy(&enc_packet
->dhcpv6_peer_address
,
7054 relay
->peer_address
, sizeof(relay
->peer_address
));
7056 if (!parse_option_buffer(enc_packet
->options
,
7058 enc_opt_data
.len
- relaylen
,
7059 &dhcpv6_universe
)) {
7060 /* no logging here, as parse_option_buffer() logs all
7061 cases where it fails */
7064 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
7065 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
7067 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7068 msg
= (struct dhcpv4_over_dhcpv6_packet
*)enc_opt_data
.data
;
7069 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
7071 /* message-specific data */
7072 memcpy(enc_packet
->dhcp4o6_flags
,
7074 sizeof(enc_packet
->dhcp4o6_flags
));
7076 if (!parse_option_buffer(enc_packet
->options
,
7078 enc_opt_data
.len
- msglen
,
7079 &dhcpv6_universe
)) {
7080 /* no logging here, as parse_option_buffer() logs all
7081 cases where it fails */
7085 log_error("dhcp4o6_relay_forw: unexpected message of type %d.",
7091 * This is recursive. It is possible to exceed maximum packet size.
7092 * XXX: This will cause the packet send to fail.
7094 build_dhcpv6_reply(&enc_reply
, enc_packet
);
7097 * If we got no encapsulated data, then it is discarded, and
7098 * our reply-forw is also discarded.
7100 if (enc_reply
.data
== NULL
) {
7105 * Now we can use the reply_data buffer.
7106 * Packet header stuff all comes from the forward message.
7108 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
7109 reply
->msg_type
= DHCPV6_RELAY_REPL
;
7110 reply
->hop_count
= packet
->dhcpv6_hop_count
;
7111 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
7112 sizeof(reply
->link_address
));
7113 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
7114 sizeof(reply
->peer_address
));
7115 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
7118 * Get the reply option state.
7120 if (!option_state_allocate(&opt_state
, MDL
)) {
7121 log_error("dhcp4o6_relay_forw: no memory for option state.");
7126 * Append the interface-id if present.
7128 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
7131 if (!evaluate_option_cache(&a_opt
, packet
,
7133 packet
->options
, NULL
,
7134 &global_scope
, oc
, MDL
)) {
7135 log_error("dhcp4o6_relay_forw: error evaluating "
7139 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7140 (unsigned char *)a_opt
.data
,
7142 D6O_INTERFACE_ID
, 0)) {
7143 log_error("dhcp4o6_relay_forw: error saving "
7147 data_string_forget(&a_opt
, MDL
);
7151 * Append our encapsulated stuff for caller.
7153 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7154 (unsigned char *)enc_reply
.data
,
7156 D6O_RELAY_MSG
, 0)) {
7157 log_error("dhcp4o6_relay_forw: error saving Relay MSG.");
7162 * Get the ERO if any.
7164 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
7169 if (!evaluate_option_cache(&packet_ero
, packet
,
7171 packet
->options
, NULL
,
7172 &global_scope
, oc
, MDL
) ||
7173 (packet_ero
.len
& 1)) {
7174 log_error("dhcp4o6_relay_forw: error evaluating ERO.");
7178 /* Decode and apply the ERO. */
7179 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
7180 req
= getUShort(packet_ero
.data
+ i
);
7181 /* Already in the reply? */
7182 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
7185 /* Get it from the packet if present. */
7186 oc
= lookup_option(&dhcpv6_universe
,
7191 if (!evaluate_option_cache(&a_opt
, packet
,
7193 packet
->options
, NULL
,
7194 &global_scope
, oc
, MDL
)) {
7195 log_error("dhcp4o6_relay_forw: error "
7196 "evaluating option %u.", req
);
7199 if (!save_option_buffer(&dhcpv6_universe
,
7202 (unsigned char *)a_opt
.data
,
7206 log_error("dhcp4o6_relay_forw: error saving "
7210 data_string_forget(&a_opt
, MDL
);
7214 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
7215 sizeof(reply_data
) - reply_ofs
,
7217 required_opts_agent
, &packet_ero
);
7220 * Return our reply to the caller.
7222 reply_ret
->len
= reply_ofs
;
7223 reply_ret
->buffer
= NULL
;
7224 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
7225 log_fatal("No memory to store reply.");
7227 reply_ret
->data
= reply_ret
->buffer
->data
;
7228 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
7231 if (opt_state
!= NULL
)
7232 option_state_dereference(&opt_state
, MDL
);
7233 if (a_opt
.data
!= NULL
) {
7234 data_string_forget(&a_opt
, MDL
);
7236 if (packet_ero
.data
!= NULL
) {
7237 data_string_forget(&packet_ero
, MDL
);
7239 if (enc_reply
.data
!= NULL
) {
7240 data_string_forget(&enc_reply
, MDL
);
7242 if (enc_opt_data
.data
!= NULL
) {
7243 data_string_forget(&enc_opt_data
, MDL
);
7245 if (enc_packet
!= NULL
) {
7246 packet_dereference(&enc_packet
, MDL
);
7251 * \brief Internal processing of a DHCPv4-query
7252 * (DHCPv4 server function)
7254 * Code copied from \ref do_packet().
7256 * \param reply_ret pointer to the response
7257 * \param packet the query
7260 dhcp4o6_dhcpv4_query(struct data_string
*reply_ret
, struct packet
*packet
) {
7261 struct option_cache
*oc
;
7262 struct data_string enc_opt_data
;
7263 struct packet
*enc_packet
;
7264 struct data_string enc_response
;
7265 struct option_state
*opt_state
;
7266 static char response_data
[65536];
7267 struct dhcpv4_over_dhcpv6_packet
*response
;
7271 * Initialize variables for early exit.
7274 memset(&enc_response
, 0, sizeof(enc_response
));
7275 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
7279 * Get our encapsulated relay message.
7281 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_DHCPV4_MSG
);
7283 log_info("DHCPv4-query from %s missing DHCPv4 Message option.",
7284 piaddr(packet
->client_addr
));
7288 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
7289 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
7290 log_error("dhcp4o6_dhcpv4_query: error evaluating "
7295 if (enc_opt_data
.len
< DHCP_FIXED_NON_UDP
) {
7296 log_error("dhcp4o6_dhcpv4_query: DHCPv4 packet too short.");
7301 * Build a packet structure from this encapsulated packet.
7303 if (!packet_allocate(&enc_packet
, MDL
)) {
7304 log_error("dhcp4o6_dhcpv4_query: "
7305 "no memory for encapsulated packet.");
7309 enc_packet
->raw
= (struct dhcp_packet
*)enc_opt_data
.data
;
7310 enc_packet
->packet_length
= enc_opt_data
.len
;
7311 enc_packet
->dhcp4o6_response
= &enc_response
;
7312 enc_packet
->client_port
= packet
->client_port
;
7313 enc_packet
->client_addr
= packet
->client_addr
;
7314 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
7315 enc_packet
->dhcpv6_container_packet
= packet
;
7316 if (packet
->dhcp4o6_flags
[0] & DHCP4O6_QUERY_UNICAST
)
7317 enc_packet
->unicast
= 1;
7319 if (enc_packet
->raw
->hlen
> sizeof(enc_packet
->raw
->chaddr
)) {
7320 log_info("dhcp4o6_dhcpv4_query: "
7321 "discarding packet with bogus hlen.");
7325 /* Allocate packet->options now so it is non-null for all packets */
7326 if (!option_state_allocate (&enc_packet
->options
, MDL
)) {
7327 log_error("dhcp4o6_dhcpv4_query: no memory for options.");
7331 /* If there's an option buffer, try to parse it. */
7332 if (enc_packet
->packet_length
>= DHCP_FIXED_NON_UDP
+ 4) {
7333 struct option_cache
*op
;
7334 if (!parse_options(enc_packet
)) {
7335 if (enc_packet
->options
)
7336 option_state_dereference
7337 (&enc_packet
->options
, MDL
);
7338 packet_dereference (&enc_packet
, MDL
);
7342 if (enc_packet
->options_valid
&&
7343 (op
= lookup_option(&dhcp_universe
,
7344 enc_packet
->options
,
7345 DHO_DHCP_MESSAGE_TYPE
))) {
7346 struct data_string dp
;
7347 memset(&dp
, 0, sizeof dp
);
7348 evaluate_option_cache(&dp
, enc_packet
, NULL
, NULL
,
7349 enc_packet
->options
, NULL
,
7352 enc_packet
->packet_type
= dp
.data
[0];
7354 enc_packet
->packet_type
= 0;
7355 data_string_forget(&dp
, MDL
);
7359 if (validate_packet(enc_packet
) != 0) {
7360 if (enc_packet
->packet_type
)
7366 /* If the caller kept the packet, they'll have upped the refcnt. */
7367 packet_dereference(&enc_packet
, MDL
);
7370 * If we got no response data, then it is discarded, and
7371 * our DHCPv4-response is also discarded.
7373 if (enc_response
.data
== NULL
) {
7378 * Now we can use the response_data buffer.
7380 response
= (struct dhcpv4_over_dhcpv6_packet
*)response_data
;
7381 response
->msg_type
= DHCPV6_DHCPV4_RESPONSE
;
7382 response
->flags
[0] = response
->flags
[1] = response
->flags
[2] = 0;
7384 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7387 * Get the response option state.
7389 if (!option_state_allocate(&opt_state
, MDL
)) {
7390 log_error("dhcp4o6_dhcpv4_query: no memory for option state.");
7395 * Append our encapsulated stuff for caller.
7397 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7398 (unsigned char *)enc_response
.data
,
7400 D6O_DHCPV4_MSG
, 0)) {
7401 log_error("dhcp4o6_dhcpv4_query: error saving DHCPv4 MSG.");
7405 response_ofs
+= store_options6(response_data
+ response_ofs
,
7406 sizeof(response_data
) - response_ofs
,
7408 required_opts_4o6
, NULL
);
7411 * Return our response to the caller.
7413 reply_ret
->len
= response_ofs
;
7414 reply_ret
->buffer
= NULL
;
7415 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
7416 log_fatal("dhcp4o6_dhcpv4_query: no memory to store reply.");
7418 reply_ret
->data
= reply_ret
->buffer
->data
;
7419 memcpy(reply_ret
->buffer
->data
, response_data
, response_ofs
);
7422 if (opt_state
!= NULL
)
7423 option_state_dereference(&opt_state
, MDL
);
7424 if (enc_response
.data
!= NULL
) {
7425 data_string_forget(&enc_response
, MDL
);
7427 if (enc_opt_data
.data
!= NULL
) {
7428 data_string_forget(&enc_opt_data
, MDL
);
7430 if (enc_packet
!= NULL
) {
7431 packet_dereference(&enc_packet
, MDL
);
7436 * \brief Forward a DHCPv4-query message to the DHCPv4 side
7437 * (DHCPv6 server function)
7439 * Format: interface:16 + address:16 + DHCPv6 DHCPv4-query message
7441 * \brief packet the DHCPv6 DHCPv4-query message
7443 static void forw_dhcpv4_query(struct packet
*packet
) {
7444 struct data_string ds
;
7448 /* Get the initial message. */
7449 while (packet
->dhcpv6_container_packet
!= NULL
)
7450 packet
= packet
->dhcpv6_container_packet
;
7452 /* Check the initial message. */
7453 if ((packet
->raw
== NULL
) ||
7454 (packet
->client_addr
.len
!= 16) ||
7455 (packet
->interface
== NULL
)) {
7456 log_error("forw_dhcpv4_query: can't find initial message.");
7461 len
= packet
->packet_length
+ 32;
7462 memset(&ds
, 0, sizeof(ds
));
7463 if (!buffer_allocate(&ds
.buffer
, len
, MDL
)) {
7464 log_error("forw_dhcpv4_query: "
7465 "no memory for encapsulating packet.");
7468 ds
.data
= ds
.buffer
->data
;
7471 /* Fill the buffer. */
7472 strncpy((char *)ds
.buffer
->data
, packet
->interface
->name
, 16);
7473 memcpy(ds
.buffer
->data
+ 16,
7474 packet
->client_addr
.iabuf
, 16);
7475 memcpy(ds
.buffer
->data
+ 32,
7476 (unsigned char *)packet
->raw
,
7477 packet
->packet_length
);
7479 /* Forward to the DHCPv4 server. */
7480 cc
= send(dhcp4o6_fd
, ds
.data
, ds
.len
, 0);
7482 log_error("forw_dhcpv4_query: send(): %m");
7483 data_string_forget(&ds
, MDL
);
7488 dhcpv6_discard(struct packet
*packet
) {
7489 /* INSIST(packet->msg_type > 0); */
7490 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
7492 log_debug("Discarding %s from %s; message type not handled by server",
7493 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7494 piaddr(packet
->client_addr
));
7498 build_dhcpv6_reply(struct data_string
*reply
, struct packet
*packet
) {
7499 memset(reply
, 0, sizeof(*reply
));
7501 /* I would like to classify the client once here, but
7502 * as I don't want to classify all of the incoming packets
7503 * I need to do it before handling specific types.
7504 * We don't need to classify if we are tossing the packet
7505 * or if it is a relay - the classification step will get
7506 * done when we process the inner client packet.
7509 switch (packet
->dhcpv6_msg_type
) {
7510 case DHCPV6_SOLICIT
:
7511 classify_client(packet
);
7512 dhcpv6_solicit(reply
, packet
);
7514 case DHCPV6_ADVERTISE
:
7515 dhcpv6_discard(packet
);
7517 case DHCPV6_REQUEST
:
7518 classify_client(packet
);
7519 dhcpv6_request(reply
, packet
);
7521 case DHCPV6_CONFIRM
:
7522 classify_client(packet
);
7523 dhcpv6_confirm(reply
, packet
);
7526 classify_client(packet
);
7527 dhcpv6_renew(reply
, packet
);
7530 classify_client(packet
);
7531 dhcpv6_rebind(reply
, packet
);
7534 dhcpv6_discard(packet
);
7536 case DHCPV6_RELEASE
:
7537 classify_client(packet
);
7538 dhcpv6_release(reply
, packet
);
7540 case DHCPV6_DECLINE
:
7541 classify_client(packet
);
7542 dhcpv6_decline(reply
, packet
);
7544 case DHCPV6_RECONFIGURE
:
7545 dhcpv6_discard(packet
);
7547 case DHCPV6_INFORMATION_REQUEST
:
7548 classify_client(packet
);
7549 dhcpv6_information_request(reply
, packet
);
7551 case DHCPV6_RELAY_FORW
:
7553 if (dhcpv4_over_dhcpv6
&& (local_family
== AF_INET
))
7554 dhcp4o6_relay_forw(reply
, packet
);
7556 #endif /* DHCP4o6 */
7557 dhcpv6_relay_forw(reply
, packet
);
7559 case DHCPV6_RELAY_REPL
:
7560 dhcpv6_discard(packet
);
7562 case DHCPV6_LEASEQUERY
:
7563 classify_client(packet
);
7564 dhcpv6_leasequery(reply
, packet
);
7566 case DHCPV6_LEASEQUERY_REPLY
:
7567 dhcpv6_discard(packet
);
7569 case DHCPV6_DHCPV4_QUERY
:
7571 if (dhcpv4_over_dhcpv6
) {
7572 if (local_family
== AF_INET6
) {
7573 forw_dhcpv4_query(packet
);
7575 dhcp4o6_dhcpv4_query(reply
, packet
);
7578 #endif /* DHCP4o6 */
7579 dhcpv6_discard(packet
);
7581 case DHCPV6_DHCPV4_RESPONSE
:
7582 dhcpv6_discard(packet
);
7585 /* XXX: would be nice if we had "notice" level,
7586 as syslog, for this */
7587 log_info("Discarding unknown DHCPv6 message type %d "
7588 "from %s", packet
->dhcpv6_msg_type
,
7589 piaddr(packet
->client_addr
));
7594 log_packet_in(const struct packet
*packet
) {
7595 struct data_string s
;
7597 char tmp_addr
[INET6_ADDRSTRLEN
];
7600 memset(&s
, 0, sizeof(s
));
7602 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
7603 data_string_sprintfa(&s
, "%s message from %s port %d",
7604 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7605 piaddr(packet
->client_addr
),
7606 ntohs(packet
->client_port
));
7608 data_string_sprintfa(&s
,
7609 "Unknown message type %d from %s port %d",
7610 packet
->dhcpv6_msg_type
,
7611 piaddr(packet
->client_addr
),
7612 ntohs(packet
->client_port
));
7614 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7615 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7616 addr
= &packet
->dhcpv6_link_address
;
7617 data_string_sprintfa(&s
, ", link address %s",
7618 inet_ntop(AF_INET6
, addr
,
7619 tmp_addr
, sizeof(tmp_addr
)));
7620 addr
= &packet
->dhcpv6_peer_address
;
7621 data_string_sprintfa(&s
, ", peer address %s",
7622 inet_ntop(AF_INET6
, addr
,
7623 tmp_addr
, sizeof(tmp_addr
)));
7624 } else if ((packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_QUERY
) &&
7625 (packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_RESPONSE
)) {
7627 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
7628 data_string_sprintfa(&s
, ", transaction ID 0x%06X", tid
);
7631 oc = lookup_option(&dhcpv6_universe, packet->options,
7634 memset(&tmp_ds, 0, sizeof(tmp_ds_));
7635 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
7636 packet->options, NULL,
7637 &global_scope, oc, MDL)) {
7638 log_error("Error evaluating Client Identifier");
7640 data_strint_sprintf(&s, ", client ID %s",
7642 data_string_forget(&tmp_ds, MDL);
7648 log_info("%s", s
.data
);
7650 data_string_forget(&s
, MDL
);
7654 dhcpv6(struct packet
*packet
) {
7655 struct data_string reply
;
7656 struct sockaddr_in6 to_addr
;
7660 * Log a message that we received this packet.
7662 log_packet_in(packet
);
7665 * Build our reply packet.
7667 build_dhcpv6_reply(&reply
, packet
);
7669 if (reply
.data
!= NULL
) {
7671 * Send our reply, if we have one.
7673 memset(&to_addr
, 0, sizeof(to_addr
));
7674 to_addr
.sin6_family
= AF_INET6
;
7675 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7676 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7677 to_addr
.sin6_port
= local_port
;
7679 to_addr
.sin6_port
= remote_port
;
7682 #if defined (REPLY_TO_SOURCE_PORT)
7684 * This appears to have been included for testing so we would
7685 * not need a root client, but was accidently left in the
7686 * final code. We continue to include it in case
7687 * some users have come to rely upon it, but leave
7688 * it off by default as it's a bad idea.
7690 to_addr
.sin6_port
= packet
->client_port
;
7693 memcpy(&to_addr
.sin6_addr
, packet
->client_addr
.iabuf
,
7694 sizeof(to_addr
.sin6_addr
));
7696 log_info("Sending %s to %s port %d",
7697 dhcpv6_type_names
[reply
.data
[0]],
7698 piaddr(packet
->client_addr
),
7699 ntohs(to_addr
.sin6_port
));
7701 send_ret
= send_packet6(packet
->interface
,
7702 reply
.data
, reply
.len
, &to_addr
);
7703 if (send_ret
!= reply
.len
) {
7704 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
7705 send_ret
, reply
.len
);
7707 data_string_forget(&reply
, MDL
);
7713 * \brief Receive a DHCPv4-query message from the DHCPv6 side
7714 * (DHCPv4 server function)
7716 * Receive a message with a DHCPv4-query inside from the DHCPv6 server.
7717 * (code copied from \ref do_packet6() \ref and dhcpv6())
7719 * Format: interface:16 + address:16 + DHCPv6 DHCPv4-query message
7721 * \param raw the DHCPv6 DHCPv4-query message raw content
7723 static void recv_dhcpv4_query(struct data_string
*raw
) {
7724 struct interface_info
*ip
;
7727 struct packet
*packet
;
7728 unsigned char msg_type
;
7729 const struct dhcpv6_relay_packet
*relay
;
7730 const struct dhcpv4_over_dhcpv6_packet
*msg
;
7731 struct data_string reply
;
7732 struct data_string ds
;
7736 memset(name
, 0, sizeof(name
));
7737 memcpy(name
, raw
->data
, 16);
7738 for (ip
= interfaces
; ip
!= NULL
; ip
= ip
->next
) {
7739 if (!strcmp(name
, ip
->name
))
7743 log_error("recv_dhcpv4_query: can't find interface %s.",
7749 memcpy(iaddr
.iabuf
, raw
->data
+ 16, 16);
7752 * From do_packet6().
7755 if (!packet6_len_okay((char *)raw
->data
+ 32, raw
->len
- 32)) {
7756 log_error("recv_dhcpv4_query: "
7757 "short packet from %s, len %d, dropped",
7758 piaddr(iaddr
), raw
->len
- 32);
7763 * Build a packet structure.
7766 if (!packet_allocate(&packet
, MDL
)) {
7767 log_error("recv_dhcpv4_query: no memory for packet.");
7771 if (!option_state_allocate(&packet
->options
, MDL
)) {
7772 log_error("recv_dhcpv4_query: no memory for options.");
7773 packet_dereference(&packet
, MDL
);
7777 packet
->raw
= (struct dhcp_packet
*)(raw
->data
+ 32);
7778 packet
->packet_length
= raw
->len
- 32;
7779 packet
->client_port
= remote_port
;
7780 packet
->client_addr
= iaddr
;
7781 interface_reference(&packet
->interface
, ip
, MDL
);
7783 msg_type
= raw
->data
[32];
7784 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
7785 (msg_type
== DHCPV6_RELAY_REPL
)) {
7787 (int)(offsetof(struct dhcpv6_relay_packet
, options
));
7788 relay
= (const struct dhcpv6_relay_packet
*)(raw
->data
+ 32);
7789 packet
->dhcpv6_msg_type
= relay
->msg_type
;
7791 /* relay-specific data */
7792 packet
->dhcpv6_hop_count
= relay
->hop_count
;
7793 memcpy(&packet
->dhcpv6_link_address
,
7794 relay
->link_address
, sizeof(relay
->link_address
));
7795 memcpy(&packet
->dhcpv6_peer_address
,
7796 relay
->peer_address
, sizeof(relay
->peer_address
));
7798 if (!parse_option_buffer(packet
->options
,
7800 raw
->len
- 32 - relaylen
,
7801 &dhcpv6_universe
)) {
7802 /* no logging here, as parse_option_buffer() logs all
7803 cases where it fails */
7804 packet_dereference(&packet
, MDL
);
7807 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
7808 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
7810 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7811 msg
= (struct dhcpv4_over_dhcpv6_packet
*)(raw
->data
+ 32);
7812 packet
->dhcpv6_msg_type
= msg
->msg_type
;
7814 /* message-specific data */
7815 memcpy(packet
->dhcp4o6_flags
, msg
->flags
,
7816 sizeof(packet
->dhcp4o6_flags
));
7818 if (!parse_option_buffer(packet
->options
,
7820 raw
->len
- 32 - msglen
,
7821 &dhcpv6_universe
)) {
7822 /* no logging here, as parse_option_buffer() logs all
7823 cases where it fails */
7824 packet_dereference(&packet
, MDL
);
7828 log_error("recv_dhcpv4_query: unexpected message of type %d.",
7830 packet_dereference(&packet
, MDL
);
7839 * Log a message that we received this packet.
7841 /* log_packet_in(packet); */
7842 memset(&ds
, 0, sizeof(ds
));
7843 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
7844 data_string_sprintfa(&ds
, "%s message from %s",
7845 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7846 piaddr(packet
->client_addr
));
7848 data_string_sprintfa(&ds
,
7849 "Unknown message type %d from %s",
7850 packet
->dhcpv6_msg_type
,
7851 piaddr(packet
->client_addr
));
7853 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7854 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7855 char tmp_addr
[INET6_ADDRSTRLEN
];
7858 addr
= &packet
->dhcpv6_link_address
;
7859 data_string_sprintfa(&ds
, ", link address %s",
7860 inet_ntop(AF_INET6
, addr
,
7861 tmp_addr
, sizeof(tmp_addr
)));
7862 addr
= &packet
->dhcpv6_peer_address
;
7863 data_string_sprintfa(&ds
, ", peer address %s",
7864 inet_ntop(AF_INET6
, addr
,
7865 tmp_addr
, sizeof(tmp_addr
)));
7866 } else if ((packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_QUERY
) &&
7867 (packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_RESPONSE
)) {
7870 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
7871 data_string_sprintfa(&ds
, ", transaction ID 0x%06X", tid
);
7873 log_info("%s", ds
.data
);
7874 data_string_forget(&ds
, MDL
);
7877 * Build our reply packet.
7879 build_dhcpv6_reply(&reply
, packet
);
7881 packet_dereference(&packet
, MDL
);
7883 if (reply
.data
== NULL
)
7887 * Forward the response.
7889 len
= reply
.len
+ 32;
7890 memset(&ds
, 0, sizeof(ds
));
7891 if (!buffer_allocate(&ds
.buffer
, len
, MDL
)) {
7892 log_error("recv_dhcpv4_query: no memory.");
7895 ds
.data
= ds
.buffer
->data
;
7898 memcpy(ds
.buffer
->data
, name
, 16);
7899 memcpy(ds
.buffer
->data
+ 16, iaddr
.iabuf
, 16);
7900 memcpy(ds
.buffer
->data
+ 32, reply
.data
, reply
.len
);
7901 cc
= send(dhcp4o6_fd
, ds
.data
, ds
.len
, 0);
7903 log_error("recv_dhcpv4_query: send(): %m");
7904 data_string_forget(&ds
, MDL
);
7906 #endif /* DHCP4o6 */
7909 seek_shared_host(struct host_decl
**hp
, struct shared_network
*shared
) {
7910 struct host_decl
*nofixed
= NULL
;
7911 struct host_decl
*seek
, *hold
= NULL
;
7914 * Seek forward through fixed addresses for the right link.
7916 * Note: how to do this for fixed prefixes???
7918 host_reference(&hold
, *hp
, MDL
);
7919 host_dereference(hp
, MDL
);
7921 while (seek
!= NULL
) {
7922 if (seek
->fixed_addr
== NULL
)
7924 else if (fixed_matches_shared(seek
, shared
))
7927 seek
= seek
->n_ipaddr
;
7930 if ((seek
== NULL
) && (nofixed
!= NULL
))
7934 host_reference(hp
, seek
, MDL
);
7937 static isc_boolean_t
7938 fixed_matches_shared(struct host_decl
*host
, struct shared_network
*shared
) {
7939 struct subnet
*subnet
;
7940 struct data_string addr
;
7941 isc_boolean_t matched
;
7944 if (host
->fixed_addr
== NULL
)
7947 memset(&addr
, 0, sizeof(addr
));
7948 if (!evaluate_option_cache(&addr
, NULL
, NULL
, NULL
, NULL
, NULL
,
7949 &global_scope
, host
->fixed_addr
, MDL
))
7952 if (addr
.len
< 16) {
7953 data_string_forget(&addr
, MDL
);
7958 memcpy(fixed
.iabuf
, addr
.data
, 16);
7960 matched
= ISC_FALSE
;
7961 for (subnet
= shared
->subnets
; subnet
!= NULL
;
7962 subnet
= subnet
->next_sibling
) {
7963 if (addr_eq(subnet_number(fixed
, subnet
->netmask
),
7970 data_string_forget(&addr
, MDL
);
7976 * \brief Constructs a REPLY with status of UseMulticast to a given packet
7978 * Per RFC 3315 Secs 18.2.1,3,6 & 7, when a server rejects a client's
7979 * unicast-sent packet, the response must only contain the client id,
7980 * server id, and a status code option of 5 (UseMulticast). This function
7981 * constructs such a packet and returns it as a data_string.
7983 * \param reply_ret = data_string which will receive the newly constructed
7985 * \param packet = client request which is being rejected
7986 * \param client_id = data_string which contains the client id
7987 * \param server_id = data_string which which contains the server id
7991 unicast_reject(struct data_string
*reply_ret
,
7992 struct packet
*packet
,
7993 const struct data_string
*client_id
,
7994 const struct data_string
*server_id
)
7996 struct reply_state reply
;
7997 memset(&reply
, 0x0, sizeof(struct reply_state
));
7999 /* Locate the client. */
8000 if (shared_network_from_packet6(&reply
.shared
, packet
)
8002 log_error("unicast_reject: could not locate client.");
8006 /* Initialize the reply. */
8007 packet_reference(&reply
.packet
, packet
, MDL
);
8008 data_string_copy(&reply
.client_id
, client_id
, MDL
);
8010 if (start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
8011 &reply
.buf
.reply
)) {
8012 /* Set the UseMulticast status code. */
8013 if (!set_status_code(STATUS_UseMulticast
,
8014 "Unicast not allowed by server.",
8016 log_error("unicast_reject: Unable to set status code.");
8018 /* Set write cursor to just past the reply header. */
8019 reply
.cursor
= REPLY_OPTIONS_INDEX
;
8020 reply
.cursor
+= store_options6(((char *)reply
.buf
.data
8026 unicast_reject_opts
,
8029 /* Return our reply to the caller. */
8030 reply_ret
->len
= reply
.cursor
;
8031 reply_ret
->buffer
= NULL
;
8032 if (!buffer_allocate(&reply_ret
->buffer
,
8033 reply
.cursor
, MDL
)) {
8034 log_fatal("unicast_reject:"
8035 "No memory to store Reply.");
8038 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
,
8040 reply_ret
->data
= reply_ret
->buffer
->data
;
8046 if (reply
.shared
!= NULL
)
8047 shared_network_dereference(&reply
.shared
, MDL
);
8048 if (reply
.opt_state
!= NULL
)
8049 option_state_dereference(&reply
.opt_state
, MDL
);
8050 if (reply
.packet
!= NULL
)
8051 packet_dereference(&reply
.packet
, MDL
);
8052 if (reply
.client_id
.data
!= NULL
)
8053 data_string_forget(&reply
.client_id
, MDL
);
8058 * \brief Checks if the dhcp6.unicast option has been defined
8060 * Scans the option space for the presence of the dhcp6.unicast option. The
8061 * function attempts to map the inbound packet to a shared network first
8062 * by an ip address specified via an D6O_IA_XX option and if that fails then
8063 * by the packet's source information (e.g. relay link, link, or interace).
8064 * Once the packet is mapped to a shared network, the function executes all
8065 * statements from the network's group outward into a local option cache.
8066 * The option cache is then scanned for the presence of unicast option. If
8067 * the packet cannot be mapped to a shared network, the function returns
8069 * \param packet inbound packet from the client
8071 * \return ISC_TRUE if the dhcp6.unicast option is defined, false otherwise.
8075 is_unicast_option_defined(struct packet
*packet
) {
8076 isc_boolean_t is_defined
= ISC_FALSE
;
8077 struct option_state
*opt_state
= NULL
;
8078 struct option_cache
*oc
= NULL
;
8079 struct shared_network
*shared
= NULL
;
8081 if (!option_state_allocate(&opt_state
, MDL
)) {
8082 log_fatal("is_unicast_option_defined:"
8083 "No memory for option state.");
8086 /* We try to map the packet to a network first by an IA_XX value.
8087 * If that fails, we try by packet source. */
8088 if (((shared_network_from_requested_addr(&shared
, packet
)
8089 != ISC_R_SUCCESS
) &&
8090 (shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
))
8091 || (shared
== NULL
)) {
8092 /* @todo what would this really mean? I think wrong network
8093 * logic will catch it */
8094 log_error("is_unicast_option_defined:"
8095 "cannot attribute packet to a network.");
8099 /* Now that we've mapped it to a network, execute statments to that
8100 * scope, looking for the unicast option. We don't care about the
8101 * value of the option, only whether or not it is defined. */
8102 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
, opt_state
,
8103 &global_scope
, shared
->group
, NULL
, NULL
);
8105 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_UNICAST
);
8106 is_defined
= (oc
!= NULL
? ISC_TRUE
: ISC_FALSE
);
8107 log_debug("is_unicast_option_defined: option found : %d", is_defined
);
8109 if (shared
!= NULL
) {
8110 shared_network_dereference(&shared
, MDL
);
8113 if (opt_state
!= NULL
) {
8114 option_state_dereference(&opt_state
, MDL
);
8117 return (is_defined
);
8122 * \brief Maps a packet to a shared network based on the requested IP address
8124 * The function attempts to find a subnet that matches the first requested IP
8125 * address contained within the given packet. Note that it looks first for
8126 * D6O_IA_NAs, then D6O_IA_PDs and lastly D6O_IA_TAs. If a matching network is
8127 * found, a reference to it is returned in the parameter, shared.
8129 * \param shared shared_network pointer which will receive the matching network
8130 * \param packet inbound packet from the client
8132 * \return ISC_R_SUCCESS if the packet can be mapped to a shared_network.
8136 shared_network_from_requested_addr (struct shared_network
**shared
,
8137 struct packet
* packet
) {
8139 struct subnet
* subnet
= NULL
;
8140 isc_result_t status
= ISC_R_FAILURE
;
8142 /* Try to match first IA_ address or prefix we find to a subnet. In
8143 * theory all IA_ values in a given request are supposed to be in the
8144 * same subnet so we only need to try one right? */
8145 if ((get_first_ia_addr_val(packet
, D6O_IA_NA
, &iaddr
) != ISC_R_SUCCESS
)
8146 && (get_first_ia_addr_val(packet
, D6O_IA_PD
, &iaddr
)
8148 && (get_first_ia_addr_val(packet
, D6O_IA_TA
, &iaddr
)
8149 != ISC_R_SUCCESS
)) {
8150 /* we found nothing to match against */
8151 log_debug("share_network_from_request_addr: nothing to match");
8152 return (ISC_R_FAILURE
);
8155 if (!find_subnet(&subnet
, iaddr
, MDL
)) {
8156 log_debug("shared_network_from_requested_addr:"
8157 "No subnet found for addr %s.", piaddr(iaddr
));
8159 status
= shared_network_reference(shared
,
8160 subnet
->shared_network
, MDL
);
8161 subnet_dereference(&subnet
, MDL
);
8162 log_debug("shared_network_from_requested_addr:"
8163 " found shared network %s for address %s.",
8164 ((*shared
)->name
? (*shared
)->name
: "unnamed"),
8169 return (ISC_R_FAILURE
);
8174 * \brief Retrieves the first IP address from a given packet of a given type
8176 * Search a packet for options of a given type (D6O_IA_AN, D6O_IA_PD, or
8177 * D6O_IA_TA) for the first non-blank IA_XX value and return its IP address
8180 * \param packet packet received from the client
8181 * \param addr_type the address option type (D6O_IA_NA , D6O_IA_PD, or
8182 * D6O_IP_TA) to look for within the packet.
8183 * \param iaddr pointer to the iaddr structure which will receive the extracted
8186 * \return ISC_R_SUCCESS if an address was succesfully extracted, ISC_R_FALURE
8191 get_first_ia_addr_val (struct packet
* packet
, int addr_type
,
8192 struct iaddr
* iaddr
) {
8193 struct option_cache
*ia
;
8194 struct option_cache
*oc
= NULL
;
8195 struct data_string cli_enc_opt_data
;
8196 struct option_state
*cli_enc_opt_state
;
8197 int addr_opt_offset
;
8199 int addr_opt_data_len
;
8202 isc_result_t status
= ISC_R_FAILURE
;
8203 memset(iaddr
, 0, sizeof(struct iaddr
));
8205 /* Set up address type specifics */
8206 switch (addr_type
) {
8208 addr_opt_offset
= IA_NA_OFFSET
;
8209 addr_opt
= D6O_IAADDR
;
8210 addr_opt_data_len
= 24;
8214 addr_opt_offset
= IA_TA_OFFSET
;
8215 addr_opt
= D6O_IAADDR
;
8216 addr_opt_data_len
= 24;
8220 addr_opt_offset
= IA_PD_OFFSET
;
8221 addr_opt
= D6O_IAPREFIX
;
8222 addr_opt_data_len
= 25;
8226 /* shouldn't be here */
8227 log_error ("get_first_ia_addr_val: invalid opt type %d",
8229 return (ISC_R_FAILURE
);
8232 /* Find the first, non-blank IA_XX value within an D6O_IA_XX option. */
8233 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, addr_type
);
8234 ia
!= NULL
&& oc
== NULL
; ia
= ia
->next
) {
8235 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
8237 packet
, ia
, addr_opt_offset
)) {
8238 log_debug ("get_first_ia_addr_val:"
8239 " couldn't unroll enclosing option");
8240 return (ISC_R_FAILURE
);
8243 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
8246 /* no address given for this IA, ignore */
8247 option_state_dereference(&cli_enc_opt_state
, MDL
);
8248 data_string_forget(&cli_enc_opt_data
, MDL
);
8252 /* If we found a non-blank IA_XX then extract its ip address. */
8254 struct data_string iaddr_str
;
8256 memset(&iaddr_str
, 0, sizeof(iaddr_str
));
8257 if (!evaluate_option_cache(&iaddr_str
, packet
, NULL
, NULL
,
8258 packet
->options
, NULL
, &global_scope
,
8260 log_error("get_first_ia_addr_val: "
8261 "error evaluating IA_XX option.");
8263 if (iaddr_str
.len
!= addr_opt_data_len
) {
8264 log_error("shared_network_from_requested_addr:"
8265 " invalid length %d, expected %d",
8266 iaddr_str
.len
, addr_opt_data_len
);
8269 memcpy (iaddr
->iabuf
,
8270 iaddr_str
.data
+ ip_addr_offset
, 16);
8271 status
= ISC_R_SUCCESS
;
8273 data_string_forget(&iaddr_str
, MDL
);
8276 option_state_dereference(&cli_enc_opt_state
, MDL
);
8277 data_string_forget(&cli_enc_opt_data
, MDL
);
8284 * \brief Calculates the reply T1/T2 times and stuffs them in outbound buffer
8286 * T1/T2 time selection is kind of weird. We actually use DHCP * (v4) scoped
8287 * options, dhcp-renewal-time and dhcp-rebinding-time, as handy existing places
8288 * where these can be configured by an administrator. A value of zero tells the
8289 * client it may choose its own value.
8291 * When those options are not defined, the values will be set to zero unless
8292 * the global option, dhcpv6-set-tee-times is enabled. When this option is
8293 * enabled the values are calculated as recommended by RFC 3315, Section 22.4:
8295 * T1 will be set to 0.5 times the shortest preferred lifetime
8296 * in the IA_XX option. If the "shortest" preferred lifetime is
8297 * 0xFFFFFFFF, T1 will set to 0xFFFFFFFF.
8299 * T2 will be set to 0.8 times the shortest preferred lifetime
8300 * in the IA_XX option. If the "shortest" preferred lifetime is
8301 * 0xFFFFFFFF, T2 will set to 0xFFFFFFFF.
8303 * Note that dhcpv6-set-tee-times is intended to be transitional and will
8304 * likely be removed in 4.4.0, leaving the behavior as getting the values
8305 * either from the configured parameters (if you want zeros, define them as
8306 * zeros) or by calculating them per the RFC.
8308 * \param reply - pointer to the reply_state structure
8309 * \param ia_cursor - offset of the beginning of the IA_XX option within the
8310 * reply's outbound data buffer
8313 set_reply_tee_times(struct reply_state
* reply
, unsigned ia_cursor
)
8315 struct option_cache
*oc
;
8318 /* Found out if calculated values are enabled. */
8319 oc
= lookup_option(&server_universe
, reply
->opt_state
,
8320 SV_DHCPV6_SET_TEE_TIMES
);
8321 set_tee_times
= (oc
&&
8322 evaluate_boolean_option_cache(NULL
, reply
->packet
,
8324 reply
->packet
->options
,
8326 &global_scope
, oc
, MDL
));
8328 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
8329 DHO_DHCP_RENEWAL_TIME
);
8331 /* dhcp-renewal-time is defined, use it */
8332 struct data_string data
;
8333 memset(&data
, 0x00, sizeof(data
));
8335 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
8336 reply
->packet
->options
,
8337 reply
->opt_state
, &global_scope
,
8340 log_error("Invalid renewal time.");
8343 reply
->renew
= getULong(data
.data
);
8346 if (data
.data
!= NULL
)
8347 data_string_forget(&data
, MDL
);
8348 } else if (set_tee_times
) {
8349 /* Setting them is enabled so T1 is either infinite or
8350 * 0.5 * the shortest preferred lifetime in the IA_XX */
8351 if (reply
->min_prefer
== INFINITE_TIME
)
8352 reply
->renew
= INFINITE_TIME
;
8354 reply
->renew
= reply
->min_prefer
/ 2;
8356 /* Default is to let the client choose */
8360 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
8363 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
8364 DHO_DHCP_REBINDING_TIME
);
8366 /* dhcp-rebinding-time is defined, use it */
8367 struct data_string data
;
8368 memset(&data
, 0x00, sizeof(data
));
8370 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
8371 reply
->packet
->options
,
8372 reply
->opt_state
, &global_scope
,
8375 log_error("Invalid rebinding time.");
8378 reply
->rebind
= getULong(data
.data
);
8381 if (data
.data
!= NULL
)
8382 data_string_forget(&data
, MDL
);
8383 } else if (set_tee_times
) {
8384 /* Setting them is enabled so T2 is either infinite or
8385 * 0.8 * the shortest preferred lifetime in the reply */
8386 if (reply
->min_prefer
== INFINITE_TIME
)
8387 reply
->rebind
= INFINITE_TIME
;
8389 reply
->rebind
= (reply
->min_prefer
/ 5) * 4;
8391 /* Default is to let the client choose */
8395 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
8399 * Releases the iasubopts in the pre-existing IA, if they are not in
8400 * the same shared-network as the new IA.
8402 * returns 1 if the release was done, 0 otherwise
8405 release_on_roam(struct reply_state
* reply
) {
8406 struct ia_xx
* old_ia
= reply
->old_ia
;
8407 struct iasubopt
*lease
= NULL
;
8410 if ((!do_release_on_roam
) || old_ia
== NULL
8411 || old_ia
->num_iasubopt
<= 0) {
8415 /* If the old shared-network and new are the same, client hasn't
8416 * roamed, nothing to do. We only check the first one because you
8417 * cannot have iasubopts on different shared-networks within a
8419 lease
= old_ia
->iasubopt
[0];
8420 if (lease
->ipv6_pool
->shared_network
== reply
->shared
) {
8424 /* Old and new are on different shared networks so the client must
8425 * roamed. Release the old leases. */
8426 for (i
= 0; i
< old_ia
->num_iasubopt
; i
++) {
8427 lease
= old_ia
->iasubopt
[i
];
8429 log_info("Client: %s roamed to new network,"
8430 " releasing lease: %s%s",
8431 print_hex_1(reply
->client_id
.len
,
8432 reply
->client_id
.data
, 60),
8433 pin6_addr(&lease
->addr
), iasubopt_plen_str(lease
));
8435 release_lease6(lease
->ipv6_pool
, lease
);
8436 lease
->ia
->cltt
= cur_time
;
8437 write_ia(lease
->ia
);
8444 * Convenience function which returns a string (static buffer)
8445 * containing either a "/" followed by the prefix length or an
8446 * empty string depending on the lease type
8448 const char *iasubopt_plen_str(struct iasubopt
*lease
) {
8449 static char prefix_buf
[16];
8451 if ((lease
->ia
) && (lease
->ia
->ia_type
== D6O_IA_PD
)) {
8452 sprintf(prefix_buf
, "/%-d", lease
->plen
);
8455 return (prefix_buf
);
8460 * Initiates DDNS updates for static v6 leases if configured to do so.
8462 * The function, which must be called after the IA has been written to the
8463 * packet, adds an iasubopt to the IA for static lease. This is done so we
8464 * have an iasubopt to pass into ddns_updates(). A reference to the IA is
8465 * added to the DDNS control block to ensure it and it's iasubopt remain in
8466 * scope until the update is complete.
8469 void ddns_update_static6(struct reply_state
* reply
) {
8470 struct iasubopt
*iasub
= NULL
;
8471 struct binding_scope
*scope
= NULL
;
8472 struct option_cache
*oc
= NULL
;
8474 oc
= lookup_option(&server_universe
, reply
->opt_state
, SV_DDNS_UPDATES
);
8476 (evaluate_boolean_option_cache(NULL
, reply
->packet
, NULL
, NULL
,
8477 reply
->packet
->options
,
8478 reply
->opt_state
, NULL
,
8483 oc
= lookup_option(&server_universe
, reply
->opt_state
,
8484 SV_UPDATE_STATIC_LEASES
);
8486 (evaluate_boolean_option_cache(NULL
, reply
->packet
,
8488 reply
->packet
->options
,
8489 reply
->opt_state
, NULL
,
8494 if (iasubopt_allocate(&iasub
, MDL
) != ISC_R_SUCCESS
) {
8495 log_fatal("No memory for iasubopt.");
8498 if (ia_add_iasubopt(reply
->ia
, iasub
, MDL
) != ISC_R_SUCCESS
) {
8499 log_fatal("Could not add iasubopt.");
8502 ia_reference(&iasub
->ia
, reply
->ia
, MDL
);
8504 memcpy(iasub
->addr
.s6_addr
, reply
->fixed
.data
, 16);
8506 iasub
->prefer
= MAX_TIME
;
8507 iasub
->valid
= MAX_TIME
;
8508 iasub
->static_lease
= 1;
8510 if (!binding_scope_allocate(&scope
, MDL
)) {
8511 log_fatal("Out of memory for binding scope.");
8514 binding_scope_reference(&iasub
->scope
, scope
, MDL
);
8516 ddns_updates(reply
->packet
, NULL
, NULL
, iasub
, NULL
, reply
->opt_state
);
8518 #endif /* NSUPDATE */