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 u_int8_t rsp_opt_exist
;
37 static int offset_data4o6
= 36; /* 16+16+4 */
41 * We use print_hex_1() to output DUID values. We could actually output
42 * the DUID with more information... MAC address if using type 1 or 3,
43 * and so on. However, RFC 3315 contains Grave Warnings against actually
44 * attempting to understand a DUID.
48 * TODO: gettext() or other method of localization for the messages
49 * for status codes (and probably for log formats eventually)
50 * TODO: refactoring (simplify, simplify, simplify)
51 * TODO: support multiple shared_networks on each interface (this
52 * will allow the server to issue multiple IPv6 addresses to
57 * DHCPv6 Reply workflow assist. A Reply packet is built by various
58 * different functions; this gives us one location where we keep state
62 /* root level persistent state */
63 struct shared_network
*shared
;
64 struct host_decl
*host
;
65 struct subnet
*subnet
; /* Used to match fixed-addrs to subnet scopes. */
66 struct option_state
*opt_state
;
67 struct packet
*packet
;
68 struct data_string client_id
;
70 /* IA level persistent state */
73 unsigned client_resources
;
74 isc_boolean_t resources_included
;
75 isc_boolean_t static_lease
;
76 unsigned static_prefixes
;
79 struct option_state
*reply_ia
;
80 struct data_string fixed
;
81 struct iaddrcidrnet fixed_pref
; /* static prefix for logging */
83 /* IAADDR/PREFIX level persistent state */
84 struct iasubopt
*lease
;
87 * "t1", "t2", preferred, and valid lifetimes records for calculating
88 * t1 and t2 (min/max).
90 u_int32_t renew
, rebind
, min_prefer
, min_valid
;
92 /* Client-requested valid and preferred lifetimes. */
93 u_int32_t client_valid
, client_prefer
;
95 /* Chosen values to transmit for valid and preferred lifetimes. */
96 u_int32_t send_valid
, send_prefer
;
98 /* Preferred prefix length (-1 is any). */
101 /* Index into the data field that has been consumed. */
104 /* Space for the on commit statements for a fixed host */
105 struct on_star on_star
;
108 unsigned char data
[65536];
109 struct dhcpv6_packet reply
;
114 * Prototypes local to this file.
116 static int get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
117 struct data_string
*enc_opt_data
,
118 struct packet
*packet
,
119 struct option_cache
*oc
,
121 static void build_dhcpv6_reply(struct data_string
*, struct packet
*);
122 static isc_result_t
shared_network_from_packet6(struct shared_network
**shared
,
123 struct packet
*packet
);
124 static void seek_shared_host(struct host_decl
**hp
,
125 struct shared_network
*shared
);
126 static isc_boolean_t
fixed_matches_shared(struct host_decl
*host
,
127 struct shared_network
*shared
);
128 static isc_result_t
reply_process_ia_na(struct reply_state
*reply
,
129 struct option_cache
*ia
);
130 static isc_result_t
reply_process_ia_ta(struct reply_state
*reply
,
131 struct option_cache
*ia
);
132 static isc_result_t
reply_process_addr(struct reply_state
*reply
,
133 struct option_cache
*addr
);
134 static isc_boolean_t
address_is_owned(struct reply_state
*reply
,
136 static isc_boolean_t
temporary_is_available(struct reply_state
*reply
,
138 static isc_result_t
find_client_temporaries(struct reply_state
*reply
);
139 static isc_result_t
reply_process_try_addr(struct reply_state
*reply
,
141 static isc_result_t
find_client_address(struct reply_state
*reply
);
142 static isc_result_t
reply_process_is_addressed(struct reply_state
*reply
,
143 struct binding_scope
**scope
,
144 struct group
*group
);
145 static isc_result_t
reply_process_send_addr(struct reply_state
*reply
,
147 static struct iasubopt
*lease_compare(struct iasubopt
*alpha
,
148 struct iasubopt
*beta
);
149 static isc_result_t
reply_process_ia_pd(struct reply_state
*reply
,
150 struct option_cache
*ia_pd
);
151 static struct group
*find_group_by_prefix(struct reply_state
*reply
);
152 static isc_result_t
reply_process_prefix(struct reply_state
*reply
,
153 struct option_cache
*pref
);
154 static isc_boolean_t
prefix_is_owned(struct reply_state
*reply
,
155 struct iaddrcidrnet
*pref
);
156 static isc_result_t
find_client_prefix(struct reply_state
*reply
);
157 static isc_result_t
reply_process_try_prefix(struct reply_state
*reply
,
158 struct iaddrcidrnet
*pref
);
159 static isc_result_t
reply_process_is_prefixed(struct reply_state
*reply
,
160 struct binding_scope
**scope
,
161 struct group
*group
);
162 static isc_result_t
reply_process_send_prefix(struct reply_state
*reply
,
163 struct iaddrcidrnet
*pref
);
164 static struct iasubopt
*prefix_compare(struct reply_state
*reply
,
165 struct iasubopt
*alpha
,
166 struct iasubopt
*beta
);
167 static void schedule_lease_timeout_reply(struct reply_state
*reply
);
169 static int eval_prefix_mode(int thislen
, int preflen
, int prefix_mode
);
170 static isc_result_t
pick_v6_prefix_helper(struct reply_state
*reply
,
173 static void unicast_reject(struct data_string
*reply_ret
, struct packet
*packet
,
174 const struct data_string
*client_id
,
175 const struct data_string
*server_id
);
177 static isc_boolean_t
is_unicast_option_defined(struct packet
*packet
);
178 static isc_result_t
shared_network_from_requested_addr (struct shared_network
180 struct packet
* packet
);
181 static isc_result_t
get_first_ia_addr_val (struct packet
* packet
, int addr_type
,
182 struct iaddr
* iaddr
);
185 set_reply_tee_times(struct reply_state
* reply
, unsigned ia_cursor
);
187 static const char *iasubopt_plen_str(struct iasubopt
*lease
);
188 static int release_on_roam(struct reply_state
*reply
);
190 static int reuse_lease6(struct reply_state
*reply
, struct iasubopt
*lease
);
191 static void shorten_lifetimes(struct reply_state
*reply
, struct iasubopt
*lease
,
192 time_t age
, int threshold
);
193 static void write_to_packet(struct reply_state
*reply
, unsigned ia_cursor
);
194 static const char *iasubopt_plen_str(struct iasubopt
*lease
);
197 static void ddns_update_static6(struct reply_state
* reply
);
202 * \brief Omapi I/O handler
204 * The inter-process communication receive handler.
205 * Get the message, put it into the raw data_string
206 * and call \ref send_dhcpv4_response() (DHCPv6 side) or
207 * \ref recv_dhcpv4_query() (DHCPv4 side)
209 * \param h the OMAPI object
210 * \return a result for I/O success or error (used by the I/O subsystem)
212 isc_result_t
dhcpv4o6_handler(omapi_object_t
*h
) {
214 struct data_string raw
;
217 if (h
->type
!= dhcp4o6_type
)
218 return DHCP_R_INVALIDARG
;
220 cc
= recv(dhcp4o6_fd
, buf
, sizeof(buf
), 0);
222 if (cc
< DHCP_FIXED_NON_UDP
+ offset_data4o6
)
223 return ISC_R_UNEXPECTED
;
224 memset(&raw
, 0, sizeof(raw
));
225 if (!buffer_allocate(&raw
.buffer
, cc
, MDL
)) {
226 log_error("dhcpv4o6_handler: no memory buffer.");
227 return ISC_R_NOMEMORY
;
229 raw
.data
= raw
.buffer
->data
;
231 memcpy(raw
.buffer
->data
, buf
, cc
);
233 if (local_family
== AF_INET6
) {
234 send_dhcpv4_response(&raw
);
236 recv_dhcpv4_query(&raw
);
239 data_string_forget(&raw
, MDL
);
241 return ISC_R_SUCCESS
;
245 * \brief Send the DHCPv4-response back to the DHCPv6 side
246 * (DHCPv6 server function)
248 * Format: interface:16 + address:16 + udp:4 + DHCPv6 DHCPv4-response message
250 * \param raw the IPC message content
252 static void send_dhcpv4_response(struct data_string
*raw
) {
253 struct interface_info
*ip
;
255 struct sockaddr_in6 to_addr
;
256 char pbuf
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
257 struct udp_data4o6 udp_data
;
260 memset(name
, 0, sizeof(name
));
261 memcpy(name
, raw
->data
, 16);
262 for (ip
= interfaces
; ip
!= NULL
; ip
= ip
->next
) {
263 if (!strcmp(name
, ip
->name
))
267 log_error("send_dhcpv4_response: can't find interface %s.",
272 memset(&to_addr
, 0, sizeof(to_addr
));
273 to_addr
.sin6_family
= AF_INET6
;
274 memcpy(&to_addr
.sin6_addr
, raw
->data
+ 16, 16);
275 memset(&udp_data
, 0, sizeof(udp_data
));
276 memcpy(&udp_data
, raw
->data
+ 32, 4);
277 if ((raw
->data
[36] == DHCPV6_RELAY_FORW
) ||
278 (raw
->data
[36] == DHCPV6_RELAY_REPL
)) {
279 if (udp_data
.rsp_opt_exist
) {
280 to_addr
.sin6_port
= udp_data
.src_port
;
282 to_addr
.sin6_port
= local_port
;
285 to_addr
.sin6_port
= remote_port
;
288 log_info("send_dhcpv4_response(): sending %s on %s to %s port %d",
289 dhcpv6_type_names
[raw
->data
[36]],
291 inet_ntop(AF_INET6
, raw
->data
+ 16, pbuf
, sizeof(pbuf
)),
292 ntohs(to_addr
.sin6_port
));
294 send_ret
= send_packet6(ip
, raw
->data
+ 36, raw
->len
- 36, &to_addr
);
296 log_error("send_dhcpv4_response: send_packet6(): %m");
297 } else if (send_ret
!= raw
->len
- 36) {
298 log_error("send_dhcpv4_response: send_packet6() "
299 "sent %d of %d bytes",
300 send_ret
, raw
->len
- 36);
306 * Schedule lease timeouts for all of the iasubopts in the reply.
307 * This is currently used to schedule timeouts for soft leases.
311 schedule_lease_timeout_reply(struct reply_state
*reply
) {
312 struct iasubopt
*tmp
;
315 /* sanity check the reply */
316 if ((reply
== NULL
) || (reply
->ia
== NULL
) || (reply
->ia
->iasubopt
== NULL
))
319 /* walk through the list, scheduling as we go */
320 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
321 tmp
= reply
->ia
->iasubopt
[i
];
322 schedule_lease_timeout(tmp
->ipv6_pool
);
327 * This function returns the time since DUID time start for the
328 * given time_t value.
331 duid_time(time_t when
) {
333 * This time is modulo 2^32.
335 while ((when
- DUID_TIME_EPOCH
) > 4294967295u) {
336 /* use 2^31 to avoid spurious compiler warnings */
341 return when
- DUID_TIME_EPOCH
;
348 * This must remain the same for the lifetime of this server, because
349 * clients return the server DUID that we sent them in Request packets.
351 * We pick the server DUID like this:
353 * 1. Check dhcpd.conf - any value the administrator has configured
354 * overrides any possible values.
355 * 2. Check the leases.txt - we want to use the previous value if
357 * 3. Check if dhcpd.conf specifies a type of server DUID to use,
358 * and generate that type.
359 * 4. Generate a type 1 (time + hardware address) DUID.
361 static struct data_string server_duid
;
364 * Check if the server_duid has been set.
367 server_duid_isset(void) {
368 return (server_duid
.data
!= NULL
);
372 * Return the server_duid.
375 copy_server_duid(struct data_string
*ds
, const char *file
, int line
) {
376 data_string_copy(ds
, &server_duid
, file
, line
);
380 * Set the server DUID to a specified value. This is used when
381 * the server DUID is stored in persistent memory (basically the
385 set_server_duid(struct data_string
*new_duid
) {
386 /* INSIST(new_duid != NULL); */
387 /* INSIST(new_duid->data != NULL); */
389 if (server_duid_isset()) {
390 data_string_forget(&server_duid
, MDL
);
392 data_string_copy(&server_duid
, new_duid
, MDL
);
397 * Set the server DUID based on the D6O_SERVERID option. This handles
398 * the case where the administrator explicitly put it in the dhcpd.conf
402 set_server_duid_from_option(void) {
403 struct option_state
*opt_state
;
404 struct option_cache
*oc
;
405 struct data_string option_duid
;
406 isc_result_t ret_val
;
409 if (!option_state_allocate(&opt_state
, MDL
)) {
410 log_fatal("No memory for server DUID.");
413 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
,
414 opt_state
, &global_scope
, root_group
,
417 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
419 ret_val
= ISC_R_NOTFOUND
;
421 memset(&option_duid
, 0, sizeof(option_duid
));
422 if (!evaluate_option_cache(&option_duid
, NULL
, NULL
, NULL
,
423 opt_state
, NULL
, &global_scope
,
425 ret_val
= ISC_R_UNEXPECTED
;
427 set_server_duid(&option_duid
);
428 data_string_forget(&option_duid
, MDL
);
429 ret_val
= ISC_R_SUCCESS
;
433 option_state_dereference(&opt_state
, MDL
);
439 * DUID layout, as defined in RFC 3315, section 9.
441 * We support type 1 (hardware address plus time) and type 3 (hardware
444 * We can support type 2 for specific vendors in the future, if they
445 * publish the specification. And of course there may be additional
448 static int server_duid_type
= DUID_LLT
;
454 set_server_duid_type(int type
) {
455 server_duid_type
= type
;
459 * Generate a new server DUID. This is done if there was no DUID in
460 * the leases.txt or in the dhcpd.conf file.
463 generate_new_server_duid(void) {
464 struct interface_info
*p
;
466 struct data_string generated_duid
;
469 * Verify we have a type that we support.
471 if ((server_duid_type
!= DUID_LL
) && (server_duid_type
!= DUID_LLT
)) {
472 log_error("Invalid DUID type %d specified, "
473 "only LL and LLT types supported", server_duid_type
);
474 return DHCP_R_INVALIDARG
;
478 * Find an interface with a hardware address.
481 for (p
= interfaces
; p
!= NULL
; p
= p
->next
) {
482 if (p
->hw_address
.hlen
> 0) {
487 return ISC_R_UNEXPECTED
;
493 memset(&generated_duid
, 0, sizeof(generated_duid
));
494 if (server_duid_type
== DUID_LLT
) {
495 time_val
= duid_time(time(NULL
));
496 generated_duid
.len
= 8 + p
->hw_address
.hlen
- 1;
497 if (!buffer_allocate(&generated_duid
.buffer
,
498 generated_duid
.len
, MDL
)) {
499 log_fatal("No memory for server DUID.");
501 generated_duid
.data
= generated_duid
.buffer
->data
;
502 putUShort(generated_duid
.buffer
->data
, DUID_LLT
);
503 putUShort(generated_duid
.buffer
->data
+ 2,
504 p
->hw_address
.hbuf
[0]);
505 putULong(generated_duid
.buffer
->data
+ 4, time_val
);
506 memcpy(generated_duid
.buffer
->data
+ 8,
507 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
508 } else if (server_duid_type
== DUID_LL
) {
509 generated_duid
.len
= 4 + p
->hw_address
.hlen
- 1;
510 if (!buffer_allocate(&generated_duid
.buffer
,
511 generated_duid
.len
, MDL
)) {
512 log_fatal("No memory for server DUID.");
514 generated_duid
.data
= generated_duid
.buffer
->data
;
515 putUShort(generated_duid
.buffer
->data
, DUID_LL
);
516 putUShort(generated_duid
.buffer
->data
+ 2,
517 p
->hw_address
.hbuf
[0]);
518 memcpy(generated_duid
.buffer
->data
+ 4,
519 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
521 log_fatal("Unsupported server DUID type %d.", server_duid_type
);
524 set_server_duid(&generated_duid
);
525 data_string_forget(&generated_duid
, MDL
);
527 return ISC_R_SUCCESS
;
531 * Get the client identifier from the packet.
534 get_client_id(struct packet
*packet
, struct data_string
*client_id
) {
535 struct option_cache
*oc
;
538 * Verify our client_id structure is empty.
540 if ((client_id
->data
!= NULL
) || (client_id
->len
!= 0)) {
541 return DHCP_R_INVALIDARG
;
544 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_CLIENTID
);
546 return ISC_R_NOTFOUND
;
549 if (!evaluate_option_cache(client_id
, packet
, NULL
, NULL
,
550 packet
->options
, NULL
,
551 &global_scope
, oc
, MDL
)) {
552 return ISC_R_FAILURE
;
555 return ISC_R_SUCCESS
;
559 * Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
561 * Servers MUST discard any Solicit messages that do not include a
562 * Client Identifier option or that do include a Server Identifier
566 valid_client_msg(struct packet
*packet
, struct data_string
*client_id
) {
568 struct option_cache
*oc
;
569 struct data_string data
;
572 memset(client_id
, 0, sizeof(*client_id
));
573 memset(&data
, 0, sizeof(data
));
575 switch (get_client_id(packet
, client_id
)) {
579 log_debug("Discarding %s from %s; "
580 "client identifier missing",
581 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
582 piaddr(packet
->client_addr
));
585 log_error("Error processing %s from %s; "
586 "unable to evaluate Client Identifier",
587 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
588 piaddr(packet
->client_addr
));
593 * Required by RFC 3315, section 15.
595 if (packet
->unicast
) {
596 log_debug("Discarding %s from %s; packet sent unicast "
598 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
599 piaddr(packet
->client_addr
),
600 print_hex_1(client_id
->len
, client_id
->data
, 60));
605 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
607 if (evaluate_option_cache(&data
, packet
, NULL
, NULL
,
608 packet
->options
, NULL
,
609 &global_scope
, oc
, MDL
)) {
610 log_debug("Discarding %s from %s; "
611 "server identifier found "
612 "(CLIENTID %s, SERVERID %s)",
613 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
614 piaddr(packet
->client_addr
),
615 print_hex_1(client_id
->len
,
616 client_id
->data
, 60),
617 print_hex_2(data
.len
,
620 log_debug("Discarding %s from %s; "
621 "server identifier found "
623 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
624 print_hex_1(client_id
->len
,
625 client_id
->data
, 60),
626 piaddr(packet
->client_addr
));
635 data_string_forget(&data
, MDL
);
637 data_string_forget(client_id
, MDL
);
643 * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
644 * 15.9 (slightly different wording, but same meaning):
646 * Servers MUST discard any received Request message that meet any of
647 * the following conditions:
649 * - the message does not include a Server Identifier option.
650 * - the contents of the Server Identifier option do not match the
652 * - the message does not include a Client Identifier option.
655 valid_client_resp(struct packet
*packet
,
656 struct data_string
*client_id
,
657 struct data_string
*server_id
)
660 struct option_cache
*oc
;
662 /* INSIST((duid.data != NULL) && (duid.len > 0)); */
665 memset(client_id
, 0, sizeof(*client_id
));
666 memset(server_id
, 0, sizeof(*server_id
));
668 switch (get_client_id(packet
, client_id
)) {
672 log_debug("Discarding %s from %s; "
673 "client identifier missing",
674 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
675 piaddr(packet
->client_addr
));
678 log_error("Error processing %s from %s; "
679 "unable to evaluate Client Identifier",
680 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
681 piaddr(packet
->client_addr
));
685 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
687 log_debug("Discarding %s from %s: "
688 "server identifier missing (CLIENTID %s)",
689 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
690 piaddr(packet
->client_addr
),
691 print_hex_1(client_id
->len
, client_id
->data
, 60));
694 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
695 packet
->options
, NULL
,
696 &global_scope
, oc
, MDL
)) {
697 log_error("Error processing %s from %s; "
698 "unable to evaluate Server Identifier (CLIENTID %s)",
699 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
700 piaddr(packet
->client_addr
),
701 print_hex_1(client_id
->len
, client_id
->data
, 60));
704 if ((server_duid
.len
!= server_id
->len
) ||
705 (memcmp(server_duid
.data
, server_id
->data
, server_duid
.len
) != 0)) {
706 log_debug("Discarding %s from %s; "
707 "not our server identifier "
708 "(CLIENTID %s, SERVERID %s, server DUID %s)",
709 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
710 piaddr(packet
->client_addr
),
711 print_hex_1(client_id
->len
, client_id
->data
, 60),
712 print_hex_2(server_id
->len
, server_id
->data
, 60),
713 print_hex_3(server_duid
.len
, server_duid
.data
, 60));
722 data_string_forget(server_id
, MDL
);
723 data_string_forget(client_id
, MDL
);
729 * Information request validation, defined in RFC 3315, section 15.12:
731 * Servers MUST discard any received Information-request message that
732 * meets any of the following conditions:
734 * - The message includes a Server Identifier option and the DUID in
735 * the option does not match the server's DUID.
737 * - The message includes an IA option.
740 valid_client_info_req(struct packet
*packet
, struct data_string
*server_id
) {
742 struct option_cache
*oc
;
743 struct data_string client_id
;
744 char client_id_str
[80]; /* print_hex_1() uses maximum 60 characters,
745 plus a few more for extra information */
748 memset(server_id
, 0, sizeof(*server_id
));
749 memset(&client_id
, 0, sizeof(client_id
));
752 * Make a string that we can print out to give more
753 * information about the client if we need to.
755 * By RFC 3315, Section 18.1.5 clients SHOULD have a
756 * client-id on an Information-request packet, but it
757 * is not strictly necessary.
759 if (get_client_id(packet
, &client_id
) == ISC_R_SUCCESS
) {
760 snprintf(client_id_str
, sizeof(client_id_str
), " (CLIENTID %s)",
761 print_hex_1(client_id
.len
, client_id
.data
, 60));
762 data_string_forget(&client_id
, MDL
);
764 client_id_str
[0] = '\0';
768 * Required by RFC 3315, section 15.
770 if (packet
->unicast
) {
771 log_debug("Discarding %s from %s; packet sent unicast%s",
772 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
773 piaddr(packet
->client_addr
), client_id_str
);
777 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
779 log_debug("Discarding %s from %s; "
780 "IA_NA option present%s",
781 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
782 piaddr(packet
->client_addr
), client_id_str
);
785 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
787 log_debug("Discarding %s from %s; "
788 "IA_TA option present%s",
789 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
790 piaddr(packet
->client_addr
), client_id_str
);
793 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
795 log_debug("Discarding %s from %s; "
796 "IA_PD option present%s",
797 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
798 piaddr(packet
->client_addr
), client_id_str
);
802 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
804 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
805 packet
->options
, NULL
,
806 &global_scope
, oc
, MDL
)) {
807 log_error("Error processing %s from %s; "
808 "unable to evaluate Server Identifier%s",
809 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
810 piaddr(packet
->client_addr
), client_id_str
);
813 if ((server_duid
.len
!= server_id
->len
) ||
814 (memcmp(server_duid
.data
, server_id
->data
,
815 server_duid
.len
) != 0)) {
816 log_debug("Discarding %s from %s; "
817 "not our server identifier "
818 "(SERVERID %s, server DUID %s)%s",
819 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
820 piaddr(packet
->client_addr
),
821 print_hex_1(server_id
->len
,
822 server_id
->data
, 60),
823 print_hex_2(server_duid
.len
,
824 server_duid
.data
, 60),
835 data_string_forget(server_id
, MDL
);
841 * Options that we want to send, in addition to what was requested
844 static const int required_opts
[] = {
851 static const int required_opts_solicit
[] = {
863 static const int required_opts_agent
[] = {
865 #if defined(RELAY_PORT)
866 D6O_RELAY_SOURCE_PORT
,
871 static const int required_opts_IA
[] = {
876 static const int required_opts_IA_PD
[] = {
881 static const int required_opts_STATUS_CODE
[] = {
886 static const int required_opts_4o6
[] = {
892 static const int unicast_reject_opts
[] = {
901 * Extracts from packet contents an IA_* option, storing the IA structure
902 * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
903 * in enc_opt_state for later lookup and evaluation. The 'offset' indicates
904 * where in the IA_* the DHCPv6 options commence.
907 get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
908 struct data_string
*enc_opt_data
,
909 struct packet
*packet
,
910 struct option_cache
*oc
,
914 * Get the raw data for the encapsulated options.
916 memset(enc_opt_data
, 0, sizeof(*enc_opt_data
));
917 if (!evaluate_option_cache(enc_opt_data
, packet
,
918 NULL
, NULL
, packet
->options
, NULL
,
919 &global_scope
, oc
, MDL
)) {
920 log_error("get_encapsulated_IA_state: "
921 "error evaluating raw option.");
924 if (enc_opt_data
->len
< offset
) {
925 log_error("get_encapsulated_IA_state: raw option too small.");
926 data_string_forget(enc_opt_data
, MDL
);
931 * Now create the option state structure, and pass it to the
932 * function that parses options.
934 *enc_opt_state
= NULL
;
935 if (!option_state_allocate(enc_opt_state
, MDL
)) {
936 log_error("get_encapsulated_IA_state: no memory for options.");
937 data_string_forget(enc_opt_data
, MDL
);
940 if (!parse_option_buffer(*enc_opt_state
,
941 enc_opt_data
->data
+ offset
,
942 enc_opt_data
->len
- offset
,
944 log_error("get_encapsulated_IA_state: error parsing options.");
945 option_state_dereference(enc_opt_state
, MDL
);
946 data_string_forget(enc_opt_data
, MDL
);
954 set_status_code(u_int16_t status_code
, const char *status_message
,
955 struct option_state
*opt_state
)
957 struct data_string d
;
960 memset(&d
, 0, sizeof(d
));
961 d
.len
= sizeof(status_code
) + strlen(status_message
);
962 if (!buffer_allocate(&d
.buffer
, d
.len
, MDL
)) {
963 log_fatal("set_status_code: no memory for status code.");
965 d
.data
= d
.buffer
->data
;
966 putUShort(d
.buffer
->data
, status_code
);
967 memcpy(d
.buffer
->data
+ sizeof(status_code
),
968 status_message
, d
.len
- sizeof(status_code
));
969 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
970 d
.buffer
, (unsigned char *)d
.data
, d
.len
,
971 D6O_STATUS_CODE
, 0)) {
972 log_error("set_status_code: error saving status code.");
977 data_string_forget(&d
, MDL
);
981 void check_pool6_threshold(struct reply_state
*reply
,
982 struct iasubopt
*lease
)
984 struct ipv6_pond
*pond
;
985 isc_uint64_t used
, count
, high_threshold
;
986 int poolhigh
= 0, poollow
= 0;
987 char *shared_name
= "no name";
988 char tmp_addr
[INET6_ADDRSTRLEN
];
990 if ((lease
->ipv6_pool
== NULL
) || (lease
->ipv6_pool
->ipv6_pond
== NULL
))
992 pond
= lease
->ipv6_pool
->ipv6_pond
;
994 /* If the address range is too large to track, just skip all this. */
995 if (pond
->jumbo_range
== 1) {
999 count
= pond
->num_total
;
1000 used
= pond
->num_active
;
1002 /* get network name for logging */
1003 if ((pond
->shared_network
!= NULL
) &&
1004 (pond
->shared_network
->name
!= NULL
)) {
1005 shared_name
= pond
->shared_network
->name
;
1008 /* The logged flag indicates if we have already crossed the high
1009 * threshold and emitted a log message. If it is set we check to
1010 * see if we have re-crossed the low threshold and need to reset
1011 * things. When we cross the high threshold we determine what
1012 * the low threshold is and save it into the low_threshold value.
1013 * When we cross that threshold we reset the logged flag and
1014 * the low_threshold to 0 which allows the high threshold message
1015 * to be emitted once again.
1016 * if we haven't recrossed the boundry we don't need to do anything.
1018 if (pond
->logged
!=0) {
1019 if (used
<= pond
->low_threshold
) {
1020 pond
->low_threshold
= 0;
1022 log_error("Pool threshold reset - shared subnet: %s; "
1023 "address: %s; low threshold %llu/%llu.",
1025 inet_ntop(AF_INET6
, &lease
->addr
,
1026 tmp_addr
, sizeof(tmp_addr
)),
1027 (long long unsigned)(used
),
1028 (long long unsigned)(count
));
1033 /* find the high threshold */
1034 if (get_option_int(&poolhigh
, &server_universe
, reply
->packet
, NULL
,
1035 NULL
, reply
->packet
->options
, reply
->opt_state
,
1036 reply
->opt_state
, &lease
->scope
,
1037 SV_LOG_THRESHOLD_HIGH
, MDL
) == 0) {
1038 /* no threshold bail out */
1042 /* We do have a threshold for this pool, see if its valid */
1043 if ((poolhigh
<= 0) || (poolhigh
> 100)) {
1048 /* we have a valid value, have we exceeded it */
1049 high_threshold
= FIND_POND6_PERCENT(count
, poolhigh
);
1050 if (used
< high_threshold
) {
1051 /* nope, no more to do */
1055 /* we've exceeded it, output a message */
1056 log_error("Pool threshold exceeded - shared subnet: %s; "
1057 "address: %s; high threshold %d%% %llu/%llu.",
1059 inet_ntop(AF_INET6
, &lease
->addr
, tmp_addr
, sizeof(tmp_addr
)),
1060 poolhigh
, (long long unsigned)(used
),
1061 (long long unsigned)(count
));
1063 /* handle the low threshold now, if we don't
1064 * have one we default to 0. */
1065 if ((get_option_int(&poollow
, &server_universe
, reply
->packet
, NULL
,
1066 NULL
, reply
->packet
->options
, reply
->opt_state
,
1067 reply
->opt_state
, &lease
->scope
,
1068 SV_LOG_THRESHOLD_LOW
, MDL
) == 0) ||
1074 * If the low theshold is higher than the high threshold we continue to log
1075 * If it isn't then we set the flag saying we already logged and determine
1076 * what the reset threshold is.
1078 if (poollow
< poolhigh
) {
1080 pond
->low_threshold
= FIND_POND6_PERCENT(count
, poollow
);
1085 * We have a set of operations we do to set up the reply packet, which
1086 * is the same for many message types.
1089 start_reply(struct packet
*packet
,
1090 const struct data_string
*client_id
,
1091 const struct data_string
*server_id
,
1092 struct option_state
**opt_state
,
1093 struct dhcpv6_packet
*reply
)
1095 struct option_cache
*oc
;
1096 const unsigned char *server_id_data
;
1100 * Build our option state for reply.
1103 if (!option_state_allocate(opt_state
, MDL
)) {
1104 log_error("start_reply: no memory for option_state.");
1107 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1108 packet
->options
, *opt_state
,
1109 &global_scope
, root_group
, NULL
, NULL
);
1112 * A small bit of special handling for Solicit messages.
1114 * We could move the logic into a flag, but for now just check
1117 if (packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
1118 reply
->msg_type
= DHCPV6_ADVERTISE
;
1122 * - this message type supports rapid commit (Solicit), and
1123 * - the server is configured to supply a rapid commit, and
1124 * - the client requests a rapid commit,
1125 * Then we add a rapid commit option, and send Reply (instead
1128 oc
= lookup_option(&dhcpv6_universe
,
1129 *opt_state
, D6O_RAPID_COMMIT
);
1131 oc
= lookup_option(&dhcpv6_universe
,
1132 packet
->options
, D6O_RAPID_COMMIT
);
1134 /* Rapid-commit in action. */
1135 reply
->msg_type
= DHCPV6_REPLY
;
1137 /* Don't want a rapid-commit in advertise. */
1138 delete_option(&dhcpv6_universe
,
1139 *opt_state
, D6O_RAPID_COMMIT
);
1143 reply
->msg_type
= DHCPV6_REPLY
;
1144 /* Delete the rapid-commit from the sent options. */
1145 oc
= lookup_option(&dhcpv6_universe
,
1146 *opt_state
, D6O_RAPID_COMMIT
);
1148 delete_option(&dhcpv6_universe
,
1149 *opt_state
, D6O_RAPID_COMMIT
);
1154 * Use the client's transaction identifier for the reply.
1156 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
1157 sizeof(reply
->transaction_id
));
1160 * RFC 3315, section 18.2 says we need server identifier and
1161 * client identifier.
1163 * If the server ID is defined via the configuration file, then
1164 * it will already be present in the option state at this point,
1165 * so we don't need to set it.
1167 * If we have a server ID passed in from the caller,
1168 * use that, otherwise use the global DUID.
1170 oc
= lookup_option(&dhcpv6_universe
, *opt_state
, D6O_SERVERID
);
1172 if (server_id
== NULL
) {
1173 server_id_data
= server_duid
.data
;
1174 server_id_len
= server_duid
.len
;
1176 server_id_data
= server_id
->data
;
1177 server_id_len
= server_id
->len
;
1179 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1180 NULL
, (unsigned char *)server_id_data
,
1181 server_id_len
, D6O_SERVERID
, 0)) {
1182 log_error("start_reply: "
1183 "error saving server identifier.");
1188 if (client_id
->buffer
!= NULL
) {
1189 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1191 (unsigned char *)client_id
->data
,
1194 log_error("start_reply: error saving "
1195 "client identifier.");
1201 * If the client accepts reconfiguration, let it know that we
1204 * Note: we don't actually do this yet, but DOCSIS requires we
1207 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
1210 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1211 NULL
, (unsigned char *)"", 0,
1212 D6O_RECONF_ACCEPT
, 0)) {
1213 log_error("start_reply: "
1214 "error saving RECONF_ACCEPT option.");
1215 option_state_dereference(opt_state
, MDL
);
1224 * Try to get the IPv6 address the client asked for from the
1227 * addr is the result (should be a pointer to NULL on entry)
1228 * pool is the pool to search in
1229 * requested_addr is the address the client wants
1232 try_client_v6_address(struct iasubopt
**addr
,
1233 struct ipv6_pool
*pool
,
1234 const struct data_string
*requested_addr
)
1236 struct in6_addr tmp_addr
;
1237 isc_result_t result
;
1239 if (requested_addr
->len
< sizeof(tmp_addr
)) {
1240 return DHCP_R_INVALIDARG
;
1242 memcpy(&tmp_addr
, requested_addr
->data
, sizeof(tmp_addr
));
1243 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
)) {
1244 return ISC_R_FAILURE
;
1248 * The address is not covered by this (or possibly any) dynamic
1251 if (!ipv6_in_pool(&tmp_addr
, pool
)) {
1252 return ISC_R_ADDRNOTAVAIL
;
1255 if (lease6_exists(pool
, &tmp_addr
)) {
1256 return ISC_R_ADDRINUSE
;
1259 result
= iasubopt_allocate(addr
, MDL
);
1260 if (result
!= ISC_R_SUCCESS
) {
1263 (*addr
)->addr
= tmp_addr
;
1266 /* Default is soft binding for 2 minutes. */
1267 result
= add_lease6(pool
, *addr
, cur_time
+ 120);
1268 if (result
!= ISC_R_SUCCESS
) {
1269 iasubopt_dereference(addr
, MDL
);
1276 * \brief Get an IPv6 address for the client.
1278 * Attempt to find a usable address for the client. We walk through
1279 * the ponds checking for permit and deny then through the pools
1280 * seeing if they have an available address.
1282 * \param reply = the state structure for the current work on this request
1283 * if we create a lease we return it using reply->lease
1286 * ISC_R_SUCCESS = we were able to find an address and are returning a
1287 * pointer to the lease
1288 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1289 * is probabalistic. We don't exhaustively try the
1290 * address range, instead we hash the duid and if
1291 * the address derived from the hash is in use we
1292 * hash the address. After a number of failures we
1293 * conclude the pool is basically full.
1296 pick_v6_address(struct reply_state
*reply
)
1298 struct ipv6_pool
*p
= NULL
;
1299 struct ipv6_pond
*pond
;
1302 unsigned int attempts
;
1303 char tmp_buf
[INET6_ADDRSTRLEN
];
1304 struct iasubopt
**addr
= &reply
->lease
;
1305 isc_uint64_t total
= 0;
1306 isc_uint64_t active
= 0;
1307 isc_uint64_t abandoned
= 0;
1308 int jumbo_range
= 0;
1309 char *shared_name
= (reply
->shared
->name
?
1310 reply
->shared
->name
: "(no name)");
1313 * Do a quick walk through of the ponds and pools
1314 * to see if we have any NA address pools
1316 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1317 if (pond
->ipv6_pools
== NULL
)
1320 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1321 if (p
->pool_type
== D6O_IA_NA
)
1328 /* If we get here and p is NULL we have no useful pools */
1330 log_debug("Unable to pick client address: "
1331 "no IPv6 pools on this shared network");
1332 return ISC_R_NORESOURCES
;
1336 * We have at least one pool that could provide an address
1337 * Now we walk through the ponds and pools again and check
1338 * to see if the client is permitted and if an address is
1341 * Within a given pond we start looking at the last pool we
1342 * allocated from, unless it had a collision trying to allocate
1343 * an address. This will tend to move us into less-filled pools.
1346 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1347 isc_result_t result
= ISC_R_FAILURE
;
1349 if (((pond
->prohibit_list
!= NULL
) &&
1350 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1351 ((pond
->permit_list
!= NULL
) &&
1352 (!permitted(reply
->packet
, pond
->permit_list
))))
1356 /* If pond is EUI-64 but client duid isn't a valid EUI-64
1357 * id, then skip this pond */
1358 if (pond
->use_eui_64
&&
1359 !valid_eui_64_duid(&reply
->ia
->iaid_duid
, IAID_LEN
)) {
1364 start_pool
= pond
->last_ipv6_pool
;
1367 p
= pond
->ipv6_pools
[i
];
1368 if (p
->pool_type
== D6O_IA_NA
) {
1370 if (pond
->use_eui_64
) {
1372 create_lease6_eui_64(p
, addr
,
1373 &reply
->ia
->iaid_duid
,
1380 create_lease6(p
, addr
, &attempts
,
1381 &reply
->ia
->iaid_duid
,
1386 if (result
== ISC_R_SUCCESS
) {
1388 * Record the pool used (or next one if
1389 * there was a collision).
1393 if (pond
->ipv6_pools
[i
]
1399 pond
->last_ipv6_pool
= i
;
1401 log_debug("Picking pool address %s",
1404 tmp_buf
, sizeof(tmp_buf
)));
1405 return (ISC_R_SUCCESS
);
1410 if (pond
->ipv6_pools
[i
] == NULL
) {
1413 } while (i
!= start_pool
);
1415 if (result
== ISC_R_NORESOURCES
) {
1416 jumbo_range
+= pond
->jumbo_range
;
1417 total
+= pond
->num_total
;
1418 active
+= pond
->num_active
;
1419 abandoned
+= pond
->num_abandoned
;
1424 * If we failed to pick an IPv6 address from any of the subnets.
1425 * Presumably that means we have no addresses for the client.
1427 if (jumbo_range
!= 0) {
1428 log_debug("Unable to pick client address: "
1429 "no addresses available - shared network %s: "
1430 " 2^64-1 < total, %llu active, %llu abandoned",
1431 shared_name
, (long long unsigned)(active
- abandoned
),
1432 (long long unsigned)(abandoned
));
1434 log_debug("Unable to pick client address: "
1435 "no addresses available - shared network %s: "
1436 "%llu total, %llu active, %llu abandoned",
1437 shared_name
, (long long unsigned)(total
),
1438 (long long unsigned)(active
- abandoned
),
1439 (long long unsigned)(abandoned
));
1442 return ISC_R_NORESOURCES
;
1446 * Try to get the IPv6 prefix the client asked for from the
1449 * pref is the result (should be a pointer to NULL on entry)
1450 * pool is the prefix pool to search in
1451 * requested_pref is the address the client wants
1454 try_client_v6_prefix(struct iasubopt
**pref
,
1455 struct ipv6_pool
*pool
,
1456 const struct data_string
*requested_pref
)
1459 struct in6_addr tmp_pref
;
1461 isc_result_t result
;
1463 if (requested_pref
->len
< sizeof(tmp_plen
) + sizeof(tmp_pref
)) {
1464 return DHCP_R_INVALIDARG
;
1467 tmp_plen
= (int) requested_pref
->data
[0];
1468 if ((tmp_plen
< 3) || (tmp_plen
> 128)) {
1469 return ISC_R_FAILURE
;
1472 memcpy(&tmp_pref
, requested_pref
->data
+ 1, sizeof(tmp_pref
));
1473 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref
)) {
1474 return ISC_R_FAILURE
;
1478 memcpy(&ia
.iabuf
, &tmp_pref
, 16);
1479 if (!is_cidr_mask_valid(&ia
, (int) tmp_plen
)) {
1480 return ISC_R_FAILURE
;
1483 if (!ipv6_in_pool(&tmp_pref
, pool
) ||
1484 ((int)tmp_plen
!= pool
->units
)) {
1485 return ISC_R_ADDRNOTAVAIL
;
1488 if (prefix6_exists(pool
, &tmp_pref
, tmp_plen
)) {
1489 return ISC_R_ADDRINUSE
;
1492 result
= iasubopt_allocate(pref
, MDL
);
1493 if (result
!= ISC_R_SUCCESS
) {
1497 (*pref
)->addr
= tmp_pref
;
1498 (*pref
)->plen
= tmp_plen
;
1500 /* Default is soft binding for 2 minutes. */
1501 result
= add_lease6(pool
, *pref
, cur_time
+ 120);
1502 if (result
!= ISC_R_SUCCESS
) {
1503 iasubopt_dereference(pref
, MDL
);
1511 * \brief Get an IPv6 prefix for the client.
1513 * Attempt to find a usable prefix for the client. Based upon the prefix
1514 * length mode and the plen supplied by the client (if one), we make one
1515 * or more calls to pick_v6_prefix_helper() to find a prefix as follows:
1517 * PLM_IGNORE or client specifies a plen of zero, use the first available
1518 * prefix regardless of it's length.
1520 * PLM_PREFER – look for an exact match to client's plen first, if none
1521 * found, use the first available prefix of any length
1523 * PLM_EXACT – look for an exact match first, if none found then fail. This
1524 * is the default behavior.
1526 * PLM_MAXIMUM - look for an exact match first, then the first available whose
1527 * prefix length is less than client's plen, otherwise fail.
1529 * PLM_MINIMUM - look for an exact match first, then the first available whose
1530 * prefix length is greater than client's plen, otherwise fail.
1532 * Note that the selection mode is configurable at the global scope only via
1535 * \param reply = the state structure for the current work on this request
1536 * if we create a lease we return it using reply->lease
1539 * ISC_R_SUCCESS = we were able to find an prefix and are returning a
1540 * pointer to the lease
1541 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1542 * is probabalistic. We don't exhaustively try the
1543 * address range, instead we hash the duid and if
1544 * the address derived from the hash is in use we
1545 * hash the address. After a number of failures we
1546 * conclude the pool is basically full.
1549 pick_v6_prefix(struct reply_state
*reply
) {
1550 struct ipv6_pool
*p
= NULL
;
1551 struct ipv6_pond
*pond
;
1553 isc_result_t result
;
1556 * Do a quick walk through of the ponds and pools
1557 * to see if we have any prefix pools
1559 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1560 if (pond
->ipv6_pools
== NULL
)
1563 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1564 if (p
->pool_type
== D6O_IA_PD
)
1571 /* If we get here and p is NULL we have no useful pools */
1573 log_debug("Unable to pick client prefix: "
1574 "no IPv6 pools on this shared network");
1575 return ISC_R_NORESOURCES
;
1578 if (reply
->preflen
<= 0) {
1579 /* If we didn't get a plen (-1) or client plen is 0, then just
1580 * select first available (same as PLM_INGORE) */
1581 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1583 switch (prefix_length_mode
) {
1585 /* First we look for an exact match, if not found
1586 * then first available */
1587 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1588 if (result
!= ISC_R_SUCCESS
) {
1589 result
= pick_v6_prefix_helper(reply
,
1595 /* Match exactly or fail */
1596 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1601 /* First we look for an exact match, if not found
1602 * then first available by mode */
1603 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1604 if (result
!= ISC_R_SUCCESS
) {
1605 result
= pick_v6_prefix_helper(reply
,
1606 prefix_length_mode
);
1611 /* First available */
1612 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1617 if (result
== ISC_R_SUCCESS
) {
1618 char tmp_buf
[INET6_ADDRSTRLEN
];
1620 log_debug("Picking pool prefix %s/%u",
1621 inet_ntop(AF_INET6
, &(reply
->lease
->addr
),
1622 tmp_buf
, sizeof(tmp_buf
)),
1623 (unsigned)(reply
->lease
->plen
));
1624 return (ISC_R_SUCCESS
);
1628 * If we failed to pick an IPv6 prefix
1629 * Presumably that means we have no prefixes for the client.
1631 log_debug("Unable to pick client prefix: no prefixes available");
1632 return ISC_R_NORESOURCES
;
1637 * \brief Get an IPv6 prefix for the client based upon selection mode.
1639 * We walk through the ponds checking for permit and deny. If a pond is
1640 * permissable to use, loop through its PD pools checking prefix lengths
1641 * against the client plen based on the prefix length mode, looking for
1642 * available prefixes.
1644 * \param reply = the state structure for the current work on this request
1645 * if we create a lease we return it using reply->lease
1646 * \prefix_mode = selection mode to use
1649 * ISC_R_SUCCESS = we were able to find a prefix and are returning a
1650 * pointer to the lease
1651 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1652 * is probabalistic. We don't exhaustively try the
1653 * address range, instead we hash the duid and if
1654 * the address derived from the hash is in use we
1655 * hash the address. After a number of failures we
1656 * conclude the pool is basically full.
1659 pick_v6_prefix_helper(struct reply_state
*reply
, int prefix_mode
) {
1660 struct ipv6_pool
*p
= NULL
;
1661 struct ipv6_pond
*pond
;
1663 unsigned int attempts
;
1664 struct iasubopt
**pref
= &reply
->lease
;
1666 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1667 if (((pond
->prohibit_list
!= NULL
) &&
1668 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1669 ((pond
->permit_list
!= NULL
) &&
1670 (!permitted(reply
->packet
, pond
->permit_list
))))
1673 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1674 if ((p
->pool_type
== D6O_IA_PD
) &&
1675 (eval_prefix_mode(p
->units
, reply
->preflen
,
1676 prefix_mode
) == 1) &&
1677 (create_prefix6(p
, pref
, &attempts
,
1678 &reply
->ia
->iaid_duid
,
1679 cur_time
+ 120) == ISC_R_SUCCESS
)) {
1680 return (ISC_R_SUCCESS
);
1685 return ISC_R_NORESOURCES
;
1690 * \brief Test a prefix length against another based on prefix length mode
1692 * \param len - prefix length to test
1693 * \param preflen - preferred prefix length against which to test
1694 * \param prefix_mode - prefix selection mode with which to test
1696 * Note that the case of preferred length of 0 is not short-cut here as it
1697 * is assumed to be done at a higher level.
1699 * \return 1 if the given length is usable based upon mode and a preferred
1703 eval_prefix_mode(int len
, int preflen
, int prefix_mode
) {
1705 switch (prefix_mode
) {
1707 use_it
= (len
== preflen
);
1710 /* they asked for a prefix length no "shorter" than preflen */
1711 use_it
= (len
>= preflen
);
1714 /* they asked for a prefix length no "longer" than preflen */
1715 use_it
= (len
<= preflen
);
1718 /* otherwise use it */
1726 *! \file server/dhcpv6.c
1728 * \brief construct a reply containing information about a client's lease
1730 * lease_to_client() is called from several messages to construct a
1731 * reply that contains all that we know about the client's correct lease
1732 * (or projected lease).
1734 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1735 * send what we "may" give them on a request.
1737 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1738 * the client should really use).
1740 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1741 * Rebind out any "wrong" addresses the client sends. This means we send
1742 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1743 * possibly send the address with zeroed lifetimes.
1745 * Information-Request - No binding.
1747 * The basic structure is to traverse the client-supplied data first, and
1748 * validate and echo back any contents that can be. If the client-supplied
1749 * data does not error out (on renew/rebind as above), but we did not send
1750 * any addresses, attempt to allocate one.
1752 * At the end of the this function we call commit_leases_timed() to
1753 * fsync and rotate the file as necessary. commit_leases_timed() will
1754 * check that we have written at least one lease to the file and that
1755 * some time has passed before doing any fsync or file rewrite so we
1756 * don't bother tracking if we did a write_ia during this function.
1758 /* TODO: look at client hints for lease times */
1761 lease_to_client(struct data_string
*reply_ret
,
1762 struct packet
*packet
,
1763 const struct data_string
*client_id
,
1764 const struct data_string
*server_id
)
1766 static struct reply_state reply
;
1767 struct option_cache
*oc
;
1768 struct data_string packet_oro
;
1771 memset(&packet_oro
, 0, sizeof(packet_oro
));
1773 /* Locate the client. */
1774 if (shared_network_from_packet6(&reply
.shared
,
1775 packet
) != ISC_R_SUCCESS
)
1779 * Initialize the reply.
1781 packet_reference(&reply
.packet
, packet
, MDL
);
1782 data_string_copy(&reply
.client_id
, client_id
, MDL
);
1784 if (!start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
1788 /* Set the write cursor to just past the reply header. */
1789 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1792 * Get the ORO from the packet, if any.
1794 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ORO
);
1796 if (!evaluate_option_cache(&packet_oro
, packet
,
1798 packet
->options
, NULL
,
1799 &global_scope
, oc
, MDL
)) {
1800 log_error("lease_to_client: error evaluating ORO.");
1806 * Find a host record that matches the packet, if any, and is
1807 * valid for the shared network the client is on.
1809 if (find_hosts6(&reply
.host
, packet
, client_id
, MDL
)) {
1811 seek_shared_host(&reply
.host
, reply
.shared
);
1814 /* Process the client supplied IA's onto the reply buffer. */
1816 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
1818 for (; oc
!= NULL
; oc
= oc
->next
) {
1819 isc_result_t status
;
1821 /* Start counting resources (addresses) offered. */
1822 reply
.client_resources
= 0;
1823 reply
.resources_included
= ISC_FALSE
;
1825 status
= reply_process_ia_na(&reply
, oc
);
1828 * We continue to try other IA's whether we can address
1829 * this one or not. Any other result is an immediate fail.
1831 if ((status
!= ISC_R_SUCCESS
) &&
1832 (status
!= ISC_R_NORESOURCES
))
1835 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
1836 for (; oc
!= NULL
; oc
= oc
->next
) {
1837 isc_result_t status
;
1839 /* Start counting resources (addresses) offered. */
1840 reply
.client_resources
= 0;
1841 reply
.resources_included
= ISC_FALSE
;
1843 status
= reply_process_ia_ta(&reply
, oc
);
1846 * We continue to try other IA's whether we can address
1847 * this one or not. Any other result is an immediate fail.
1849 if ((status
!= ISC_R_SUCCESS
) &&
1850 (status
!= ISC_R_NORESOURCES
))
1854 /* Same for IA_PD's. */
1856 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
1857 for (; oc
!= NULL
; oc
= oc
->next
) {
1858 isc_result_t status
;
1860 /* Start counting resources (prefixes) offered. */
1861 reply
.client_resources
= 0;
1862 reply
.resources_included
= ISC_FALSE
;
1864 status
= reply_process_ia_pd(&reply
, oc
);
1867 * We continue to try other IA_PD's whether we can address
1868 * this one or not. Any other result is an immediate fail.
1870 if ((status
!= ISC_R_SUCCESS
) &&
1871 (status
!= ISC_R_NORESOURCES
))
1876 * Make no reply if we gave no resources and is not
1877 * for Information-Request.
1879 if ((reply
.ia_count
== 0) && (reply
.pd_count
== 0)) {
1880 if (reply
.packet
->dhcpv6_msg_type
!=
1881 DHCPV6_INFORMATION_REQUEST
)
1885 * Because we only execute statements on a per-IA basis,
1886 * we need to execute statements in any non-IA reply to
1887 * source configuration.
1889 execute_statements_in_scope(NULL
, reply
.packet
, NULL
, NULL
,
1890 reply
.packet
->options
,
1891 reply
.opt_state
, &global_scope
,
1892 reply
.shared
->group
, root_group
,
1895 /* Execute statements from class scopes. */
1896 for (i
= reply
.packet
->class_count
; i
> 0; i
--) {
1897 execute_statements_in_scope(NULL
, reply
.packet
,
1899 reply
.packet
->options
,
1902 reply
.packet
->classes
[i
- 1]->group
,
1903 reply
.shared
->group
, NULL
);
1906 /* Bring in any configuration from a host record. */
1907 if (reply
.host
!= NULL
)
1908 execute_statements_in_scope(NULL
, reply
.packet
,
1910 reply
.packet
->options
,
1914 reply
.shared
->group
, NULL
);
1918 * RFC3315 section 17.2.2 (Solicit):
1920 * If the server will not assign any addresses to any IAs in a
1921 * subsequent Request from the client, the server MUST send an
1922 * Advertise message to the client that includes only a Status
1923 * Code option with code NoAddrsAvail and a status message for
1924 * the user, a Server Identifier option with the server's DUID,
1925 * and a Client Identifier option with the client's DUID.
1927 * This has been updated by an errata such that the server
1928 * can always send an IA.
1930 * Section 18.2.1 (Request):
1932 * If the server cannot assign any addresses to an IA in the
1933 * message from the client, the server MUST include the IA in
1934 * the Reply message with no addresses in the IA and a Status
1935 * Code option in the IA containing status code NoAddrsAvail.
1937 * Section 18.1.8 (Client Behavior):
1939 * Leave unchanged any information about addresses the client has
1940 * recorded in the IA but that were not included in the IA from
1942 * Sends a Renew/Rebind if the IA is not in the Reply message.
1946 * Having stored the client's IA's, store any options that
1947 * will fit in the remaining space.
1949 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+ reply
.cursor
,
1950 sizeof(reply
.buf
) - reply
.cursor
,
1951 reply
.opt_state
, reply
.packet
,
1952 required_opts_solicit
,
1955 /* Return our reply to the caller. */
1956 reply_ret
->len
= reply
.cursor
;
1957 reply_ret
->buffer
= NULL
;
1958 if (!buffer_allocate(&reply_ret
->buffer
, reply
.cursor
, MDL
)) {
1959 log_fatal("No memory to store Reply.");
1961 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
, reply
.cursor
);
1962 reply_ret
->data
= reply_ret
->buffer
->data
;
1964 /* If appropriate commit and rotate the lease file */
1965 (void) commit_leases_timed();
1969 if (reply
.shared
!= NULL
)
1970 shared_network_dereference(&reply
.shared
, MDL
);
1971 if (reply
.host
!= NULL
)
1972 host_dereference(&reply
.host
, MDL
);
1973 if (reply
.opt_state
!= NULL
)
1974 option_state_dereference(&reply
.opt_state
, MDL
);
1975 if (reply
.packet
!= NULL
)
1976 packet_dereference(&reply
.packet
, MDL
);
1977 if (reply
.client_id
.data
!= NULL
)
1978 data_string_forget(&reply
.client_id
, MDL
);
1979 if (packet_oro
.buffer
!= NULL
)
1980 data_string_forget(&packet_oro
, MDL
);
1981 reply
.renew
= reply
.rebind
= reply
.min_prefer
= reply
.min_valid
= 0;
1985 /* Process a client-supplied IA_NA. This may append options to the tail of
1986 * the reply packet being built in the reply_state structure.
1989 reply_process_ia_na(struct reply_state
*reply
, struct option_cache
*ia
) {
1990 isc_result_t status
= ISC_R_SUCCESS
;
1993 struct option_state
*packet_ia
;
1994 struct option_cache
*oc
;
1995 struct data_string ia_data
, data
;
1997 /* Initialize values that will get cleaned up on return. */
1999 memset(&ia_data
, 0, sizeof(ia_data
));
2000 memset(&data
, 0, sizeof(data
));
2002 * Note that find_client_address() may set reply->lease.
2005 /* Make sure there is at least room for the header. */
2006 if ((reply
->cursor
+ IA_NA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2007 log_error("reply_process_ia_na: Reply too long for IA.");
2008 return ISC_R_NOSPACE
;
2012 /* Fetch the IA_NA contents. */
2013 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2014 ia
, IA_NA_OFFSET
)) {
2015 log_error("reply_process_ia_na: error evaluating ia");
2016 status
= ISC_R_FAILURE
;
2020 /* Extract IA_NA header contents. */
2021 iaid
= getULong(ia_data
.data
);
2022 reply
->renew
= getULong(ia_data
.data
+ 4);
2023 reply
->rebind
= getULong(ia_data
.data
+ 8);
2025 /* Create an IA_NA structure. */
2026 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2027 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2028 log_error("reply_process_ia_na: no memory for ia.");
2029 status
= ISC_R_NOMEMORY
;
2032 reply
->ia
->ia_type
= D6O_IA_NA
;
2034 /* Cache pre-existing IA, if any. */
2035 ia_hash_lookup(&reply
->old_ia
, ia_na_active
,
2036 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2037 reply
->ia
->iaid_duid
.len
, MDL
);
2040 * Create an option cache to carry the IA_NA option contents, and
2041 * execute any user-supplied values into it.
2043 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2044 status
= ISC_R_NOMEMORY
;
2048 /* Check & cache the fixed host record. */
2049 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_addr
!= NULL
)) {
2050 struct iaddr tmp_addr
;
2052 if (!evaluate_option_cache(&reply
->fixed
, NULL
, NULL
, NULL
,
2053 NULL
, NULL
, &global_scope
,
2054 reply
->host
->fixed_addr
, MDL
)) {
2055 log_error("reply_process_ia_na: unable to evaluate "
2057 status
= ISC_R_FAILURE
;
2061 if (reply
->fixed
.len
< 16) {
2062 log_error("reply_process_ia_na: invalid fixed address.");
2063 status
= DHCP_R_INVALIDARG
;
2067 /* Find the static lease's subnet. */
2069 memcpy(tmp_addr
.iabuf
, reply
->fixed
.data
, 16);
2071 if (find_grouped_subnet(&reply
->subnet
, reply
->shared
,
2072 tmp_addr
, MDL
) == 0)
2073 log_fatal("Impossible condition at %s:%d.", MDL
);
2075 reply
->static_lease
= ISC_TRUE
;
2077 reply
->static_lease
= ISC_FALSE
;
2080 * Save the cursor position at the start of the IA, so we can
2081 * set length and adjust t1/t2 values later. We write a temporary
2082 * header out now just in case we decide to adjust the packet
2083 * within sub-process functions.
2085 ia_cursor
= reply
->cursor
;
2087 /* Initialize the IA_NA header. First the code. */
2088 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_NA
);
2091 /* Then option length. */
2092 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
2095 /* Then IA_NA header contents; IAID. */
2096 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2099 /* We store the client's t1 for now, and may over-ride it later. */
2100 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
2103 /* We store the client's t2 for now, and may over-ride it later. */
2104 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
2108 * For each address in this IA_NA, decide what to do about it.
2112 * The client leaves unchanged any information about addresses
2113 * it has recorded but are not included ("cancel/break" below).
2114 * A not included IA ("cleanup" below) could give a Renew/Rebind.
2116 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2117 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
2118 reply
->client_valid
= reply
->client_prefer
= 0;
2119 for (; oc
!= NULL
; oc
= oc
->next
) {
2120 status
= reply_process_addr(reply
, oc
);
2123 * Canceled means we did not allocate addresses to the
2124 * client, but we're "done" with this IA - we set a status
2125 * code. So transmit this reply, e.g., move on to the next
2128 if (status
== ISC_R_CANCELED
)
2131 if ((status
!= ISC_R_SUCCESS
) &&
2132 (status
!= ISC_R_ADDRINUSE
) &&
2133 (status
!= ISC_R_ADDRNOTAVAIL
))
2140 * If we fell through the above and never gave the client
2141 * an address, give it one now.
2143 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
2144 status
= find_client_address(reply
);
2146 if (status
== ISC_R_NORESOURCES
) {
2147 switch (reply
->packet
->dhcpv6_msg_type
) {
2148 case DHCPV6_SOLICIT
:
2150 * No address for any IA is handled
2155 case DHCPV6_REQUEST
:
2156 /* Section 18.2.1 (Request):
2158 * If the server cannot assign any addresses to
2159 * an IA in the message from the client, the
2160 * server MUST include the IA in the Reply
2161 * message with no addresses in the IA and a
2162 * Status Code option in the IA containing
2163 * status code NoAddrsAvail.
2165 option_state_dereference(&reply
->reply_ia
, MDL
);
2166 if (!option_state_allocate(&reply
->reply_ia
,
2169 log_error("reply_process_ia_na: No "
2170 "memory for option state "
2172 status
= ISC_R_NOMEMORY
;
2176 if (!set_status_code(STATUS_NoAddrsAvail
,
2177 "No addresses available "
2178 "for this interface.",
2180 log_error("reply_process_ia_na: Unable "
2181 "to set NoAddrsAvail status "
2183 status
= ISC_R_FAILURE
;
2187 status
= ISC_R_SUCCESS
;
2192 * RFC 3315 does not tell us to emit a status
2193 * code in this condition, or anything else.
2195 * If we included non-allocated addresses
2196 * (zeroed lifetimes) in an IA, then the client
2197 * will deconfigure them.
2199 * So we want to include the IA even if we
2200 * can't give it a new address if it includes
2201 * zeroed lifetime addresses.
2203 * We don't want to include the IA if we
2204 * provide zero addresses including zeroed
2207 if (reply
->resources_included
)
2208 status
= ISC_R_SUCCESS
;
2215 if (status
!= ISC_R_SUCCESS
)
2220 * yes, goto's aren't the best but we also want to avoid extra
2223 if (status
== ISC_R_CANCELED
) {
2224 /* We're replying with a status code so we still need to
2225 * write it out in wire-format to the outbound buffer */
2226 write_to_packet(reply
, ia_cursor
);
2231 * Handle static leases, we always log stuff and if it's
2232 * a hard binding we run any commit statements that we have
2234 if (reply
->static_lease
) {
2235 char tmp_addr
[INET6_ADDRSTRLEN
];
2236 log_info("%s NA: address %s to client with duid %s iaid = %d "
2238 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2239 inet_ntop(AF_INET6
, reply
->fixed
.data
, tmp_addr
,
2241 print_hex_1(reply
->client_id
.len
,
2242 reply
->client_id
.data
, 60),
2245 /* Write the lease out in wire-format to the outbound buffer */
2246 write_to_packet(reply
, ia_cursor
);
2248 /* Performs DDNS updates if we're configured to do them */
2249 ddns_update_static6(reply
);
2251 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
2252 (reply
->on_star
.on_commit
!= NULL
)) {
2253 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
2254 reply
->packet
->options
,
2255 reply
->opt_state
, NULL
,
2256 reply
->on_star
.on_commit
, NULL
);
2257 executable_statement_dereference
2258 (&reply
->on_star
.on_commit
, MDL
);
2264 * If we have any addresses log what we are doing.
2266 if (reply
->ia
->num_iasubopt
!= 0) {
2267 struct iasubopt
*tmp
;
2269 char tmp_addr
[INET6_ADDRSTRLEN
];
2271 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2272 tmp
= reply
->ia
->iasubopt
[i
];
2274 log_info("%s NA: address %s to client with duid %s "
2275 "iaid = %d valid for %u seconds",
2276 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2277 inet_ntop(AF_INET6
, &tmp
->addr
,
2278 tmp_addr
, sizeof(tmp_addr
)),
2279 print_hex_1(reply
->client_id
.len
,
2280 reply
->client_id
.data
, 60),
2286 * If this is not a 'soft' binding, consume the new changes into
2287 * the database (if any have been attached to the ia_na).
2289 * Loop through the assigned dynamic addresses, referencing the
2290 * leases onto this IA_NA rather than any old ones, and updating
2291 * pool timers for each (if any).
2293 * Note that we must do ddns_updates() before we test for lease
2294 * reuse (so we'll know if DNS entries are different). To ensure
2295 * we don't break any configs, we run on_commit statements before
2296 * we do ddns_updates() just in case the former affects the later.
2297 * This is symetrical with v4 logic. We always run on_commit and
2298 * ddns_udpates() whether a lease is reused or renewed.
2300 if ((reply
->ia
->num_iasubopt
!= 0) &&
2301 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
2302 int must_commit
= 0;
2303 struct iasubopt
*tmp
;
2304 struct data_string
*ia_id
;
2307 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2308 tmp
= reply
->ia
->iasubopt
[i
];
2309 if (tmp
->ia
!= NULL
) {
2310 ia_dereference(&tmp
->ia
, MDL
);
2313 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2315 /* If we have anything to do on commit do it now */
2316 if (tmp
->on_star
.on_commit
!= NULL
) {
2317 execute_statements(NULL
, reply
->packet
,
2319 reply
->packet
->options
,
2322 tmp
->on_star
.on_commit
,
2324 executable_statement_dereference
2325 (&tmp
->on_star
.on_commit
, MDL
);
2328 #if defined (NSUPDATE)
2330 /* Perform ddns updates */
2331 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2334 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2336 reply
->packet
->options
,
2340 ddns_updates(reply
->packet
, NULL
, NULL
,
2341 tmp
, NULL
, reply
->opt_state
);
2344 if (!reuse_lease6(reply
, tmp
)) {
2345 /* Commit 'hard' bindings. */
2347 renew_lease6(tmp
->ipv6_pool
, tmp
);
2348 schedule_lease_timeout(tmp
->ipv6_pool
);
2350 /* Do our threshold check. */
2351 check_pool6_threshold(reply
, tmp
);
2355 /* write the IA_NA in wire-format to the outbound buffer */
2356 write_to_packet(reply
, ia_cursor
);
2358 /* Remove any old ia from the hash. */
2359 if (reply
->old_ia
!= NULL
) {
2360 if (!release_on_roam(reply
)) {
2361 ia_id
= &reply
->old_ia
->iaid_duid
;
2362 ia_hash_delete(ia_na_active
,
2363 (unsigned char *)ia_id
->data
,
2367 ia_dereference(&reply
->old_ia
, MDL
);
2370 /* Put new ia into the hash. */
2371 reply
->ia
->cltt
= cur_time
;
2372 ia_id
= &reply
->ia
->iaid_duid
;
2373 ia_hash_add(ia_na_active
, (unsigned char *)ia_id
->data
,
2374 ia_id
->len
, reply
->ia
, MDL
);
2376 /* If we couldn't reuse all of the iasubopts, we
2377 * must update udpate the lease db */
2379 write_ia(reply
->ia
);
2382 /* write the IA_NA in wire-format to the outbound buffer */
2383 write_to_packet(reply
, ia_cursor
);
2384 schedule_lease_timeout_reply(reply
);
2388 if (packet_ia
!= NULL
)
2389 option_state_dereference(&packet_ia
, MDL
);
2390 if (reply
->reply_ia
!= NULL
)
2391 option_state_dereference(&reply
->reply_ia
, MDL
);
2392 if (ia_data
.data
!= NULL
)
2393 data_string_forget(&ia_data
, MDL
);
2394 if (data
.data
!= NULL
)
2395 data_string_forget(&data
, MDL
);
2396 if (reply
->ia
!= NULL
)
2397 ia_dereference(&reply
->ia
, MDL
);
2398 if (reply
->old_ia
!= NULL
)
2399 ia_dereference(&reply
->old_ia
, MDL
);
2400 if (reply
->lease
!= NULL
)
2401 iasubopt_dereference(&reply
->lease
, MDL
);
2402 if (reply
->fixed
.data
!= NULL
)
2403 data_string_forget(&reply
->fixed
, MDL
);
2404 if (reply
->subnet
!= NULL
)
2405 subnet_dereference(&reply
->subnet
, MDL
);
2406 if (reply
->on_star
.on_expiry
!= NULL
)
2407 executable_statement_dereference
2408 (&reply
->on_star
.on_expiry
, MDL
);
2409 if (reply
->on_star
.on_release
!= NULL
)
2410 executable_statement_dereference
2411 (&reply
->on_star
.on_release
, MDL
);
2414 * ISC_R_CANCELED is a status code used by the addr processing to
2415 * indicate we're replying with a status code. This is still a
2416 * success at higher layers.
2418 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2422 * Writes the populated IA_xx in wire format to the reply buffer
2425 write_to_packet(struct reply_state
*reply
, unsigned ia_cursor
) {
2426 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2427 sizeof(reply
->buf
) - reply
->cursor
,
2428 reply
->reply_ia
, reply
->packet
,
2429 (reply
->ia
->ia_type
!= D6O_IA_PD
?
2430 required_opts_IA
: required_opts_IA_PD
),
2433 /* Reset the length of this IA to match what was just written. */
2434 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2435 reply
->cursor
- (ia_cursor
+ 4));
2437 if (reply
->ia
->ia_type
!= D6O_IA_TA
) {
2438 /* Calculate T1/T2 and stuff them in the reply */
2439 set_reply_tee_times(reply
, ia_cursor
);
2444 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
2445 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
2446 * in the event we are replying with a status code and do not wish to process
2447 * more IAADDRs within this IA.
2450 reply_process_addr(struct reply_state
*reply
, struct option_cache
*addr
) {
2451 u_int32_t pref_life
, valid_life
;
2452 struct binding_scope
**scope
;
2453 struct group
*group
;
2454 struct subnet
*subnet
;
2455 struct iaddr tmp_addr
;
2456 struct option_cache
*oc
;
2457 struct data_string iaaddr
, data
;
2458 isc_result_t status
= ISC_R_SUCCESS
;
2460 int invalid_for_eui_64
= 0;
2463 /* Initializes values that will be cleaned up. */
2464 memset(&iaaddr
, 0, sizeof(iaaddr
));
2465 memset(&data
, 0, sizeof(data
));
2466 /* Note that reply->lease may be set by address_is_owned() */
2469 * There is no point trying to process an incoming address if there
2470 * is no room for an outgoing address.
2472 if ((reply
->cursor
+ 28) > sizeof(reply
->buf
)) {
2473 log_error("reply_process_addr: Out of room for address.");
2474 return ISC_R_NOSPACE
;
2477 /* Extract this IAADDR option. */
2478 if (!evaluate_option_cache(&iaaddr
, reply
->packet
, NULL
, NULL
,
2479 reply
->packet
->options
, NULL
, &global_scope
,
2481 (iaaddr
.len
< IAADDR_OFFSET
)) {
2482 log_error("reply_process_addr: error evaluating IAADDR.");
2483 status
= ISC_R_FAILURE
;
2487 /* The first 16 bytes are the IPv6 address. */
2488 pref_life
= getULong(iaaddr
.data
+ 16);
2489 valid_life
= getULong(iaaddr
.data
+ 20);
2491 if ((reply
->client_valid
== 0) ||
2492 (reply
->client_valid
> valid_life
))
2493 reply
->client_valid
= valid_life
;
2495 if ((reply
->client_prefer
== 0) ||
2496 (reply
->client_prefer
> pref_life
))
2497 reply
->client_prefer
= pref_life
;
2500 * Clients may choose to send :: as an address, with the idea to give
2501 * hints about preferred-lifetime or valid-lifetime.
2504 memset(tmp_addr
.iabuf
, 0, 16);
2505 if (!memcmp(iaaddr
.data
, tmp_addr
.iabuf
, 16)) {
2506 /* Status remains success; we just ignore this one. */
2510 /* tmp_addr len remains 16 */
2511 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2514 * Verify that this address is on the client's network.
2516 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
2517 subnet
= subnet
->next_sibling
) {
2518 if (addr_eq(subnet_number(tmp_addr
, subnet
->netmask
),
2525 /* If the requested address falls into an EUI-64 pool, then
2526 * we need to verify if it has EUI-64 duid AND the requested
2527 * address is correct for that duid. If not we treat it just
2528 * like an not-on-link request. */
2529 struct ipv6_pool
* pool
= NULL
;
2530 struct in6_addr
* addr
= (struct in6_addr
*)(iaaddr
.data
);
2531 if ((find_ipv6_pool(&pool
, D6O_IA_NA
, addr
) == ISC_R_SUCCESS
)
2532 && (pool
->ipv6_pond
->use_eui_64
) &&
2533 (!valid_for_eui_64_pool(pool
, &reply
->client_id
, 0, addr
))) {
2534 log_debug ("Requested address: %s,"
2535 " not valid for EUI-64 pool",
2537 invalid_for_eui_64
= 1;
2542 /* Address not found on shared network. */
2544 if ((subnet
== NULL
) || invalid_for_eui_64
) {
2546 if (subnet
== NULL
) {
2548 /* Ignore this address on 'soft' bindings. */
2549 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
2550 /* disable rapid commit */
2551 reply
->buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
2552 delete_option(&dhcpv6_universe
,
2555 /* status remains success */
2560 * RFC3315 section 18.2.1:
2562 * If the server finds that the prefix on one or more IP
2563 * addresses in any IA in the message from the client is not
2564 * appropriate for the link to which the client is connected,
2565 * the server MUST return the IA to the client with a Status
2566 * Code option with the value NotOnLink.
2568 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) {
2569 /* Rewind the IA_NA to empty. */
2570 option_state_dereference(&reply
->reply_ia
, MDL
);
2571 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2572 log_error("reply_process_addr: No memory for "
2573 "option state wipe.");
2574 status
= ISC_R_NOMEMORY
;
2578 /* Append a NotOnLink status code. */
2579 if (!set_status_code(STATUS_NotOnLink
,
2580 "Address not for use on this "
2581 "link.", reply
->reply_ia
)) {
2582 log_error("reply_process_addr: Failure "
2583 "setting status code.");
2584 status
= ISC_R_FAILURE
;
2588 /* Fin (no more IAADDRs). */
2589 status
= ISC_R_CANCELED
;
2594 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2596 * If the server finds that any of the addresses are not
2597 * appropriate for the link to which the client is attached,
2598 * the server returns the address to the client with lifetimes
2601 if ((reply
->packet
->dhcpv6_msg_type
!= DHCPV6_RENEW
) &&
2602 (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
2603 log_error("It is impossible to lease a client that is "
2604 "not sending a solicit, request, renew, or "
2606 status
= ISC_R_FAILURE
;
2610 reply
->send_prefer
= reply
->send_valid
= 0;
2615 /* Verify the address belongs to the client. */
2616 if (!address_is_owned(reply
, &tmp_addr
)) {
2618 * For solicit and request, any addresses included are
2619 * 'requested' addresses. For rebind, we actually have
2620 * no direction on what to do from 3315 section 18.2.4!
2621 * So I think the best bet is to try and give it out, and if
2622 * we can't, zero lifetimes.
2624 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
2625 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
2626 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
2627 status
= reply_process_try_addr(reply
, &tmp_addr
);
2630 * If the address is in use, or isn't in any dynamic
2631 * range, continue as normal. If any other error was
2634 if ((status
!= ISC_R_SUCCESS
) &&
2635 (status
!= ISC_R_ADDRINUSE
) &&
2636 (status
!= ISC_R_ADDRNOTAVAIL
))
2640 * If we didn't honor this lease, for solicit and
2641 * request we simply omit it from our answer. For
2642 * rebind, we send it with zeroed lifetimes.
2644 if (reply
->lease
== NULL
) {
2645 if (reply
->packet
->dhcpv6_msg_type
==
2647 reply
->send_prefer
= 0;
2648 reply
->send_valid
= 0;
2652 /* status remains success - ignore */
2656 * RFC3315 section 18.2.3:
2658 * If the server cannot find a client entry for the IA the
2659 * server returns the IA containing no addresses with a Status
2660 * Code option set to NoBinding in the Reply message.
2662 * On mismatch we (ab)use this pretending we have not the IA
2663 * as soon as we have not an address.
2665 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
2666 /* Rewind the IA_NA to empty. */
2667 option_state_dereference(&reply
->reply_ia
, MDL
);
2668 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2669 log_error("reply_process_addr: No memory for "
2670 "option state wipe.");
2671 status
= ISC_R_NOMEMORY
;
2675 /* Append a NoBinding status code. */
2676 if (!set_status_code(STATUS_NoBinding
,
2677 "Address not bound to this "
2678 "interface.", reply
->reply_ia
)) {
2679 log_error("reply_process_addr: Unable to "
2680 "attach status code.");
2681 status
= ISC_R_FAILURE
;
2685 /* Fin (no more IAADDRs). */
2686 status
= ISC_R_CANCELED
;
2689 log_error("It is impossible to lease a client that is "
2690 "not sending a solicit, request, renew, or "
2692 status
= ISC_R_FAILURE
;
2697 if (reply
->static_lease
) {
2698 if (reply
->host
== NULL
)
2699 log_fatal("Impossible condition at %s:%d.", MDL
);
2701 scope
= &global_scope
;
2702 group
= reply
->subnet
->group
;
2704 if (reply
->lease
== NULL
)
2705 log_fatal("Impossible condition at %s:%d.", MDL
);
2707 scope
= &reply
->lease
->scope
;
2708 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
2712 * If client_resources is nonzero, then the reply_process_is_addressed
2713 * function has executed configuration state into the reply option
2714 * cache. We will use that valid cache to derive configuration for
2715 * whether or not to engage in additional addresses, and similar.
2717 if (reply
->client_resources
!= 0) {
2721 * Does this client have "enough" addresses already? Default
2722 * to one. Everybody gets one, and one should be enough for
2725 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2726 SV_LIMIT_ADDRS_PER_IA
);
2728 if (!evaluate_option_cache(&data
, reply
->packet
,
2730 reply
->packet
->options
,
2734 log_error("reply_process_addr: unable to "
2735 "evaluate addrs-per-ia value.");
2736 status
= ISC_R_FAILURE
;
2740 limit
= getULong(data
.data
);
2741 data_string_forget(&data
, MDL
);
2745 * If we wish to limit the client to a certain number of
2746 * addresses, then omit the address from the reply.
2748 if (reply
->client_resources
>= limit
)
2752 status
= reply_process_is_addressed(reply
, scope
, group
);
2753 if (status
!= ISC_R_SUCCESS
)
2757 status
= reply_process_send_addr(reply
, &tmp_addr
);
2760 if (iaaddr
.data
!= NULL
)
2761 data_string_forget(&iaaddr
, MDL
);
2762 if (data
.data
!= NULL
)
2763 data_string_forget(&data
, MDL
);
2764 if (reply
->lease
!= NULL
)
2765 iasubopt_dereference(&reply
->lease
, MDL
);
2771 * Verify the address belongs to the client. If we've got a host
2772 * record with a fixed address, it has to be the assigned address
2773 * (fault out all else). Otherwise it's a dynamic address, so lookup
2774 * that address and make sure it belongs to this DUID:IAID pair.
2776 static isc_boolean_t
2777 address_is_owned(struct reply_state
*reply
, struct iaddr
*addr
) {
2779 struct ipv6_pond
*pond
;
2782 * This faults out addresses that don't match fixed addresses.
2784 if (reply
->static_lease
) {
2785 if (reply
->fixed
.data
== NULL
)
2786 log_fatal("Impossible condition at %s:%d.", MDL
);
2788 if (memcmp(addr
->iabuf
, reply
->fixed
.data
, 16) == 0)
2794 if ((reply
->old_ia
== NULL
) || (reply
->old_ia
->num_iasubopt
== 0))
2797 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2798 struct iasubopt
*tmp
;
2800 tmp
= reply
->old_ia
->iasubopt
[i
];
2802 if (memcmp(addr
->iabuf
, &tmp
->addr
, 16) == 0) {
2803 if (lease6_usable(tmp
) == ISC_FALSE
) {
2807 pond
= tmp
->ipv6_pool
->ipv6_pond
;
2808 if (((pond
->prohibit_list
!= NULL
) &&
2809 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
2810 ((pond
->permit_list
!= NULL
) &&
2811 (!permitted(reply
->packet
, pond
->permit_list
))))
2814 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
2823 /* Process a client-supplied IA_TA. This may append options to the tail of
2824 * the reply packet being built in the reply_state structure.
2827 reply_process_ia_ta(struct reply_state
*reply
, struct option_cache
*ia
) {
2828 isc_result_t status
= ISC_R_SUCCESS
;
2831 struct option_state
*packet_ia
;
2832 struct option_cache
*oc
;
2833 struct data_string ia_data
, data
;
2834 struct data_string iaaddr
;
2835 u_int32_t pref_life
, valid_life
;
2836 struct iaddr tmp_addr
;
2838 /* Initialize values that will get cleaned up on return. */
2840 memset(&ia_data
, 0, sizeof(ia_data
));
2841 memset(&data
, 0, sizeof(data
));
2842 memset(&iaaddr
, 0, sizeof(iaaddr
));
2844 /* Make sure there is at least room for the header. */
2845 if ((reply
->cursor
+ IA_TA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2846 log_error("reply_process_ia_ta: Reply too long for IA.");
2847 return ISC_R_NOSPACE
;
2851 /* Fetch the IA_TA contents. */
2852 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2853 ia
, IA_TA_OFFSET
)) {
2854 log_error("reply_process_ia_ta: error evaluating ia");
2855 status
= ISC_R_FAILURE
;
2859 /* Extract IA_TA header contents. */
2860 iaid
= getULong(ia_data
.data
);
2862 /* Create an IA_TA structure. */
2863 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2864 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2865 log_error("reply_process_ia_ta: no memory for ia.");
2866 status
= ISC_R_NOMEMORY
;
2869 reply
->ia
->ia_type
= D6O_IA_TA
;
2871 /* Cache pre-existing IA, if any. */
2872 ia_hash_lookup(&reply
->old_ia
, ia_ta_active
,
2873 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2874 reply
->ia
->iaid_duid
.len
, MDL
);
2877 * Create an option cache to carry the IA_TA option contents, and
2878 * execute any user-supplied values into it.
2880 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2881 status
= ISC_R_NOMEMORY
;
2886 * Temporary leases are dynamic by definition.
2888 reply
->static_lease
= ISC_FALSE
;
2891 * Save the cursor position at the start of the IA, so we can
2892 * set length later. We write a temporary
2893 * header out now just in case we decide to adjust the packet
2894 * within sub-process functions.
2896 ia_cursor
= reply
->cursor
;
2898 /* Initialize the IA_TA header. First the code. */
2899 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_TA
);
2902 /* Then option length. */
2903 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x04u
);
2906 /* Then IA_TA header contents; IAID. */
2907 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2911 * Deal with an IAADDR for lifetimes.
2912 * For all or none, process IAADDRs as hints.
2914 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
2915 reply
->client_valid
= reply
->client_prefer
= 0;
2916 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2917 for (; oc
!= NULL
; oc
= oc
->next
) {
2918 memset(&iaaddr
, 0, sizeof(iaaddr
));
2919 if (!evaluate_option_cache(&iaaddr
, reply
->packet
,
2921 reply
->packet
->options
, NULL
,
2922 &global_scope
, oc
, MDL
) ||
2923 (iaaddr
.len
< IAADDR_OFFSET
)) {
2924 log_error("reply_process_ia_ta: error "
2925 "evaluating IAADDR.");
2926 status
= ISC_R_FAILURE
;
2929 /* The first 16 bytes are the IPv6 address. */
2930 pref_life
= getULong(iaaddr
.data
+ 16);
2931 valid_life
= getULong(iaaddr
.data
+ 20);
2933 if ((reply
->client_valid
== 0) ||
2934 (reply
->client_valid
> valid_life
))
2935 reply
->client_valid
= valid_life
;
2937 if ((reply
->client_prefer
== 0) ||
2938 (reply
->client_prefer
> pref_life
))
2939 reply
->client_prefer
= pref_life
;
2941 /* Nothing more if something has failed. */
2942 if (status
== ISC_R_CANCELED
)
2946 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2947 if (!temporary_is_available(reply
, &tmp_addr
))
2949 status
= reply_process_is_addressed(reply
,
2950 &reply
->lease
->scope
,
2951 reply
->lease
->ipv6_pool
->ipv6_pond
->group
);
2952 if (status
!= ISC_R_SUCCESS
)
2954 status
= reply_process_send_addr(reply
, &tmp_addr
);
2955 if (status
!= ISC_R_SUCCESS
)
2957 if (reply
->lease
!= NULL
)
2958 iasubopt_dereference(&reply
->lease
, MDL
);
2962 /* Rewind the IA_TA to empty. */
2963 option_state_dereference(&reply
->reply_ia
, MDL
);
2964 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2965 status
= ISC_R_NOMEMORY
;
2968 status
= ISC_R_CANCELED
;
2969 reply
->client_resources
= 0;
2970 reply
->resources_included
= ISC_FALSE
;
2971 if (reply
->lease
!= NULL
)
2972 iasubopt_dereference(&reply
->lease
, MDL
);
2977 * Give the client temporary addresses.
2979 if (reply
->client_resources
!= 0)
2981 status
= find_client_temporaries(reply
);
2982 if (status
== ISC_R_NORESOURCES
) {
2983 switch (reply
->packet
->dhcpv6_msg_type
) {
2984 case DHCPV6_SOLICIT
:
2986 * No address for any IA is handled
2991 case DHCPV6_REQUEST
:
2992 /* Section 18.2.1 (Request):
2994 * If the server cannot assign any addresses to
2995 * an IA in the message from the client, the
2996 * server MUST include the IA in the Reply
2997 * message with no addresses in the IA and a
2998 * Status Code option in the IA containing
2999 * status code NoAddrsAvail.
3001 option_state_dereference(&reply
->reply_ia
, MDL
);
3002 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
3003 log_error("reply_process_ia_ta: No "
3004 "memory for option state wipe.");
3005 status
= ISC_R_NOMEMORY
;
3009 if (!set_status_code(STATUS_NoAddrsAvail
,
3010 "No addresses available "
3011 "for this interface.",
3013 log_error("reply_process_ia_ta: Unable "
3014 "to set NoAddrsAvail status code.");
3015 status
= ISC_R_FAILURE
;
3019 status
= ISC_R_SUCCESS
;
3024 * We don't want to include the IA if we
3025 * provide zero addresses including zeroed
3028 if (reply
->resources_included
)
3029 status
= ISC_R_SUCCESS
;
3034 } else if (status
!= ISC_R_SUCCESS
)
3040 * yes, goto's aren't the best but we also want to avoid extra
3043 if (status
== ISC_R_CANCELED
) {
3044 /* We're replying with a status code so we still need to
3045 * write it out in wire-format to the outbound buffer */
3046 write_to_packet(reply
, ia_cursor
);
3051 * If we have any addresses log what we are doing.
3053 if (reply
->ia
->num_iasubopt
!= 0) {
3054 struct iasubopt
*tmp
;
3056 char tmp_addr
[INET6_ADDRSTRLEN
];
3058 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3059 tmp
= reply
->ia
->iasubopt
[i
];
3061 log_info("%s TA: address %s to client with duid %s "
3062 "iaid = %d valid for %u seconds",
3063 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
3064 inet_ntop(AF_INET6
, &tmp
->addr
,
3065 tmp_addr
, sizeof(tmp_addr
)),
3066 print_hex_1(reply
->client_id
.len
,
3067 reply
->client_id
.data
, 60),
3074 * For hard bindings we consume the new changes into
3075 * the database (if any have been attached to the ia_ta).
3077 * Loop through the assigned dynamic addresses, referencing the
3078 * leases onto this IA_TA rather than any old ones, and updating
3079 * pool timers for each (if any).
3081 if ((reply
->ia
->num_iasubopt
!= 0) &&
3082 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
3083 int must_commit
= 0;
3084 struct iasubopt
*tmp
;
3085 struct data_string
*ia_id
;
3088 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3089 tmp
= reply
->ia
->iasubopt
[i
];
3091 if (tmp
->ia
!= NULL
)
3092 ia_dereference(&tmp
->ia
, MDL
);
3093 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
3095 /* If we have anything to do on commit do it now */
3096 if (tmp
->on_star
.on_commit
!= NULL
) {
3097 execute_statements(NULL
, reply
->packet
,
3099 reply
->packet
->options
,
3102 tmp
->on_star
.on_commit
,
3104 executable_statement_dereference
3105 (&tmp
->on_star
.on_commit
, MDL
);
3108 #if defined (NSUPDATE)
3110 * Perform ddns updates.
3112 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3115 evaluate_boolean_option_cache(NULL
, reply
->packet
,
3117 reply
->packet
->options
,
3121 ddns_updates(reply
->packet
, NULL
, NULL
,
3122 tmp
, NULL
, reply
->opt_state
);
3126 if (!reuse_lease6(reply
, tmp
)) {
3127 /* Commit 'hard' bindings. */
3129 renew_lease6(tmp
->ipv6_pool
, tmp
);
3130 schedule_lease_timeout(tmp
->ipv6_pool
);
3132 /* Do our threshold check. */
3133 check_pool6_threshold(reply
, tmp
);
3137 /* write the IA_TA in wire-format to the outbound buffer */
3138 write_to_packet(reply
, ia_cursor
);
3140 /* Remove any old ia from the hash. */
3141 if (reply
->old_ia
!= NULL
) {
3142 if (!release_on_roam(reply
)) {
3143 ia_id
= &reply
->old_ia
->iaid_duid
;
3144 ia_hash_delete(ia_ta_active
,
3145 (unsigned char *)ia_id
->data
,
3149 ia_dereference(&reply
->old_ia
, MDL
);
3152 /* Put new ia into the hash. */
3153 reply
->ia
->cltt
= cur_time
;
3154 ia_id
= &reply
->ia
->iaid_duid
;
3155 ia_hash_add(ia_ta_active
, (unsigned char *)ia_id
->data
,
3156 ia_id
->len
, reply
->ia
, MDL
);
3158 /* If we couldn't reuse all of the iasubopts, we
3159 * must update udpate the lease db */
3161 write_ia(reply
->ia
);
3164 /* write the IA_TA in wire-format to the outbound buffer */
3165 write_to_packet(reply
, ia_cursor
);
3166 schedule_lease_timeout_reply(reply
);
3170 if (packet_ia
!= NULL
)
3171 option_state_dereference(&packet_ia
, MDL
);
3172 if (iaaddr
.data
!= NULL
)
3173 data_string_forget(&iaaddr
, MDL
);
3174 if (reply
->reply_ia
!= NULL
)
3175 option_state_dereference(&reply
->reply_ia
, MDL
);
3176 if (ia_data
.data
!= NULL
)
3177 data_string_forget(&ia_data
, MDL
);
3178 if (data
.data
!= NULL
)
3179 data_string_forget(&data
, MDL
);
3180 if (reply
->ia
!= NULL
)
3181 ia_dereference(&reply
->ia
, MDL
);
3182 if (reply
->old_ia
!= NULL
)
3183 ia_dereference(&reply
->old_ia
, MDL
);
3184 if (reply
->lease
!= NULL
)
3185 iasubopt_dereference(&reply
->lease
, MDL
);
3188 * ISC_R_CANCELED is a status code used by the addr processing to
3189 * indicate we're replying with other addresses. This is still a
3190 * success at higher layers.
3192 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
3195 * Determines if a lease (iasubopt) can be reused without extending it.
3196 * If dhcp-cache-threshold is greater than zero (i.e enabled) then
3197 * a lease may be reused without going through a full renewal if
3198 * it meets all the requirements. In short it must be active, younger
3199 * than the threshold, and not have DNS changes.
3201 * If it is determined that it can be reused, that a call to
3202 * shorten_lifetimes() is made to reduce the valid and preferred lifetimes
3203 * sent to the client by the age of the lease.
3205 * Returns 1 if lease can be reused, 0 otherwise
3208 reuse_lease6(struct reply_state
*reply
, struct iasubopt
*lease
) {
3209 int threshold
= DEFAULT_CACHE_THRESHOLD
;
3210 struct option_cache
* oc
= NULL
;
3211 struct data_string d1
;
3216 /* In order to even qualify for reuse consideration:
3217 * 1. Lease must be active
3218 * 2. It must have been accepted at least once
3219 * 3. DNS info must not have changed */
3220 if ((lease
->state
!= FTS_ACTIVE
) ||
3221 (lease
->hard_lifetime_end_time
== 0) ||
3222 (lease
->ddns_cb
!= NULL
)) {
3226 /* Look up threshold value */
3227 memset(&d1
, 0, sizeof(struct data_string
));
3228 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3229 SV_CACHE_THRESHOLD
);
3231 evaluate_option_cache(&d1
, reply
->packet
, NULL
, NULL
,
3232 reply
->packet
->options
, reply
->opt_state
,
3233 &lease
->scope
, oc
, MDL
)) {
3234 if (d1
.len
== 1 && (d1
.data
[0] < 100)) {
3235 threshold
= d1
.data
[0];
3238 data_string_forget(&d1
, MDL
);
3241 if (threshold
<= 0) {
3245 if (lease
->valid
>= MAX_TIME
) {
3246 /* Infinite leases are always reused. We have to make
3247 * a choice because we cannot determine when they actually
3248 * began, so we either always reuse them or we never do. */
3249 log_debug ("reusing infinite lease for: %s%s",
3250 pin6_addr(&lease
->addr
), iasubopt_plen_str(lease
));
3254 age
= cur_tv
.tv_sec
- (lease
->hard_lifetime_end_time
- lease
->valid
);
3255 if (lease
->valid
<= (INT_MAX
/ threshold
))
3256 limit
= lease
->valid
* threshold
/ 100;
3258 limit
= lease
->valid
/ 100 * threshold
;
3261 /* Reduce valid/preferred going to the client by age */
3262 shorten_lifetimes(reply
, lease
, age
, threshold
);
3270 * Reduces the valid and preferred lifetimes for a given lease (iasubopt)
3272 * We cannot determine until after a iasubopt has been added to
3273 * the reply if the lease can be reused. Therefore, when we do reuse a
3274 * lease we need a way to alter the lifetimes that will be sent to the client.
3275 * That's where this function comes in handy:
3277 * Locate the iasubopt by it's address within the reply the reduce both
3278 * the preferred and valid lifetimes by the given number of seconds.
3280 * Note that this function, by necessity, works directly with the
3281 * option_cache data. Sort of a no-no but I don't have any better ideas.
3283 void shorten_lifetimes(struct reply_state
*reply
, struct iasubopt
*lease
,
3284 time_t age
, int threshold
) {
3285 struct option_cache
* oc
= NULL
;
3292 if (reply
->ia
->ia_type
!= D6O_IA_PD
) {
3293 subopt_type
= D6O_IAADDR
;
3294 addr_offset
= IASUBOPT_NA_ADDR_OFFSET
;
3295 pref_offset
= IASUBOPT_NA_PREF_OFFSET
;
3296 val_offset
= IASUBOPT_NA_VALID_OFFSET
;
3297 exp_length
= IASUBOPT_NA_LEN
;
3300 subopt_type
= D6O_IAPREFIX
;
3301 addr_offset
= IASUBOPT_PD_PREFIX_OFFSET
;
3302 pref_offset
= IASUBOPT_PD_PREF_OFFSET
;
3303 val_offset
= IASUBOPT_PD_VALID_OFFSET
;
3304 exp_length
= IASUBOPT_PD_LEN
;
3307 // loop through the iasubopts for the one that matches this lease
3308 oc
= lookup_option(&dhcpv6_universe
, reply
->reply_ia
, subopt_type
);
3309 for (; oc
!= NULL
; oc
= oc
->next
) {
3310 if (oc
->data
.data
== NULL
|| oc
->data
.len
!= exp_length
) {
3311 /* shouldn't happen */
3315 /* If address matches (and for PDs the prefix len matches)
3316 * we assume this is our subopt, so update the lifetimes */
3317 if (!memcmp(oc
->data
.data
+ addr_offset
, &lease
->addr
, 16) &&
3318 (subopt_type
!= D6O_IAPREFIX
||
3319 (oc
->data
.data
[IASUBOPT_PD_PREFLEN_OFFSET
] ==
3321 u_int32_t pref_life
= getULong(oc
->data
.data
+
3323 u_int32_t valid_life
= getULong(oc
->data
.data
+
3326 if (pref_life
< MAX_TIME
&& pref_life
> age
) {
3328 putULong((unsigned char*)(oc
->data
.data
) +
3329 pref_offset
, pref_life
);
3331 if (reply
->min_prefer
> pref_life
) {
3332 reply
->min_prefer
= pref_life
;
3336 if (valid_life
< MAX_TIME
&& valid_life
> age
) {
3338 putULong((unsigned char*)(oc
->data
.data
) +
3339 val_offset
, valid_life
);
3341 if (reply
->min_valid
> reply
->send_valid
) {
3342 reply
->min_valid
= valid_life
;
3346 log_debug ("Reusing lease for: %s%s, "
3347 "age %ld secs < %d%%,"
3348 " sending shortened lifetimes -"
3349 " preferred: %u, valid %u",
3350 pin6_addr(&lease
->addr
),
3351 iasubopt_plen_str(lease
),
3352 (long)age
, threshold
,
3353 pref_life
, valid_life
);
3360 * Verify the temporary address is available.
3362 static isc_boolean_t
3363 temporary_is_available(struct reply_state
*reply
, struct iaddr
*addr
) {
3364 struct in6_addr tmp_addr
;
3365 struct subnet
*subnet
;
3366 struct ipv6_pool
*pool
= NULL
;
3367 struct ipv6_pond
*pond
= NULL
;
3370 memcpy(&tmp_addr
, addr
->iabuf
, sizeof(tmp_addr
));
3372 * Clients may choose to send :: as an address, with the idea to give
3373 * hints about preferred-lifetime or valid-lifetime.
3374 * So this is not a request for this address.
3376 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
))
3380 * Verify that this address is on the client's network.
3382 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
3383 subnet
= subnet
->next_sibling
) {
3384 if (addr_eq(subnet_number(*addr
, subnet
->netmask
),
3389 /* Address not found on shared network. */
3394 * Check if this address is owned (must be before next step).
3396 if (address_is_owned(reply
, addr
))
3400 * Verify that this address is in a temporary pool and try to get it.
3402 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3403 if (((pond
->prohibit_list
!= NULL
) &&
3404 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3405 ((pond
->permit_list
!= NULL
) &&
3406 (!permitted(reply
->packet
, pond
->permit_list
))))
3409 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3410 if (pool
->pool_type
!= D6O_IA_TA
)
3413 if (ipv6_in_pool(&tmp_addr
, pool
))
3423 if (lease6_exists(pool
, &tmp_addr
))
3425 if (iasubopt_allocate(&reply
->lease
, MDL
) != ISC_R_SUCCESS
)
3427 reply
->lease
->addr
= tmp_addr
;
3428 reply
->lease
->plen
= 0;
3429 /* Default is soft binding for 2 minutes. */
3430 if (add_lease6(pool
, reply
->lease
, cur_time
+ 120) != ISC_R_SUCCESS
)
3437 * Get a temporary address per prefix.
3440 find_client_temporaries(struct reply_state
*reply
) {
3442 struct ipv6_pool
*p
= NULL
;
3443 struct ipv6_pond
*pond
;
3444 isc_result_t status
= ISC_R_NORESOURCES
;;
3445 unsigned int attempts
;
3446 struct iaddr send_addr
;
3449 * Do a quick walk through of the ponds and pools
3450 * to see if we have any prefix pools
3452 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3453 if (pond
->ipv6_pools
== NULL
)
3456 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3457 if (p
->pool_type
== D6O_IA_TA
)
3464 /* If we get here and p is NULL we have no useful pools */
3466 log_debug("Unable to get client addresses: "
3467 "no IPv6 pools on this shared network");
3468 return ISC_R_NORESOURCES
;
3472 * We have at least one pool that could provide an address
3473 * Now we walk through the ponds and pools again and check
3474 * to see if the client is permitted and if an address is
3478 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3479 if (((pond
->prohibit_list
!= NULL
) &&
3480 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3481 ((pond
->permit_list
!= NULL
) &&
3482 (!permitted(reply
->packet
, pond
->permit_list
))))
3485 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3486 if (p
->pool_type
!= D6O_IA_TA
) {
3491 * Get an address in this temporary pool.
3493 status
= create_lease6(p
, &reply
->lease
, &attempts
,
3497 if (status
!= ISC_R_SUCCESS
) {
3498 log_debug("Unable to get a temporary address.");
3502 status
= reply_process_is_addressed(reply
,
3503 &reply
->lease
->scope
,
3505 if (status
!= ISC_R_SUCCESS
) {
3509 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3510 status
= reply_process_send_addr(reply
, &send_addr
);
3511 if (status
!= ISC_R_SUCCESS
) {
3515 * reply->lease can't be null as we use it above
3516 * add check if that changes
3518 iasubopt_dereference(&reply
->lease
, MDL
);
3523 if (reply
->lease
!= NULL
) {
3524 iasubopt_dereference(&reply
->lease
, MDL
);
3530 * This function only returns failure on 'hard' failures. If it succeeds,
3531 * it will leave a lease structure behind.
3534 reply_process_try_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3535 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
3536 struct ipv6_pool
*pool
= NULL
;
3537 struct ipv6_pond
*pond
= NULL
;
3539 struct data_string data_addr
;
3541 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
3542 (addr
== NULL
) || (reply
->lease
!= NULL
))
3543 return (DHCP_R_INVALIDARG
);
3546 * Do a quick walk through of the ponds and pools
3547 * to see if we have any NA address pools
3549 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3550 if (pond
->ipv6_pools
== NULL
)
3553 for (i
= 0; ; i
++) {
3554 pool
= pond
->ipv6_pools
[i
];
3555 if ((pool
== NULL
) ||
3556 (pool
->pool_type
== D6O_IA_NA
))
3563 /* If we get here and p is NULL we have no useful pools */
3565 return (ISC_R_ADDRNOTAVAIL
);
3568 memset(&data_addr
, 0, sizeof(data_addr
));
3569 data_addr
.len
= addr
->len
;
3570 data_addr
.data
= addr
->iabuf
;
3573 * We have at least one pool that could provide an address
3574 * Now we walk through the ponds and pools again and check
3575 * to see if the client is permitted and if an address is
3578 * Within a given pond we start looking at the last pool we
3579 * allocated from, unless it had a collision trying to allocate
3580 * an address. This will tend to move us into less-filled pools.
3583 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3584 if (((pond
->prohibit_list
!= NULL
) &&
3585 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3586 ((pond
->permit_list
!= NULL
) &&
3587 (!permitted(reply
->packet
, pond
->permit_list
))))
3590 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3591 if (pool
->pool_type
!= D6O_IA_NA
)
3594 status
= try_client_v6_address(&reply
->lease
, pool
,
3596 if (status
== ISC_R_SUCCESS
)
3600 if (status
== ISC_R_SUCCESS
)
3604 /* Note that this is just pedantry. There is no allocation to free. */
3605 data_string_forget(&data_addr
, MDL
);
3606 /* Return just the most recent status... */
3610 /* Look around for an address to give the client. First, look through the
3611 * old IA for addresses we can extend. Second, try to allocate a new address.
3612 * Finally, actually add that address into the current reply IA.
3615 find_client_address(struct reply_state
*reply
) {
3616 struct iaddr send_addr
;
3617 isc_result_t status
= ISC_R_NORESOURCES
;
3618 struct iasubopt
*lease
, *best_lease
= NULL
;
3619 struct binding_scope
**scope
;
3620 struct group
*group
;
3623 if (reply
->static_lease
) {
3624 if (reply
->host
== NULL
)
3625 return DHCP_R_INVALIDARG
;
3628 memcpy(send_addr
.iabuf
, reply
->fixed
.data
, 16);
3630 scope
= &global_scope
;
3631 group
= reply
->subnet
->group
;
3635 if (reply
->old_ia
!= NULL
) {
3636 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3637 struct shared_network
*candidate_shared
;
3638 struct ipv6_pond
*pond
;
3640 lease
= reply
->old_ia
->iasubopt
[i
];
3641 candidate_shared
= lease
->ipv6_pool
->shared_network
;
3642 pond
= lease
->ipv6_pool
->ipv6_pond
;
3645 * Look for the best lease on the client's shared
3646 * network, that is still permitted
3649 if ((candidate_shared
!= reply
->shared
) ||
3650 (lease6_usable(lease
) != ISC_TRUE
))
3653 if (((pond
->prohibit_list
!= NULL
) &&
3654 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3655 ((pond
->permit_list
!= NULL
) &&
3656 (!permitted(reply
->packet
, pond
->permit_list
))))
3659 best_lease
= lease_compare(lease
, best_lease
);
3663 /* Try to pick a new address if we didn't find one, or if we found an
3666 if ((best_lease
== NULL
) || (best_lease
->state
== FTS_ABANDONED
)) {
3667 status
= pick_v6_address(reply
);
3668 } else if (best_lease
!= NULL
) {
3669 iasubopt_reference(&reply
->lease
, best_lease
, MDL
);
3670 status
= ISC_R_SUCCESS
;
3673 /* Pick the abandoned lease as a last resort. */
3674 if ((status
== ISC_R_NORESOURCES
) && (best_lease
!= NULL
)) {
3675 /* I don't see how this is supposed to be done right now. */
3676 log_error("Best match for DUID %s is an abandoned address,"
3677 " This may be a result of multiple clients attempting"
3678 " to use this DUID",
3679 print_hex_1(reply
->client_id
.len
,
3680 reply
->client_id
.data
, 60));
3681 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
3684 /* Give up now if we didn't find a lease. */
3685 if (status
!= ISC_R_SUCCESS
)
3688 if (reply
->lease
== NULL
)
3689 log_fatal("Impossible condition at %s:%d.", MDL
);
3691 /* Draw binding scopes from the lease's binding scope, and config
3692 * from the lease's containing subnet and higher. Note that it may
3693 * be desirable to place the group attachment directly in the pool.
3695 scope
= &reply
->lease
->scope
;
3696 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
3699 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3702 status
= reply_process_is_addressed(reply
, scope
, group
);
3703 if (status
!= ISC_R_SUCCESS
)
3706 status
= reply_process_send_addr(reply
, &send_addr
);
3710 /* Once an address is found for a client, perform several common functions;
3711 * Calculate and store valid and preferred lease times, draw client options
3712 * into the option state.
3715 reply_process_is_addressed(struct reply_state
*reply
,
3716 struct binding_scope
**scope
, struct group
*group
)
3718 isc_result_t status
= ISC_R_SUCCESS
;
3719 struct data_string data
;
3720 struct option_cache
*oc
;
3721 struct option_state
*tmp_options
= NULL
;
3722 struct on_star
*on_star
;
3725 /* Initialize values we will cleanup. */
3726 memset(&data
, 0, sizeof(data
));
3729 * Find the proper on_star block to use. We use the
3730 * one in the lease if we have a lease or the one in
3731 * the reply if we don't have a lease because this is
3735 on_star
= &reply
->lease
->on_star
;
3737 on_star
= &reply
->on_star
;
3741 * Bring in the root configuration. We only do this to bring
3742 * in the on * statements, as we didn't have the lease available
3743 * we did it the first time.
3745 option_state_allocate(&tmp_options
, MDL
);
3746 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3747 reply
->packet
->options
, tmp_options
,
3748 &global_scope
, root_group
, NULL
,
3750 if (tmp_options
!= NULL
) {
3751 option_state_dereference(&tmp_options
, MDL
);
3755 * Bring configured options into the root packet level cache - start
3756 * with the lease's closest enclosing group (passed in by the caller
3759 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3760 reply
->packet
->options
, reply
->opt_state
,
3761 scope
, group
, root_group
, on_star
);
3763 /* Execute statements from class scopes. */
3764 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3765 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3766 reply
->packet
->options
,
3767 reply
->opt_state
, scope
,
3768 reply
->packet
->classes
[i
- 1]->group
,
3773 * If there is a host record, over-ride with values configured there,
3774 * without re-evaluating configuration from the previously executed
3775 * group or its common enclosers.
3777 if (reply
->host
!= NULL
)
3778 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3779 reply
->packet
->options
,
3780 reply
->opt_state
, scope
,
3781 reply
->host
->group
, group
,
3784 /* Determine valid lifetime. */
3785 if (reply
->client_valid
== 0)
3786 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
3788 reply
->send_valid
= reply
->client_valid
;
3790 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3791 SV_DEFAULT_LEASE_TIME
);
3793 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3794 reply
->packet
->options
,
3798 log_error("reply_process_is_addressed: unable to "
3799 "evaluate default lease time");
3800 status
= ISC_R_FAILURE
;
3804 reply
->send_valid
= getULong(data
.data
);
3805 data_string_forget(&data
, MDL
);
3808 /* Check to see if the lease time would cause us to wrap
3809 * in which case we make it infinite.
3810 * The following doesn't work on at least some systems:
3811 * (cur_time + reply->send_valid < cur_time)
3813 if (reply
->send_valid
!= INFINITE_TIME
) {
3814 time_t test_time
= cur_time
+ reply
->send_valid
;
3815 if (test_time
< cur_time
)
3816 reply
->send_valid
= INFINITE_TIME
;
3819 if (reply
->client_prefer
== 0)
3820 reply
->send_prefer
= reply
->send_valid
;
3822 reply
->send_prefer
= reply
->client_prefer
;
3824 if ((reply
->send_prefer
>= reply
->send_valid
) &&
3825 (reply
->send_valid
!= INFINITE_TIME
))
3826 reply
->send_prefer
= (reply
->send_valid
/ 2) +
3827 (reply
->send_valid
/ 8);
3829 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3830 SV_PREFER_LIFETIME
);
3832 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3833 reply
->packet
->options
,
3837 log_error("reply_process_is_addressed: unable to "
3838 "evaluate preferred lease time");
3839 status
= ISC_R_FAILURE
;
3843 reply
->send_prefer
= getULong(data
.data
);
3844 data_string_forget(&data
, MDL
);
3847 /* Note lowest values for later calculation of renew/rebind times. */
3848 if (reply
->min_prefer
> reply
->send_prefer
)
3849 reply
->min_prefer
= reply
->send_prefer
;
3851 if (reply
->min_valid
> reply
->send_valid
)
3852 reply
->min_valid
= reply
->send_valid
;
3856 * XXX: Old 4.0.0 alpha code would change the host {} record
3857 * XXX: uid upon lease assignment. This was intended to cover the
3858 * XXX: case where a client first identifies itself using vendor
3859 * XXX: options in a solicit, or request, but later neglects to include
3860 * XXX: these options in a Renew or Rebind. It is not clear that this
3861 * XXX: is required, and has some startling ramifications (such as
3862 * XXX: how to recover this dynamic host {} state across restarts).
3864 if (reply
->host
!= NULL
)
3865 change_host_uid(host
, reply
->client_id
->data
,
3866 reply
->client_id
->len
);
3869 /* Perform dynamic lease related update work. */
3870 if (reply
->lease
!= NULL
) {
3871 /* Cached lifetimes */
3872 reply
->lease
->prefer
= reply
->send_prefer
;
3873 reply
->lease
->valid
= reply
->send_valid
;
3875 /* Advance (or rewind) the valid lifetime.
3876 * In the protocol 0xFFFFFFFF is infinite
3877 * when connecting to the lease file MAX_TIME is
3879 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
3880 if (reply
->send_valid
== INFINITE_TIME
) {
3881 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
3883 reply
->lease
->soft_lifetime_end_time
=
3884 cur_time
+ reply
->send_valid
;
3886 /* Wait before renew! */
3889 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
3890 if (status
!= ISC_R_SUCCESS
) {
3891 log_fatal("reply_process_is_addressed: Unable to "
3892 "attach lease to new IA: %s",
3893 isc_result_totext(status
));
3897 * If this is a new lease, make sure it is attached somewhere.
3899 if (reply
->lease
->ia
== NULL
) {
3900 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
3904 /* Bring a copy of the relevant options into the IA scope. */
3905 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3906 reply
->packet
->options
, reply
->reply_ia
,
3907 scope
, group
, root_group
, NULL
);
3909 /* Execute statements from class scopes. */
3910 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3911 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3912 reply
->packet
->options
,
3913 reply
->reply_ia
, scope
,
3914 reply
->packet
->classes
[i
- 1]->group
,
3919 * And bring in host record configuration, if any, but not to overlap
3920 * the previous group or its common enclosers.
3922 if (reply
->host
!= NULL
)
3923 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3924 reply
->packet
->options
,
3925 reply
->reply_ia
, scope
,
3926 reply
->host
->group
, group
, NULL
);
3929 if (data
.data
!= NULL
)
3930 data_string_forget(&data
, MDL
);
3932 if (status
== ISC_R_SUCCESS
)
3933 reply
->client_resources
++;
3938 /* Simply send an IAADDR within the IA scope as described. */
3940 reply_process_send_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3941 isc_result_t status
= ISC_R_SUCCESS
;
3942 struct data_string data
;
3944 memset(&data
, 0, sizeof(data
));
3946 /* Now append the lease. */
3947 data
.len
= IAADDR_OFFSET
;
3948 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
3949 log_error("reply_process_send_addr: out of memory"
3950 "allocating new IAADDR buffer.");
3951 status
= ISC_R_NOMEMORY
;
3954 data
.data
= data
.buffer
->data
;
3956 memcpy(data
.buffer
->data
, addr
->iabuf
, 16);
3957 putULong(data
.buffer
->data
+ 16, reply
->send_prefer
);
3958 putULong(data
.buffer
->data
+ 20, reply
->send_valid
);
3960 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
3961 data
.buffer
, data
.buffer
->data
,
3962 data
.len
, D6O_IAADDR
, 0)) {
3963 log_error("reply_process_send_addr: unable "
3964 "to save IAADDR option");
3965 status
= ISC_R_FAILURE
;
3969 reply
->resources_included
= ISC_TRUE
;
3972 if (data
.data
!= NULL
)
3973 data_string_forget(&data
, MDL
);
3978 /* Choose the better of two leases. */
3979 static struct iasubopt
*
3980 lease_compare(struct iasubopt
*alpha
, struct iasubopt
*beta
) {
3986 switch(alpha
->state
) {
3988 switch(beta
->state
) {
3990 /* Choose the lease with the longest lifetime (most
3991 * likely the most recently allocated).
3993 if (alpha
->hard_lifetime_end_time
<
3994 beta
->hard_lifetime_end_time
)
4004 log_fatal("Impossible condition at %s:%d.", MDL
);
4009 switch (beta
->state
) {
4014 /* Choose the most recently expired lease. */
4015 if (alpha
->hard_lifetime_end_time
<
4016 beta
->hard_lifetime_end_time
)
4018 else if ((alpha
->hard_lifetime_end_time
==
4019 beta
->hard_lifetime_end_time
) &&
4020 (alpha
->soft_lifetime_end_time
<
4021 beta
->soft_lifetime_end_time
))
4030 log_fatal("Impossible condition at %s:%d.", MDL
);
4035 switch (beta
->state
) {
4041 /* Choose the lease that was abandoned longest ago. */
4042 if (alpha
->hard_lifetime_end_time
<
4043 beta
->hard_lifetime_end_time
)
4049 log_fatal("Impossible condition at %s:%d.", MDL
);
4054 log_fatal("Impossible condition at %s:%d.", MDL
);
4057 log_fatal("Triple impossible condition at %s:%d.", MDL
);
4061 /* Process a client-supplied IA_PD. This may append options to the tail of
4062 * the reply packet being built in the reply_state structure.
4065 reply_process_ia_pd(struct reply_state
*reply
, struct option_cache
*ia
) {
4066 isc_result_t status
= ISC_R_SUCCESS
;
4069 struct option_state
*packet_ia
;
4070 struct option_cache
*oc
;
4071 struct data_string ia_data
, data
;
4073 /* Initialize values that will get cleaned up on return. */
4075 memset(&ia_data
, 0, sizeof(ia_data
));
4076 memset(&data
, 0, sizeof(data
));
4078 * Note that find_client_prefix() may set reply->lease.
4081 /* Make sure there is at least room for the header. */
4082 if ((reply
->cursor
+ IA_PD_OFFSET
+ 4) > sizeof(reply
->buf
)) {
4083 log_error("reply_process_ia_pd: Reply too long for IA.");
4084 return ISC_R_NOSPACE
;
4088 /* Fetch the IA_PD contents. */
4089 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
4090 ia
, IA_PD_OFFSET
)) {
4091 log_error("reply_process_ia_pd: error evaluating ia");
4092 status
= ISC_R_FAILURE
;
4096 /* Extract IA_PD header contents. */
4097 iaid
= getULong(ia_data
.data
);
4098 reply
->renew
= getULong(ia_data
.data
+ 4);
4099 reply
->rebind
= getULong(ia_data
.data
+ 8);
4101 /* Create an IA_PD structure. */
4102 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
4103 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
4104 log_error("reply_process_ia_pd: no memory for ia.");
4105 status
= ISC_R_NOMEMORY
;
4108 reply
->ia
->ia_type
= D6O_IA_PD
;
4110 /* Cache pre-existing IA_PD, if any. */
4111 ia_hash_lookup(&reply
->old_ia
, ia_pd_active
,
4112 (unsigned char *)reply
->ia
->iaid_duid
.data
,
4113 reply
->ia
->iaid_duid
.len
, MDL
);
4116 * Create an option cache to carry the IA_PD option contents, and
4117 * execute any user-supplied values into it.
4119 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
4120 status
= ISC_R_NOMEMORY
;
4124 /* Check & count the fixed prefix host records. */
4125 reply
->static_prefixes
= 0;
4126 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_prefix
!= NULL
)) {
4127 struct iaddrcidrnetlist
*fp
;
4129 for (fp
= reply
->host
->fixed_prefix
; fp
!= NULL
;
4131 reply
->static_prefixes
+= 1;
4136 * Save the cursor position at the start of the IA_PD, so we can
4137 * set length and adjust t1/t2 values later. We write a temporary
4138 * header out now just in case we decide to adjust the packet
4139 * within sub-process functions.
4141 ia_cursor
= reply
->cursor
;
4143 /* Initialize the IA_PD header. First the code. */
4144 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_PD
);
4147 /* Then option length. */
4148 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
4151 /* Then IA_PD header contents; IAID. */
4152 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
4155 /* We store the client's t1 for now, and may over-ride it later. */
4156 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
4159 /* We store the client's t2 for now, and may over-ride it later. */
4160 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
4164 * For each prefix in this IA_PD, decide what to do about it.
4166 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAPREFIX
);
4167 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
4168 reply
->client_valid
= reply
->client_prefer
= 0;
4169 reply
->preflen
= -1;
4170 for (; oc
!= NULL
; oc
= oc
->next
) {
4171 status
= reply_process_prefix(reply
, oc
);
4174 * Canceled means we did not allocate prefixes to the
4175 * client, but we're "done" with this IA - we set a status
4176 * code. So transmit this reply, e.g., move on to the next
4179 if (status
== ISC_R_CANCELED
)
4182 if ((status
!= ISC_R_SUCCESS
) &&
4183 (status
!= ISC_R_ADDRINUSE
) &&
4184 (status
!= ISC_R_ADDRNOTAVAIL
))
4191 * If we fell through the above and never gave the client
4192 * a prefix, give it one now.
4194 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
4195 status
= find_client_prefix(reply
);
4197 if (status
== ISC_R_NORESOURCES
) {
4198 switch (reply
->packet
->dhcpv6_msg_type
) {
4199 case DHCPV6_SOLICIT
:
4201 * No prefix for any IA is handled
4206 case DHCPV6_REQUEST
:
4207 /* Same than for addresses. */
4208 option_state_dereference(&reply
->reply_ia
, MDL
);
4209 if (!option_state_allocate(&reply
->reply_ia
,
4212 log_error("reply_process_ia_pd: No "
4213 "memory for option state "
4215 status
= ISC_R_NOMEMORY
;
4219 if (!set_status_code(STATUS_NoPrefixAvail
,
4220 "No prefixes available "
4221 "for this interface.",
4223 log_error("reply_process_ia_pd: "
4225 "NoPrefixAvail status "
4227 status
= ISC_R_FAILURE
;
4231 status
= ISC_R_SUCCESS
;
4235 if (reply
->resources_included
)
4236 status
= ISC_R_SUCCESS
;
4243 if (status
!= ISC_R_SUCCESS
)
4248 * yes, goto's aren't the best but we also want to avoid extra
4251 if (status
== ISC_R_CANCELED
) {
4252 /* We're replying with a status code so we still need to
4253 * write it out in wire-format to the outbound buffer */
4254 write_to_packet(reply
, ia_cursor
);
4259 * Handle static prefixes, we always log stuff and if it's
4260 * a hard binding we run any commit statements that we have
4262 if (reply
->static_prefixes
!= 0) {
4263 char tmp_addr
[INET6_ADDRSTRLEN
];
4264 log_info("%s PD: address %s/%d to client with duid %s "
4266 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
4267 inet_ntop(AF_INET6
, reply
->fixed_pref
.lo_addr
.iabuf
,
4268 tmp_addr
, sizeof(tmp_addr
)),
4269 reply
->fixed_pref
.bits
,
4270 print_hex_1(reply
->client_id
.len
,
4271 reply
->client_id
.data
, 60),
4274 /* Write the lease out in wire-format to the outbound buffer */
4275 write_to_packet(reply
, ia_cursor
);
4277 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
4278 (reply
->on_star
.on_commit
!= NULL
)) {
4279 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
4280 reply
->packet
->options
,
4282 NULL
, reply
->on_star
.on_commit
,
4284 executable_statement_dereference
4285 (&reply
->on_star
.on_commit
, MDL
);
4291 * If we have any addresses log what we are doing.
4293 if (reply
->ia
->num_iasubopt
!= 0) {
4294 struct iasubopt
*tmp
;
4296 char tmp_addr
[INET6_ADDRSTRLEN
];
4298 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
4299 tmp
= reply
->ia
->iasubopt
[i
];
4301 log_info("%s PD: address %s/%d to client with duid %s"
4302 " iaid = %d valid for %u seconds",
4303 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
4304 inet_ntop(AF_INET6
, &tmp
->addr
,
4305 tmp_addr
, sizeof(tmp_addr
)),
4307 print_hex_1(reply
->client_id
.len
,
4308 reply
->client_id
.data
, 60),
4314 * If this is not a 'soft' binding, consume the new changes into
4315 * the database (if any have been attached to the ia_pd).
4317 * Loop through the assigned dynamic prefixes, referencing the
4318 * prefixes onto this IA_PD rather than any old ones, and updating
4319 * prefix pool timers for each (if any).
4321 * If a lease can be reused we skip renewing it or checking the
4322 * pool threshold. If it can't we flag that the IA must be commited
4323 * to the db and do the renewal and pool check.
4325 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
4326 (reply
->ia
->num_iasubopt
!= 0)) {
4327 int must_commit
= 0;
4328 struct iasubopt
*tmp
;
4329 struct data_string
*ia_id
;
4332 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
4333 tmp
= reply
->ia
->iasubopt
[i
];
4335 if (tmp
->ia
!= NULL
)
4336 ia_dereference(&tmp
->ia
, MDL
);
4337 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
4339 /* If we have anything to do on commit do it now */
4340 if (tmp
->on_star
.on_commit
!= NULL
) {
4341 execute_statements(NULL
, reply
->packet
,
4343 reply
->packet
->options
,
4346 tmp
->on_star
.on_commit
,
4348 executable_statement_dereference
4349 (&tmp
->on_star
.on_commit
, MDL
);
4352 if (!reuse_lease6(reply
, tmp
)) {
4353 /* Commit 'hard' bindings. */
4355 renew_lease6(tmp
->ipv6_pool
, tmp
);
4356 schedule_lease_timeout(tmp
->ipv6_pool
);
4358 /* Do our threshold check. */
4359 check_pool6_threshold(reply
, tmp
);
4363 /* write the IA_PD in wire-format to the outbound buffer */
4364 write_to_packet(reply
, ia_cursor
);
4366 /* Remove any old ia from the hash. */
4367 if (reply
->old_ia
!= NULL
) {
4368 if (!release_on_roam(reply
)) {
4369 ia_id
= &reply
->old_ia
->iaid_duid
;
4370 ia_hash_delete(ia_pd_active
,
4371 (unsigned char *)ia_id
->data
,
4375 ia_dereference(&reply
->old_ia
, MDL
);
4378 /* Put new ia into the hash. */
4379 reply
->ia
->cltt
= cur_time
;
4380 ia_id
= &reply
->ia
->iaid_duid
;
4381 ia_hash_add(ia_pd_active
, (unsigned char *)ia_id
->data
,
4382 ia_id
->len
, reply
->ia
, MDL
);
4384 /* If we couldn't reuse all of the iasubopts, we
4385 * must udpate the lease db */
4387 write_ia(reply
->ia
);
4390 /* write the IA_PD in wire-format to the outbound buffer */
4391 write_to_packet(reply
, ia_cursor
);
4392 schedule_lease_timeout_reply(reply
);
4396 if (packet_ia
!= NULL
)
4397 option_state_dereference(&packet_ia
, MDL
);
4398 if (reply
->reply_ia
!= NULL
)
4399 option_state_dereference(&reply
->reply_ia
, MDL
);
4400 if (ia_data
.data
!= NULL
)
4401 data_string_forget(&ia_data
, MDL
);
4402 if (data
.data
!= NULL
)
4403 data_string_forget(&data
, MDL
);
4404 if (reply
->ia
!= NULL
)
4405 ia_dereference(&reply
->ia
, MDL
);
4406 if (reply
->old_ia
!= NULL
)
4407 ia_dereference(&reply
->old_ia
, MDL
);
4408 if (reply
->lease
!= NULL
)
4409 iasubopt_dereference(&reply
->lease
, MDL
);
4410 if (reply
->on_star
.on_expiry
!= NULL
)
4411 executable_statement_dereference
4412 (&reply
->on_star
.on_expiry
, MDL
);
4413 if (reply
->on_star
.on_release
!= NULL
)
4414 executable_statement_dereference
4415 (&reply
->on_star
.on_release
, MDL
);
4418 * ISC_R_CANCELED is a status code used by the prefix processing to
4419 * indicate we're replying with a status code. This is still a
4420 * success at higher layers.
4422 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
4427 * \brief Find the proper scoping group for use with a v6 static prefix.
4429 * We start by trying to find a subnet based on the given prefix and
4430 * the shared network. If we don't find one then the prefix has been
4431 * declared outside of any subnets. If there is a static address
4432 * associated with the host we use it to try and find a subnet (this
4433 * should succeed). If there isn't a static address we fall back
4434 * to the shared subnet itself.
4435 * Once we have a subnet we extract the group from it and return it.
4437 * \param reply - the reply structure we use to collect information
4438 * we will use the fields shared, fixed_pref and host
4439 * from the structure
4441 * \return a pointer to the group structure to use for scoping
4444 static struct group
*
4445 find_group_by_prefix(struct reply_state
*reply
) {
4446 /* default group if we don't find anything better */
4447 struct group
*group
= reply
->shared
->group
;
4448 struct subnet
*subnet
= NULL
;
4449 struct iaddr tmp_addr
;
4450 struct data_string fixed_addr
;
4452 /* Try with the prefix first */
4453 if (find_grouped_subnet(&subnet
, reply
->shared
,
4454 reply
->fixed_pref
.lo_addr
, MDL
) != 0) {
4455 group
= subnet
->group
;
4456 subnet_dereference(&subnet
, MDL
);
4460 /* Didn't find a subnet via prefix, what about fixed address */
4461 /* The caller has already tested reply->host != NULL */
4463 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
4465 if ((reply
->host
->fixed_addr
!= NULL
) &&
4466 (evaluate_option_cache(&fixed_addr
, NULL
, NULL
, NULL
,
4467 NULL
, NULL
, &global_scope
,
4468 reply
->host
->fixed_addr
, MDL
))) {
4469 if (fixed_addr
.len
>= 16) {
4471 memcpy(tmp_addr
.iabuf
, fixed_addr
.data
, 16);
4472 if (find_grouped_subnet(&subnet
, reply
->shared
,
4473 tmp_addr
, MDL
) != 0) {
4474 group
= subnet
->group
;
4475 subnet_dereference(&subnet
, MDL
);
4478 data_string_forget(&fixed_addr
, MDL
);
4481 /* return whatever we got */
4486 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
4487 * contents into the reply's current ia_pd-scoped option cache. Returns
4488 * ISC_R_CANCELED in the event we are replying with a status code and do
4489 * not wish to process more IAPREFIXes within this IA_PD.
4492 reply_process_prefix(struct reply_state
*reply
, struct option_cache
*pref
) {
4493 u_int32_t pref_life
, valid_life
;
4494 struct binding_scope
**scope
;
4495 struct iaddrcidrnet tmp_pref
;
4496 struct option_cache
*oc
;
4497 struct data_string iapref
, data
;
4498 isc_result_t status
= ISC_R_SUCCESS
;
4499 struct group
*group
;
4501 /* Initializes values that will be cleaned up. */
4502 memset(&iapref
, 0, sizeof(iapref
));
4503 memset(&data
, 0, sizeof(data
));
4504 /* Note that reply->lease may be set by prefix_is_owned() */
4507 * There is no point trying to process an incoming prefix if there
4508 * is no room for an outgoing prefix.
4510 if ((reply
->cursor
+ 29) > sizeof(reply
->buf
)) {
4511 log_error("reply_process_prefix: Out of room for prefix.");
4512 return ISC_R_NOSPACE
;
4515 /* Extract this IAPREFIX option. */
4516 if (!evaluate_option_cache(&iapref
, reply
->packet
, NULL
, NULL
,
4517 reply
->packet
->options
, NULL
, &global_scope
,
4519 (iapref
.len
< IAPREFIX_OFFSET
)) {
4520 log_error("reply_process_prefix: error evaluating IAPREFIX.");
4521 status
= ISC_R_FAILURE
;
4526 * Layout: preferred and valid lifetimes followed by the prefix
4527 * length and the IPv6 address.
4529 pref_life
= getULong(iapref
.data
);
4530 valid_life
= getULong(iapref
.data
+ 4);
4532 if ((reply
->client_valid
== 0) ||
4533 (reply
->client_valid
> valid_life
))
4534 reply
->client_valid
= valid_life
;
4536 if ((reply
->client_prefer
== 0) ||
4537 (reply
->client_prefer
> pref_life
))
4538 reply
->client_prefer
= pref_life
;
4541 * Clients may choose to send ::/0 as a prefix, with the idea to give
4542 * hints about preferred-lifetime or valid-lifetime.
4544 tmp_pref
.lo_addr
.len
= 16;
4545 memset(tmp_pref
.lo_addr
.iabuf
, 0, 16);
4546 if ((iapref
.data
[8] == 0) &&
4547 (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0)) {
4548 /* Status remains success; we just ignore this one. */
4553 * Clients may choose to send ::/X as a prefix to specify a
4554 * preferred/requested prefix length. Note X is never zero here.
4556 tmp_pref
.bits
= (int) iapref
.data
[8];
4557 if (reply
->preflen
< 0) {
4558 /* Cache the first preferred prefix length. */
4559 reply
->preflen
= tmp_pref
.bits
;
4561 if (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0) {
4565 memcpy(tmp_pref
.lo_addr
.iabuf
, iapref
.data
+ 9, 16);
4567 /* Verify the prefix belongs to the client. */
4568 if (!prefix_is_owned(reply
, &tmp_pref
)) {
4569 /* Same than for addresses. */
4570 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
4571 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
4572 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
4573 status
= reply_process_try_prefix(reply
, &tmp_pref
);
4575 /* Either error out or skip this prefix. */
4576 if ((status
!= ISC_R_SUCCESS
) &&
4577 (status
!= ISC_R_ADDRINUSE
) &&
4578 (status
!= ISC_R_ADDRNOTAVAIL
))
4581 if (reply
->lease
== NULL
) {
4582 if (reply
->packet
->dhcpv6_msg_type
==
4584 reply
->send_prefer
= 0;
4585 reply
->send_valid
= 0;
4589 /* status remains success - ignore */
4593 * RFC3633 section 18.2.3:
4595 * If the delegating router cannot find a binding
4596 * for the requesting router's IA_PD the delegating
4597 * router returns the IA_PD containing no prefixes
4598 * with a Status Code option set to NoBinding in the
4601 * On mismatch we (ab)use this pretending we have not the IA
4602 * as soon as we have not a prefix.
4604 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
4605 /* Rewind the IA_PD to empty. */
4606 option_state_dereference(&reply
->reply_ia
, MDL
);
4607 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
4608 log_error("reply_process_prefix: No memory "
4609 "for option state wipe.");
4610 status
= ISC_R_NOMEMORY
;
4614 /* Append a NoBinding status code. */
4615 if (!set_status_code(STATUS_NoBinding
,
4616 "Prefix not bound to this "
4617 "interface.", reply
->reply_ia
)) {
4618 log_error("reply_process_prefix: Unable to "
4619 "attach status code.");
4620 status
= ISC_R_FAILURE
;
4624 /* Fin (no more IAPREFIXes). */
4625 status
= ISC_R_CANCELED
;
4628 log_error("It is impossible to lease a client that is "
4629 "not sending a solicit, request, renew, or "
4631 status
= ISC_R_FAILURE
;
4636 if (reply
->static_prefixes
> 0) {
4637 if (reply
->host
== NULL
)
4638 log_fatal("Impossible condition at %s:%d.", MDL
);
4640 scope
= &global_scope
;
4642 /* Copy the static prefix for logging and finding the group */
4643 memcpy(&reply
->fixed_pref
, &tmp_pref
, sizeof(tmp_pref
));
4645 /* Try to find a group for the static prefix */
4646 group
= find_group_by_prefix(reply
);
4648 if (reply
->lease
== NULL
)
4649 log_fatal("Impossible condition at %s:%d.", MDL
);
4651 scope
= &reply
->lease
->scope
;
4652 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4656 * If client_resources is nonzero, then the reply_process_is_prefixed
4657 * function has executed configuration state into the reply option
4658 * cache. We will use that valid cache to derive configuration for
4659 * whether or not to engage in additional prefixes, and similar.
4661 if (reply
->client_resources
!= 0) {
4665 * Does this client have "enough" prefixes already? Default
4666 * to one. Everybody gets one, and one should be enough for
4669 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4670 SV_LIMIT_PREFS_PER_IA
);
4672 if (!evaluate_option_cache(&data
, reply
->packet
,
4674 reply
->packet
->options
,
4678 log_error("reply_process_prefix: unable to "
4679 "evaluate prefs-per-ia value.");
4680 status
= ISC_R_FAILURE
;
4684 limit
= getULong(data
.data
);
4685 data_string_forget(&data
, MDL
);
4689 * If we wish to limit the client to a certain number of
4690 * prefixes, then omit the prefix from the reply.
4692 if (reply
->client_resources
>= limit
)
4696 status
= reply_process_is_prefixed(reply
, scope
, group
);
4697 if (status
!= ISC_R_SUCCESS
)
4701 status
= reply_process_send_prefix(reply
, &tmp_pref
);
4704 if (iapref
.data
!= NULL
)
4705 data_string_forget(&iapref
, MDL
);
4706 if (data
.data
!= NULL
)
4707 data_string_forget(&data
, MDL
);
4708 if (reply
->lease
!= NULL
)
4709 iasubopt_dereference(&reply
->lease
, MDL
);
4715 * Verify the prefix belongs to the client. If we've got a host
4716 * record with fixed prefixes, it has to be an assigned prefix
4717 * (fault out all else). Otherwise it's a dynamic prefix, so lookup
4718 * that prefix and make sure it belongs to this DUID:IAID pair.
4720 static isc_boolean_t
4721 prefix_is_owned(struct reply_state
*reply
, struct iaddrcidrnet
*pref
) {
4722 struct iaddrcidrnetlist
*l
;
4724 struct ipv6_pond
*pond
;
4727 * This faults out prefixes that don't match fixed prefixes.
4729 if (reply
->static_prefixes
> 0) {
4730 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4731 if ((pref
->bits
== l
->cidrnet
.bits
) &&
4732 (memcmp(pref
->lo_addr
.iabuf
,
4733 l
->cidrnet
.lo_addr
.iabuf
, 16) == 0))
4739 if ((reply
->old_ia
== NULL
) ||
4740 (reply
->old_ia
->num_iasubopt
== 0))
4743 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4744 struct iasubopt
*tmp
;
4746 tmp
= reply
->old_ia
->iasubopt
[i
];
4748 if ((pref
->bits
== (int) tmp
->plen
) &&
4749 (memcmp(pref
->lo_addr
.iabuf
, &tmp
->addr
, 16) == 0)) {
4750 if (lease6_usable(tmp
) == ISC_FALSE
) {
4754 pond
= tmp
->ipv6_pool
->ipv6_pond
;
4755 if (((pond
->prohibit_list
!= NULL
) &&
4756 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4757 ((pond
->permit_list
!= NULL
) &&
4758 (!permitted(reply
->packet
, pond
->permit_list
))))
4761 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
4770 * This function only returns failure on 'hard' failures. If it succeeds,
4771 * it will leave a prefix structure behind.
4774 reply_process_try_prefix(struct reply_state
*reply
,
4775 struct iaddrcidrnet
*pref
) {
4776 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
4777 struct ipv6_pool
*pool
= NULL
;
4778 struct ipv6_pond
*pond
= NULL
;
4780 struct data_string data_pref
;
4782 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
4783 (pref
== NULL
) || (reply
->lease
!= NULL
))
4784 return (DHCP_R_INVALIDARG
);
4787 * Do a quick walk through of the ponds and pools
4788 * to see if we have any prefix pools
4790 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4791 if (pond
->ipv6_pools
== NULL
)
4794 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4795 if (pool
->pool_type
== D6O_IA_PD
)
4802 /* If we get here and p is NULL we have no useful pools */
4804 return (ISC_R_ADDRNOTAVAIL
);
4807 memset(&data_pref
, 0, sizeof(data_pref
));
4809 if (!buffer_allocate(&data_pref
.buffer
, data_pref
.len
, MDL
)) {
4810 log_error("reply_process_try_prefix: out of memory.");
4811 return (ISC_R_NOMEMORY
);
4813 data_pref
.data
= data_pref
.buffer
->data
;
4814 data_pref
.buffer
->data
[0] = (u_int8_t
) pref
->bits
;
4815 memcpy(data_pref
.buffer
->data
+ 1, pref
->lo_addr
.iabuf
, 16);
4818 * We have at least one pool that could provide a prefix
4819 * Now we walk through the ponds and pools again and check
4820 * to see if the client is permitted and if an prefix is
4825 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4826 if (((pond
->prohibit_list
!= NULL
) &&
4827 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4828 ((pond
->permit_list
!= NULL
) &&
4829 (!permitted(reply
->packet
, pond
->permit_list
))))
4832 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4833 if (pool
->pool_type
!= D6O_IA_PD
) {
4837 status
= try_client_v6_prefix(&reply
->lease
, pool
,
4839 /* If we found it in this pool (either in use or available),
4840 there is no need to look further. */
4841 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4844 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4848 data_string_forget(&data_pref
, MDL
);
4849 /* Return just the most recent status... */
4853 /* Look around for a prefix to give the client. First, look through the old
4854 * IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
4855 * Finally, actually add that prefix into the current reply IA_PD.
4858 find_client_prefix(struct reply_state
*reply
) {
4859 struct iaddrcidrnet send_pref
;
4860 isc_result_t status
= ISC_R_NORESOURCES
;
4861 struct iasubopt
*prefix
, *best_prefix
= NULL
;
4862 struct binding_scope
**scope
;
4864 struct group
*group
;
4866 if (reply
->static_prefixes
> 0) {
4867 struct iaddrcidrnetlist
*l
;
4869 if (reply
->host
== NULL
)
4870 return DHCP_R_INVALIDARG
;
4872 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4873 if (l
->cidrnet
.bits
== reply
->preflen
)
4878 * If no fixed prefix has the preferred length,
4879 * get the first one.
4881 l
= reply
->host
->fixed_prefix
;
4883 memcpy(&send_pref
, &l
->cidrnet
, sizeof(send_pref
));
4885 scope
= &global_scope
;
4887 /* Copy the prefix for logging purposes */
4888 memcpy(&reply
->fixed_pref
, &l
->cidrnet
, sizeof(send_pref
));
4890 /* Try to find a group for the static prefix */
4891 group
= find_group_by_prefix(reply
);
4896 if (reply
->old_ia
!= NULL
) {
4897 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4898 struct shared_network
*candidate_shared
;
4899 struct ipv6_pond
*pond
;
4901 prefix
= reply
->old_ia
->iasubopt
[i
];
4902 candidate_shared
= prefix
->ipv6_pool
->shared_network
;
4903 pond
= prefix
->ipv6_pool
->ipv6_pond
;
4906 * Consider this prefix if it is in a global pool or
4907 * if it is scoped in a pool under the client's shared
4910 if (((candidate_shared
!= NULL
) &&
4911 (candidate_shared
!= reply
->shared
)) ||
4912 (lease6_usable(prefix
) != ISC_TRUE
))
4916 * And check if the prefix is still permitted
4919 if (((pond
->prohibit_list
!= NULL
) &&
4920 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4921 ((pond
->permit_list
!= NULL
) &&
4922 (!permitted(reply
->packet
, pond
->permit_list
))))
4925 best_prefix
= prefix_compare(reply
, prefix
,
4930 * If we have prefix length hint and we're not igoring them,
4931 * then toss the best match if it doesn't match the hint,
4932 * unless this is in response to a rebind. In the latter
4933 * case we're supposed to return it with zero lifetimes.
4935 if (best_prefix
&& (reply
->preflen
> 0)
4936 && (prefix_length_mode
!= PLM_IGNORE
)
4937 && (reply
->preflen
!= best_prefix
->plen
)
4938 && (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
4943 /* Try to pick a new prefix if we didn't find one, or if we found an
4946 if ((best_prefix
== NULL
) || (best_prefix
->state
== FTS_ABANDONED
)) {
4947 status
= pick_v6_prefix(reply
);
4948 } else if (best_prefix
!= NULL
) {
4949 iasubopt_reference(&reply
->lease
, best_prefix
, MDL
);
4950 status
= ISC_R_SUCCESS
;
4953 /* Pick the abandoned prefix as a last resort. */
4954 if ((status
== ISC_R_NORESOURCES
) && (best_prefix
!= NULL
)) {
4955 /* I don't see how this is supposed to be done right now. */
4956 log_error("Reclaiming abandoned prefixes is not yet "
4957 "supported. Treating this as an out of space "
4959 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
4962 /* Give up now if we didn't find a prefix. */
4963 if (status
!= ISC_R_SUCCESS
)
4966 if (reply
->lease
== NULL
)
4967 log_fatal("Impossible condition at %s:%d.", MDL
);
4969 scope
= &reply
->lease
->scope
;
4970 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4972 send_pref
.lo_addr
.len
= 16;
4973 memcpy(send_pref
.lo_addr
.iabuf
, &reply
->lease
->addr
, 16);
4974 send_pref
.bits
= (int) reply
->lease
->plen
;
4977 status
= reply_process_is_prefixed(reply
, scope
, group
);
4978 if (status
!= ISC_R_SUCCESS
)
4981 status
= reply_process_send_prefix(reply
, &send_pref
);
4985 /* Once a prefix is found for a client, perform several common functions;
4986 * Calculate and store valid and preferred prefix times, draw client options
4987 * into the option state.
4990 reply_process_is_prefixed(struct reply_state
*reply
,
4991 struct binding_scope
**scope
, struct group
*group
)
4993 isc_result_t status
= ISC_R_SUCCESS
;
4994 struct data_string data
;
4995 struct option_cache
*oc
;
4996 struct option_state
*tmp_options
= NULL
;
4997 struct on_star
*on_star
;
5000 /* Initialize values we will cleanup. */
5001 memset(&data
, 0, sizeof(data
));
5004 * Find the proper on_star block to use. We use the
5005 * one in the lease if we have a lease or the one in
5006 * the reply if we don't have a lease because this is
5010 on_star
= &reply
->lease
->on_star
;
5012 on_star
= &reply
->on_star
;
5016 * Bring in the root configuration. We only do this to bring
5017 * in the on * statements, as we didn't have the lease available
5018 * we we did it the first time.
5020 option_state_allocate(&tmp_options
, MDL
);
5021 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5022 reply
->packet
->options
, tmp_options
,
5023 &global_scope
, root_group
, NULL
,
5025 if (tmp_options
!= NULL
) {
5026 option_state_dereference(&tmp_options
, MDL
);
5030 * Bring configured options into the root packet level cache - start
5031 * with the lease's closest enclosing group (passed in by the caller
5034 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5035 reply
->packet
->options
, reply
->opt_state
,
5036 scope
, group
, root_group
, on_star
);
5038 /* Execute statements from class scopes. */
5039 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
5040 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5041 reply
->packet
->options
,
5042 reply
->opt_state
, scope
,
5043 reply
->packet
->classes
[i
- 1]->group
,
5048 * If there is a host record, over-ride with values configured there,
5049 * without re-evaluating configuration from the previously executed
5050 * group or its common enclosers.
5052 if (reply
->host
!= NULL
)
5053 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5054 reply
->packet
->options
,
5055 reply
->opt_state
, scope
,
5056 reply
->host
->group
, group
,
5059 /* Determine valid lifetime. */
5060 if (reply
->client_valid
== 0)
5061 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
5063 reply
->send_valid
= reply
->client_valid
;
5065 oc
= lookup_option(&server_universe
, reply
->opt_state
,
5066 SV_DEFAULT_LEASE_TIME
);
5068 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
5069 reply
->packet
->options
,
5073 log_error("reply_process_is_prefixed: unable to "
5074 "evaluate default prefix time");
5075 status
= ISC_R_FAILURE
;
5079 reply
->send_valid
= getULong(data
.data
);
5080 data_string_forget(&data
, MDL
);
5083 /* Check to see if the lease time would cause us to wrap
5084 * in which case we make it infinite.
5085 * The following doesn't work on at least some systems:
5086 * (cur_time + reply->send_valid < cur_time)
5088 if (reply
->send_valid
!= INFINITE_TIME
) {
5089 time_t test_time
= cur_time
+ reply
->send_valid
;
5090 if (test_time
< cur_time
)
5091 reply
->send_valid
= INFINITE_TIME
;
5094 if (reply
->client_prefer
== 0)
5095 reply
->send_prefer
= reply
->send_valid
;
5097 reply
->send_prefer
= reply
->client_prefer
;
5099 if ((reply
->send_prefer
>= reply
->send_valid
) &&
5100 (reply
->send_valid
!= INFINITE_TIME
))
5101 reply
->send_prefer
= (reply
->send_valid
/ 2) +
5102 (reply
->send_valid
/ 8);
5104 oc
= lookup_option(&server_universe
, reply
->opt_state
,
5105 SV_PREFER_LIFETIME
);
5107 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
5108 reply
->packet
->options
,
5112 log_error("reply_process_is_prefixed: unable to "
5113 "evaluate preferred prefix time");
5114 status
= ISC_R_FAILURE
;
5118 reply
->send_prefer
= getULong(data
.data
);
5119 data_string_forget(&data
, MDL
);
5122 /* Note lowest values for later calculation of renew/rebind times. */
5123 if (reply
->min_prefer
> reply
->send_prefer
)
5124 reply
->min_prefer
= reply
->send_prefer
;
5126 if (reply
->min_valid
> reply
->send_valid
)
5127 reply
->min_valid
= reply
->send_valid
;
5129 /* Perform dynamic prefix related update work. */
5130 if (reply
->lease
!= NULL
) {
5131 /* Cached lifetimes */
5132 reply
->lease
->prefer
= reply
->send_prefer
;
5133 reply
->lease
->valid
= reply
->send_valid
;
5135 /* Advance (or rewind) the valid lifetime.
5136 * In the protocol 0xFFFFFFFF is infinite
5137 * when connecting to the lease file MAX_TIME is
5139 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
5140 if (reply
->send_valid
== INFINITE_TIME
) {
5141 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
5143 reply
->lease
->soft_lifetime_end_time
=
5144 cur_time
+ reply
->send_valid
;
5146 /* Wait before renew! */
5149 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
5150 if (status
!= ISC_R_SUCCESS
) {
5151 log_fatal("reply_process_is_prefixed: Unable to "
5152 "attach prefix to new IA_PD: %s",
5153 isc_result_totext(status
));
5157 * If this is a new prefix, make sure it is attached somewhere.
5159 if (reply
->lease
->ia
== NULL
) {
5160 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
5164 /* Bring a copy of the relevant options into the IA_PD scope. */
5165 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5166 reply
->packet
->options
, reply
->reply_ia
,
5167 scope
, group
, root_group
, NULL
);
5169 /* Execute statements from class scopes. */
5170 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
5171 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5172 reply
->packet
->options
,
5173 reply
->reply_ia
, scope
,
5174 reply
->packet
->classes
[i
- 1]->group
,
5179 * And bring in host record configuration, if any, but not to overlap
5180 * the previous group or its common enclosers.
5182 if (reply
->host
!= NULL
)
5183 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5184 reply
->packet
->options
,
5185 reply
->reply_ia
, scope
,
5186 reply
->host
->group
, group
, NULL
);
5189 if (data
.data
!= NULL
)
5190 data_string_forget(&data
, MDL
);
5192 if (status
== ISC_R_SUCCESS
)
5193 reply
->client_resources
++;
5198 /* Simply send an IAPREFIX within the IA_PD scope as described. */
5200 reply_process_send_prefix(struct reply_state
*reply
,
5201 struct iaddrcidrnet
*pref
) {
5202 isc_result_t status
= ISC_R_SUCCESS
;
5203 struct data_string data
;
5205 memset(&data
, 0, sizeof(data
));
5207 /* Now append the prefix. */
5208 data
.len
= IAPREFIX_OFFSET
;
5209 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
5210 log_error("reply_process_send_prefix: out of memory"
5211 "allocating new IAPREFIX buffer.");
5212 status
= ISC_R_NOMEMORY
;
5215 data
.data
= data
.buffer
->data
;
5217 putULong(data
.buffer
->data
, reply
->send_prefer
);
5218 putULong(data
.buffer
->data
+ 4, reply
->send_valid
);
5219 data
.buffer
->data
[8] = pref
->bits
;
5220 memcpy(data
.buffer
->data
+ 9, pref
->lo_addr
.iabuf
, 16);
5222 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
5223 data
.buffer
, data
.buffer
->data
,
5224 data
.len
, D6O_IAPREFIX
, 0)) {
5225 log_error("reply_process_send_prefix: unable "
5226 "to save IAPREFIX option");
5227 status
= ISC_R_FAILURE
;
5231 reply
->resources_included
= ISC_TRUE
;
5234 if (data
.data
!= NULL
)
5235 data_string_forget(&data
, MDL
);
5240 /* Choose the better of two prefixes. */
5241 static struct iasubopt
*
5242 prefix_compare(struct reply_state
*reply
,
5243 struct iasubopt
*alpha
, struct iasubopt
*beta
) {
5249 if (reply
->preflen
>= 0) {
5250 if ((alpha
->plen
== reply
->preflen
) &&
5251 (beta
->plen
!= reply
->preflen
))
5253 if ((beta
->plen
== reply
->preflen
) &&
5254 (alpha
->plen
!= reply
->preflen
))
5258 switch(alpha
->state
) {
5260 switch(beta
->state
) {
5262 /* Choose the prefix with the longest lifetime (most
5263 * likely the most recently allocated).
5265 if (alpha
->hard_lifetime_end_time
<
5266 beta
->hard_lifetime_end_time
)
5276 log_fatal("Impossible condition at %s:%d.", MDL
);
5281 switch (beta
->state
) {
5286 /* Choose the most recently expired prefix. */
5287 if (alpha
->hard_lifetime_end_time
<
5288 beta
->hard_lifetime_end_time
)
5290 else if ((alpha
->hard_lifetime_end_time
==
5291 beta
->hard_lifetime_end_time
) &&
5292 (alpha
->soft_lifetime_end_time
<
5293 beta
->soft_lifetime_end_time
))
5302 log_fatal("Impossible condition at %s:%d.", MDL
);
5307 switch (beta
->state
) {
5313 /* Choose the prefix that was abandoned longest ago. */
5314 if (alpha
->hard_lifetime_end_time
<
5315 beta
->hard_lifetime_end_time
)
5321 log_fatal("Impossible condition at %s:%d.", MDL
);
5326 log_fatal("Impossible condition at %s:%d.", MDL
);
5329 log_fatal("Triple impossible condition at %s:%d.", MDL
);
5334 * Solicit is how a client starts requesting addresses.
5336 * If the client asks for rapid commit, and we support it, we will
5337 * allocate the addresses and reply.
5339 * Otherwise we will send an advertise message.
5343 dhcpv6_solicit(struct data_string
*reply_ret
, struct packet
*packet
) {
5344 struct data_string client_id
;
5347 * Validate our input.
5349 if (!valid_client_msg(packet
, &client_id
)) {
5353 lease_to_client(reply_ret
, packet
, &client_id
, NULL
);
5358 data_string_forget(&client_id
, MDL
);
5362 * Request is how a client actually requests addresses.
5364 * Very similar to Solicit handling, except the server DUID is required.
5368 dhcpv6_request(struct data_string
*reply_ret
, struct packet
*packet
) {
5369 struct data_string client_id
;
5370 struct data_string server_id
;
5373 * Validate our input.
5375 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5379 /* If the REQUEST arrived via unicast and unicast option isn't set,
5380 * reject it per RFC 3315, Sec 18.2.1 */
5381 if (packet
->unicast
== ISC_TRUE
&&
5382 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5383 unicast_reject(reply_ret
, packet
, &client_id
, &server_id
);
5388 lease_to_client(reply_ret
, packet
, &client_id
, &server_id
);
5394 data_string_forget(&client_id
, MDL
);
5395 data_string_forget(&server_id
, MDL
);
5398 /* Find a DHCPv6 packet's shared network from hints in the packet.
5401 shared_network_from_packet6(struct shared_network
**shared
,
5402 struct packet
*packet
)
5404 const struct packet
*chk_packet
;
5405 const struct in6_addr
*link_addr
, *first_link_addr
;
5406 struct iaddr tmp_addr
;
5407 struct subnet
*subnet
;
5408 isc_result_t status
;
5410 if ((shared
== NULL
) || (*shared
!= NULL
) || (packet
== NULL
))
5411 return DHCP_R_INVALIDARG
;
5414 * First, find the link address where the packet from the client
5415 * first appeared (if this packet was relayed).
5417 first_link_addr
= NULL
;
5418 chk_packet
= packet
->dhcpv6_container_packet
;
5419 while (chk_packet
!= NULL
) {
5420 link_addr
= &chk_packet
->dhcpv6_link_address
;
5421 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
5422 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
5423 first_link_addr
= link_addr
;
5426 chk_packet
= chk_packet
->dhcpv6_container_packet
;
5430 * If there is a relayed link address, find the subnet associated
5431 * with that, and use that to get the appropriate
5434 if (first_link_addr
!= NULL
) {
5435 tmp_addr
.len
= sizeof(*first_link_addr
);
5436 memcpy(tmp_addr
.iabuf
,
5437 first_link_addr
, sizeof(*first_link_addr
));
5439 if (!find_subnet(&subnet
, tmp_addr
, MDL
)) {
5440 log_debug("No subnet found for link-address %s.",
5442 return ISC_R_NOTFOUND
;
5444 status
= shared_network_reference(shared
,
5445 subnet
->shared_network
, MDL
);
5446 subnet_dereference(&subnet
, MDL
);
5449 * If there is no link address, we will use the interface
5450 * that this packet came in on to pick the shared_network.
5452 } else if (packet
->interface
!= NULL
) {
5453 status
= shared_network_reference(shared
,
5454 packet
->interface
->shared_network
,
5456 if (packet
->dhcpv6_container_packet
!= NULL
) {
5457 log_info("[L2 Relay] No link address in relay packet "
5458 "assuming L2 relay and using receiving "
5464 * We shouldn't be able to get here but if there is no link
5465 * address and no interface we don't know where to get the
5466 * pool from log an error and return an error.
5468 log_error("No interface and no link address "
5469 "can't determine pool");
5470 status
= DHCP_R_INVALIDARG
;
5477 * When a client thinks it might be on a new link, it sends a
5480 * From RFC3315 section 18.2.2:
5482 * When the server receives a Confirm message, the server determines
5483 * whether the addresses in the Confirm message are appropriate for the
5484 * link to which the client is attached. If all of the addresses in the
5485 * Confirm message pass this test, the server returns a status of
5486 * Success. If any of the addresses do not pass this test, the server
5487 * returns a status of NotOnLink. If the server is unable to perform
5488 * this test (for example, the server does not have information about
5489 * prefixes on the link to which the client is connected), or there were
5490 * no addresses in any of the IAs sent by the client, the server MUST
5491 * NOT send a reply to the client.
5495 dhcpv6_confirm(struct data_string
*reply_ret
, struct packet
*packet
) {
5496 struct shared_network
*shared
;
5497 struct subnet
*subnet
;
5498 struct option_cache
*ia
, *ta
, *oc
;
5499 struct data_string cli_enc_opt_data
, iaaddr
, client_id
, packet_oro
;
5500 struct option_state
*cli_enc_opt_state
, *opt_state
;
5501 struct iaddr cli_addr
;
5503 isc_boolean_t inappropriate
, has_addrs
;
5504 char reply_data
[65536];
5505 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5506 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5509 * Basic client message validation.
5511 memset(&client_id
, 0, sizeof(client_id
));
5512 if (!valid_client_msg(packet
, &client_id
)) {
5517 * Do not process Confirms that do not have IA's we do not recognize.
5519 ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5520 ta
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
5521 if ((ia
== NULL
) && (ta
== NULL
))
5525 * IA_PD's are simply ignored.
5527 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5530 * Bit of variable initialization.
5532 opt_state
= cli_enc_opt_state
= NULL
;
5533 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5534 memset(&iaaddr
, 0, sizeof(iaaddr
));
5535 memset(&packet_oro
, 0, sizeof(packet_oro
));
5537 /* Determine what shared network the client is connected to. We
5538 * must not respond if we don't have any information about the
5539 * network the client is on.
5542 if ((shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
) ||
5546 /* If there are no recorded subnets, then we have no
5547 * information about this subnet - ignore Confirms.
5549 subnet
= shared
->subnets
;
5553 /* Are the addresses in all the IA's appropriate for that link? */
5554 has_addrs
= inappropriate
= ISC_FALSE
;
5556 while(!inappropriate
) {
5557 /* If we've reached the end of the IA_NA pass, move to the
5560 if ((pass
== D6O_IA_NA
) && (ia
== NULL
)) {
5565 /* If we've reached the end of all passes, we're done. */
5569 if (((pass
== D6O_IA_NA
) &&
5570 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5572 packet
, ia
, IA_NA_OFFSET
)) ||
5573 ((pass
== D6O_IA_TA
) &&
5574 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5576 packet
, ia
, IA_TA_OFFSET
))) {
5580 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5583 for ( ; oc
!= NULL
; oc
= oc
->next
) {
5584 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5585 packet
->options
, NULL
,
5586 &global_scope
, oc
, MDL
) ||
5587 (iaaddr
.len
< IAADDR_OFFSET
)) {
5588 log_error("dhcpv6_confirm: "
5589 "error evaluating IAADDR.");
5593 /* Copy out the IPv6 address for processing. */
5595 memcpy(cli_addr
.iabuf
, iaaddr
.data
, 16);
5597 data_string_forget(&iaaddr
, MDL
);
5599 /* Record that we've processed at least one address. */
5600 has_addrs
= ISC_TRUE
;
5602 /* Find out if any subnets cover this address. */
5603 for (subnet
= shared
->subnets
; subnet
!= NULL
;
5604 subnet
= subnet
->next_sibling
) {
5605 if (addr_eq(subnet_number(cli_addr
,
5611 /* If we reach the end of the subnet list, and no
5612 * subnet matches the client address, then it must
5613 * be inappropriate to the link (so far as our
5614 * configuration says). Once we've found one
5615 * inappropriate address, there is no reason to
5616 * continue searching.
5618 if (subnet
== NULL
) {
5619 inappropriate
= ISC_TRUE
;
5624 option_state_dereference(&cli_enc_opt_state
, MDL
);
5625 data_string_forget(&cli_enc_opt_data
, MDL
);
5627 /* Advance to the next IA_*. */
5631 /* If the client supplied no addresses, do not reply. */
5638 if (!start_reply(packet
, &client_id
, NULL
, &opt_state
, reply
)) {
5645 if (inappropriate
) {
5646 if (!set_status_code(STATUS_NotOnLink
,
5647 "Some of the addresses are not on link.",
5652 if (!set_status_code(STATUS_Success
,
5653 "All addresses still on link.",
5660 * Only one option: add it.
5662 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5663 sizeof(reply_data
)-reply_ofs
,
5665 required_opts
, &packet_oro
);
5668 * Return our reply to the caller.
5670 reply_ret
->len
= reply_ofs
;
5671 reply_ret
->buffer
= NULL
;
5672 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5673 log_fatal("No memory to store reply.");
5675 reply_ret
->data
= reply_ret
->buffer
->data
;
5676 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5679 /* Cleanup any stale data strings. */
5680 if (cli_enc_opt_data
.buffer
!= NULL
)
5681 data_string_forget(&cli_enc_opt_data
, MDL
);
5682 if (iaaddr
.buffer
!= NULL
)
5683 data_string_forget(&iaaddr
, MDL
);
5684 if (client_id
.buffer
!= NULL
)
5685 data_string_forget(&client_id
, MDL
);
5686 if (packet_oro
.buffer
!= NULL
)
5687 data_string_forget(&packet_oro
, MDL
);
5689 /* Release any stale option states. */
5690 if (cli_enc_opt_state
!= NULL
)
5691 option_state_dereference(&cli_enc_opt_state
, MDL
);
5692 if (opt_state
!= NULL
)
5693 option_state_dereference(&opt_state
, MDL
);
5697 * Renew is when a client wants to extend its lease/prefix, at time T1.
5699 * We handle this the same as if the client wants a new lease/prefix,
5700 * except for the error code of when addresses don't match.
5704 dhcpv6_renew(struct data_string
*reply
, struct packet
*packet
) {
5705 struct data_string client_id
;
5706 struct data_string server_id
;
5709 * Validate the request.
5711 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5715 /* If the RENEW arrived via unicast and unicast option isn't set,
5716 * reject it per RFC 3315, Sec 18.2.3 */
5717 if (packet
->unicast
== ISC_TRUE
&&
5718 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5719 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5724 lease_to_client(reply
, packet
, &client_id
, &server_id
);
5730 data_string_forget(&server_id
, MDL
);
5731 data_string_forget(&client_id
, MDL
);
5735 * Rebind is when a client wants to extend its lease, at time T2.
5737 * We handle this the same as if the client wants a new lease, except
5738 * for the error code of when addresses don't match.
5742 dhcpv6_rebind(struct data_string
*reply
, struct packet
*packet
) {
5743 struct data_string client_id
;
5745 if (!valid_client_msg(packet
, &client_id
)) {
5749 lease_to_client(reply
, packet
, &client_id
, NULL
);
5751 data_string_forget(&client_id
, MDL
);
5755 ia_na_match_decline(const struct data_string
*client_id
,
5756 const struct data_string
*iaaddr
,
5757 struct iasubopt
*lease
)
5759 char tmp_addr
[INET6_ADDRSTRLEN
];
5761 log_error("Client %s reports address %s is "
5762 "already in use by another host!",
5763 print_hex_1(client_id
->len
, client_id
->data
, 60),
5764 inet_ntop(AF_INET6
, iaaddr
->data
,
5765 tmp_addr
, sizeof(tmp_addr
)));
5766 if (lease
!= NULL
) {
5767 decline_lease6(lease
->ipv6_pool
, lease
);
5768 lease
->ia
->cltt
= cur_time
;
5769 write_ia(lease
->ia
);
5774 ia_na_nomatch_decline(const struct data_string
*client_id
,
5775 const struct data_string
*iaaddr
,
5776 u_int32_t
*ia_na_id
,
5777 struct packet
*packet
,
5782 char tmp_addr
[INET6_ADDRSTRLEN
];
5783 struct option_state
*host_opt_state
;
5786 log_info("Client %s declines address %s, which is not offered to it.",
5787 print_hex_1(client_id
->len
, client_id
->data
, 60),
5788 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5791 * Create state for this IA_NA.
5793 host_opt_state
= NULL
;
5794 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5795 log_error("ia_na_nomatch_decline: out of memory "
5796 "allocating option_state.");
5800 if (!set_status_code(STATUS_NoBinding
, "Decline for unknown address.",
5806 * Insure we have enough space
5808 if (reply_len
< (*reply_ofs
+ 16)) {
5809 log_error("ia_na_nomatch_decline: "
5810 "out of space for reply packet.");
5815 * Put our status code into the reply packet.
5817 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5818 reply_len
-(*reply_ofs
)-16,
5819 host_opt_state
, packet
,
5820 required_opts_STATUS_CODE
, NULL
);
5823 * Store the non-encapsulated option data for this
5824 * IA_NA into our reply packet. Defined in RFC 3315,
5828 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5830 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5831 /* IA_NA, copied from the client */
5832 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5833 /* t1 and t2, odd that we need them, but here it is */
5834 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5835 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5838 * Get ready for next IA_NA.
5840 *reply_ofs
+= (len
+ 16);
5843 option_state_dereference(&host_opt_state
, MDL
);
5847 iterate_over_ia_na(struct data_string
*reply_ret
,
5848 struct packet
*packet
,
5849 const struct data_string
*client_id
,
5850 const struct data_string
*server_id
,
5851 const char *packet_type
,
5852 void (*ia_na_match
)(),
5853 void (*ia_na_nomatch
)())
5855 struct option_state
*opt_state
;
5856 struct host_decl
*packet_host
;
5857 struct option_cache
*ia
;
5858 struct option_cache
*oc
;
5859 /* cli_enc_... variables come from the IA_NA/IA_TA options */
5860 struct data_string cli_enc_opt_data
;
5861 struct option_state
*cli_enc_opt_state
;
5862 struct host_decl
*host
;
5863 struct data_string iaaddr
;
5864 struct data_string fixed_addr
;
5865 char reply_data
[65536];
5866 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5867 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5868 char status_msg
[32];
5869 struct iasubopt
*lease
;
5870 struct ia_xx
*existing_ia_na
;
5872 struct data_string key
;
5876 * Initialize to empty values, in case we have to exit early.
5879 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5880 cli_enc_opt_state
= NULL
;
5881 memset(&iaaddr
, 0, sizeof(iaaddr
));
5882 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
5886 * Find the host record that matches from the packet, if any.
5889 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
5892 * Set our reply information.
5894 reply
->msg_type
= DHCPV6_REPLY
;
5895 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
5896 sizeof(reply
->transaction_id
));
5899 * Build our option state for reply.
5902 if (!option_state_allocate(&opt_state
, MDL
)) {
5903 log_error("iterate_over_ia_na: no memory for option_state.");
5906 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5907 packet
->options
, opt_state
,
5908 &global_scope
, root_group
, NULL
, NULL
);
5911 * RFC 3315, section 18.2.7 tells us which options to include.
5913 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
5915 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5916 (unsigned char *)server_duid
.data
,
5917 server_duid
.len
, D6O_SERVERID
, 0)) {
5918 log_error("iterate_over_ia_na: "
5919 "error saving server identifier.");
5924 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
5926 (unsigned char *)client_id
->data
,
5929 log_error("iterate_over_ia_na: "
5930 "error saving client identifier.");
5934 snprintf(status_msg
, sizeof(status_msg
), "%s received.", packet_type
);
5935 if (!set_status_code(STATUS_Success
, status_msg
, opt_state
)) {
5940 * Add our options that are not associated with any IA_NA or IA_TA.
5942 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5943 sizeof(reply_data
)-reply_ofs
,
5945 required_opts
, NULL
);
5948 * Loop through the IA_NA reported by the client, and deal with
5949 * addresses reported as already in use.
5951 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5952 ia
!= NULL
; ia
= ia
->next
) {
5954 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
5956 packet
, ia
, IA_NA_OFFSET
)) {
5960 iaid
= getULong(cli_enc_opt_data
.data
);
5963 * XXX: It is possible that we can get multiple addresses
5964 * sent by the client. We don't send multiple
5965 * addresses, so this indicates a client error.
5966 * We should check for multiple IAADDR options, log
5967 * if found, and set as an error.
5969 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5972 /* no address given for this IA, ignore */
5973 option_state_dereference(&cli_enc_opt_state
, MDL
);
5974 data_string_forget(&cli_enc_opt_data
, MDL
);
5978 memset(&iaaddr
, 0, sizeof(iaaddr
));
5979 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5980 packet
->options
, NULL
,
5981 &global_scope
, oc
, MDL
)) {
5982 log_error("iterate_over_ia_na: "
5983 "error evaluating IAADDR.");
5988 * Now we need to figure out which host record matches
5989 * this IA_NA and IAADDR (encapsulated option contents
5990 * matching a host record by option).
5992 * XXX: We don't currently track IA_NA separately, but
5993 * we will need to do this!
5996 if (!find_hosts_by_option(&host
, packet
,
5997 cli_enc_opt_state
, MDL
)) {
5998 if (packet_host
!= NULL
) {
6004 while (host
!= NULL
) {
6005 if (host
->fixed_addr
!= NULL
) {
6006 if (!evaluate_option_cache(&fixed_addr
, NULL
,
6008 NULL
, &global_scope
,
6011 log_error("iterate_over_ia_na: error "
6012 "evaluating host address.");
6015 if ((iaaddr
.len
>= 16) &&
6016 !memcmp(fixed_addr
.data
, iaaddr
.data
, 16)) {
6017 data_string_forget(&fixed_addr
, MDL
);
6020 data_string_forget(&fixed_addr
, MDL
);
6022 host
= host
->n_ipaddr
;
6025 if ((host
== NULL
) && (iaaddr
.len
>= IAADDR_OFFSET
)) {
6027 * Find existing IA_NA.
6029 if (ia_make_key(&key
, iaid
,
6030 (char *)client_id
->data
,
6032 MDL
) != ISC_R_SUCCESS
) {
6033 log_fatal("iterate_over_ia_na: no memory for "
6037 existing_ia_na
= NULL
;
6038 if (ia_hash_lookup(&existing_ia_na
, ia_na_active
,
6039 (unsigned char *)key
.data
,
6042 * Make sure this address is in the IA_NA.
6044 for (i
=0; i
<existing_ia_na
->num_iasubopt
; i
++) {
6045 struct iasubopt
*tmp
;
6046 struct in6_addr
*in6_addr
;
6048 tmp
= existing_ia_na
->iasubopt
[i
];
6049 in6_addr
= &tmp
->addr
;
6050 if (memcmp(in6_addr
,
6051 iaaddr
.data
, 16) == 0) {
6052 iasubopt_reference(&lease
,
6059 data_string_forget(&key
, MDL
);
6062 if ((host
!= NULL
) || (lease
!= NULL
)) {
6063 ia_na_match(client_id
, &iaaddr
, lease
);
6065 ia_na_nomatch(client_id
, &iaaddr
,
6066 (u_int32_t
*)cli_enc_opt_data
.data
,
6067 packet
, reply_data
, &reply_ofs
,
6068 sizeof(reply_data
));
6071 if (lease
!= NULL
) {
6072 iasubopt_dereference(&lease
, MDL
);
6075 data_string_forget(&iaaddr
, MDL
);
6076 option_state_dereference(&cli_enc_opt_state
, MDL
);
6077 data_string_forget(&cli_enc_opt_data
, MDL
);
6081 * Return our reply to the caller.
6083 reply_ret
->len
= reply_ofs
;
6084 reply_ret
->buffer
= NULL
;
6085 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
6086 log_fatal("No memory to store reply.");
6088 reply_ret
->data
= reply_ret
->buffer
->data
;
6089 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
6092 if (lease
!= NULL
) {
6093 iasubopt_dereference(&lease
, MDL
);
6095 if (fixed_addr
.buffer
!= NULL
) {
6096 data_string_forget(&fixed_addr
, MDL
);
6098 if (iaaddr
.buffer
!= NULL
) {
6099 data_string_forget(&iaaddr
, MDL
);
6101 if (cli_enc_opt_state
!= NULL
) {
6102 option_state_dereference(&cli_enc_opt_state
, MDL
);
6104 if (cli_enc_opt_data
.buffer
!= NULL
) {
6105 data_string_forget(&cli_enc_opt_data
, MDL
);
6107 if (opt_state
!= NULL
) {
6108 option_state_dereference(&opt_state
, MDL
);
6113 * Decline means a client has detected that something else is using an
6114 * address we gave it.
6116 * Since we're only dealing with fixed leases for now, there's not
6117 * much we can do, other that log the occurrence.
6119 * When we start issuing addresses from pools, then we will have to
6120 * record our declined addresses and issue another. In general with
6121 * IPv6 there is no worry about DoS by clients exhausting space, but
6122 * we still need to be aware of this possibility.
6127 dhcpv6_decline(struct data_string
*reply
, struct packet
*packet
) {
6128 struct data_string client_id
;
6129 struct data_string server_id
;
6132 * Validate our input.
6134 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
6138 /* If the DECLINE arrived via unicast and unicast option isn't set,
6139 * reject it per RFC 3315, Sec 18.2.7 */
6140 if (packet
->unicast
== ISC_TRUE
&&
6141 is_unicast_option_defined(packet
) == ISC_FALSE
) {
6142 unicast_reject(reply
, packet
, &client_id
, &server_id
);
6145 * Undefined for IA_PD.
6147 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
6150 * And operate on each IA_NA in this packet.
6152 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
6153 "Decline", ia_na_match_decline
,
6154 ia_na_nomatch_decline
);
6158 data_string_forget(&server_id
, MDL
);
6159 data_string_forget(&client_id
, MDL
);
6163 ia_na_match_release(const struct data_string
*client_id
,
6164 const struct data_string
*iaaddr
,
6165 struct iasubopt
*lease
)
6167 char tmp_addr
[INET6_ADDRSTRLEN
];
6169 log_info("Client %s releases address %s",
6170 print_hex_1(client_id
->len
, client_id
->data
, 60),
6171 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
6172 if (lease
!= NULL
) {
6173 release_lease6(lease
->ipv6_pool
, lease
);
6174 lease
->ia
->cltt
= cur_time
;
6175 write_ia(lease
->ia
);
6180 ia_na_nomatch_release(const struct data_string
*client_id
,
6181 const struct data_string
*iaaddr
,
6182 u_int32_t
*ia_na_id
,
6183 struct packet
*packet
,
6188 char tmp_addr
[INET6_ADDRSTRLEN
];
6189 struct option_state
*host_opt_state
;
6192 log_info("Client %s releases address %s, which is not leased to it.",
6193 print_hex_1(client_id
->len
, client_id
->data
, 60),
6194 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
6197 * Create state for this IA_NA.
6199 host_opt_state
= NULL
;
6200 if (!option_state_allocate(&host_opt_state
, MDL
)) {
6201 log_error("ia_na_nomatch_release: out of memory "
6202 "allocating option_state.");
6206 if (!set_status_code(STATUS_NoBinding
,
6207 "Release for non-leased address.",
6213 * Insure we have enough space
6215 if (reply_len
< (*reply_ofs
+ 16)) {
6216 log_error("ia_na_nomatch_release: "
6217 "out of space for reply packet.");
6222 * Put our status code into the reply packet.
6224 len
= store_options6(reply_data
+(*reply_ofs
)+16,
6225 reply_len
-(*reply_ofs
)-16,
6226 host_opt_state
, packet
,
6227 required_opts_STATUS_CODE
, NULL
);
6230 * Store the non-encapsulated option data for this
6231 * IA_NA into our reply packet. Defined in RFC 3315,
6235 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
6237 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
6238 /* IA_NA, copied from the client */
6239 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
6240 /* t1 and t2, odd that we need them, but here it is */
6241 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
6242 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
6245 * Get ready for next IA_NA.
6247 *reply_ofs
+= (len
+ 16);
6250 option_state_dereference(&host_opt_state
, MDL
);
6254 ia_pd_match_release(const struct data_string
*client_id
,
6255 const struct data_string
*iapref
,
6256 struct iasubopt
*prefix
)
6258 char tmp_addr
[INET6_ADDRSTRLEN
];
6260 log_info("Client %s releases prefix %s/%u",
6261 print_hex_1(client_id
->len
, client_id
->data
, 60),
6262 inet_ntop(AF_INET6
, iapref
->data
+ 9,
6263 tmp_addr
, sizeof(tmp_addr
)),
6264 (unsigned) getUChar(iapref
->data
+ 8));
6265 if (prefix
!= NULL
) {
6266 release_lease6(prefix
->ipv6_pool
, prefix
);
6267 prefix
->ia
->cltt
= cur_time
;
6268 write_ia(prefix
->ia
);
6273 ia_pd_nomatch_release(const struct data_string
*client_id
,
6274 const struct data_string
*iapref
,
6275 u_int32_t
*ia_pd_id
,
6276 struct packet
*packet
,
6281 char tmp_addr
[INET6_ADDRSTRLEN
];
6282 struct option_state
*host_opt_state
;
6285 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
6286 print_hex_1(client_id
->len
, client_id
->data
, 60),
6287 inet_ntop(AF_INET6
, iapref
->data
+ 9,
6288 tmp_addr
, sizeof(tmp_addr
)),
6289 (unsigned) getUChar(iapref
->data
+ 8));
6292 * Create state for this IA_PD.
6294 host_opt_state
= NULL
;
6295 if (!option_state_allocate(&host_opt_state
, MDL
)) {
6296 log_error("ia_pd_nomatch_release: out of memory "
6297 "allocating option_state.");
6301 if (!set_status_code(STATUS_NoBinding
,
6302 "Release for non-leased prefix.",
6308 * Insure we have enough space
6310 if (reply_len
< (*reply_ofs
+ 16)) {
6311 log_error("ia_pd_nomatch_release: "
6312 "out of space for reply packet.");
6317 * Put our status code into the reply packet.
6319 len
= store_options6(reply_data
+(*reply_ofs
)+16,
6320 reply_len
-(*reply_ofs
)-16,
6321 host_opt_state
, packet
,
6322 required_opts_STATUS_CODE
, NULL
);
6325 * Store the non-encapsulated option data for this
6326 * IA_PD into our reply packet. Defined in RFC 3315,
6330 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_PD
);
6332 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
6333 /* IA_PD, copied from the client */
6334 memcpy(reply_data
+(*reply_ofs
)+4, ia_pd_id
, 4);
6335 /* t1 and t2, odd that we need them, but here it is */
6336 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
6337 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
6340 * Get ready for next IA_PD.
6342 *reply_ofs
+= (len
+ 16);
6345 option_state_dereference(&host_opt_state
, MDL
);
6349 iterate_over_ia_pd(struct data_string
*reply_ret
,
6350 struct packet
*packet
,
6351 const struct data_string
*client_id
,
6352 const struct data_string
*server_id
,
6353 const char *packet_type
,
6354 void (*ia_pd_match
)(),
6355 void (*ia_pd_nomatch
)())
6357 struct data_string reply_new
;
6359 struct option_state
*opt_state
;
6360 struct host_decl
*packet_host
;
6361 struct option_cache
*ia
;
6362 struct option_cache
*oc
;
6363 /* cli_enc_... variables come from the IA_PD options */
6364 struct data_string cli_enc_opt_data
;
6365 struct option_state
*cli_enc_opt_state
;
6366 struct host_decl
*host
;
6367 struct data_string iaprefix
;
6368 char reply_data
[65536];
6370 struct iasubopt
*prefix
;
6371 struct ia_xx
*existing_ia_pd
;
6373 struct data_string key
;
6377 * Initialize to empty values, in case we have to exit early.
6379 memset(&reply_new
, 0, sizeof(reply_new
));
6381 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
6382 cli_enc_opt_state
= NULL
;
6383 memset(&iaprefix
, 0, sizeof(iaprefix
));
6387 * Compute the available length for the reply.
6389 reply_len
= sizeof(reply_data
) - reply_ret
->len
;
6393 * Find the host record that matches from the packet, if any.
6396 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
6399 * Build our option state for reply.
6402 if (!option_state_allocate(&opt_state
, MDL
)) {
6403 log_error("iterate_over_ia_pd: no memory for option_state.");
6406 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
6407 packet
->options
, opt_state
,
6408 &global_scope
, root_group
, NULL
, NULL
);
6411 * Loop through the IA_PD reported by the client, and deal with
6412 * prefixes reported as already in use.
6414 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
6415 ia
!= NULL
; ia
= ia
->next
) {
6417 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
6419 packet
, ia
, IA_PD_OFFSET
)) {
6423 iaid
= getULong(cli_enc_opt_data
.data
);
6425 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
6428 /* no prefix given for this IA_PD, ignore */
6429 option_state_dereference(&cli_enc_opt_state
, MDL
);
6430 data_string_forget(&cli_enc_opt_data
, MDL
);
6434 for (; oc
!= NULL
; oc
= oc
->next
) {
6435 memset(&iaprefix
, 0, sizeof(iaprefix
));
6436 if (!evaluate_option_cache(&iaprefix
, packet
, NULL
, NULL
,
6437 packet
->options
, NULL
,
6438 &global_scope
, oc
, MDL
)) {
6439 log_error("iterate_over_ia_pd: "
6440 "error evaluating IAPREFIX.");
6445 * Now we need to figure out which host record matches
6446 * this IA_PD and IAPREFIX (encapsulated option contents
6447 * matching a host record by option).
6449 * XXX: We don't currently track IA_PD separately, but
6450 * we will need to do this!
6453 if (!find_hosts_by_option(&host
, packet
,
6454 cli_enc_opt_state
, MDL
)) {
6455 if (packet_host
!= NULL
) {
6461 while (host
!= NULL
) {
6462 if (host
->fixed_prefix
!= NULL
) {
6463 struct iaddrcidrnetlist
*l
;
6464 int plen
= (int) getUChar(iaprefix
.data
+ 8);
6466 for (l
= host
->fixed_prefix
; l
!= NULL
;
6468 if (plen
!= l
->cidrnet
.bits
)
6470 if (memcmp(iaprefix
.data
+ 9,
6471 l
->cidrnet
.lo_addr
.iabuf
,
6475 if ((l
!= NULL
) && (iaprefix
.len
>= 17))
6478 host
= host
->n_ipaddr
;
6481 if ((host
== NULL
) && (iaprefix
.len
>= IAPREFIX_OFFSET
)) {
6483 * Find existing IA_PD.
6485 if (ia_make_key(&key
, iaid
,
6486 (char *)client_id
->data
,
6488 MDL
) != ISC_R_SUCCESS
) {
6489 log_fatal("iterate_over_ia_pd: no memory for "
6493 existing_ia_pd
= NULL
;
6494 if (ia_hash_lookup(&existing_ia_pd
, ia_pd_active
,
6495 (unsigned char *)key
.data
,
6498 * Make sure this prefix is in the IA_PD.
6501 i
< existing_ia_pd
->num_iasubopt
;
6503 struct iasubopt
*tmp
;
6506 plen
= getUChar(iaprefix
.data
+ 8);
6507 tmp
= existing_ia_pd
->iasubopt
[i
];
6508 if ((tmp
->plen
== plen
) &&
6512 iasubopt_reference(&prefix
,
6519 data_string_forget(&key
, MDL
);
6522 if ((host
!= NULL
) || (prefix
!= NULL
)) {
6523 ia_pd_match(client_id
, &iaprefix
, prefix
);
6525 ia_pd_nomatch(client_id
, &iaprefix
,
6526 (u_int32_t
*)cli_enc_opt_data
.data
,
6527 packet
, reply_data
, &reply_ofs
,
6528 reply_len
- reply_ofs
);
6531 if (prefix
!= NULL
) {
6532 iasubopt_dereference(&prefix
, MDL
);
6535 data_string_forget(&iaprefix
, MDL
);
6538 option_state_dereference(&cli_enc_opt_state
, MDL
);
6539 data_string_forget(&cli_enc_opt_data
, MDL
);
6543 * Return our reply to the caller.
6544 * The IA_NA routine has already filled at least the header.
6546 reply_new
.len
= reply_ret
->len
+ reply_ofs
;
6547 if (!buffer_allocate(&reply_new
.buffer
, reply_new
.len
, MDL
)) {
6548 log_fatal("No memory to store reply.");
6550 reply_new
.data
= reply_new
.buffer
->data
;
6551 memcpy(reply_new
.buffer
->data
,
6552 reply_ret
->buffer
->data
, reply_ret
->len
);
6553 memcpy(reply_new
.buffer
->data
+ reply_ret
->len
,
6554 reply_data
, reply_ofs
);
6555 data_string_forget(reply_ret
, MDL
);
6556 data_string_copy(reply_ret
, &reply_new
, MDL
);
6557 data_string_forget(&reply_new
, MDL
);
6560 if (prefix
!= NULL
) {
6561 iasubopt_dereference(&prefix
, MDL
);
6563 if (iaprefix
.buffer
!= NULL
) {
6564 data_string_forget(&iaprefix
, MDL
);
6566 if (cli_enc_opt_state
!= NULL
) {
6567 option_state_dereference(&cli_enc_opt_state
, MDL
);
6569 if (cli_enc_opt_data
.buffer
!= NULL
) {
6570 data_string_forget(&cli_enc_opt_data
, MDL
);
6572 if (opt_state
!= NULL
) {
6573 option_state_dereference(&opt_state
, MDL
);
6578 * Release means a client is done with the leases.
6582 dhcpv6_release(struct data_string
*reply
, struct packet
*packet
) {
6583 struct data_string client_id
;
6584 struct data_string server_id
;
6587 * Validate our input.
6589 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
6593 /* If the RELEASE arrived via unicast and unicast option isn't set,
6594 * reject it per RFC 3315, Sec 18.2.6 */
6595 if (packet
->unicast
== ISC_TRUE
&&
6596 is_unicast_option_defined(packet
) == ISC_FALSE
) {
6597 unicast_reject(reply
, packet
, &client_id
, &server_id
);
6600 * And operate on each IA_NA in this packet.
6602 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
6603 "Release", ia_na_match_release
,
6604 ia_na_nomatch_release
);
6607 * And operate on each IA_PD in this packet.
6609 iterate_over_ia_pd(reply
, packet
, &client_id
, &server_id
,
6610 "Release", ia_pd_match_release
,
6611 ia_pd_nomatch_release
);
6614 data_string_forget(&server_id
, MDL
);
6615 data_string_forget(&client_id
, MDL
);
6619 * Information-Request is used by clients who have obtained an address
6620 * from other means, but want configuration information from the server.
6624 dhcpv6_information_request(struct data_string
*reply
, struct packet
*packet
) {
6625 struct data_string client_id
;
6626 struct data_string server_id
;
6629 * Validate our input.
6631 if (!valid_client_info_req(packet
, &server_id
)) {
6636 * Get our client ID, if there is one.
6638 memset(&client_id
, 0, sizeof(client_id
));
6639 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
) {
6640 data_string_forget(&client_id
, MDL
);
6644 * Use the lease_to_client() function. This will work fine,
6645 * because the valid_client_info_req() insures that we
6646 * don't have any IA that would cause us to allocate
6647 * resources to the client.
6649 lease_to_client(reply
, packet
, &client_id
,
6650 server_id
.data
!= NULL
? &server_id
: NULL
);
6655 if (client_id
.data
!= NULL
) {
6656 data_string_forget(&client_id
, MDL
);
6658 data_string_forget(&server_id
, MDL
);
6662 * The Relay-forw message is sent by relays. It typically contains a
6663 * single option, which encapsulates an entire packet.
6665 * We need to build an encapsulated reply.
6668 /* XXX: this is very, very similar to do_packet6(), and should probably
6669 be combined in a clever way */
6670 /* DHCPv6 server side */
6672 dhcpv6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
6673 struct option_cache
*oc
;
6674 struct data_string enc_opt_data
;
6675 struct packet
*enc_packet
;
6676 unsigned char msg_type
;
6677 const struct dhcpv6_packet
*msg
;
6678 const struct dhcpv6_relay_packet
*relay
;
6679 struct data_string enc_reply
;
6680 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6681 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6682 struct data_string a_opt
, packet_ero
;
6683 struct option_state
*opt_state
;
6684 static char reply_data
[65536];
6685 struct dhcpv6_relay_packet
*reply
;
6689 * Initialize variables for early exit.
6692 memset(&a_opt
, 0, sizeof(a_opt
));
6693 memset(&packet_ero
, 0, sizeof(packet_ero
));
6694 memset(&enc_reply
, 0, sizeof(enc_reply
));
6695 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6699 * Get our encapsulated relay message.
6701 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
6703 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
6704 link_addr
, sizeof(link_addr
));
6705 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
6706 peer_addr
, sizeof(peer_addr
));
6707 log_info("Relay-forward from %s with link address=%s and "
6708 "peer address=%s missing Relay Message option.",
6709 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
6713 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
6714 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
6715 /* should be dhcpv6_relay_forw */
6716 log_error("dhcpv6_forw_relay: error evaluating "
6717 "relayed message.");
6721 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
6722 /* should be dhcpv6_relay_forw */
6723 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
6728 * Build a packet structure from this encapsulated packet.
6731 if (!packet_allocate(&enc_packet
, MDL
)) {
6732 /* should be dhcpv6_relay_forw */
6733 log_error("dhcpv6_forw_relay: "
6734 "no memory for encapsulated packet.");
6738 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
6739 /* should be dhcpv6_relay_forw */
6740 log_error("dhcpv6_forw_relay: "
6741 "no memory for encapsulated packet's options.");
6745 enc_packet
->client_port
= packet
->client_port
;
6746 enc_packet
->client_addr
= packet
->client_addr
;
6747 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
6748 enc_packet
->dhcpv6_container_packet
= packet
;
6750 msg_type
= enc_opt_data
.data
[0];
6751 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
6752 (msg_type
== DHCPV6_RELAY_REPL
)) {
6753 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6754 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
6755 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
6757 /* relay-specific data */
6758 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
6759 memcpy(&enc_packet
->dhcpv6_link_address
,
6760 relay
->link_address
, sizeof(relay
->link_address
));
6761 memcpy(&enc_packet
->dhcpv6_peer_address
,
6762 relay
->peer_address
, sizeof(relay
->peer_address
));
6764 if (!parse_option_buffer(enc_packet
->options
,
6766 enc_opt_data
.len
- relaylen
,
6767 &dhcpv6_universe
)) {
6768 /* no logging here, as parse_option_buffer() logs all
6769 cases where it fails */
6772 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
6773 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6775 if (!dhcpv4_over_dhcpv6
||
6776 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6777 log_error("dhcpv6_relay_forw: "
6778 "unsupported %s message type.",
6779 dhcpv6_type_names
[msg_type
]);
6782 forw_dhcpv4_query(packet
);
6785 log_error("dhcpv6_relay_forw: unsupported %s message type.",
6786 dhcpv6_type_names
[msg_type
]);
6788 #endif /* DHCP4o6 */
6790 int msglen
= (int)(offsetof(struct dhcpv6_packet
, options
));
6791 msg
= (struct dhcpv6_packet
*)enc_opt_data
.data
;
6792 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
6794 /* message-specific data */
6795 memcpy(enc_packet
->dhcpv6_transaction_id
,
6796 msg
->transaction_id
,
6797 sizeof(enc_packet
->dhcpv6_transaction_id
));
6799 if (!parse_option_buffer(enc_packet
->options
,
6801 enc_opt_data
.len
- msglen
,
6802 &dhcpv6_universe
)) {
6803 /* no logging here, as parse_option_buffer() logs all
6804 cases where it fails */
6810 * This is recursive. It is possible to exceed maximum packet size.
6811 * XXX: This will cause the packet send to fail.
6813 build_dhcpv6_reply(&enc_reply
, enc_packet
);
6816 * If we got no encapsulated data, then it is discarded, and
6817 * our reply-forw is also discarded.
6819 if (enc_reply
.data
== NULL
) {
6824 * Now we can use the reply_data buffer.
6825 * Packet header stuff all comes from the forward message.
6827 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
6828 reply
->msg_type
= DHCPV6_RELAY_REPL
;
6829 reply
->hop_count
= packet
->dhcpv6_hop_count
;
6830 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
6831 sizeof(reply
->link_address
));
6832 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
6833 sizeof(reply
->peer_address
));
6834 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6837 * Get the reply option state.
6840 if (!option_state_allocate(&opt_state
, MDL
)) {
6841 log_error("dhcpv6_relay_forw: no memory for option state.");
6846 * Append the interface-id if present.
6848 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6851 if (!evaluate_option_cache(&a_opt
, packet
,
6853 packet
->options
, NULL
,
6854 &global_scope
, oc
, MDL
)) {
6855 log_error("dhcpv6_relay_forw: error evaluating "
6859 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6860 (unsigned char *)a_opt
.data
,
6862 D6O_INTERFACE_ID
, 0)) {
6863 log_error("dhcpv6_relay_forw: error saving "
6867 data_string_forget(&a_opt
, MDL
);
6870 #if defined(RELAY_PORT)
6872 * Append the relay_source_port option if present.
6874 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6875 D6O_RELAY_SOURCE_PORT
);
6877 if (!evaluate_option_cache(&a_opt
, packet
,
6879 packet
->options
, NULL
,
6880 &global_scope
, oc
, MDL
)) {
6881 log_error("dhcpv6_relay_forw: error evaluating "
6882 "Relay Source Port.");
6885 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6886 (unsigned char *)a_opt
.data
,
6888 D6O_RELAY_SOURCE_PORT
, 0)) {
6889 log_error("dhcpv6_relay_forw: error saving "
6890 "Relay Source Port.");
6893 data_string_forget(&a_opt
, MDL
);
6895 packet
->relay_source_port
= ISC_TRUE
;
6900 * Append our encapsulated stuff for caller.
6902 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6903 (unsigned char *)enc_reply
.data
,
6905 D6O_RELAY_MSG
, 0)) {
6906 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
6911 * Get the ERO if any.
6913 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
6918 if (!evaluate_option_cache(&packet_ero
, packet
,
6920 packet
->options
, NULL
,
6921 &global_scope
, oc
, MDL
) ||
6922 (packet_ero
.len
& 1)) {
6923 log_error("dhcpv6_relay_forw: error evaluating ERO.");
6927 /* Decode and apply the ERO. */
6928 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
6929 req
= getUShort(packet_ero
.data
+ i
);
6930 /* Already in the reply? */
6931 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
6934 /* Get it from the packet if present. */
6935 oc
= lookup_option(&dhcpv6_universe
,
6940 if (!evaluate_option_cache(&a_opt
, packet
,
6942 packet
->options
, NULL
,
6943 &global_scope
, oc
, MDL
)) {
6944 log_error("dhcpv6_relay_forw: error "
6945 "evaluating option %u.", req
);
6948 if (!save_option_buffer(&dhcpv6_universe
,
6951 (unsigned char *)a_opt
.data
,
6955 log_error("dhcpv6_relay_forw: error saving "
6959 data_string_forget(&a_opt
, MDL
);
6963 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
6964 sizeof(reply_data
) - reply_ofs
,
6966 required_opts_agent
, &packet_ero
);
6969 * Return our reply to the caller.
6971 reply_ret
->len
= reply_ofs
;
6972 reply_ret
->buffer
= NULL
;
6973 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
6974 log_fatal("No memory to store reply.");
6976 reply_ret
->data
= reply_ret
->buffer
->data
;
6977 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
6980 if (opt_state
!= NULL
)
6981 option_state_dereference(&opt_state
, MDL
);
6982 if (a_opt
.data
!= NULL
) {
6983 data_string_forget(&a_opt
, MDL
);
6985 if (packet_ero
.data
!= NULL
) {
6986 data_string_forget(&packet_ero
, MDL
);
6988 if (enc_reply
.data
!= NULL
) {
6989 data_string_forget(&enc_reply
, MDL
);
6991 if (enc_opt_data
.data
!= NULL
) {
6992 data_string_forget(&enc_opt_data
, MDL
);
6994 if (enc_packet
!= NULL
) {
6995 packet_dereference(&enc_packet
, MDL
);
7000 /* \brief Internal processing of a relayed DHCPv4-query
7001 * (DHCPv4 server side)
7003 * Code copied from \ref dhcpv6_relay_forw() which itself is
7004 * from \ref do_packet6().
7006 * \param reply_ret pointer to the response
7007 * \param packet the query
7010 dhcp4o6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
7011 struct option_cache
*oc
;
7012 struct data_string enc_opt_data
;
7013 struct packet
*enc_packet
;
7014 unsigned char msg_type
;
7015 const struct dhcpv6_relay_packet
*relay
;
7016 const struct dhcpv4_over_dhcpv6_packet
*msg
;
7017 struct data_string enc_reply
;
7018 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
7019 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
7020 struct data_string a_opt
, packet_ero
;
7021 struct option_state
*opt_state
;
7022 static char reply_data
[65536];
7023 struct dhcpv6_relay_packet
*reply
;
7027 * Initialize variables for early exit.
7030 memset(&a_opt
, 0, sizeof(a_opt
));
7031 memset(&packet_ero
, 0, sizeof(packet_ero
));
7032 memset(&enc_reply
, 0, sizeof(enc_reply
));
7033 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
7037 * Get our encapsulated relay message.
7039 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
7041 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
7042 link_addr
, sizeof(link_addr
));
7043 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
7044 peer_addr
, sizeof(peer_addr
));
7045 log_info("Relay-forward from %s with link address=%s and "
7046 "peer address=%s missing Relay Message option.",
7047 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
7051 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
7052 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
7053 log_error("dhcp4o6_relay_forw: error evaluating "
7054 "relayed message.");
7058 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
7059 log_error("dhcp4o6_relay_forw: "
7060 "encapsulated packet too short.");
7065 * Build a packet structure from this encapsulated packet.
7067 if (!packet_allocate(&enc_packet
, MDL
)) {
7068 log_error("dhcp4o6_relay_forw: "
7069 "no memory for encapsulated packet.");
7073 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
7074 log_error("dhcp4o6_relay_forw: "
7075 "no memory for encapsulated packet's options.");
7079 enc_packet
->client_port
= packet
->client_port
;
7080 enc_packet
->client_addr
= packet
->client_addr
;
7081 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
7082 enc_packet
->dhcpv6_container_packet
= packet
;
7084 msg_type
= enc_opt_data
.data
[0];
7085 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
7086 (msg_type
== DHCPV6_RELAY_REPL
)) {
7087 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
7088 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
7089 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
7091 /* relay-specific data */
7092 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
7093 memcpy(&enc_packet
->dhcpv6_link_address
,
7094 relay
->link_address
, sizeof(relay
->link_address
));
7095 memcpy(&enc_packet
->dhcpv6_peer_address
,
7096 relay
->peer_address
, sizeof(relay
->peer_address
));
7098 if (!parse_option_buffer(enc_packet
->options
,
7100 enc_opt_data
.len
- relaylen
,
7101 &dhcpv6_universe
)) {
7102 /* no logging here, as parse_option_buffer() logs all
7103 cases where it fails */
7106 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
7107 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
7109 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7110 msg
= (struct dhcpv4_over_dhcpv6_packet
*)enc_opt_data
.data
;
7111 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
7113 /* message-specific data */
7114 memcpy(enc_packet
->dhcp4o6_flags
,
7116 sizeof(enc_packet
->dhcp4o6_flags
));
7118 if (!parse_option_buffer(enc_packet
->options
,
7120 enc_opt_data
.len
- msglen
,
7121 &dhcpv6_universe
)) {
7122 /* no logging here, as parse_option_buffer() logs all
7123 cases where it fails */
7127 log_error("dhcp4o6_relay_forw: unexpected message of type %d.",
7133 * This is recursive. It is possible to exceed maximum packet size.
7134 * XXX: This will cause the packet send to fail.
7136 build_dhcpv6_reply(&enc_reply
, enc_packet
);
7139 * If we got no encapsulated data, then it is discarded, and
7140 * our reply-forw is also discarded.
7142 if (enc_reply
.data
== NULL
) {
7147 * Now we can use the reply_data buffer.
7148 * Packet header stuff all comes from the forward message.
7150 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
7151 reply
->msg_type
= DHCPV6_RELAY_REPL
;
7152 reply
->hop_count
= packet
->dhcpv6_hop_count
;
7153 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
7154 sizeof(reply
->link_address
));
7155 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
7156 sizeof(reply
->peer_address
));
7157 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
7160 * Get the reply option state.
7162 if (!option_state_allocate(&opt_state
, MDL
)) {
7163 log_error("dhcp4o6_relay_forw: no memory for option state.");
7168 * Append the interface-id if present.
7170 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
7173 if (!evaluate_option_cache(&a_opt
, packet
,
7175 packet
->options
, NULL
,
7176 &global_scope
, oc
, MDL
)) {
7177 log_error("dhcp4o6_relay_forw: error evaluating "
7181 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7182 (unsigned char *)a_opt
.data
,
7184 D6O_INTERFACE_ID
, 0)) {
7185 log_error("dhcp4o6_relay_forw: error saving "
7189 data_string_forget(&a_opt
, MDL
);
7192 #if defined(RELAY_PORT)
7194 * Append the relay_source_port option if present.
7196 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
7197 D6O_RELAY_SOURCE_PORT
);
7199 if (!evaluate_option_cache(&a_opt
, packet
,
7201 packet
->options
, NULL
,
7202 &global_scope
, oc
, MDL
)) {
7203 log_error("dhcpv4o6_relay_forw: error evaluating "
7204 "Relay Source Port.");
7207 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7208 (unsigned char *)a_opt
.data
,
7210 D6O_RELAY_SOURCE_PORT
, 0)) {
7211 log_error("dhcpv4o6_relay_forw: error saving "
7212 "Relay Source Port.");
7215 data_string_forget(&a_opt
, MDL
);
7217 packet
->relay_source_port
= ISC_TRUE
;
7222 * Append our encapsulated stuff for caller.
7224 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7225 (unsigned char *)enc_reply
.data
,
7227 D6O_RELAY_MSG
, 0)) {
7228 log_error("dhcp4o6_relay_forw: error saving Relay MSG.");
7233 * Get the ERO if any.
7235 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
7240 if (!evaluate_option_cache(&packet_ero
, packet
,
7242 packet
->options
, NULL
,
7243 &global_scope
, oc
, MDL
) ||
7244 (packet_ero
.len
& 1)) {
7245 log_error("dhcp4o6_relay_forw: error evaluating ERO.");
7249 /* Decode and apply the ERO. */
7250 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
7251 req
= getUShort(packet_ero
.data
+ i
);
7252 /* Already in the reply? */
7253 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
7256 /* Get it from the packet if present. */
7257 oc
= lookup_option(&dhcpv6_universe
,
7262 if (!evaluate_option_cache(&a_opt
, packet
,
7264 packet
->options
, NULL
,
7265 &global_scope
, oc
, MDL
)) {
7266 log_error("dhcp4o6_relay_forw: error "
7267 "evaluating option %u.", req
);
7270 if (!save_option_buffer(&dhcpv6_universe
,
7273 (unsigned char *)a_opt
.data
,
7277 log_error("dhcp4o6_relay_forw: error saving "
7281 data_string_forget(&a_opt
, MDL
);
7285 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
7286 sizeof(reply_data
) - reply_ofs
,
7288 required_opts_agent
, &packet_ero
);
7291 * Return our reply to the caller.
7293 reply_ret
->len
= reply_ofs
;
7294 reply_ret
->buffer
= NULL
;
7295 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
7296 log_fatal("No memory to store reply.");
7298 reply_ret
->data
= reply_ret
->buffer
->data
;
7299 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
7302 if (opt_state
!= NULL
)
7303 option_state_dereference(&opt_state
, MDL
);
7304 if (a_opt
.data
!= NULL
) {
7305 data_string_forget(&a_opt
, MDL
);
7307 if (packet_ero
.data
!= NULL
) {
7308 data_string_forget(&packet_ero
, MDL
);
7310 if (enc_reply
.data
!= NULL
) {
7311 data_string_forget(&enc_reply
, MDL
);
7313 if (enc_opt_data
.data
!= NULL
) {
7314 data_string_forget(&enc_opt_data
, MDL
);
7316 if (enc_packet
!= NULL
) {
7317 packet_dereference(&enc_packet
, MDL
);
7322 * \brief Internal processing of a DHCPv4-query
7323 * (DHCPv4 server function)
7325 * Code copied from \ref do_packet().
7327 * \param reply_ret pointer to the response
7328 * \param packet the query
7331 dhcp4o6_dhcpv4_query(struct data_string
*reply_ret
, struct packet
*packet
) {
7332 struct option_cache
*oc
;
7333 struct data_string enc_opt_data
;
7334 struct packet
*enc_packet
;
7335 struct data_string enc_response
;
7336 struct option_state
*opt_state
;
7337 static char response_data
[65536];
7338 struct dhcpv4_over_dhcpv6_packet
*response
;
7342 * Initialize variables for early exit.
7345 memset(&enc_response
, 0, sizeof(enc_response
));
7346 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
7350 * Get our encapsulated relay message.
7352 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_DHCPV4_MSG
);
7354 log_info("DHCPv4-query from %s missing DHCPv4 Message option.",
7355 piaddr(packet
->client_addr
));
7359 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
7360 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
7361 log_error("dhcp4o6_dhcpv4_query: error evaluating "
7366 if (enc_opt_data
.len
< DHCP_FIXED_NON_UDP
) {
7367 log_error("dhcp4o6_dhcpv4_query: DHCPv4 packet too short.");
7372 * Build a packet structure from this encapsulated packet.
7374 if (!packet_allocate(&enc_packet
, MDL
)) {
7375 log_error("dhcp4o6_dhcpv4_query: "
7376 "no memory for encapsulated packet.");
7380 enc_packet
->raw
= (struct dhcp_packet
*)enc_opt_data
.data
;
7381 enc_packet
->packet_length
= enc_opt_data
.len
;
7382 enc_packet
->dhcp4o6_response
= &enc_response
;
7383 enc_packet
->client_port
= packet
->client_port
;
7384 enc_packet
->client_addr
= packet
->client_addr
;
7385 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
7386 enc_packet
->dhcpv6_container_packet
= packet
;
7387 if (packet
->dhcp4o6_flags
[0] & DHCP4O6_QUERY_UNICAST
)
7388 enc_packet
->unicast
= 1;
7390 if (enc_packet
->raw
->hlen
> sizeof(enc_packet
->raw
->chaddr
)) {
7391 log_info("dhcp4o6_dhcpv4_query: "
7392 "discarding packet with bogus hlen.");
7396 /* Allocate packet->options now so it is non-null for all packets */
7397 if (!option_state_allocate (&enc_packet
->options
, MDL
)) {
7398 log_error("dhcp4o6_dhcpv4_query: no memory for options.");
7402 /* If there's an option buffer, try to parse it. */
7403 if (enc_packet
->packet_length
>= DHCP_FIXED_NON_UDP
+ 4) {
7404 struct option_cache
*op
;
7405 if (!parse_options(enc_packet
)) {
7406 if (enc_packet
->options
)
7407 option_state_dereference
7408 (&enc_packet
->options
, MDL
);
7409 packet_dereference (&enc_packet
, MDL
);
7413 if (enc_packet
->options_valid
&&
7414 (op
= lookup_option(&dhcp_universe
,
7415 enc_packet
->options
,
7416 DHO_DHCP_MESSAGE_TYPE
))) {
7417 struct data_string dp
;
7418 memset(&dp
, 0, sizeof dp
);
7419 evaluate_option_cache(&dp
, enc_packet
, NULL
, NULL
,
7420 enc_packet
->options
, NULL
,
7423 enc_packet
->packet_type
= dp
.data
[0];
7425 enc_packet
->packet_type
= 0;
7426 data_string_forget(&dp
, MDL
);
7430 if (validate_packet(enc_packet
) != 0) {
7431 if (enc_packet
->packet_type
)
7437 /* If the caller kept the packet, they'll have upped the refcnt. */
7438 packet_dereference(&enc_packet
, MDL
);
7441 * If we got no response data, then it is discarded, and
7442 * our DHCPv4-response is also discarded.
7444 if (enc_response
.data
== NULL
) {
7449 * Now we can use the response_data buffer.
7451 response
= (struct dhcpv4_over_dhcpv6_packet
*)response_data
;
7452 response
->msg_type
= DHCPV6_DHCPV4_RESPONSE
;
7453 response
->flags
[0] = response
->flags
[1] = response
->flags
[2] = 0;
7455 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7458 * Get the response option state.
7460 if (!option_state_allocate(&opt_state
, MDL
)) {
7461 log_error("dhcp4o6_dhcpv4_query: no memory for option state.");
7466 * Append our encapsulated stuff for caller.
7468 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7469 (unsigned char *)enc_response
.data
,
7471 D6O_DHCPV4_MSG
, 0)) {
7472 log_error("dhcp4o6_dhcpv4_query: error saving DHCPv4 MSG.");
7476 response_ofs
+= store_options6(response_data
+ response_ofs
,
7477 sizeof(response_data
) - response_ofs
,
7479 required_opts_4o6
, NULL
);
7482 * Return our response to the caller.
7484 reply_ret
->len
= response_ofs
;
7485 reply_ret
->buffer
= NULL
;
7486 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
7487 log_fatal("dhcp4o6_dhcpv4_query: no memory to store reply.");
7489 reply_ret
->data
= reply_ret
->buffer
->data
;
7490 memcpy(reply_ret
->buffer
->data
, response_data
, response_ofs
);
7493 if (opt_state
!= NULL
)
7494 option_state_dereference(&opt_state
, MDL
);
7495 if (enc_response
.data
!= NULL
) {
7496 data_string_forget(&enc_response
, MDL
);
7498 if (enc_opt_data
.data
!= NULL
) {
7499 data_string_forget(&enc_opt_data
, MDL
);
7501 if (enc_packet
!= NULL
) {
7502 packet_dereference(&enc_packet
, MDL
);
7507 * \brief Forward a DHCPv4-query message to the DHCPv4 side
7508 * (DHCPv6 server function)
7510 * Format: interface:16 + address:16 + udp:4 + DHCPv6 DHCPv4-query message
7512 * \brief packet the DHCPv6 DHCPv4-query message
7514 static void forw_dhcpv4_query(struct packet
*packet
) {
7515 struct data_string ds
;
7516 struct udp_data4o6 udp_data
;
7520 /* Get the initial message. */
7521 while (packet
->dhcpv6_container_packet
!= NULL
)
7522 packet
= packet
->dhcpv6_container_packet
;
7524 /* Check the initial message. */
7525 if ((packet
->raw
== NULL
) ||
7526 (packet
->client_addr
.len
!= 16) ||
7527 (packet
->interface
== NULL
)) {
7528 log_error("forw_dhcpv4_query: can't find initial message.");
7533 len
= packet
->packet_length
+ 36;
7534 memset(&ds
, 0, sizeof(ds
));
7535 if (!buffer_allocate(&ds
.buffer
, len
, MDL
)) {
7536 log_error("forw_dhcpv4_query: "
7537 "no memory for encapsulating packet.");
7540 ds
.data
= ds
.buffer
->data
;
7543 /* Fill the buffer. */
7544 strncpy((char *)ds
.buffer
->data
, packet
->interface
->name
, 16);
7545 memcpy(ds
.buffer
->data
+ 16,
7546 packet
->client_addr
.iabuf
, 16);
7547 memset(&udp_data
, 0, sizeof(udp_data
));
7548 udp_data
.src_port
= packet
->client_port
;
7549 memcpy(ds
.buffer
->data
+ 32, &udp_data
, 4);
7550 memcpy(ds
.buffer
->data
+ 36,
7551 (unsigned char *)packet
->raw
,
7552 packet
->packet_length
);
7554 /* Forward to the DHCPv4 server. */
7555 cc
= send(dhcp4o6_fd
, ds
.data
, ds
.len
, 0);
7557 log_error("forw_dhcpv4_query: send(): %m");
7558 data_string_forget(&ds
, MDL
);
7563 dhcpv6_discard(struct packet
*packet
) {
7564 /* INSIST(packet->msg_type > 0); */
7565 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
7567 log_debug("Discarding %s from %s; message type not handled by server",
7568 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7569 piaddr(packet
->client_addr
));
7573 build_dhcpv6_reply(struct data_string
*reply
, struct packet
*packet
) {
7574 memset(reply
, 0, sizeof(*reply
));
7576 /* I would like to classify the client once here, but
7577 * as I don't want to classify all of the incoming packets
7578 * I need to do it before handling specific types.
7579 * We don't need to classify if we are tossing the packet
7580 * or if it is a relay - the classification step will get
7581 * done when we process the inner client packet.
7584 switch (packet
->dhcpv6_msg_type
) {
7585 case DHCPV6_SOLICIT
:
7586 classify_client(packet
);
7587 dhcpv6_solicit(reply
, packet
);
7589 case DHCPV6_ADVERTISE
:
7590 dhcpv6_discard(packet
);
7592 case DHCPV6_REQUEST
:
7593 classify_client(packet
);
7594 dhcpv6_request(reply
, packet
);
7596 case DHCPV6_CONFIRM
:
7597 classify_client(packet
);
7598 dhcpv6_confirm(reply
, packet
);
7601 classify_client(packet
);
7602 dhcpv6_renew(reply
, packet
);
7605 classify_client(packet
);
7606 dhcpv6_rebind(reply
, packet
);
7609 dhcpv6_discard(packet
);
7611 case DHCPV6_RELEASE
:
7612 classify_client(packet
);
7613 dhcpv6_release(reply
, packet
);
7615 case DHCPV6_DECLINE
:
7616 classify_client(packet
);
7617 dhcpv6_decline(reply
, packet
);
7619 case DHCPV6_RECONFIGURE
:
7620 dhcpv6_discard(packet
);
7622 case DHCPV6_INFORMATION_REQUEST
:
7623 classify_client(packet
);
7624 dhcpv6_information_request(reply
, packet
);
7626 case DHCPV6_RELAY_FORW
:
7628 if (dhcpv4_over_dhcpv6
&& (local_family
== AF_INET
))
7629 dhcp4o6_relay_forw(reply
, packet
);
7631 #endif /* DHCP4o6 */
7632 dhcpv6_relay_forw(reply
, packet
);
7634 case DHCPV6_RELAY_REPL
:
7635 dhcpv6_discard(packet
);
7637 case DHCPV6_LEASEQUERY
:
7638 classify_client(packet
);
7639 dhcpv6_leasequery(reply
, packet
);
7641 case DHCPV6_LEASEQUERY_REPLY
:
7642 dhcpv6_discard(packet
);
7644 case DHCPV6_DHCPV4_QUERY
:
7646 if (dhcpv4_over_dhcpv6
) {
7647 if (local_family
== AF_INET6
) {
7648 forw_dhcpv4_query(packet
);
7650 dhcp4o6_dhcpv4_query(reply
, packet
);
7653 #endif /* DHCP4o6 */
7654 dhcpv6_discard(packet
);
7656 case DHCPV6_DHCPV4_RESPONSE
:
7657 dhcpv6_discard(packet
);
7660 /* XXX: would be nice if we had "notice" level,
7661 as syslog, for this */
7662 log_info("Discarding unknown DHCPv6 message type %d "
7663 "from %s", packet
->dhcpv6_msg_type
,
7664 piaddr(packet
->client_addr
));
7669 log_packet_in(const struct packet
*packet
) {
7670 struct data_string s
;
7672 char tmp_addr
[INET6_ADDRSTRLEN
];
7675 memset(&s
, 0, sizeof(s
));
7677 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
7678 data_string_sprintfa(&s
, "%s message from %s port %d",
7679 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7680 piaddr(packet
->client_addr
),
7681 ntohs(packet
->client_port
));
7683 data_string_sprintfa(&s
,
7684 "Unknown message type %d from %s port %d",
7685 packet
->dhcpv6_msg_type
,
7686 piaddr(packet
->client_addr
),
7687 ntohs(packet
->client_port
));
7689 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7690 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7691 addr
= &packet
->dhcpv6_link_address
;
7692 data_string_sprintfa(&s
, ", link address %s",
7693 inet_ntop(AF_INET6
, addr
,
7694 tmp_addr
, sizeof(tmp_addr
)));
7695 addr
= &packet
->dhcpv6_peer_address
;
7696 data_string_sprintfa(&s
, ", peer address %s",
7697 inet_ntop(AF_INET6
, addr
,
7698 tmp_addr
, sizeof(tmp_addr
)));
7699 } else if ((packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_QUERY
) &&
7700 (packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_RESPONSE
)) {
7702 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
7703 data_string_sprintfa(&s
, ", transaction ID 0x%06X", tid
);
7706 oc = lookup_option(&dhcpv6_universe, packet->options,
7709 memset(&tmp_ds, 0, sizeof(tmp_ds_));
7710 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
7711 packet->options, NULL,
7712 &global_scope, oc, MDL)) {
7713 log_error("Error evaluating Client Identifier");
7715 data_strint_sprintf(&s, ", client ID %s",
7717 data_string_forget(&tmp_ds, MDL);
7723 log_info("%s", s
.data
);
7725 data_string_forget(&s
, MDL
);
7729 dhcpv6(struct packet
*packet
) {
7730 struct data_string reply
;
7731 struct sockaddr_in6 to_addr
;
7735 * Log a message that we received this packet.
7737 log_packet_in(packet
);
7740 * Build our reply packet.
7742 build_dhcpv6_reply(&reply
, packet
);
7744 if (reply
.data
!= NULL
) {
7746 * Send our reply, if we have one.
7748 memset(&to_addr
, 0, sizeof(to_addr
));
7749 to_addr
.sin6_family
= AF_INET6
;
7750 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7751 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7752 to_addr
.sin6_port
= local_port
;
7754 to_addr
.sin6_port
= remote_port
;
7757 #if defined (REPLY_TO_SOURCE_PORT)
7759 * This appears to have been included for testing so we would
7760 * not need a root client, but was accidently left in the
7761 * final code. We continue to include it in case
7762 * some users have come to rely upon it, but leave
7763 * it off by default as it's a bad idea.
7765 to_addr
.sin6_port
= packet
->client_port
;
7768 #if defined(RELAY_PORT)
7770 * Check relay source port.
7772 if (packet
->relay_source_port
) {
7773 to_addr
.sin6_port
= packet
->client_port
;
7777 memcpy(&to_addr
.sin6_addr
, packet
->client_addr
.iabuf
,
7778 sizeof(to_addr
.sin6_addr
));
7780 log_info("Sending %s to %s port %d",
7781 dhcpv6_type_names
[reply
.data
[0]],
7782 piaddr(packet
->client_addr
),
7783 ntohs(to_addr
.sin6_port
));
7785 send_ret
= send_packet6(packet
->interface
,
7786 reply
.data
, reply
.len
, &to_addr
);
7787 if (send_ret
!= reply
.len
) {
7788 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
7789 send_ret
, reply
.len
);
7791 data_string_forget(&reply
, MDL
);
7797 * \brief Receive a DHCPv4-query message from the DHCPv6 side
7798 * (DHCPv4 server function)
7800 * Receive a message with a DHCPv4-query inside from the DHCPv6 server.
7801 * (code copied from \ref do_packet6() \ref and dhcpv6())
7803 * Format: interface:16 + address:16 + udp:4 + DHCPv6 DHCPv4-query message
7805 * \param raw the DHCPv6 DHCPv4-query message raw content
7807 static void recv_dhcpv4_query(struct data_string
*raw
) {
7808 struct interface_info
*ip
;
7811 struct packet
*packet
;
7812 unsigned char msg_type
;
7813 const struct dhcpv6_relay_packet
*relay
;
7814 const struct dhcpv4_over_dhcpv6_packet
*msg
;
7815 struct data_string reply
;
7816 struct data_string ds
;
7817 struct udp_data4o6 udp_data
;
7821 memset(name
, 0, sizeof(name
));
7822 memcpy(name
, raw
->data
, 16);
7823 for (ip
= interfaces
; ip
!= NULL
; ip
= ip
->next
) {
7824 if (!strcmp(name
, ip
->name
))
7828 log_error("recv_dhcpv4_query: can't find interface %s.",
7834 memcpy(iaddr
.iabuf
, raw
->data
+ 16, 16);
7836 memset(&udp_data
, 0, sizeof(udp_data
));
7837 memcpy(&udp_data
, raw
->data
+ 32, 4);
7840 * From do_packet6().
7843 if (!packet6_len_okay((char *)raw
->data
+ 36, raw
->len
- 36)) {
7844 log_error("recv_dhcpv4_query: "
7845 "short packet from %s, len %d, dropped",
7846 piaddr(iaddr
), raw
->len
- 36);
7851 * Build a packet structure.
7854 if (!packet_allocate(&packet
, MDL
)) {
7855 log_error("recv_dhcpv4_query: no memory for packet.");
7859 if (!option_state_allocate(&packet
->options
, MDL
)) {
7860 log_error("recv_dhcpv4_query: no memory for options.");
7861 packet_dereference(&packet
, MDL
);
7865 packet
->raw
= (struct dhcp_packet
*)(raw
->data
+ 36);
7866 packet
->packet_length
= raw
->len
- 36;
7867 packet
->client_port
= udp_data
.src_port
;
7868 packet
->client_addr
= iaddr
;
7869 interface_reference(&packet
->interface
, ip
, MDL
);
7871 msg_type
= raw
->data
[36];
7872 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
7873 (msg_type
== DHCPV6_RELAY_REPL
)) {
7875 (int)(offsetof(struct dhcpv6_relay_packet
, options
));
7876 relay
= (const struct dhcpv6_relay_packet
*)(raw
->data
+ 36);
7877 packet
->dhcpv6_msg_type
= relay
->msg_type
;
7879 /* relay-specific data */
7880 packet
->dhcpv6_hop_count
= relay
->hop_count
;
7881 memcpy(&packet
->dhcpv6_link_address
,
7882 relay
->link_address
, sizeof(relay
->link_address
));
7883 memcpy(&packet
->dhcpv6_peer_address
,
7884 relay
->peer_address
, sizeof(relay
->peer_address
));
7886 if (!parse_option_buffer(packet
->options
,
7888 raw
->len
- 36 - relaylen
,
7889 &dhcpv6_universe
)) {
7890 /* no logging here, as parse_option_buffer() logs all
7891 cases where it fails */
7892 packet_dereference(&packet
, MDL
);
7895 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
7896 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
7898 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7899 msg
= (struct dhcpv4_over_dhcpv6_packet
*)(raw
->data
+ 36);
7900 packet
->dhcpv6_msg_type
= msg
->msg_type
;
7902 /* message-specific data */
7903 memcpy(packet
->dhcp4o6_flags
, msg
->flags
,
7904 sizeof(packet
->dhcp4o6_flags
));
7906 if (!parse_option_buffer(packet
->options
,
7908 raw
->len
- 36 - msglen
,
7909 &dhcpv6_universe
)) {
7910 /* no logging here, as parse_option_buffer() logs all
7911 cases where it fails */
7912 packet_dereference(&packet
, MDL
);
7916 log_error("recv_dhcpv4_query: unexpected message of type %d.",
7918 packet_dereference(&packet
, MDL
);
7927 * Log a message that we received this packet.
7929 /* log_packet_in(packet); */
7930 memset(&ds
, 0, sizeof(ds
));
7931 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
7932 data_string_sprintfa(&ds
, "%s message from %s",
7933 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7934 piaddr(packet
->client_addr
));
7936 data_string_sprintfa(&ds
,
7937 "Unknown message type %d from %s",
7938 packet
->dhcpv6_msg_type
,
7939 piaddr(packet
->client_addr
));
7941 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7942 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7943 char tmp_addr
[INET6_ADDRSTRLEN
];
7946 addr
= &packet
->dhcpv6_link_address
;
7947 data_string_sprintfa(&ds
, ", link address %s",
7948 inet_ntop(AF_INET6
, addr
,
7949 tmp_addr
, sizeof(tmp_addr
)));
7950 addr
= &packet
->dhcpv6_peer_address
;
7951 data_string_sprintfa(&ds
, ", peer address %s",
7952 inet_ntop(AF_INET6
, addr
,
7953 tmp_addr
, sizeof(tmp_addr
)));
7954 } else if ((packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_QUERY
) &&
7955 (packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_RESPONSE
)) {
7958 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
7959 data_string_sprintfa(&ds
, ", transaction ID 0x%06X", tid
);
7961 log_info("%s", ds
.data
);
7962 data_string_forget(&ds
, MDL
);
7965 * Build our reply packet.
7967 build_dhcpv6_reply(&reply
, packet
);
7969 if (reply
.data
== NULL
) {
7970 packet_dereference(&packet
, MDL
);
7975 * Forward the response.
7977 len
= reply
.len
+ 36;
7978 memset(&ds
, 0, sizeof(ds
));
7979 if (!buffer_allocate(&ds
.buffer
, len
, MDL
)) {
7980 log_error("recv_dhcpv4_query: no memory.");
7981 packet_dereference(&packet
, MDL
);
7984 ds
.data
= ds
.buffer
->data
;
7987 memcpy(ds
.buffer
->data
, name
, 16);
7988 memcpy(ds
.buffer
->data
+ 16, iaddr
.iabuf
, 16);
7989 udp_data
.rsp_opt_exist
= packet
->relay_source_port
? 1 : 0;
7990 memcpy(ds
.buffer
->data
+ 32, &udp_data
, 4);
7991 memcpy(ds
.buffer
->data
+ 36, reply
.data
, reply
.len
);
7994 * Now we can release the packet.
7996 packet_dereference(&packet
, MDL
);
7998 cc
= send(dhcp4o6_fd
, ds
.data
, ds
.len
, 0);
8000 log_error("recv_dhcpv4_query: send(): %m");
8001 data_string_forget(&ds
, MDL
);
8003 #endif /* DHCP4o6 */
8006 seek_shared_host(struct host_decl
**hp
, struct shared_network
*shared
) {
8007 struct host_decl
*nofixed
= NULL
;
8008 struct host_decl
*seek
, *hold
= NULL
;
8011 * Seek forward through fixed addresses for the right link.
8013 * Note: how to do this for fixed prefixes???
8015 host_reference(&hold
, *hp
, MDL
);
8016 host_dereference(hp
, MDL
);
8018 while (seek
!= NULL
) {
8019 if (seek
->fixed_addr
== NULL
)
8021 else if (fixed_matches_shared(seek
, shared
))
8024 seek
= seek
->n_ipaddr
;
8027 if ((seek
== NULL
) && (nofixed
!= NULL
))
8031 host_reference(hp
, seek
, MDL
);
8034 static isc_boolean_t
8035 fixed_matches_shared(struct host_decl
*host
, struct shared_network
*shared
) {
8036 struct subnet
*subnet
;
8037 struct data_string addr
;
8038 isc_boolean_t matched
;
8041 if (host
->fixed_addr
== NULL
)
8044 memset(&addr
, 0, sizeof(addr
));
8045 if (!evaluate_option_cache(&addr
, NULL
, NULL
, NULL
, NULL
, NULL
,
8046 &global_scope
, host
->fixed_addr
, MDL
))
8049 if (addr
.len
< 16) {
8050 data_string_forget(&addr
, MDL
);
8055 memcpy(fixed
.iabuf
, addr
.data
, 16);
8057 matched
= ISC_FALSE
;
8058 for (subnet
= shared
->subnets
; subnet
!= NULL
;
8059 subnet
= subnet
->next_sibling
) {
8060 if (addr_eq(subnet_number(fixed
, subnet
->netmask
),
8067 data_string_forget(&addr
, MDL
);
8073 * \brief Constructs a REPLY with status of UseMulticast to a given packet
8075 * Per RFC 3315 Secs 18.2.1,3,6 & 7, when a server rejects a client's
8076 * unicast-sent packet, the response must only contain the client id,
8077 * server id, and a status code option of 5 (UseMulticast). This function
8078 * constructs such a packet and returns it as a data_string.
8080 * \param reply_ret = data_string which will receive the newly constructed
8082 * \param packet = client request which is being rejected
8083 * \param client_id = data_string which contains the client id
8084 * \param server_id = data_string which which contains the server id
8088 unicast_reject(struct data_string
*reply_ret
,
8089 struct packet
*packet
,
8090 const struct data_string
*client_id
,
8091 const struct data_string
*server_id
)
8093 struct reply_state reply
;
8094 memset(&reply
, 0x0, sizeof(struct reply_state
));
8096 /* Locate the client. */
8097 if (shared_network_from_packet6(&reply
.shared
, packet
)
8099 log_error("unicast_reject: could not locate client.");
8103 /* Initialize the reply. */
8104 packet_reference(&reply
.packet
, packet
, MDL
);
8105 data_string_copy(&reply
.client_id
, client_id
, MDL
);
8107 if (start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
8108 &reply
.buf
.reply
)) {
8109 /* Set the UseMulticast status code. */
8110 if (!set_status_code(STATUS_UseMulticast
,
8111 "Unicast not allowed by server.",
8113 log_error("unicast_reject: Unable to set status code.");
8115 /* Set write cursor to just past the reply header. */
8116 reply
.cursor
= REPLY_OPTIONS_INDEX
;
8117 reply
.cursor
+= store_options6(((char *)reply
.buf
.data
8123 unicast_reject_opts
,
8126 /* Return our reply to the caller. */
8127 reply_ret
->len
= reply
.cursor
;
8128 reply_ret
->buffer
= NULL
;
8129 if (!buffer_allocate(&reply_ret
->buffer
,
8130 reply
.cursor
, MDL
)) {
8131 log_fatal("unicast_reject:"
8132 "No memory to store Reply.");
8135 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
,
8137 reply_ret
->data
= reply_ret
->buffer
->data
;
8143 if (reply
.shared
!= NULL
)
8144 shared_network_dereference(&reply
.shared
, MDL
);
8145 if (reply
.opt_state
!= NULL
)
8146 option_state_dereference(&reply
.opt_state
, MDL
);
8147 if (reply
.packet
!= NULL
)
8148 packet_dereference(&reply
.packet
, MDL
);
8149 if (reply
.client_id
.data
!= NULL
)
8150 data_string_forget(&reply
.client_id
, MDL
);
8155 * \brief Checks if the dhcp6.unicast option has been defined
8157 * Scans the option space for the presence of the dhcp6.unicast option. The
8158 * function attempts to map the inbound packet to a shared network first
8159 * by an ip address specified via an D6O_IA_XX option and if that fails then
8160 * by the packet's source information (e.g. relay link, link, or interace).
8161 * Once the packet is mapped to a shared network, the function executes all
8162 * statements from the network's group outward into a local option cache.
8163 * The option cache is then scanned for the presence of unicast option. If
8164 * the packet cannot be mapped to a shared network, the function returns
8166 * \param packet inbound packet from the client
8168 * \return ISC_TRUE if the dhcp6.unicast option is defined, false otherwise.
8172 is_unicast_option_defined(struct packet
*packet
) {
8173 isc_boolean_t is_defined
= ISC_FALSE
;
8174 struct option_state
*opt_state
= NULL
;
8175 struct option_cache
*oc
= NULL
;
8176 struct shared_network
*shared
= NULL
;
8178 if (!option_state_allocate(&opt_state
, MDL
)) {
8179 log_fatal("is_unicast_option_defined:"
8180 "No memory for option state.");
8183 /* We try to map the packet to a network first by an IA_XX value.
8184 * If that fails, we try by packet source. */
8185 if (((shared_network_from_requested_addr(&shared
, packet
)
8186 != ISC_R_SUCCESS
) &&
8187 (shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
))
8188 || (shared
== NULL
)) {
8189 /* @todo what would this really mean? I think wrong network
8190 * logic will catch it */
8191 log_error("is_unicast_option_defined:"
8192 "cannot attribute packet to a network.");
8196 /* Now that we've mapped it to a network, execute statments to that
8197 * scope, looking for the unicast option. We don't care about the
8198 * value of the option, only whether or not it is defined. */
8199 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
, opt_state
,
8200 &global_scope
, shared
->group
, NULL
, NULL
);
8202 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_UNICAST
);
8203 is_defined
= (oc
!= NULL
? ISC_TRUE
: ISC_FALSE
);
8204 log_debug("is_unicast_option_defined: option found : %d", is_defined
);
8206 if (shared
!= NULL
) {
8207 shared_network_dereference(&shared
, MDL
);
8210 if (opt_state
!= NULL
) {
8211 option_state_dereference(&opt_state
, MDL
);
8214 return (is_defined
);
8219 * \brief Maps a packet to a shared network based on the requested IP address
8221 * The function attempts to find a subnet that matches the first requested IP
8222 * address contained within the given packet. Note that it looks first for
8223 * D6O_IA_NAs, then D6O_IA_PDs and lastly D6O_IA_TAs. If a matching network is
8224 * found, a reference to it is returned in the parameter, shared.
8226 * \param shared shared_network pointer which will receive the matching network
8227 * \param packet inbound packet from the client
8229 * \return ISC_R_SUCCESS if the packet can be mapped to a shared_network.
8233 shared_network_from_requested_addr (struct shared_network
**shared
,
8234 struct packet
* packet
) {
8236 struct subnet
* subnet
= NULL
;
8237 isc_result_t status
= ISC_R_FAILURE
;
8239 /* Try to match first IA_ address or prefix we find to a subnet. In
8240 * theory all IA_ values in a given request are supposed to be in the
8241 * same subnet so we only need to try one right? */
8242 if ((get_first_ia_addr_val(packet
, D6O_IA_NA
, &iaddr
) != ISC_R_SUCCESS
)
8243 && (get_first_ia_addr_val(packet
, D6O_IA_PD
, &iaddr
)
8245 && (get_first_ia_addr_val(packet
, D6O_IA_TA
, &iaddr
)
8246 != ISC_R_SUCCESS
)) {
8247 /* we found nothing to match against */
8248 log_debug("share_network_from_request_addr: nothing to match");
8249 return (ISC_R_FAILURE
);
8252 if (!find_subnet(&subnet
, iaddr
, MDL
)) {
8253 log_debug("shared_network_from_requested_addr:"
8254 "No subnet found for addr %s.", piaddr(iaddr
));
8256 status
= shared_network_reference(shared
,
8257 subnet
->shared_network
, MDL
);
8258 subnet_dereference(&subnet
, MDL
);
8259 log_debug("shared_network_from_requested_addr:"
8260 " found shared network %s for address %s.",
8261 ((*shared
)->name
? (*shared
)->name
: "unnamed"),
8266 return (ISC_R_FAILURE
);
8271 * \brief Retrieves the first IP address from a given packet of a given type
8273 * Search a packet for options of a given type (D6O_IA_AN, D6O_IA_PD, or
8274 * D6O_IA_TA) for the first non-blank IA_XX value and return its IP address
8277 * \param packet packet received from the client
8278 * \param addr_type the address option type (D6O_IA_NA , D6O_IA_PD, or
8279 * D6O_IP_TA) to look for within the packet.
8280 * \param iaddr pointer to the iaddr structure which will receive the extracted
8283 * \return ISC_R_SUCCESS if an address was succesfully extracted, ISC_R_FALURE
8288 get_first_ia_addr_val (struct packet
* packet
, int addr_type
,
8289 struct iaddr
* iaddr
) {
8290 struct option_cache
*ia
;
8291 struct option_cache
*oc
= NULL
;
8292 struct data_string cli_enc_opt_data
;
8293 struct option_state
*cli_enc_opt_state
;
8294 int addr_opt_offset
;
8296 int addr_opt_data_len
;
8299 isc_result_t status
= ISC_R_FAILURE
;
8300 memset(iaddr
, 0, sizeof(struct iaddr
));
8302 /* Set up address type specifics */
8303 switch (addr_type
) {
8305 addr_opt_offset
= IA_NA_OFFSET
;
8306 addr_opt
= D6O_IAADDR
;
8307 addr_opt_data_len
= 24;
8311 addr_opt_offset
= IA_TA_OFFSET
;
8312 addr_opt
= D6O_IAADDR
;
8313 addr_opt_data_len
= 24;
8317 addr_opt_offset
= IA_PD_OFFSET
;
8318 addr_opt
= D6O_IAPREFIX
;
8319 addr_opt_data_len
= 25;
8323 /* shouldn't be here */
8324 log_error ("get_first_ia_addr_val: invalid opt type %d",
8326 return (ISC_R_FAILURE
);
8329 /* Find the first, non-blank IA_XX value within an D6O_IA_XX option. */
8330 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, addr_type
);
8331 ia
!= NULL
&& oc
== NULL
; ia
= ia
->next
) {
8332 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
8334 packet
, ia
, addr_opt_offset
)) {
8335 log_debug ("get_first_ia_addr_val:"
8336 " couldn't unroll enclosing option");
8337 return (ISC_R_FAILURE
);
8340 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
8343 /* no address given for this IA, ignore */
8344 option_state_dereference(&cli_enc_opt_state
, MDL
);
8345 data_string_forget(&cli_enc_opt_data
, MDL
);
8349 /* If we found a non-blank IA_XX then extract its ip address. */
8351 struct data_string iaddr_str
;
8353 memset(&iaddr_str
, 0, sizeof(iaddr_str
));
8354 if (!evaluate_option_cache(&iaddr_str
, packet
, NULL
, NULL
,
8355 packet
->options
, NULL
, &global_scope
,
8357 log_error("get_first_ia_addr_val: "
8358 "error evaluating IA_XX option.");
8360 if (iaddr_str
.len
!= addr_opt_data_len
) {
8361 log_error("shared_network_from_requested_addr:"
8362 " invalid length %d, expected %d",
8363 iaddr_str
.len
, addr_opt_data_len
);
8366 memcpy (iaddr
->iabuf
,
8367 iaddr_str
.data
+ ip_addr_offset
, 16);
8368 status
= ISC_R_SUCCESS
;
8370 data_string_forget(&iaddr_str
, MDL
);
8373 option_state_dereference(&cli_enc_opt_state
, MDL
);
8374 data_string_forget(&cli_enc_opt_data
, MDL
);
8381 * \brief Calculates the reply T1/T2 times and stuffs them in outbound buffer
8383 * T1/T2 time selection is kind of weird. We actually use DHCP * (v4) scoped
8384 * options, dhcp-renewal-time and dhcp-rebinding-time, as handy existing places
8385 * where these can be configured by an administrator. A value of zero tells the
8386 * client it may choose its own value.
8388 * When those options are not defined, the values will be set to zero unless
8389 * the global option, dhcpv6-set-tee-times is enabled. When this option is
8390 * enabled the values are calculated as recommended by RFC 3315, Section 22.4:
8392 * T1 will be set to 0.5 times the shortest preferred lifetime
8393 * in the IA_XX option. If the "shortest" preferred lifetime is
8394 * 0xFFFFFFFF, T1 will set to 0xFFFFFFFF.
8396 * T2 will be set to 0.8 times the shortest preferred lifetime
8397 * in the IA_XX option. If the "shortest" preferred lifetime is
8398 * 0xFFFFFFFF, T2 will set to 0xFFFFFFFF.
8400 * Note that dhcpv6-set-tee-times is intended to be transitional and will
8401 * likely be removed in 4.4.0, leaving the behavior as getting the values
8402 * either from the configured parameters (if you want zeros, define them as
8403 * zeros) or by calculating them per the RFC.
8405 * \param reply - pointer to the reply_state structure
8406 * \param ia_cursor - offset of the beginning of the IA_XX option within the
8407 * reply's outbound data buffer
8410 set_reply_tee_times(struct reply_state
* reply
, unsigned ia_cursor
)
8412 struct option_cache
*oc
;
8415 /* Found out if calculated values are enabled. */
8416 oc
= lookup_option(&server_universe
, reply
->opt_state
,
8417 SV_DHCPV6_SET_TEE_TIMES
);
8418 set_tee_times
= (oc
&&
8419 evaluate_boolean_option_cache(NULL
, reply
->packet
,
8421 reply
->packet
->options
,
8423 &global_scope
, oc
, MDL
));
8425 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
8426 DHO_DHCP_RENEWAL_TIME
);
8428 /* dhcp-renewal-time is defined, use it */
8429 struct data_string data
;
8430 memset(&data
, 0x00, sizeof(data
));
8432 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
8433 reply
->packet
->options
,
8434 reply
->opt_state
, &global_scope
,
8437 log_error("Invalid renewal time.");
8440 reply
->renew
= getULong(data
.data
);
8443 if (data
.data
!= NULL
)
8444 data_string_forget(&data
, MDL
);
8445 } else if (set_tee_times
) {
8446 /* Setting them is enabled so T1 is either infinite or
8447 * 0.5 * the shortest preferred lifetime in the IA_XX */
8448 if (reply
->min_prefer
== INFINITE_TIME
)
8449 reply
->renew
= INFINITE_TIME
;
8451 reply
->renew
= reply
->min_prefer
/ 2;
8453 /* Default is to let the client choose */
8457 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
8460 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
8461 DHO_DHCP_REBINDING_TIME
);
8463 /* dhcp-rebinding-time is defined, use it */
8464 struct data_string data
;
8465 memset(&data
, 0x00, sizeof(data
));
8467 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
8468 reply
->packet
->options
,
8469 reply
->opt_state
, &global_scope
,
8472 log_error("Invalid rebinding time.");
8475 reply
->rebind
= getULong(data
.data
);
8478 if (data
.data
!= NULL
)
8479 data_string_forget(&data
, MDL
);
8480 } else if (set_tee_times
) {
8481 /* Setting them is enabled so T2 is either infinite or
8482 * 0.8 * the shortest preferred lifetime in the reply */
8483 if (reply
->min_prefer
== INFINITE_TIME
)
8484 reply
->rebind
= INFINITE_TIME
;
8486 reply
->rebind
= (reply
->min_prefer
/ 5) * 4;
8488 /* Default is to let the client choose */
8492 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
8496 * Releases the iasubopts in the pre-existing IA, if they are not in
8497 * the same shared-network as the new IA.
8499 * returns 1 if the release was done, 0 otherwise
8502 release_on_roam(struct reply_state
* reply
) {
8503 struct ia_xx
* old_ia
= reply
->old_ia
;
8504 struct iasubopt
*lease
= NULL
;
8507 if ((!do_release_on_roam
) || old_ia
== NULL
8508 || old_ia
->num_iasubopt
<= 0) {
8512 /* If the old shared-network and new are the same, client hasn't
8513 * roamed, nothing to do. We only check the first one because you
8514 * cannot have iasubopts on different shared-networks within a
8516 lease
= old_ia
->iasubopt
[0];
8517 if (lease
->ipv6_pool
->shared_network
== reply
->shared
) {
8521 /* Old and new are on different shared networks so the client must
8522 * roamed. Release the old leases. */
8523 for (i
= 0; i
< old_ia
->num_iasubopt
; i
++) {
8524 lease
= old_ia
->iasubopt
[i
];
8526 log_info("Client: %s roamed to new network,"
8527 " releasing lease: %s%s",
8528 print_hex_1(reply
->client_id
.len
,
8529 reply
->client_id
.data
, 60),
8530 pin6_addr(&lease
->addr
), iasubopt_plen_str(lease
));
8532 release_lease6(lease
->ipv6_pool
, lease
);
8533 lease
->ia
->cltt
= cur_time
;
8534 write_ia(lease
->ia
);
8541 * Convenience function which returns a string (static buffer)
8542 * containing either a "/" followed by the prefix length or an
8543 * empty string depending on the lease type
8545 const char *iasubopt_plen_str(struct iasubopt
*lease
) {
8546 static char prefix_buf
[16];
8548 if ((lease
->ia
) && (lease
->ia
->ia_type
== D6O_IA_PD
)) {
8549 sprintf(prefix_buf
, "/%-d", lease
->plen
);
8552 return (prefix_buf
);
8557 * Initiates DDNS updates for static v6 leases if configured to do so.
8559 * The function, which must be called after the IA has been written to the
8560 * packet, adds an iasubopt to the IA for static lease. This is done so we
8561 * have an iasubopt to pass into ddns_updates(). A reference to the IA is
8562 * added to the DDNS control block to ensure it and it's iasubopt remain in
8563 * scope until the update is complete.
8566 void ddns_update_static6(struct reply_state
* reply
) {
8567 struct iasubopt
*iasub
= NULL
;
8568 struct binding_scope
*scope
= NULL
;
8569 struct option_cache
*oc
= NULL
;
8571 oc
= lookup_option(&server_universe
, reply
->opt_state
, SV_DDNS_UPDATES
);
8573 (evaluate_boolean_option_cache(NULL
, reply
->packet
, NULL
, NULL
,
8574 reply
->packet
->options
,
8575 reply
->opt_state
, NULL
,
8580 oc
= lookup_option(&server_universe
, reply
->opt_state
,
8581 SV_UPDATE_STATIC_LEASES
);
8583 (evaluate_boolean_option_cache(NULL
, reply
->packet
,
8585 reply
->packet
->options
,
8586 reply
->opt_state
, NULL
,
8591 if (iasubopt_allocate(&iasub
, MDL
) != ISC_R_SUCCESS
) {
8592 log_fatal("No memory for iasubopt.");
8595 if (ia_add_iasubopt(reply
->ia
, iasub
, MDL
) != ISC_R_SUCCESS
) {
8596 log_fatal("Could not add iasubopt.");
8599 ia_reference(&iasub
->ia
, reply
->ia
, MDL
);
8601 memcpy(iasub
->addr
.s6_addr
, reply
->fixed
.data
, 16);
8603 iasub
->prefer
= MAX_TIME
;
8604 iasub
->valid
= MAX_TIME
;
8605 iasub
->static_lease
= 1;
8607 if (!binding_scope_allocate(&scope
, MDL
)) {
8608 log_fatal("Out of memory for binding scope.");
8611 binding_scope_reference(&iasub
->scope
, scope
, MDL
);
8613 ddns_updates(reply
->packet
, NULL
, NULL
, iasub
, NULL
, reply
->opt_state
);
8615 #endif /* NSUPDATE */