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
));
636 data_string_forget(&data
, MDL
);
639 if (client_id
->len
> 0) {
640 data_string_forget(client_id
, MDL
);
647 * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
648 * 15.9 (slightly different wording, but same meaning):
650 * Servers MUST discard any received Request message that meet any of
651 * the following conditions:
653 * - the message does not include a Server Identifier option.
654 * - the contents of the Server Identifier option do not match the
656 * - the message does not include a Client Identifier option.
659 valid_client_resp(struct packet
*packet
,
660 struct data_string
*client_id
,
661 struct data_string
*server_id
)
664 struct option_cache
*oc
;
666 /* INSIST((duid.data != NULL) && (duid.len > 0)); */
669 memset(client_id
, 0, sizeof(*client_id
));
670 memset(server_id
, 0, sizeof(*server_id
));
672 switch (get_client_id(packet
, client_id
)) {
676 log_debug("Discarding %s from %s; "
677 "client identifier missing",
678 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
679 piaddr(packet
->client_addr
));
682 log_error("Error processing %s from %s; "
683 "unable to evaluate Client Identifier",
684 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
685 piaddr(packet
->client_addr
));
689 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
691 log_debug("Discarding %s from %s: "
692 "server identifier missing (CLIENTID %s)",
693 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
694 piaddr(packet
->client_addr
),
695 print_hex_1(client_id
->len
, client_id
->data
, 60));
698 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
699 packet
->options
, NULL
,
700 &global_scope
, oc
, MDL
)) {
701 log_error("Error processing %s from %s; "
702 "unable to evaluate Server Identifier (CLIENTID %s)",
703 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
704 piaddr(packet
->client_addr
),
705 print_hex_1(client_id
->len
, client_id
->data
, 60));
708 if ((server_duid
.len
!= server_id
->len
) ||
709 (memcmp(server_duid
.data
, server_id
->data
, server_duid
.len
) != 0)) {
710 log_debug("Discarding %s from %s; "
711 "not our server identifier "
712 "(CLIENTID %s, SERVERID %s, server DUID %s)",
713 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
714 piaddr(packet
->client_addr
),
715 print_hex_1(client_id
->len
, client_id
->data
, 60),
716 print_hex_2(server_id
->len
, server_id
->data
, 60),
717 print_hex_3(server_duid
.len
, server_duid
.data
, 60));
726 if (server_id
->len
> 0) {
727 data_string_forget(server_id
, MDL
);
729 if (client_id
->len
> 0) {
730 data_string_forget(client_id
, MDL
);
737 * Information request validation, defined in RFC 3315, section 15.12:
739 * Servers MUST discard any received Information-request message that
740 * meets any of the following conditions:
742 * - The message includes a Server Identifier option and the DUID in
743 * the option does not match the server's DUID.
745 * - The message includes an IA option.
748 valid_client_info_req(struct packet
*packet
, struct data_string
*server_id
) {
750 struct option_cache
*oc
;
751 struct data_string client_id
;
752 char client_id_str
[80]; /* print_hex_1() uses maximum 60 characters,
753 plus a few more for extra information */
756 memset(server_id
, 0, sizeof(*server_id
));
757 memset(&client_id
, 0, sizeof(client_id
));
760 * Make a string that we can print out to give more
761 * information about the client if we need to.
763 * By RFC 3315, Section 18.1.5 clients SHOULD have a
764 * client-id on an Information-request packet, but it
765 * is not strictly necessary.
767 if (get_client_id(packet
, &client_id
) == ISC_R_SUCCESS
) {
768 snprintf(client_id_str
, sizeof(client_id_str
), " (CLIENTID %s)",
769 print_hex_1(client_id
.len
, client_id
.data
, 60));
770 data_string_forget(&client_id
, MDL
);
772 client_id_str
[0] = '\0';
776 * Required by RFC 3315, section 15.
778 if (packet
->unicast
) {
779 log_debug("Discarding %s from %s; packet sent unicast%s",
780 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
781 piaddr(packet
->client_addr
), client_id_str
);
785 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
787 log_debug("Discarding %s from %s; "
788 "IA_NA 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_TA
);
795 log_debug("Discarding %s from %s; "
796 "IA_TA option present%s",
797 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
798 piaddr(packet
->client_addr
), client_id_str
);
801 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
803 log_debug("Discarding %s from %s; "
804 "IA_PD option present%s",
805 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
806 piaddr(packet
->client_addr
), client_id_str
);
810 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
812 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
813 packet
->options
, NULL
,
814 &global_scope
, oc
, MDL
)) {
815 log_error("Error processing %s from %s; "
816 "unable to evaluate Server Identifier%s",
817 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
818 piaddr(packet
->client_addr
), client_id_str
);
821 if ((server_duid
.len
!= server_id
->len
) ||
822 (memcmp(server_duid
.data
, server_id
->data
,
823 server_duid
.len
) != 0)) {
824 log_debug("Discarding %s from %s; "
825 "not our server identifier "
826 "(SERVERID %s, server DUID %s)%s",
827 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
828 piaddr(packet
->client_addr
),
829 print_hex_1(server_id
->len
,
830 server_id
->data
, 60),
831 print_hex_2(server_duid
.len
,
832 server_duid
.data
, 60),
843 if (server_id
->len
> 0) {
844 data_string_forget(server_id
, MDL
);
851 * Options that we want to send, in addition to what was requested
854 static const int required_opts
[] = {
861 static const int required_opts_solicit
[] = {
873 static const int required_opts_agent
[] = {
875 #if defined(RELAY_PORT)
876 D6O_RELAY_SOURCE_PORT
,
881 static const int required_opts_IA
[] = {
886 static const int required_opts_IA_PD
[] = {
891 static const int required_opts_STATUS_CODE
[] = {
896 static const int required_opts_4o6
[] = {
902 static const int unicast_reject_opts
[] = {
911 * Extracts from packet contents an IA_* option, storing the IA structure
912 * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
913 * in enc_opt_state for later lookup and evaluation. The 'offset' indicates
914 * where in the IA_* the DHCPv6 options commence.
917 get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
918 struct data_string
*enc_opt_data
,
919 struct packet
*packet
,
920 struct option_cache
*oc
,
924 * Get the raw data for the encapsulated options.
926 memset(enc_opt_data
, 0, sizeof(*enc_opt_data
));
927 if (!evaluate_option_cache(enc_opt_data
, packet
,
928 NULL
, NULL
, packet
->options
, NULL
,
929 &global_scope
, oc
, MDL
)) {
930 log_error("get_encapsulated_IA_state: "
931 "error evaluating raw option.");
934 if (enc_opt_data
->len
< offset
) {
935 log_error("get_encapsulated_IA_state: raw option too small.");
936 data_string_forget(enc_opt_data
, MDL
);
941 * Now create the option state structure, and pass it to the
942 * function that parses options.
944 *enc_opt_state
= NULL
;
945 if (!option_state_allocate(enc_opt_state
, MDL
)) {
946 log_error("get_encapsulated_IA_state: no memory for options.");
947 data_string_forget(enc_opt_data
, MDL
);
950 if (!parse_option_buffer(*enc_opt_state
,
951 enc_opt_data
->data
+ offset
,
952 enc_opt_data
->len
- offset
,
954 log_error("get_encapsulated_IA_state: error parsing options.");
955 option_state_dereference(enc_opt_state
, MDL
);
956 data_string_forget(enc_opt_data
, MDL
);
964 set_status_code(u_int16_t status_code
, const char *status_message
,
965 struct option_state
*opt_state
)
967 struct data_string d
;
970 memset(&d
, 0, sizeof(d
));
971 d
.len
= sizeof(status_code
) + strlen(status_message
);
972 if (!buffer_allocate(&d
.buffer
, d
.len
, MDL
)) {
973 log_fatal("set_status_code: no memory for status code.");
975 d
.data
= d
.buffer
->data
;
976 putUShort(d
.buffer
->data
, status_code
);
977 memcpy(d
.buffer
->data
+ sizeof(status_code
),
978 status_message
, d
.len
- sizeof(status_code
));
979 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
980 d
.buffer
, (unsigned char *)d
.data
, d
.len
,
981 D6O_STATUS_CODE
, 0)) {
982 log_error("set_status_code: error saving status code.");
987 data_string_forget(&d
, MDL
);
991 void check_pool6_threshold(struct reply_state
*reply
,
992 struct iasubopt
*lease
)
994 struct ipv6_pond
*pond
;
995 isc_uint64_t used
, count
, high_threshold
;
996 int poolhigh
= 0, poollow
= 0;
997 char *shared_name
= "no name";
998 char tmp_addr
[INET6_ADDRSTRLEN
];
1000 if ((lease
->ipv6_pool
== NULL
) || (lease
->ipv6_pool
->ipv6_pond
== NULL
))
1002 pond
= lease
->ipv6_pool
->ipv6_pond
;
1004 /* If the address range is too large to track, just skip all this. */
1005 if (pond
->jumbo_range
== 1) {
1009 count
= pond
->num_total
;
1010 used
= pond
->num_active
;
1012 /* get network name for logging */
1013 if ((pond
->shared_network
!= NULL
) &&
1014 (pond
->shared_network
->name
!= NULL
)) {
1015 shared_name
= pond
->shared_network
->name
;
1018 /* The logged flag indicates if we have already crossed the high
1019 * threshold and emitted a log message. If it is set we check to
1020 * see if we have re-crossed the low threshold and need to reset
1021 * things. When we cross the high threshold we determine what
1022 * the low threshold is and save it into the low_threshold value.
1023 * When we cross that threshold we reset the logged flag and
1024 * the low_threshold to 0 which allows the high threshold message
1025 * to be emitted once again.
1026 * if we haven't recrossed the boundry we don't need to do anything.
1028 if (pond
->logged
!=0) {
1029 if (used
<= pond
->low_threshold
) {
1030 pond
->low_threshold
= 0;
1032 log_error("Pool threshold reset - shared subnet: %s; "
1033 "address: %s; low threshold %llu/%llu.",
1035 inet_ntop(AF_INET6
, &lease
->addr
,
1036 tmp_addr
, sizeof(tmp_addr
)),
1037 (long long unsigned)(used
),
1038 (long long unsigned)(count
));
1043 /* find the high threshold */
1044 if (get_option_int(&poolhigh
, &server_universe
, reply
->packet
, NULL
,
1045 NULL
, reply
->packet
->options
, reply
->opt_state
,
1046 reply
->opt_state
, &lease
->scope
,
1047 SV_LOG_THRESHOLD_HIGH
, MDL
) == 0) {
1048 /* no threshold bail out */
1052 /* We do have a threshold for this pool, see if its valid */
1053 if ((poolhigh
<= 0) || (poolhigh
> 100)) {
1058 /* we have a valid value, have we exceeded it */
1059 high_threshold
= FIND_POND6_PERCENT(count
, poolhigh
);
1060 if (used
< high_threshold
) {
1061 /* nope, no more to do */
1065 /* we've exceeded it, output a message */
1066 log_error("Pool threshold exceeded - shared subnet: %s; "
1067 "address: %s; high threshold %d%% %llu/%llu.",
1069 inet_ntop(AF_INET6
, &lease
->addr
, tmp_addr
, sizeof(tmp_addr
)),
1070 poolhigh
, (long long unsigned)(used
),
1071 (long long unsigned)(count
));
1073 /* handle the low threshold now, if we don't
1074 * have one we default to 0. */
1075 if ((get_option_int(&poollow
, &server_universe
, reply
->packet
, NULL
,
1076 NULL
, reply
->packet
->options
, reply
->opt_state
,
1077 reply
->opt_state
, &lease
->scope
,
1078 SV_LOG_THRESHOLD_LOW
, MDL
) == 0) ||
1084 * If the low theshold is higher than the high threshold we continue to log
1085 * If it isn't then we set the flag saying we already logged and determine
1086 * what the reset threshold is.
1088 if (poollow
< poolhigh
) {
1090 pond
->low_threshold
= FIND_POND6_PERCENT(count
, poollow
);
1095 * We have a set of operations we do to set up the reply packet, which
1096 * is the same for many message types.
1099 start_reply(struct packet
*packet
,
1100 const struct data_string
*client_id
,
1101 const struct data_string
*server_id
,
1102 struct option_state
**opt_state
,
1103 struct dhcpv6_packet
*reply
)
1105 struct option_cache
*oc
;
1106 const unsigned char *server_id_data
;
1110 * Build our option state for reply.
1113 if (!option_state_allocate(opt_state
, MDL
)) {
1114 log_error("start_reply: no memory for option_state.");
1117 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1118 packet
->options
, *opt_state
,
1119 &global_scope
, root_group
, NULL
, NULL
);
1122 * A small bit of special handling for Solicit messages.
1124 * We could move the logic into a flag, but for now just check
1127 if (packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
1128 reply
->msg_type
= DHCPV6_ADVERTISE
;
1132 * - this message type supports rapid commit (Solicit), and
1133 * - the server is configured to supply a rapid commit, and
1134 * - the client requests a rapid commit,
1135 * Then we add a rapid commit option, and send Reply (instead
1138 oc
= lookup_option(&dhcpv6_universe
,
1139 *opt_state
, D6O_RAPID_COMMIT
);
1141 oc
= lookup_option(&dhcpv6_universe
,
1142 packet
->options
, D6O_RAPID_COMMIT
);
1144 /* Rapid-commit in action. */
1145 reply
->msg_type
= DHCPV6_REPLY
;
1147 /* Don't want a rapid-commit in advertise. */
1148 delete_option(&dhcpv6_universe
,
1149 *opt_state
, D6O_RAPID_COMMIT
);
1153 reply
->msg_type
= DHCPV6_REPLY
;
1154 /* Delete the rapid-commit from the sent options. */
1155 oc
= lookup_option(&dhcpv6_universe
,
1156 *opt_state
, D6O_RAPID_COMMIT
);
1158 delete_option(&dhcpv6_universe
,
1159 *opt_state
, D6O_RAPID_COMMIT
);
1164 * Use the client's transaction identifier for the reply.
1166 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
1167 sizeof(reply
->transaction_id
));
1170 * RFC 3315, section 18.2 says we need server identifier and
1171 * client identifier.
1173 * If the server ID is defined via the configuration file, then
1174 * it will already be present in the option state at this point,
1175 * so we don't need to set it.
1177 * If we have a server ID passed in from the caller,
1178 * use that, otherwise use the global DUID.
1180 oc
= lookup_option(&dhcpv6_universe
, *opt_state
, D6O_SERVERID
);
1182 if (server_id
== NULL
) {
1183 server_id_data
= server_duid
.data
;
1184 server_id_len
= server_duid
.len
;
1186 server_id_data
= server_id
->data
;
1187 server_id_len
= server_id
->len
;
1189 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1190 NULL
, (unsigned char *)server_id_data
,
1191 server_id_len
, D6O_SERVERID
, 0)) {
1192 log_error("start_reply: "
1193 "error saving server identifier.");
1198 if (client_id
->buffer
!= NULL
) {
1199 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1201 (unsigned char *)client_id
->data
,
1204 log_error("start_reply: error saving "
1205 "client identifier.");
1211 * If the client accepts reconfiguration, let it know that we
1214 * Note: we don't actually do this yet, but DOCSIS requires we
1217 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
1220 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1221 NULL
, (unsigned char *)"", 0,
1222 D6O_RECONF_ACCEPT
, 0)) {
1223 log_error("start_reply: "
1224 "error saving RECONF_ACCEPT option.");
1225 option_state_dereference(opt_state
, MDL
);
1234 * Try to get the IPv6 address the client asked for from the
1237 * addr is the result (should be a pointer to NULL on entry)
1238 * pool is the pool to search in
1239 * requested_addr is the address the client wants
1242 try_client_v6_address(struct iasubopt
**addr
,
1243 struct ipv6_pool
*pool
,
1244 const struct data_string
*requested_addr
)
1246 struct in6_addr tmp_addr
;
1247 isc_result_t result
;
1249 if (requested_addr
->len
< sizeof(tmp_addr
)) {
1250 return DHCP_R_INVALIDARG
;
1252 memcpy(&tmp_addr
, requested_addr
->data
, sizeof(tmp_addr
));
1253 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
)) {
1254 return ISC_R_FAILURE
;
1258 * The address is not covered by this (or possibly any) dynamic
1261 if (!ipv6_in_pool(&tmp_addr
, pool
)) {
1262 return ISC_R_ADDRNOTAVAIL
;
1265 if (lease6_exists(pool
, &tmp_addr
)) {
1266 return ISC_R_ADDRINUSE
;
1269 result
= iasubopt_allocate(addr
, MDL
);
1270 if (result
!= ISC_R_SUCCESS
) {
1273 (*addr
)->addr
= tmp_addr
;
1276 /* Default is soft binding for 2 minutes. */
1277 result
= add_lease6(pool
, *addr
, cur_time
+ 120);
1278 if (result
!= ISC_R_SUCCESS
) {
1279 iasubopt_dereference(addr
, MDL
);
1286 * \brief Get an IPv6 address for the client.
1288 * Attempt to find a usable address for the client. We walk through
1289 * the ponds checking for permit and deny then through the pools
1290 * seeing if they have an available address.
1292 * \param reply = the state structure for the current work on this request
1293 * if we create a lease we return it using reply->lease
1296 * ISC_R_SUCCESS = we were able to find an address and are returning a
1297 * pointer to the lease
1298 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1299 * is probabalistic. We don't exhaustively try the
1300 * address range, instead we hash the duid and if
1301 * the address derived from the hash is in use we
1302 * hash the address. After a number of failures we
1303 * conclude the pool is basically full.
1306 pick_v6_address(struct reply_state
*reply
)
1308 struct ipv6_pool
*p
= NULL
;
1309 struct ipv6_pond
*pond
;
1312 unsigned int attempts
;
1313 char tmp_buf
[INET6_ADDRSTRLEN
];
1314 struct iasubopt
**addr
= &reply
->lease
;
1315 isc_uint64_t total
= 0;
1316 isc_uint64_t active
= 0;
1317 isc_uint64_t abandoned
= 0;
1318 int jumbo_range
= 0;
1319 char *shared_name
= (reply
->shared
->name
?
1320 reply
->shared
->name
: "(no name)");
1323 * Do a quick walk through of the ponds and pools
1324 * to see if we have any NA address pools
1326 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1327 if (pond
->ipv6_pools
== NULL
)
1330 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1331 if (p
->pool_type
== D6O_IA_NA
)
1338 /* If we get here and p is NULL we have no useful pools */
1340 log_debug("Unable to pick client address: "
1341 "no IPv6 pools on this shared network");
1342 return ISC_R_NORESOURCES
;
1346 * We have at least one pool that could provide an address
1347 * Now we walk through the ponds and pools again and check
1348 * to see if the client is permitted and if an address is
1351 * Within a given pond we start looking at the last pool we
1352 * allocated from, unless it had a collision trying to allocate
1353 * an address. This will tend to move us into less-filled pools.
1356 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1357 isc_result_t result
= ISC_R_FAILURE
;
1359 if (((pond
->prohibit_list
!= NULL
) &&
1360 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1361 ((pond
->permit_list
!= NULL
) &&
1362 (!permitted(reply
->packet
, pond
->permit_list
))))
1366 /* If pond is EUI-64 but client duid isn't a valid EUI-64
1367 * id, then skip this pond */
1368 if (pond
->use_eui_64
&&
1369 !valid_eui_64_duid(&reply
->ia
->iaid_duid
, IAID_LEN
)) {
1374 start_pool
= pond
->last_ipv6_pool
;
1377 p
= pond
->ipv6_pools
[i
];
1378 if (p
->pool_type
== D6O_IA_NA
) {
1380 if (pond
->use_eui_64
) {
1382 create_lease6_eui_64(p
, addr
,
1383 &reply
->ia
->iaid_duid
,
1390 create_lease6(p
, addr
, &attempts
,
1391 &reply
->ia
->iaid_duid
,
1396 if (result
== ISC_R_SUCCESS
) {
1398 * Record the pool used (or next one if
1399 * there was a collision).
1403 if (pond
->ipv6_pools
[i
]
1409 pond
->last_ipv6_pool
= i
;
1411 log_debug("Picking pool address %s",
1414 tmp_buf
, sizeof(tmp_buf
)));
1415 return (ISC_R_SUCCESS
);
1420 if (pond
->ipv6_pools
[i
] == NULL
) {
1423 } while (i
!= start_pool
);
1425 if (result
== ISC_R_NORESOURCES
) {
1426 jumbo_range
+= pond
->jumbo_range
;
1427 total
+= pond
->num_total
;
1428 active
+= pond
->num_active
;
1429 abandoned
+= pond
->num_abandoned
;
1434 * If we failed to pick an IPv6 address from any of the subnets.
1435 * Presumably that means we have no addresses for the client.
1437 if (jumbo_range
!= 0) {
1438 log_debug("Unable to pick client address: "
1439 "no addresses available - shared network %s: "
1440 " 2^64-1 < total, %llu active, %llu abandoned",
1441 shared_name
, (long long unsigned)(active
- abandoned
),
1442 (long long unsigned)(abandoned
));
1444 log_debug("Unable to pick client address: "
1445 "no addresses available - shared network %s: "
1446 "%llu total, %llu active, %llu abandoned",
1447 shared_name
, (long long unsigned)(total
),
1448 (long long unsigned)(active
- abandoned
),
1449 (long long unsigned)(abandoned
));
1452 return ISC_R_NORESOURCES
;
1456 * Try to get the IPv6 prefix the client asked for from the
1459 * pref is the result (should be a pointer to NULL on entry)
1460 * pool is the prefix pool to search in
1461 * requested_pref is the address the client wants
1464 try_client_v6_prefix(struct iasubopt
**pref
,
1465 struct ipv6_pool
*pool
,
1466 const struct data_string
*requested_pref
)
1469 struct in6_addr tmp_pref
;
1471 isc_result_t result
;
1473 if (requested_pref
->len
< sizeof(tmp_plen
) + sizeof(tmp_pref
)) {
1474 return DHCP_R_INVALIDARG
;
1477 tmp_plen
= (int) requested_pref
->data
[0];
1478 if ((tmp_plen
< 3) || (tmp_plen
> 128)) {
1479 return ISC_R_FAILURE
;
1482 memcpy(&tmp_pref
, requested_pref
->data
+ 1, sizeof(tmp_pref
));
1483 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref
)) {
1484 return ISC_R_FAILURE
;
1488 memcpy(&ia
.iabuf
, &tmp_pref
, 16);
1489 if (!is_cidr_mask_valid(&ia
, (int) tmp_plen
)) {
1490 return ISC_R_FAILURE
;
1493 if (!ipv6_in_pool(&tmp_pref
, pool
) ||
1494 ((int)tmp_plen
!= pool
->units
)) {
1495 return ISC_R_ADDRNOTAVAIL
;
1498 if (prefix6_exists(pool
, &tmp_pref
, tmp_plen
)) {
1499 return ISC_R_ADDRINUSE
;
1502 result
= iasubopt_allocate(pref
, MDL
);
1503 if (result
!= ISC_R_SUCCESS
) {
1507 (*pref
)->addr
= tmp_pref
;
1508 (*pref
)->plen
= tmp_plen
;
1510 /* Default is soft binding for 2 minutes. */
1511 result
= add_lease6(pool
, *pref
, cur_time
+ 120);
1512 if (result
!= ISC_R_SUCCESS
) {
1513 iasubopt_dereference(pref
, MDL
);
1521 * \brief Get an IPv6 prefix for the client.
1523 * Attempt to find a usable prefix for the client. Based upon the prefix
1524 * length mode and the plen supplied by the client (if one), we make one
1525 * or more calls to pick_v6_prefix_helper() to find a prefix as follows:
1527 * PLM_IGNORE or client specifies a plen of zero, use the first available
1528 * prefix regardless of it's length.
1530 * PLM_PREFER – look for an exact match to client's plen first, if none
1531 * found, use the first available prefix of any length
1533 * PLM_EXACT – look for an exact match first, if none found then fail. This
1534 * is the default behavior.
1536 * PLM_MAXIMUM - look for an exact match first, then the first available whose
1537 * prefix length is less than client's plen, otherwise fail.
1539 * PLM_MINIMUM - look for an exact match first, then the first available whose
1540 * prefix length is greater than client's plen, otherwise fail.
1542 * Note that the selection mode is configurable at the global scope only via
1545 * \param reply = the state structure for the current work on this request
1546 * if we create a lease we return it using reply->lease
1549 * ISC_R_SUCCESS = we were able to find an prefix and are returning a
1550 * pointer to the lease
1551 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1552 * is probabalistic. We don't exhaustively try the
1553 * address range, instead we hash the duid and if
1554 * the address derived from the hash is in use we
1555 * hash the address. After a number of failures we
1556 * conclude the pool is basically full.
1559 pick_v6_prefix(struct reply_state
*reply
) {
1560 struct ipv6_pool
*p
= NULL
;
1561 struct ipv6_pond
*pond
;
1563 isc_result_t result
;
1566 * Do a quick walk through of the ponds and pools
1567 * to see if we have any prefix pools
1569 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1570 if (pond
->ipv6_pools
== NULL
)
1573 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1574 if (p
->pool_type
== D6O_IA_PD
)
1581 /* If we get here and p is NULL we have no useful pools */
1583 log_debug("Unable to pick client prefix: "
1584 "no IPv6 pools on this shared network");
1585 return ISC_R_NORESOURCES
;
1588 if (reply
->preflen
<= 0) {
1589 /* If we didn't get a plen (-1) or client plen is 0, then just
1590 * select first available (same as PLM_INGORE) */
1591 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1593 switch (prefix_length_mode
) {
1595 /* First we look for an exact match, if not found
1596 * then first available */
1597 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1598 if (result
!= ISC_R_SUCCESS
) {
1599 result
= pick_v6_prefix_helper(reply
,
1605 /* Match exactly or fail */
1606 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1611 /* First we look for an exact match, if not found
1612 * then first available by mode */
1613 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1614 if (result
!= ISC_R_SUCCESS
) {
1615 result
= pick_v6_prefix_helper(reply
,
1616 prefix_length_mode
);
1621 /* First available */
1622 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1627 if (result
== ISC_R_SUCCESS
) {
1628 char tmp_buf
[INET6_ADDRSTRLEN
];
1630 log_debug("Picking pool prefix %s/%u",
1631 inet_ntop(AF_INET6
, &(reply
->lease
->addr
),
1632 tmp_buf
, sizeof(tmp_buf
)),
1633 (unsigned)(reply
->lease
->plen
));
1634 return (ISC_R_SUCCESS
);
1638 * If we failed to pick an IPv6 prefix
1639 * Presumably that means we have no prefixes for the client.
1641 log_debug("Unable to pick client prefix: no prefixes available");
1642 return ISC_R_NORESOURCES
;
1647 * \brief Get an IPv6 prefix for the client based upon selection mode.
1649 * We walk through the ponds checking for permit and deny. If a pond is
1650 * permissable to use, loop through its PD pools checking prefix lengths
1651 * against the client plen based on the prefix length mode, looking for
1652 * available prefixes.
1654 * \param reply = the state structure for the current work on this request
1655 * if we create a lease we return it using reply->lease
1656 * \prefix_mode = selection mode to use
1659 * ISC_R_SUCCESS = we were able to find a prefix and are returning a
1660 * pointer to the lease
1661 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1662 * is probabalistic. We don't exhaustively try the
1663 * address range, instead we hash the duid and if
1664 * the address derived from the hash is in use we
1665 * hash the address. After a number of failures we
1666 * conclude the pool is basically full.
1669 pick_v6_prefix_helper(struct reply_state
*reply
, int prefix_mode
) {
1670 struct ipv6_pool
*p
= NULL
;
1671 struct ipv6_pond
*pond
;
1673 unsigned int attempts
;
1674 struct iasubopt
**pref
= &reply
->lease
;
1676 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1677 if (((pond
->prohibit_list
!= NULL
) &&
1678 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1679 ((pond
->permit_list
!= NULL
) &&
1680 (!permitted(reply
->packet
, pond
->permit_list
))))
1683 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1684 if ((p
->pool_type
== D6O_IA_PD
) &&
1685 (eval_prefix_mode(p
->units
, reply
->preflen
,
1686 prefix_mode
) == 1) &&
1687 (create_prefix6(p
, pref
, &attempts
,
1688 &reply
->ia
->iaid_duid
,
1689 cur_time
+ 120) == ISC_R_SUCCESS
)) {
1690 return (ISC_R_SUCCESS
);
1695 return ISC_R_NORESOURCES
;
1700 * \brief Test a prefix length against another based on prefix length mode
1702 * \param len - prefix length to test
1703 * \param preflen - preferred prefix length against which to test
1704 * \param prefix_mode - prefix selection mode with which to test
1706 * Note that the case of preferred length of 0 is not short-cut here as it
1707 * is assumed to be done at a higher level.
1709 * \return 1 if the given length is usable based upon mode and a preferred
1713 eval_prefix_mode(int len
, int preflen
, int prefix_mode
) {
1715 switch (prefix_mode
) {
1717 use_it
= (len
== preflen
);
1720 /* they asked for a prefix length no "shorter" than preflen */
1721 use_it
= (len
>= preflen
);
1724 /* they asked for a prefix length no "longer" than preflen */
1725 use_it
= (len
<= preflen
);
1728 /* otherwise use it */
1736 *! \file server/dhcpv6.c
1738 * \brief construct a reply containing information about a client's lease
1740 * lease_to_client() is called from several messages to construct a
1741 * reply that contains all that we know about the client's correct lease
1742 * (or projected lease).
1744 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1745 * send what we "may" give them on a request.
1747 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1748 * the client should really use).
1750 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1751 * Rebind out any "wrong" addresses the client sends. This means we send
1752 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1753 * possibly send the address with zeroed lifetimes.
1755 * Information-Request - No binding.
1757 * The basic structure is to traverse the client-supplied data first, and
1758 * validate and echo back any contents that can be. If the client-supplied
1759 * data does not error out (on renew/rebind as above), but we did not send
1760 * any addresses, attempt to allocate one.
1762 * At the end of the this function we call commit_leases_timed() to
1763 * fsync and rotate the file as necessary. commit_leases_timed() will
1764 * check that we have written at least one lease to the file and that
1765 * some time has passed before doing any fsync or file rewrite so we
1766 * don't bother tracking if we did a write_ia during this function.
1768 /* TODO: look at client hints for lease times */
1771 lease_to_client(struct data_string
*reply_ret
,
1772 struct packet
*packet
,
1773 const struct data_string
*client_id
,
1774 const struct data_string
*server_id
)
1776 static struct reply_state reply
;
1777 struct option_cache
*oc
;
1778 struct data_string packet_oro
;
1781 memset(&packet_oro
, 0, sizeof(packet_oro
));
1783 /* Locate the client. */
1784 if (shared_network_from_packet6(&reply
.shared
,
1785 packet
) != ISC_R_SUCCESS
)
1789 * Initialize the reply.
1791 packet_reference(&reply
.packet
, packet
, MDL
);
1792 data_string_copy(&reply
.client_id
, client_id
, MDL
);
1794 if (!start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
1798 /* Set the write cursor to just past the reply header. */
1799 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1802 * Get the ORO from the packet, if any.
1804 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ORO
);
1806 if (!evaluate_option_cache(&packet_oro
, packet
,
1808 packet
->options
, NULL
,
1809 &global_scope
, oc
, MDL
)) {
1810 log_error("lease_to_client: error evaluating ORO.");
1816 * Find a host record that matches the packet, if any, and is
1817 * valid for the shared network the client is on.
1819 if (find_hosts6(&reply
.host
, packet
, client_id
, MDL
)) {
1821 seek_shared_host(&reply
.host
, reply
.shared
);
1824 /* Process the client supplied IA's onto the reply buffer. */
1826 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
1828 for (; oc
!= NULL
; oc
= oc
->next
) {
1829 isc_result_t status
;
1831 /* Start counting resources (addresses) offered. */
1832 reply
.client_resources
= 0;
1833 reply
.resources_included
= ISC_FALSE
;
1835 status
= reply_process_ia_na(&reply
, oc
);
1838 * We continue to try other IA's whether we can address
1839 * this one or not. Any other result is an immediate fail.
1841 if ((status
!= ISC_R_SUCCESS
) &&
1842 (status
!= ISC_R_NORESOURCES
))
1845 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
1846 for (; oc
!= NULL
; oc
= oc
->next
) {
1847 isc_result_t status
;
1849 /* Start counting resources (addresses) offered. */
1850 reply
.client_resources
= 0;
1851 reply
.resources_included
= ISC_FALSE
;
1853 status
= reply_process_ia_ta(&reply
, oc
);
1856 * We continue to try other IA's whether we can address
1857 * this one or not. Any other result is an immediate fail.
1859 if ((status
!= ISC_R_SUCCESS
) &&
1860 (status
!= ISC_R_NORESOURCES
))
1864 /* Same for IA_PD's. */
1866 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
1867 for (; oc
!= NULL
; oc
= oc
->next
) {
1868 isc_result_t status
;
1870 /* Start counting resources (prefixes) offered. */
1871 reply
.client_resources
= 0;
1872 reply
.resources_included
= ISC_FALSE
;
1874 status
= reply_process_ia_pd(&reply
, oc
);
1877 * We continue to try other IA_PD's whether we can address
1878 * this one or not. Any other result is an immediate fail.
1880 if ((status
!= ISC_R_SUCCESS
) &&
1881 (status
!= ISC_R_NORESOURCES
))
1886 * Make no reply if we gave no resources and is not
1887 * for Information-Request.
1889 if ((reply
.ia_count
== 0) && (reply
.pd_count
== 0)) {
1890 if (reply
.packet
->dhcpv6_msg_type
!=
1891 DHCPV6_INFORMATION_REQUEST
)
1895 * Because we only execute statements on a per-IA basis,
1896 * we need to execute statements in any non-IA reply to
1897 * source configuration.
1899 execute_statements_in_scope(NULL
, reply
.packet
, NULL
, NULL
,
1900 reply
.packet
->options
,
1901 reply
.opt_state
, &global_scope
,
1902 reply
.shared
->group
, root_group
,
1905 /* Execute statements from class scopes. */
1906 for (i
= reply
.packet
->class_count
; i
> 0; i
--) {
1907 execute_statements_in_scope(NULL
, reply
.packet
,
1909 reply
.packet
->options
,
1912 reply
.packet
->classes
[i
- 1]->group
,
1913 reply
.shared
->group
, NULL
);
1916 /* Bring in any configuration from a host record. */
1917 if (reply
.host
!= NULL
)
1918 execute_statements_in_scope(NULL
, reply
.packet
,
1920 reply
.packet
->options
,
1924 reply
.shared
->group
, NULL
);
1928 * RFC3315 section 17.2.2 (Solicit):
1930 * If the server will not assign any addresses to any IAs in a
1931 * subsequent Request from the client, the server MUST send an
1932 * Advertise message to the client that includes only a Status
1933 * Code option with code NoAddrsAvail and a status message for
1934 * the user, a Server Identifier option with the server's DUID,
1935 * and a Client Identifier option with the client's DUID.
1937 * This has been updated by an errata such that the server
1938 * can always send an IA.
1940 * Section 18.2.1 (Request):
1942 * If the server cannot assign any addresses to an IA in the
1943 * message from the client, the server MUST include the IA in
1944 * the Reply message with no addresses in the IA and a Status
1945 * Code option in the IA containing status code NoAddrsAvail.
1947 * Section 18.1.8 (Client Behavior):
1949 * Leave unchanged any information about addresses the client has
1950 * recorded in the IA but that were not included in the IA from
1952 * Sends a Renew/Rebind if the IA is not in the Reply message.
1956 * Having stored the client's IA's, store any options that
1957 * will fit in the remaining space.
1959 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+ reply
.cursor
,
1960 sizeof(reply
.buf
) - reply
.cursor
,
1961 reply
.opt_state
, reply
.packet
,
1962 required_opts_solicit
,
1965 /* Return our reply to the caller. */
1966 reply_ret
->len
= reply
.cursor
;
1967 reply_ret
->buffer
= NULL
;
1968 if (!buffer_allocate(&reply_ret
->buffer
, reply
.cursor
, MDL
)) {
1969 log_fatal("No memory to store Reply.");
1971 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
, reply
.cursor
);
1972 reply_ret
->data
= reply_ret
->buffer
->data
;
1974 /* If appropriate commit and rotate the lease file */
1975 (void) commit_leases_timed();
1979 if (reply
.shared
!= NULL
)
1980 shared_network_dereference(&reply
.shared
, MDL
);
1981 if (reply
.host
!= NULL
)
1982 host_dereference(&reply
.host
, MDL
);
1983 if (reply
.opt_state
!= NULL
)
1984 option_state_dereference(&reply
.opt_state
, MDL
);
1985 if (reply
.packet
!= NULL
)
1986 packet_dereference(&reply
.packet
, MDL
);
1987 if (reply
.client_id
.data
!= NULL
)
1988 data_string_forget(&reply
.client_id
, MDL
);
1989 if (packet_oro
.buffer
!= NULL
)
1990 data_string_forget(&packet_oro
, MDL
);
1991 reply
.renew
= reply
.rebind
= reply
.min_prefer
= reply
.min_valid
= 0;
1995 /* Process a client-supplied IA_NA. This may append options to the tail of
1996 * the reply packet being built in the reply_state structure.
1999 reply_process_ia_na(struct reply_state
*reply
, struct option_cache
*ia
) {
2000 isc_result_t status
= ISC_R_SUCCESS
;
2003 struct option_state
*packet_ia
;
2004 struct option_cache
*oc
;
2005 struct data_string ia_data
, data
;
2007 /* Initialize values that will get cleaned up on return. */
2009 memset(&ia_data
, 0, sizeof(ia_data
));
2010 memset(&data
, 0, sizeof(data
));
2012 * Note that find_client_address() may set reply->lease.
2015 /* Make sure there is at least room for the header. */
2016 if ((reply
->cursor
+ IA_NA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2017 log_error("reply_process_ia_na: Reply too long for IA.");
2018 return ISC_R_NOSPACE
;
2022 /* Fetch the IA_NA contents. */
2023 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2024 ia
, IA_NA_OFFSET
)) {
2025 log_error("reply_process_ia_na: error evaluating ia");
2026 status
= ISC_R_FAILURE
;
2030 /* Extract IA_NA header contents. */
2031 iaid
= getULong(ia_data
.data
);
2032 reply
->renew
= getULong(ia_data
.data
+ 4);
2033 reply
->rebind
= getULong(ia_data
.data
+ 8);
2035 /* Create an IA_NA structure. */
2036 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2037 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2038 log_error("reply_process_ia_na: no memory for ia.");
2039 status
= ISC_R_NOMEMORY
;
2042 reply
->ia
->ia_type
= D6O_IA_NA
;
2044 /* Cache pre-existing IA, if any. */
2045 ia_hash_lookup(&reply
->old_ia
, ia_na_active
,
2046 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2047 reply
->ia
->iaid_duid
.len
, MDL
);
2050 * Create an option cache to carry the IA_NA option contents, and
2051 * execute any user-supplied values into it.
2053 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2054 status
= ISC_R_NOMEMORY
;
2058 /* Check & cache the fixed host record. */
2059 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_addr
!= NULL
)) {
2060 struct iaddr tmp_addr
;
2062 if (!evaluate_option_cache(&reply
->fixed
, NULL
, NULL
, NULL
,
2063 NULL
, NULL
, &global_scope
,
2064 reply
->host
->fixed_addr
, MDL
)) {
2065 log_error("reply_process_ia_na: unable to evaluate "
2067 status
= ISC_R_FAILURE
;
2071 if (reply
->fixed
.len
< 16) {
2072 log_error("reply_process_ia_na: invalid fixed address.");
2073 status
= DHCP_R_INVALIDARG
;
2077 /* Find the static lease's subnet. */
2079 memcpy(tmp_addr
.iabuf
, reply
->fixed
.data
, 16);
2081 if (find_grouped_subnet(&reply
->subnet
, reply
->shared
,
2082 tmp_addr
, MDL
) == 0)
2083 log_fatal("Impossible condition at %s:%d.", MDL
);
2085 reply
->static_lease
= ISC_TRUE
;
2087 reply
->static_lease
= ISC_FALSE
;
2090 * Save the cursor position at the start of the IA, so we can
2091 * set length and adjust t1/t2 values later. We write a temporary
2092 * header out now just in case we decide to adjust the packet
2093 * within sub-process functions.
2095 ia_cursor
= reply
->cursor
;
2097 /* Initialize the IA_NA header. First the code. */
2098 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_NA
);
2101 /* Then option length. */
2102 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
2105 /* Then IA_NA header contents; IAID. */
2106 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2109 /* We store the client's t1 for now, and may over-ride it later. */
2110 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
2113 /* We store the client's t2 for now, and may over-ride it later. */
2114 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
2118 * For each address in this IA_NA, decide what to do about it.
2122 * The client leaves unchanged any information about addresses
2123 * it has recorded but are not included ("cancel/break" below).
2124 * A not included IA ("cleanup" below) could give a Renew/Rebind.
2126 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2127 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
2128 reply
->client_valid
= reply
->client_prefer
= 0;
2129 for (; oc
!= NULL
; oc
= oc
->next
) {
2130 status
= reply_process_addr(reply
, oc
);
2133 * Canceled means we did not allocate addresses to the
2134 * client, but we're "done" with this IA - we set a status
2135 * code. So transmit this reply, e.g., move on to the next
2138 if (status
== ISC_R_CANCELED
)
2141 if ((status
!= ISC_R_SUCCESS
) &&
2142 (status
!= ISC_R_ADDRINUSE
) &&
2143 (status
!= ISC_R_ADDRNOTAVAIL
))
2150 * If we fell through the above and never gave the client
2151 * an address, give it one now.
2153 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
2154 status
= find_client_address(reply
);
2156 if (status
== ISC_R_NORESOURCES
) {
2157 switch (reply
->packet
->dhcpv6_msg_type
) {
2158 case DHCPV6_SOLICIT
:
2160 * No address for any IA is handled
2165 case DHCPV6_REQUEST
:
2166 /* Section 18.2.1 (Request):
2168 * If the server cannot assign any addresses to
2169 * an IA in the message from the client, the
2170 * server MUST include the IA in the Reply
2171 * message with no addresses in the IA and a
2172 * Status Code option in the IA containing
2173 * status code NoAddrsAvail.
2175 option_state_dereference(&reply
->reply_ia
, MDL
);
2176 if (!option_state_allocate(&reply
->reply_ia
,
2179 log_error("reply_process_ia_na: No "
2180 "memory for option state "
2182 status
= ISC_R_NOMEMORY
;
2186 if (!set_status_code(STATUS_NoAddrsAvail
,
2187 "No addresses available "
2188 "for this interface.",
2190 log_error("reply_process_ia_na: Unable "
2191 "to set NoAddrsAvail status "
2193 status
= ISC_R_FAILURE
;
2197 status
= ISC_R_SUCCESS
;
2202 * RFC 3315 does not tell us to emit a status
2203 * code in this condition, or anything else.
2205 * If we included non-allocated addresses
2206 * (zeroed lifetimes) in an IA, then the client
2207 * will deconfigure them.
2209 * So we want to include the IA even if we
2210 * can't give it a new address if it includes
2211 * zeroed lifetime addresses.
2213 * We don't want to include the IA if we
2214 * provide zero addresses including zeroed
2217 if (reply
->resources_included
)
2218 status
= ISC_R_SUCCESS
;
2225 if (status
!= ISC_R_SUCCESS
)
2230 * yes, goto's aren't the best but we also want to avoid extra
2233 if (status
== ISC_R_CANCELED
) {
2234 /* We're replying with a status code so we still need to
2235 * write it out in wire-format to the outbound buffer */
2236 write_to_packet(reply
, ia_cursor
);
2241 * Handle static leases, we always log stuff and if it's
2242 * a hard binding we run any commit statements that we have
2244 if (reply
->static_lease
) {
2245 char tmp_addr
[INET6_ADDRSTRLEN
];
2246 log_info("%s NA: address %s to client with duid %s iaid = %d "
2248 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2249 inet_ntop(AF_INET6
, reply
->fixed
.data
, tmp_addr
,
2251 print_hex_1(reply
->client_id
.len
,
2252 reply
->client_id
.data
, 60),
2255 /* Write the lease out in wire-format to the outbound buffer */
2256 write_to_packet(reply
, ia_cursor
);
2258 /* Performs DDNS updates if we're configured to do them */
2259 ddns_update_static6(reply
);
2261 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
2262 (reply
->on_star
.on_commit
!= NULL
)) {
2263 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
2264 reply
->packet
->options
,
2265 reply
->opt_state
, NULL
,
2266 reply
->on_star
.on_commit
, NULL
);
2267 executable_statement_dereference
2268 (&reply
->on_star
.on_commit
, MDL
);
2274 * If we have any addresses log what we are doing.
2276 if (reply
->ia
->num_iasubopt
!= 0) {
2277 struct iasubopt
*tmp
;
2279 char tmp_addr
[INET6_ADDRSTRLEN
];
2281 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2282 tmp
= reply
->ia
->iasubopt
[i
];
2284 log_info("%s NA: address %s to client with duid %s "
2285 "iaid = %d valid for %u seconds",
2286 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2287 inet_ntop(AF_INET6
, &tmp
->addr
,
2288 tmp_addr
, sizeof(tmp_addr
)),
2289 print_hex_1(reply
->client_id
.len
,
2290 reply
->client_id
.data
, 60),
2296 * If this is not a 'soft' binding, consume the new changes into
2297 * the database (if any have been attached to the ia_na).
2299 * Loop through the assigned dynamic addresses, referencing the
2300 * leases onto this IA_NA rather than any old ones, and updating
2301 * pool timers for each (if any).
2303 * Note that we must do ddns_updates() before we test for lease
2304 * reuse (so we'll know if DNS entries are different). To ensure
2305 * we don't break any configs, we run on_commit statements before
2306 * we do ddns_updates() just in case the former affects the later.
2307 * This is symetrical with v4 logic. We always run on_commit and
2308 * ddns_udpates() whether a lease is reused or renewed.
2310 if ((reply
->ia
->num_iasubopt
!= 0) &&
2311 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
2312 int must_commit
= 0;
2313 struct iasubopt
*tmp
;
2314 struct data_string
*ia_id
;
2317 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2318 tmp
= reply
->ia
->iasubopt
[i
];
2319 if (tmp
->ia
!= NULL
) {
2320 ia_dereference(&tmp
->ia
, MDL
);
2323 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2325 /* If we have anything to do on commit do it now */
2326 if (tmp
->on_star
.on_commit
!= NULL
) {
2327 execute_statements(NULL
, reply
->packet
,
2329 reply
->packet
->options
,
2332 tmp
->on_star
.on_commit
,
2334 executable_statement_dereference
2335 (&tmp
->on_star
.on_commit
, MDL
);
2338 #if defined (NSUPDATE)
2340 /* Perform ddns updates */
2341 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2344 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2346 reply
->packet
->options
,
2350 ddns_updates(reply
->packet
, NULL
, NULL
,
2351 tmp
, NULL
, reply
->opt_state
);
2354 if (!reuse_lease6(reply
, tmp
)) {
2355 /* Commit 'hard' bindings. */
2357 renew_lease6(tmp
->ipv6_pool
, tmp
);
2358 schedule_lease_timeout(tmp
->ipv6_pool
);
2360 /* Do our threshold check. */
2361 check_pool6_threshold(reply
, tmp
);
2365 /* write the IA_NA in wire-format to the outbound buffer */
2366 write_to_packet(reply
, ia_cursor
);
2368 /* Remove any old ia from the hash. */
2369 if (reply
->old_ia
!= NULL
) {
2370 if (!release_on_roam(reply
)) {
2371 ia_id
= &reply
->old_ia
->iaid_duid
;
2372 ia_hash_delete(ia_na_active
,
2373 (unsigned char *)ia_id
->data
,
2377 ia_dereference(&reply
->old_ia
, MDL
);
2380 /* Put new ia into the hash. */
2381 reply
->ia
->cltt
= cur_time
;
2382 ia_id
= &reply
->ia
->iaid_duid
;
2383 ia_hash_add(ia_na_active
, (unsigned char *)ia_id
->data
,
2384 ia_id
->len
, reply
->ia
, MDL
);
2386 /* If we couldn't reuse all of the iasubopts, we
2387 * must update udpate the lease db */
2389 write_ia(reply
->ia
);
2392 /* write the IA_NA in wire-format to the outbound buffer */
2393 write_to_packet(reply
, ia_cursor
);
2394 schedule_lease_timeout_reply(reply
);
2398 if (packet_ia
!= NULL
)
2399 option_state_dereference(&packet_ia
, MDL
);
2400 if (reply
->reply_ia
!= NULL
)
2401 option_state_dereference(&reply
->reply_ia
, MDL
);
2402 if (ia_data
.data
!= NULL
)
2403 data_string_forget(&ia_data
, MDL
);
2404 if (data
.data
!= NULL
)
2405 data_string_forget(&data
, MDL
);
2406 if (reply
->ia
!= NULL
)
2407 ia_dereference(&reply
->ia
, MDL
);
2408 if (reply
->old_ia
!= NULL
)
2409 ia_dereference(&reply
->old_ia
, MDL
);
2410 if (reply
->lease
!= NULL
)
2411 iasubopt_dereference(&reply
->lease
, MDL
);
2412 if (reply
->fixed
.data
!= NULL
)
2413 data_string_forget(&reply
->fixed
, MDL
);
2414 if (reply
->subnet
!= NULL
)
2415 subnet_dereference(&reply
->subnet
, MDL
);
2416 if (reply
->on_star
.on_expiry
!= NULL
)
2417 executable_statement_dereference
2418 (&reply
->on_star
.on_expiry
, MDL
);
2419 if (reply
->on_star
.on_release
!= NULL
)
2420 executable_statement_dereference
2421 (&reply
->on_star
.on_release
, MDL
);
2424 * ISC_R_CANCELED is a status code used by the addr processing to
2425 * indicate we're replying with a status code. This is still a
2426 * success at higher layers.
2428 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2432 * Writes the populated IA_xx in wire format to the reply buffer
2435 write_to_packet(struct reply_state
*reply
, unsigned ia_cursor
) {
2436 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2437 sizeof(reply
->buf
) - reply
->cursor
,
2438 reply
->reply_ia
, reply
->packet
,
2439 (reply
->ia
->ia_type
!= D6O_IA_PD
?
2440 required_opts_IA
: required_opts_IA_PD
),
2443 /* Reset the length of this IA to match what was just written. */
2444 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2445 reply
->cursor
- (ia_cursor
+ 4));
2447 if (reply
->ia
->ia_type
!= D6O_IA_TA
) {
2448 /* Calculate T1/T2 and stuff them in the reply */
2449 set_reply_tee_times(reply
, ia_cursor
);
2454 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
2455 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
2456 * in the event we are replying with a status code and do not wish to process
2457 * more IAADDRs within this IA.
2460 reply_process_addr(struct reply_state
*reply
, struct option_cache
*addr
) {
2461 u_int32_t pref_life
, valid_life
;
2462 struct binding_scope
**scope
;
2463 struct group
*group
;
2464 struct subnet
*subnet
;
2465 struct iaddr tmp_addr
;
2466 struct option_cache
*oc
;
2467 struct data_string iaaddr
, data
;
2468 isc_result_t status
= ISC_R_SUCCESS
;
2470 int invalid_for_eui_64
= 0;
2473 /* Initializes values that will be cleaned up. */
2474 memset(&iaaddr
, 0, sizeof(iaaddr
));
2475 memset(&data
, 0, sizeof(data
));
2476 /* Note that reply->lease may be set by address_is_owned() */
2479 * There is no point trying to process an incoming address if there
2480 * is no room for an outgoing address.
2482 if ((reply
->cursor
+ 28) > sizeof(reply
->buf
)) {
2483 log_error("reply_process_addr: Out of room for address.");
2484 return ISC_R_NOSPACE
;
2487 /* Extract this IAADDR option. */
2488 if (!evaluate_option_cache(&iaaddr
, reply
->packet
, NULL
, NULL
,
2489 reply
->packet
->options
, NULL
, &global_scope
,
2491 (iaaddr
.len
< IAADDR_OFFSET
)) {
2492 log_error("reply_process_addr: error evaluating IAADDR.");
2493 status
= ISC_R_FAILURE
;
2497 /* The first 16 bytes are the IPv6 address. */
2498 pref_life
= getULong(iaaddr
.data
+ 16);
2499 valid_life
= getULong(iaaddr
.data
+ 20);
2501 if ((reply
->client_valid
== 0) ||
2502 (reply
->client_valid
> valid_life
))
2503 reply
->client_valid
= valid_life
;
2505 if ((reply
->client_prefer
== 0) ||
2506 (reply
->client_prefer
> pref_life
))
2507 reply
->client_prefer
= pref_life
;
2510 * Clients may choose to send :: as an address, with the idea to give
2511 * hints about preferred-lifetime or valid-lifetime.
2514 memset(tmp_addr
.iabuf
, 0, 16);
2515 if (!memcmp(iaaddr
.data
, tmp_addr
.iabuf
, 16)) {
2516 /* Status remains success; we just ignore this one. */
2520 /* tmp_addr len remains 16 */
2521 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2524 * Verify that this address is on the client's network.
2526 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
2527 subnet
= subnet
->next_sibling
) {
2528 if (addr_eq(subnet_number(tmp_addr
, subnet
->netmask
),
2535 /* If the requested address falls into an EUI-64 pool, then
2536 * we need to verify if it has EUI-64 duid AND the requested
2537 * address is correct for that duid. If not we treat it just
2538 * like an not-on-link request. */
2539 struct ipv6_pool
* pool
= NULL
;
2540 struct in6_addr
* addr
= (struct in6_addr
*)(iaaddr
.data
);
2541 if ((find_ipv6_pool(&pool
, D6O_IA_NA
, addr
) == ISC_R_SUCCESS
)
2542 && (pool
->ipv6_pond
->use_eui_64
) &&
2543 (!valid_for_eui_64_pool(pool
, &reply
->client_id
, 0, addr
))) {
2544 log_debug ("Requested address: %s,"
2545 " not valid for EUI-64 pool",
2547 invalid_for_eui_64
= 1;
2552 /* Address not found on shared network. */
2554 if ((subnet
== NULL
) || invalid_for_eui_64
) {
2556 if (subnet
== NULL
) {
2558 /* Ignore this address on 'soft' bindings. */
2559 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
2560 /* disable rapid commit */
2561 reply
->buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
2562 delete_option(&dhcpv6_universe
,
2565 /* status remains success */
2570 * RFC3315 section 18.2.1:
2572 * If the server finds that the prefix on one or more IP
2573 * addresses in any IA in the message from the client is not
2574 * appropriate for the link to which the client is connected,
2575 * the server MUST return the IA to the client with a Status
2576 * Code option with the value NotOnLink.
2578 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) {
2579 /* Rewind the IA_NA to empty. */
2580 option_state_dereference(&reply
->reply_ia
, MDL
);
2581 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2582 log_error("reply_process_addr: No memory for "
2583 "option state wipe.");
2584 status
= ISC_R_NOMEMORY
;
2588 /* Append a NotOnLink status code. */
2589 if (!set_status_code(STATUS_NotOnLink
,
2590 "Address not for use on this "
2591 "link.", reply
->reply_ia
)) {
2592 log_error("reply_process_addr: Failure "
2593 "setting status code.");
2594 status
= ISC_R_FAILURE
;
2598 /* Fin (no more IAADDRs). */
2599 status
= ISC_R_CANCELED
;
2604 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2606 * If the server finds that any of the addresses are not
2607 * appropriate for the link to which the client is attached,
2608 * the server returns the address to the client with lifetimes
2611 if ((reply
->packet
->dhcpv6_msg_type
!= DHCPV6_RENEW
) &&
2612 (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
2613 log_error("It is impossible to lease a client that is "
2614 "not sending a solicit, request, renew, or "
2616 status
= ISC_R_FAILURE
;
2620 reply
->send_prefer
= reply
->send_valid
= 0;
2625 /* Verify the address belongs to the client. */
2626 if (!address_is_owned(reply
, &tmp_addr
)) {
2628 * For solicit and request, any addresses included are
2629 * 'requested' addresses. For rebind, we actually have
2630 * no direction on what to do from 3315 section 18.2.4!
2631 * So I think the best bet is to try and give it out, and if
2632 * we can't, zero lifetimes.
2634 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
2635 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
2636 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
2637 status
= reply_process_try_addr(reply
, &tmp_addr
);
2640 * If the address is in use, or isn't in any dynamic
2641 * range, continue as normal. If any other error was
2644 if ((status
!= ISC_R_SUCCESS
) &&
2645 (status
!= ISC_R_ADDRINUSE
) &&
2646 (status
!= ISC_R_ADDRNOTAVAIL
))
2650 * If we didn't honor this lease, for solicit and
2651 * request we simply omit it from our answer. For
2652 * rebind, we send it with zeroed lifetimes.
2654 if (reply
->lease
== NULL
) {
2655 if (reply
->packet
->dhcpv6_msg_type
==
2657 reply
->send_prefer
= 0;
2658 reply
->send_valid
= 0;
2662 /* status remains success - ignore */
2666 * RFC3315 section 18.2.3:
2668 * If the server cannot find a client entry for the IA the
2669 * server returns the IA containing no addresses with a Status
2670 * Code option set to NoBinding in the Reply message.
2672 * On mismatch we (ab)use this pretending we have not the IA
2673 * as soon as we have not an address.
2675 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
2676 /* Rewind the IA_NA to empty. */
2677 option_state_dereference(&reply
->reply_ia
, MDL
);
2678 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2679 log_error("reply_process_addr: No memory for "
2680 "option state wipe.");
2681 status
= ISC_R_NOMEMORY
;
2685 /* Append a NoBinding status code. */
2686 if (!set_status_code(STATUS_NoBinding
,
2687 "Address not bound to this "
2688 "interface.", reply
->reply_ia
)) {
2689 log_error("reply_process_addr: Unable to "
2690 "attach status code.");
2691 status
= ISC_R_FAILURE
;
2695 /* Fin (no more IAADDRs). */
2696 status
= ISC_R_CANCELED
;
2699 log_error("It is impossible to lease a client that is "
2700 "not sending a solicit, request, renew, or "
2702 status
= ISC_R_FAILURE
;
2707 if (reply
->static_lease
) {
2708 if (reply
->host
== NULL
)
2709 log_fatal("Impossible condition at %s:%d.", MDL
);
2711 scope
= &global_scope
;
2712 group
= reply
->subnet
->group
;
2714 if (reply
->lease
== NULL
)
2715 log_fatal("Impossible condition at %s:%d.", MDL
);
2717 scope
= &reply
->lease
->scope
;
2718 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
2722 * If client_resources is nonzero, then the reply_process_is_addressed
2723 * function has executed configuration state into the reply option
2724 * cache. We will use that valid cache to derive configuration for
2725 * whether or not to engage in additional addresses, and similar.
2727 if (reply
->client_resources
!= 0) {
2731 * Does this client have "enough" addresses already? Default
2732 * to one. Everybody gets one, and one should be enough for
2735 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2736 SV_LIMIT_ADDRS_PER_IA
);
2738 if (!evaluate_option_cache(&data
, reply
->packet
,
2740 reply
->packet
->options
,
2744 log_error("reply_process_addr: unable to "
2745 "evaluate addrs-per-ia value.");
2746 status
= ISC_R_FAILURE
;
2750 limit
= getULong(data
.data
);
2751 data_string_forget(&data
, MDL
);
2755 * If we wish to limit the client to a certain number of
2756 * addresses, then omit the address from the reply.
2758 if (reply
->client_resources
>= limit
)
2762 status
= reply_process_is_addressed(reply
, scope
, group
);
2763 if (status
!= ISC_R_SUCCESS
)
2767 status
= reply_process_send_addr(reply
, &tmp_addr
);
2770 if (iaaddr
.data
!= NULL
)
2771 data_string_forget(&iaaddr
, MDL
);
2772 if (data
.data
!= NULL
)
2773 data_string_forget(&data
, MDL
);
2774 if (reply
->lease
!= NULL
)
2775 iasubopt_dereference(&reply
->lease
, MDL
);
2781 * Verify the address belongs to the client. If we've got a host
2782 * record with a fixed address, it has to be the assigned address
2783 * (fault out all else). Otherwise it's a dynamic address, so lookup
2784 * that address and make sure it belongs to this DUID:IAID pair.
2786 static isc_boolean_t
2787 address_is_owned(struct reply_state
*reply
, struct iaddr
*addr
) {
2789 struct ipv6_pond
*pond
;
2792 * This faults out addresses that don't match fixed addresses.
2794 if (reply
->static_lease
) {
2795 if (reply
->fixed
.data
== NULL
)
2796 log_fatal("Impossible condition at %s:%d.", MDL
);
2798 if (memcmp(addr
->iabuf
, reply
->fixed
.data
, 16) == 0)
2804 if ((reply
->old_ia
== NULL
) || (reply
->old_ia
->num_iasubopt
== 0))
2807 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2808 struct iasubopt
*tmp
;
2810 tmp
= reply
->old_ia
->iasubopt
[i
];
2812 if (memcmp(addr
->iabuf
, &tmp
->addr
, 16) == 0) {
2813 if (lease6_usable(tmp
) == ISC_FALSE
) {
2817 pond
= tmp
->ipv6_pool
->ipv6_pond
;
2818 if (((pond
->prohibit_list
!= NULL
) &&
2819 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
2820 ((pond
->permit_list
!= NULL
) &&
2821 (!permitted(reply
->packet
, pond
->permit_list
))))
2824 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
2833 /* Process a client-supplied IA_TA. This may append options to the tail of
2834 * the reply packet being built in the reply_state structure.
2837 reply_process_ia_ta(struct reply_state
*reply
, struct option_cache
*ia
) {
2838 isc_result_t status
= ISC_R_SUCCESS
;
2841 struct option_state
*packet_ia
;
2842 struct option_cache
*oc
;
2843 struct data_string ia_data
, data
;
2844 struct data_string iaaddr
;
2845 u_int32_t pref_life
, valid_life
;
2846 struct iaddr tmp_addr
;
2848 /* Initialize values that will get cleaned up on return. */
2850 memset(&ia_data
, 0, sizeof(ia_data
));
2851 memset(&data
, 0, sizeof(data
));
2852 memset(&iaaddr
, 0, sizeof(iaaddr
));
2854 /* Make sure there is at least room for the header. */
2855 if ((reply
->cursor
+ IA_TA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2856 log_error("reply_process_ia_ta: Reply too long for IA.");
2857 return ISC_R_NOSPACE
;
2861 /* Fetch the IA_TA contents. */
2862 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2863 ia
, IA_TA_OFFSET
)) {
2864 log_error("reply_process_ia_ta: error evaluating ia");
2865 status
= ISC_R_FAILURE
;
2869 /* Extract IA_TA header contents. */
2870 iaid
= getULong(ia_data
.data
);
2872 /* Create an IA_TA structure. */
2873 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2874 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2875 log_error("reply_process_ia_ta: no memory for ia.");
2876 status
= ISC_R_NOMEMORY
;
2879 reply
->ia
->ia_type
= D6O_IA_TA
;
2881 /* Cache pre-existing IA, if any. */
2882 ia_hash_lookup(&reply
->old_ia
, ia_ta_active
,
2883 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2884 reply
->ia
->iaid_duid
.len
, MDL
);
2887 * Create an option cache to carry the IA_TA option contents, and
2888 * execute any user-supplied values into it.
2890 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2891 status
= ISC_R_NOMEMORY
;
2896 * Temporary leases are dynamic by definition.
2898 reply
->static_lease
= ISC_FALSE
;
2901 * Save the cursor position at the start of the IA, so we can
2902 * set length later. We write a temporary
2903 * header out now just in case we decide to adjust the packet
2904 * within sub-process functions.
2906 ia_cursor
= reply
->cursor
;
2908 /* Initialize the IA_TA header. First the code. */
2909 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_TA
);
2912 /* Then option length. */
2913 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x04u
);
2916 /* Then IA_TA header contents; IAID. */
2917 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2921 * Deal with an IAADDR for lifetimes.
2922 * For all or none, process IAADDRs as hints.
2924 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
2925 reply
->client_valid
= reply
->client_prefer
= 0;
2926 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2927 for (; oc
!= NULL
; oc
= oc
->next
) {
2928 memset(&iaaddr
, 0, sizeof(iaaddr
));
2929 if (!evaluate_option_cache(&iaaddr
, reply
->packet
,
2931 reply
->packet
->options
, NULL
,
2932 &global_scope
, oc
, MDL
) ||
2933 (iaaddr
.len
< IAADDR_OFFSET
)) {
2934 log_error("reply_process_ia_ta: error "
2935 "evaluating IAADDR.");
2936 status
= ISC_R_FAILURE
;
2939 /* The first 16 bytes are the IPv6 address. */
2940 pref_life
= getULong(iaaddr
.data
+ 16);
2941 valid_life
= getULong(iaaddr
.data
+ 20);
2943 if ((reply
->client_valid
== 0) ||
2944 (reply
->client_valid
> valid_life
))
2945 reply
->client_valid
= valid_life
;
2947 if ((reply
->client_prefer
== 0) ||
2948 (reply
->client_prefer
> pref_life
))
2949 reply
->client_prefer
= pref_life
;
2951 /* Nothing more if something has failed. */
2952 if (status
== ISC_R_CANCELED
)
2956 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2957 if (!temporary_is_available(reply
, &tmp_addr
))
2959 status
= reply_process_is_addressed(reply
,
2960 &reply
->lease
->scope
,
2961 reply
->lease
->ipv6_pool
->ipv6_pond
->group
);
2962 if (status
!= ISC_R_SUCCESS
)
2964 status
= reply_process_send_addr(reply
, &tmp_addr
);
2965 if (status
!= ISC_R_SUCCESS
)
2967 if (reply
->lease
!= NULL
)
2968 iasubopt_dereference(&reply
->lease
, MDL
);
2972 /* Rewind the IA_TA to empty. */
2973 option_state_dereference(&reply
->reply_ia
, MDL
);
2974 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2975 status
= ISC_R_NOMEMORY
;
2978 status
= ISC_R_CANCELED
;
2979 reply
->client_resources
= 0;
2980 reply
->resources_included
= ISC_FALSE
;
2981 if (reply
->lease
!= NULL
)
2982 iasubopt_dereference(&reply
->lease
, MDL
);
2987 * Give the client temporary addresses.
2989 if (reply
->client_resources
!= 0)
2991 status
= find_client_temporaries(reply
);
2992 if (status
== ISC_R_NORESOURCES
) {
2993 switch (reply
->packet
->dhcpv6_msg_type
) {
2994 case DHCPV6_SOLICIT
:
2996 * No address for any IA is handled
3001 case DHCPV6_REQUEST
:
3002 /* Section 18.2.1 (Request):
3004 * If the server cannot assign any addresses to
3005 * an IA in the message from the client, the
3006 * server MUST include the IA in the Reply
3007 * message with no addresses in the IA and a
3008 * Status Code option in the IA containing
3009 * status code NoAddrsAvail.
3011 option_state_dereference(&reply
->reply_ia
, MDL
);
3012 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
3013 log_error("reply_process_ia_ta: No "
3014 "memory for option state wipe.");
3015 status
= ISC_R_NOMEMORY
;
3019 if (!set_status_code(STATUS_NoAddrsAvail
,
3020 "No addresses available "
3021 "for this interface.",
3023 log_error("reply_process_ia_ta: Unable "
3024 "to set NoAddrsAvail status code.");
3025 status
= ISC_R_FAILURE
;
3029 status
= ISC_R_SUCCESS
;
3034 * We don't want to include the IA if we
3035 * provide zero addresses including zeroed
3038 if (reply
->resources_included
)
3039 status
= ISC_R_SUCCESS
;
3044 } else if (status
!= ISC_R_SUCCESS
)
3050 * yes, goto's aren't the best but we also want to avoid extra
3053 if (status
== ISC_R_CANCELED
) {
3054 /* We're replying with a status code so we still need to
3055 * write it out in wire-format to the outbound buffer */
3056 write_to_packet(reply
, ia_cursor
);
3061 * If we have any addresses log what we are doing.
3063 if (reply
->ia
->num_iasubopt
!= 0) {
3064 struct iasubopt
*tmp
;
3066 char tmp_addr
[INET6_ADDRSTRLEN
];
3068 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3069 tmp
= reply
->ia
->iasubopt
[i
];
3071 log_info("%s TA: address %s to client with duid %s "
3072 "iaid = %d valid for %u seconds",
3073 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
3074 inet_ntop(AF_INET6
, &tmp
->addr
,
3075 tmp_addr
, sizeof(tmp_addr
)),
3076 print_hex_1(reply
->client_id
.len
,
3077 reply
->client_id
.data
, 60),
3084 * For hard bindings we consume the new changes into
3085 * the database (if any have been attached to the ia_ta).
3087 * Loop through the assigned dynamic addresses, referencing the
3088 * leases onto this IA_TA rather than any old ones, and updating
3089 * pool timers for each (if any).
3091 if ((reply
->ia
->num_iasubopt
!= 0) &&
3092 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
3093 int must_commit
= 0;
3094 struct iasubopt
*tmp
;
3095 struct data_string
*ia_id
;
3098 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3099 tmp
= reply
->ia
->iasubopt
[i
];
3101 if (tmp
->ia
!= NULL
)
3102 ia_dereference(&tmp
->ia
, MDL
);
3103 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
3105 /* If we have anything to do on commit do it now */
3106 if (tmp
->on_star
.on_commit
!= NULL
) {
3107 execute_statements(NULL
, reply
->packet
,
3109 reply
->packet
->options
,
3112 tmp
->on_star
.on_commit
,
3114 executable_statement_dereference
3115 (&tmp
->on_star
.on_commit
, MDL
);
3118 #if defined (NSUPDATE)
3120 * Perform ddns updates.
3122 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3125 evaluate_boolean_option_cache(NULL
, reply
->packet
,
3127 reply
->packet
->options
,
3131 ddns_updates(reply
->packet
, NULL
, NULL
,
3132 tmp
, NULL
, reply
->opt_state
);
3136 if (!reuse_lease6(reply
, tmp
)) {
3137 /* Commit 'hard' bindings. */
3139 renew_lease6(tmp
->ipv6_pool
, tmp
);
3140 schedule_lease_timeout(tmp
->ipv6_pool
);
3142 /* Do our threshold check. */
3143 check_pool6_threshold(reply
, tmp
);
3147 /* write the IA_TA in wire-format to the outbound buffer */
3148 write_to_packet(reply
, ia_cursor
);
3150 /* Remove any old ia from the hash. */
3151 if (reply
->old_ia
!= NULL
) {
3152 if (!release_on_roam(reply
)) {
3153 ia_id
= &reply
->old_ia
->iaid_duid
;
3154 ia_hash_delete(ia_ta_active
,
3155 (unsigned char *)ia_id
->data
,
3159 ia_dereference(&reply
->old_ia
, MDL
);
3162 /* Put new ia into the hash. */
3163 reply
->ia
->cltt
= cur_time
;
3164 ia_id
= &reply
->ia
->iaid_duid
;
3165 ia_hash_add(ia_ta_active
, (unsigned char *)ia_id
->data
,
3166 ia_id
->len
, reply
->ia
, MDL
);
3168 /* If we couldn't reuse all of the iasubopts, we
3169 * must update udpate the lease db */
3171 write_ia(reply
->ia
);
3174 /* write the IA_TA in wire-format to the outbound buffer */
3175 write_to_packet(reply
, ia_cursor
);
3176 schedule_lease_timeout_reply(reply
);
3180 if (packet_ia
!= NULL
)
3181 option_state_dereference(&packet_ia
, MDL
);
3182 if (iaaddr
.data
!= NULL
)
3183 data_string_forget(&iaaddr
, MDL
);
3184 if (reply
->reply_ia
!= NULL
)
3185 option_state_dereference(&reply
->reply_ia
, MDL
);
3186 if (ia_data
.data
!= NULL
)
3187 data_string_forget(&ia_data
, MDL
);
3188 if (data
.data
!= NULL
)
3189 data_string_forget(&data
, MDL
);
3190 if (reply
->ia
!= NULL
)
3191 ia_dereference(&reply
->ia
, MDL
);
3192 if (reply
->old_ia
!= NULL
)
3193 ia_dereference(&reply
->old_ia
, MDL
);
3194 if (reply
->lease
!= NULL
)
3195 iasubopt_dereference(&reply
->lease
, MDL
);
3198 * ISC_R_CANCELED is a status code used by the addr processing to
3199 * indicate we're replying with other addresses. This is still a
3200 * success at higher layers.
3202 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
3205 * Determines if a lease (iasubopt) can be reused without extending it.
3206 * If dhcp-cache-threshold is greater than zero (i.e enabled) then
3207 * a lease may be reused without going through a full renewal if
3208 * it meets all the requirements. In short it must be active, younger
3209 * than the threshold, and not have DNS changes.
3211 * If it is determined that it can be reused, that a call to
3212 * shorten_lifetimes() is made to reduce the valid and preferred lifetimes
3213 * sent to the client by the age of the lease.
3215 * Returns 1 if lease can be reused, 0 otherwise
3218 reuse_lease6(struct reply_state
*reply
, struct iasubopt
*lease
) {
3219 int threshold
= DEFAULT_CACHE_THRESHOLD
;
3220 struct option_cache
* oc
= NULL
;
3221 struct data_string d1
;
3226 /* In order to even qualify for reuse consideration:
3227 * 1. Lease must be active
3228 * 2. It must have been accepted at least once
3229 * 3. DNS info must not have changed */
3230 if ((lease
->state
!= FTS_ACTIVE
) ||
3231 (lease
->hard_lifetime_end_time
== 0) ||
3232 (lease
->ddns_cb
!= NULL
)) {
3236 /* Look up threshold value */
3237 memset(&d1
, 0, sizeof(struct data_string
));
3238 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3239 SV_CACHE_THRESHOLD
);
3241 evaluate_option_cache(&d1
, reply
->packet
, NULL
, NULL
,
3242 reply
->packet
->options
, reply
->opt_state
,
3243 &lease
->scope
, oc
, MDL
)) {
3244 if (d1
.len
== 1 && (d1
.data
[0] < 100)) {
3245 threshold
= d1
.data
[0];
3248 data_string_forget(&d1
, MDL
);
3251 if (threshold
<= 0) {
3255 if (lease
->valid
>= MAX_TIME
) {
3256 /* Infinite leases are always reused. We have to make
3257 * a choice because we cannot determine when they actually
3258 * began, so we either always reuse them or we never do. */
3259 log_debug ("reusing infinite lease for: %s%s",
3260 pin6_addr(&lease
->addr
), iasubopt_plen_str(lease
));
3264 age
= cur_tv
.tv_sec
- (lease
->hard_lifetime_end_time
- lease
->valid
);
3265 if (lease
->valid
<= (INT_MAX
/ threshold
))
3266 limit
= lease
->valid
* threshold
/ 100;
3268 limit
= lease
->valid
/ 100 * threshold
;
3271 /* Reduce valid/preferred going to the client by age */
3272 shorten_lifetimes(reply
, lease
, age
, threshold
);
3280 * Reduces the valid and preferred lifetimes for a given lease (iasubopt)
3282 * We cannot determine until after a iasubopt has been added to
3283 * the reply if the lease can be reused. Therefore, when we do reuse a
3284 * lease we need a way to alter the lifetimes that will be sent to the client.
3285 * That's where this function comes in handy:
3287 * Locate the iasubopt by it's address within the reply the reduce both
3288 * the preferred and valid lifetimes by the given number of seconds.
3290 * Note that this function, by necessity, works directly with the
3291 * option_cache data. Sort of a no-no but I don't have any better ideas.
3293 void shorten_lifetimes(struct reply_state
*reply
, struct iasubopt
*lease
,
3294 time_t age
, int threshold
) {
3295 struct option_cache
* oc
= NULL
;
3302 if (reply
->ia
->ia_type
!= D6O_IA_PD
) {
3303 subopt_type
= D6O_IAADDR
;
3304 addr_offset
= IASUBOPT_NA_ADDR_OFFSET
;
3305 pref_offset
= IASUBOPT_NA_PREF_OFFSET
;
3306 val_offset
= IASUBOPT_NA_VALID_OFFSET
;
3307 exp_length
= IASUBOPT_NA_LEN
;
3310 subopt_type
= D6O_IAPREFIX
;
3311 addr_offset
= IASUBOPT_PD_PREFIX_OFFSET
;
3312 pref_offset
= IASUBOPT_PD_PREF_OFFSET
;
3313 val_offset
= IASUBOPT_PD_VALID_OFFSET
;
3314 exp_length
= IASUBOPT_PD_LEN
;
3317 // loop through the iasubopts for the one that matches this lease
3318 oc
= lookup_option(&dhcpv6_universe
, reply
->reply_ia
, subopt_type
);
3319 for (; oc
!= NULL
; oc
= oc
->next
) {
3320 if (oc
->data
.data
== NULL
|| oc
->data
.len
!= exp_length
) {
3321 /* shouldn't happen */
3325 /* If address matches (and for PDs the prefix len matches)
3326 * we assume this is our subopt, so update the lifetimes */
3327 if (!memcmp(oc
->data
.data
+ addr_offset
, &lease
->addr
, 16) &&
3328 (subopt_type
!= D6O_IAPREFIX
||
3329 (oc
->data
.data
[IASUBOPT_PD_PREFLEN_OFFSET
] ==
3331 u_int32_t pref_life
= getULong(oc
->data
.data
+
3333 u_int32_t valid_life
= getULong(oc
->data
.data
+
3336 if (pref_life
< MAX_TIME
&& pref_life
> age
) {
3338 putULong((unsigned char*)(oc
->data
.data
) +
3339 pref_offset
, pref_life
);
3341 if (reply
->min_prefer
> pref_life
) {
3342 reply
->min_prefer
= pref_life
;
3346 if (valid_life
< MAX_TIME
&& valid_life
> age
) {
3348 putULong((unsigned char*)(oc
->data
.data
) +
3349 val_offset
, valid_life
);
3351 if (reply
->min_valid
> reply
->send_valid
) {
3352 reply
->min_valid
= valid_life
;
3356 log_debug ("Reusing lease for: %s%s, "
3357 "age %ld secs < %d%%,"
3358 " sending shortened lifetimes -"
3359 " preferred: %u, valid %u",
3360 pin6_addr(&lease
->addr
),
3361 iasubopt_plen_str(lease
),
3362 (long)age
, threshold
,
3363 pref_life
, valid_life
);
3370 * Verify the temporary address is available.
3372 static isc_boolean_t
3373 temporary_is_available(struct reply_state
*reply
, struct iaddr
*addr
) {
3374 struct in6_addr tmp_addr
;
3375 struct subnet
*subnet
;
3376 struct ipv6_pool
*pool
= NULL
;
3377 struct ipv6_pond
*pond
= NULL
;
3380 memcpy(&tmp_addr
, addr
->iabuf
, sizeof(tmp_addr
));
3382 * Clients may choose to send :: as an address, with the idea to give
3383 * hints about preferred-lifetime or valid-lifetime.
3384 * So this is not a request for this address.
3386 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
))
3390 * Verify that this address is on the client's network.
3392 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
3393 subnet
= subnet
->next_sibling
) {
3394 if (addr_eq(subnet_number(*addr
, subnet
->netmask
),
3399 /* Address not found on shared network. */
3404 * Check if this address is owned (must be before next step).
3406 if (address_is_owned(reply
, addr
))
3410 * Verify that this address is in a temporary pool and try to get it.
3412 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3413 if (((pond
->prohibit_list
!= NULL
) &&
3414 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3415 ((pond
->permit_list
!= NULL
) &&
3416 (!permitted(reply
->packet
, pond
->permit_list
))))
3419 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3420 if (pool
->pool_type
!= D6O_IA_TA
)
3423 if (ipv6_in_pool(&tmp_addr
, pool
))
3433 if (lease6_exists(pool
, &tmp_addr
))
3435 if (iasubopt_allocate(&reply
->lease
, MDL
) != ISC_R_SUCCESS
)
3437 reply
->lease
->addr
= tmp_addr
;
3438 reply
->lease
->plen
= 0;
3439 /* Default is soft binding for 2 minutes. */
3440 if (add_lease6(pool
, reply
->lease
, cur_time
+ 120) != ISC_R_SUCCESS
)
3447 * Get a temporary address per prefix.
3450 find_client_temporaries(struct reply_state
*reply
) {
3452 struct ipv6_pool
*p
= NULL
;
3453 struct ipv6_pond
*pond
;
3454 isc_result_t status
= ISC_R_NORESOURCES
;;
3455 unsigned int attempts
;
3456 struct iaddr send_addr
;
3459 * Do a quick walk through of the ponds and pools
3460 * to see if we have any prefix pools
3462 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3463 if (pond
->ipv6_pools
== NULL
)
3466 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3467 if (p
->pool_type
== D6O_IA_TA
)
3474 /* If we get here and p is NULL we have no useful pools */
3476 log_debug("Unable to get client addresses: "
3477 "no IPv6 pools on this shared network");
3478 return ISC_R_NORESOURCES
;
3482 * We have at least one pool that could provide an address
3483 * Now we walk through the ponds and pools again and check
3484 * to see if the client is permitted and if an address is
3488 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3489 if (((pond
->prohibit_list
!= NULL
) &&
3490 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3491 ((pond
->permit_list
!= NULL
) &&
3492 (!permitted(reply
->packet
, pond
->permit_list
))))
3495 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3496 if (p
->pool_type
!= D6O_IA_TA
) {
3501 * Get an address in this temporary pool.
3503 status
= create_lease6(p
, &reply
->lease
, &attempts
,
3507 if (status
!= ISC_R_SUCCESS
) {
3508 log_debug("Unable to get a temporary address.");
3512 status
= reply_process_is_addressed(reply
,
3513 &reply
->lease
->scope
,
3515 if (status
!= ISC_R_SUCCESS
) {
3519 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3520 status
= reply_process_send_addr(reply
, &send_addr
);
3521 if (status
!= ISC_R_SUCCESS
) {
3525 * reply->lease can't be null as we use it above
3526 * add check if that changes
3528 iasubopt_dereference(&reply
->lease
, MDL
);
3533 if (reply
->lease
!= NULL
) {
3534 iasubopt_dereference(&reply
->lease
, MDL
);
3540 * This function only returns failure on 'hard' failures. If it succeeds,
3541 * it will leave a lease structure behind.
3544 reply_process_try_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3545 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
3546 struct ipv6_pool
*pool
= NULL
;
3547 struct ipv6_pond
*pond
= NULL
;
3549 struct data_string data_addr
;
3551 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
3552 (addr
== NULL
) || (reply
->lease
!= NULL
))
3553 return (DHCP_R_INVALIDARG
);
3556 * Do a quick walk through of the ponds and pools
3557 * to see if we have any NA address pools
3559 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3560 if (pond
->ipv6_pools
== NULL
)
3563 for (i
= 0; ; i
++) {
3564 pool
= pond
->ipv6_pools
[i
];
3565 if ((pool
== NULL
) ||
3566 (pool
->pool_type
== D6O_IA_NA
))
3573 /* If we get here and p is NULL we have no useful pools */
3575 return (ISC_R_ADDRNOTAVAIL
);
3578 memset(&data_addr
, 0, sizeof(data_addr
));
3579 data_addr
.len
= addr
->len
;
3580 data_addr
.data
= addr
->iabuf
;
3583 * We have at least one pool that could provide an address
3584 * Now we walk through the ponds and pools again and check
3585 * to see if the client is permitted and if an address is
3588 * Within a given pond we start looking at the last pool we
3589 * allocated from, unless it had a collision trying to allocate
3590 * an address. This will tend to move us into less-filled pools.
3593 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3594 if (((pond
->prohibit_list
!= NULL
) &&
3595 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3596 ((pond
->permit_list
!= NULL
) &&
3597 (!permitted(reply
->packet
, pond
->permit_list
))))
3600 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3601 if (pool
->pool_type
!= D6O_IA_NA
)
3604 status
= try_client_v6_address(&reply
->lease
, pool
,
3606 if (status
== ISC_R_SUCCESS
)
3610 if (status
== ISC_R_SUCCESS
)
3614 /* Note that this is just pedantry. There is no allocation to free. */
3615 data_string_forget(&data_addr
, MDL
);
3616 /* Return just the most recent status... */
3620 /* Look around for an address to give the client. First, look through the
3621 * old IA for addresses we can extend. Second, try to allocate a new address.
3622 * Finally, actually add that address into the current reply IA.
3625 find_client_address(struct reply_state
*reply
) {
3626 struct iaddr send_addr
;
3627 isc_result_t status
= ISC_R_NORESOURCES
;
3628 struct iasubopt
*lease
, *best_lease
= NULL
;
3629 struct binding_scope
**scope
;
3630 struct group
*group
;
3633 if (reply
->static_lease
) {
3634 if (reply
->host
== NULL
)
3635 return DHCP_R_INVALIDARG
;
3638 memcpy(send_addr
.iabuf
, reply
->fixed
.data
, 16);
3640 scope
= &global_scope
;
3641 group
= reply
->subnet
->group
;
3645 if (reply
->old_ia
!= NULL
) {
3646 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3647 struct shared_network
*candidate_shared
;
3648 struct ipv6_pond
*pond
;
3650 lease
= reply
->old_ia
->iasubopt
[i
];
3651 candidate_shared
= lease
->ipv6_pool
->shared_network
;
3652 pond
= lease
->ipv6_pool
->ipv6_pond
;
3655 * Look for the best lease on the client's shared
3656 * network, that is still permitted
3659 if ((candidate_shared
!= reply
->shared
) ||
3660 (lease6_usable(lease
) != ISC_TRUE
))
3663 if (((pond
->prohibit_list
!= NULL
) &&
3664 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3665 ((pond
->permit_list
!= NULL
) &&
3666 (!permitted(reply
->packet
, pond
->permit_list
))))
3669 best_lease
= lease_compare(lease
, best_lease
);
3673 /* Try to pick a new address if we didn't find one, or if we found an
3676 if ((best_lease
== NULL
) || (best_lease
->state
== FTS_ABANDONED
)) {
3677 status
= pick_v6_address(reply
);
3678 } else if (best_lease
!= NULL
) {
3679 iasubopt_reference(&reply
->lease
, best_lease
, MDL
);
3680 status
= ISC_R_SUCCESS
;
3683 /* Pick the abandoned lease as a last resort. */
3684 if ((status
== ISC_R_NORESOURCES
) && (best_lease
!= NULL
)) {
3685 /* I don't see how this is supposed to be done right now. */
3686 log_error("Best match for DUID %s is an abandoned address,"
3687 " This may be a result of multiple clients attempting"
3688 " to use this DUID",
3689 print_hex_1(reply
->client_id
.len
,
3690 reply
->client_id
.data
, 60));
3691 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
3694 /* Give up now if we didn't find a lease. */
3695 if (status
!= ISC_R_SUCCESS
)
3698 if (reply
->lease
== NULL
)
3699 log_fatal("Impossible condition at %s:%d.", MDL
);
3701 /* Draw binding scopes from the lease's binding scope, and config
3702 * from the lease's containing subnet and higher. Note that it may
3703 * be desirable to place the group attachment directly in the pool.
3705 scope
= &reply
->lease
->scope
;
3706 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
3709 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3712 status
= reply_process_is_addressed(reply
, scope
, group
);
3713 if (status
!= ISC_R_SUCCESS
)
3716 status
= reply_process_send_addr(reply
, &send_addr
);
3720 /* Once an address is found for a client, perform several common functions;
3721 * Calculate and store valid and preferred lease times, draw client options
3722 * into the option state.
3725 reply_process_is_addressed(struct reply_state
*reply
,
3726 struct binding_scope
**scope
, struct group
*group
)
3728 isc_result_t status
= ISC_R_SUCCESS
;
3729 struct data_string data
;
3730 struct option_cache
*oc
;
3731 struct option_state
*tmp_options
= NULL
;
3732 struct on_star
*on_star
;
3735 /* Initialize values we will cleanup. */
3736 memset(&data
, 0, sizeof(data
));
3739 * Find the proper on_star block to use. We use the
3740 * one in the lease if we have a lease or the one in
3741 * the reply if we don't have a lease because this is
3745 on_star
= &reply
->lease
->on_star
;
3747 on_star
= &reply
->on_star
;
3751 * Bring in the root configuration. We only do this to bring
3752 * in the on * statements, as we didn't have the lease available
3753 * we did it the first time.
3755 option_state_allocate(&tmp_options
, MDL
);
3756 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3757 reply
->packet
->options
, tmp_options
,
3758 &global_scope
, root_group
, NULL
,
3760 if (tmp_options
!= NULL
) {
3761 option_state_dereference(&tmp_options
, MDL
);
3765 * Bring configured options into the root packet level cache - start
3766 * with the lease's closest enclosing group (passed in by the caller
3769 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3770 reply
->packet
->options
, reply
->opt_state
,
3771 scope
, group
, root_group
, on_star
);
3773 /* Execute statements from class scopes. */
3774 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3775 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3776 reply
->packet
->options
,
3777 reply
->opt_state
, scope
,
3778 reply
->packet
->classes
[i
- 1]->group
,
3783 * If there is a host record, over-ride with values configured there,
3784 * without re-evaluating configuration from the previously executed
3785 * group or its common enclosers.
3787 if (reply
->host
!= NULL
)
3788 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3789 reply
->packet
->options
,
3790 reply
->opt_state
, scope
,
3791 reply
->host
->group
, group
,
3794 /* Determine valid lifetime. */
3795 if (reply
->client_valid
== 0)
3796 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
3798 reply
->send_valid
= reply
->client_valid
;
3800 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3801 SV_DEFAULT_LEASE_TIME
);
3803 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3804 reply
->packet
->options
,
3808 log_error("reply_process_is_addressed: unable to "
3809 "evaluate default lease time");
3810 status
= ISC_R_FAILURE
;
3814 reply
->send_valid
= getULong(data
.data
);
3815 data_string_forget(&data
, MDL
);
3818 /* Check to see if the lease time would cause us to wrap
3819 * in which case we make it infinite.
3820 * The following doesn't work on at least some systems:
3821 * (cur_time + reply->send_valid < cur_time)
3823 if (reply
->send_valid
!= INFINITE_TIME
) {
3824 time_t test_time
= cur_time
+ reply
->send_valid
;
3825 if (test_time
< cur_time
)
3826 reply
->send_valid
= INFINITE_TIME
;
3829 if (reply
->client_prefer
== 0)
3830 reply
->send_prefer
= reply
->send_valid
;
3832 reply
->send_prefer
= reply
->client_prefer
;
3834 if ((reply
->send_prefer
>= reply
->send_valid
) &&
3835 (reply
->send_valid
!= INFINITE_TIME
))
3836 reply
->send_prefer
= (reply
->send_valid
/ 2) +
3837 (reply
->send_valid
/ 8);
3839 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3840 SV_PREFER_LIFETIME
);
3842 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3843 reply
->packet
->options
,
3847 log_error("reply_process_is_addressed: unable to "
3848 "evaluate preferred lease time");
3849 status
= ISC_R_FAILURE
;
3853 reply
->send_prefer
= getULong(data
.data
);
3854 data_string_forget(&data
, MDL
);
3857 /* Note lowest values for later calculation of renew/rebind times. */
3858 if (reply
->min_prefer
> reply
->send_prefer
)
3859 reply
->min_prefer
= reply
->send_prefer
;
3861 if (reply
->min_valid
> reply
->send_valid
)
3862 reply
->min_valid
= reply
->send_valid
;
3866 * XXX: Old 4.0.0 alpha code would change the host {} record
3867 * XXX: uid upon lease assignment. This was intended to cover the
3868 * XXX: case where a client first identifies itself using vendor
3869 * XXX: options in a solicit, or request, but later neglects to include
3870 * XXX: these options in a Renew or Rebind. It is not clear that this
3871 * XXX: is required, and has some startling ramifications (such as
3872 * XXX: how to recover this dynamic host {} state across restarts).
3874 if (reply
->host
!= NULL
)
3875 change_host_uid(host
, reply
->client_id
->data
,
3876 reply
->client_id
->len
);
3879 /* Perform dynamic lease related update work. */
3880 if (reply
->lease
!= NULL
) {
3881 /* Cached lifetimes */
3882 reply
->lease
->prefer
= reply
->send_prefer
;
3883 reply
->lease
->valid
= reply
->send_valid
;
3885 /* Advance (or rewind) the valid lifetime.
3886 * In the protocol 0xFFFFFFFF is infinite
3887 * when connecting to the lease file MAX_TIME is
3889 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
3890 if (reply
->send_valid
== INFINITE_TIME
) {
3891 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
3893 reply
->lease
->soft_lifetime_end_time
=
3894 cur_time
+ reply
->send_valid
;
3896 /* Wait before renew! */
3899 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
3900 if (status
!= ISC_R_SUCCESS
) {
3901 log_fatal("reply_process_is_addressed: Unable to "
3902 "attach lease to new IA: %s",
3903 isc_result_totext(status
));
3907 * If this is a new lease, make sure it is attached somewhere.
3909 if (reply
->lease
->ia
== NULL
) {
3910 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
3914 /* Bring a copy of the relevant options into the IA scope. */
3915 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3916 reply
->packet
->options
, reply
->reply_ia
,
3917 scope
, group
, root_group
, NULL
);
3919 /* Execute statements from class scopes. */
3920 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3921 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3922 reply
->packet
->options
,
3923 reply
->reply_ia
, scope
,
3924 reply
->packet
->classes
[i
- 1]->group
,
3929 * And bring in host record configuration, if any, but not to overlap
3930 * the previous group or its common enclosers.
3932 if (reply
->host
!= NULL
)
3933 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3934 reply
->packet
->options
,
3935 reply
->reply_ia
, scope
,
3936 reply
->host
->group
, group
, NULL
);
3939 if (data
.data
!= NULL
)
3940 data_string_forget(&data
, MDL
);
3942 if (status
== ISC_R_SUCCESS
)
3943 reply
->client_resources
++;
3948 /* Simply send an IAADDR within the IA scope as described. */
3950 reply_process_send_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3951 isc_result_t status
= ISC_R_SUCCESS
;
3952 struct data_string data
;
3954 memset(&data
, 0, sizeof(data
));
3956 /* Now append the lease. */
3957 data
.len
= IAADDR_OFFSET
;
3958 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
3959 log_error("reply_process_send_addr: out of memory"
3960 "allocating new IAADDR buffer.");
3961 status
= ISC_R_NOMEMORY
;
3964 data
.data
= data
.buffer
->data
;
3966 memcpy(data
.buffer
->data
, addr
->iabuf
, 16);
3967 putULong(data
.buffer
->data
+ 16, reply
->send_prefer
);
3968 putULong(data
.buffer
->data
+ 20, reply
->send_valid
);
3970 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
3971 data
.buffer
, data
.buffer
->data
,
3972 data
.len
, D6O_IAADDR
, 0)) {
3973 log_error("reply_process_send_addr: unable "
3974 "to save IAADDR option");
3975 status
= ISC_R_FAILURE
;
3979 reply
->resources_included
= ISC_TRUE
;
3982 if (data
.data
!= NULL
)
3983 data_string_forget(&data
, MDL
);
3988 /* Choose the better of two leases. */
3989 static struct iasubopt
*
3990 lease_compare(struct iasubopt
*alpha
, struct iasubopt
*beta
) {
3996 switch(alpha
->state
) {
3998 switch(beta
->state
) {
4000 /* Choose the lease with the longest lifetime (most
4001 * likely the most recently allocated).
4003 if (alpha
->hard_lifetime_end_time
<
4004 beta
->hard_lifetime_end_time
)
4014 log_fatal("Impossible condition at %s:%d.", MDL
);
4019 switch (beta
->state
) {
4024 /* Choose the most recently expired lease. */
4025 if (alpha
->hard_lifetime_end_time
<
4026 beta
->hard_lifetime_end_time
)
4028 else if ((alpha
->hard_lifetime_end_time
==
4029 beta
->hard_lifetime_end_time
) &&
4030 (alpha
->soft_lifetime_end_time
<
4031 beta
->soft_lifetime_end_time
))
4040 log_fatal("Impossible condition at %s:%d.", MDL
);
4045 switch (beta
->state
) {
4051 /* Choose the lease that was abandoned longest ago. */
4052 if (alpha
->hard_lifetime_end_time
<
4053 beta
->hard_lifetime_end_time
)
4059 log_fatal("Impossible condition at %s:%d.", MDL
);
4064 log_fatal("Impossible condition at %s:%d.", MDL
);
4067 log_fatal("Triple impossible condition at %s:%d.", MDL
);
4071 /* Process a client-supplied IA_PD. This may append options to the tail of
4072 * the reply packet being built in the reply_state structure.
4075 reply_process_ia_pd(struct reply_state
*reply
, struct option_cache
*ia
) {
4076 isc_result_t status
= ISC_R_SUCCESS
;
4079 struct option_state
*packet_ia
;
4080 struct option_cache
*oc
;
4081 struct data_string ia_data
, data
;
4083 /* Initialize values that will get cleaned up on return. */
4085 memset(&ia_data
, 0, sizeof(ia_data
));
4086 memset(&data
, 0, sizeof(data
));
4088 * Note that find_client_prefix() may set reply->lease.
4091 /* Make sure there is at least room for the header. */
4092 if ((reply
->cursor
+ IA_PD_OFFSET
+ 4) > sizeof(reply
->buf
)) {
4093 log_error("reply_process_ia_pd: Reply too long for IA.");
4094 return ISC_R_NOSPACE
;
4098 /* Fetch the IA_PD contents. */
4099 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
4100 ia
, IA_PD_OFFSET
)) {
4101 log_error("reply_process_ia_pd: error evaluating ia");
4102 status
= ISC_R_FAILURE
;
4106 /* Extract IA_PD header contents. */
4107 iaid
= getULong(ia_data
.data
);
4108 reply
->renew
= getULong(ia_data
.data
+ 4);
4109 reply
->rebind
= getULong(ia_data
.data
+ 8);
4111 /* Create an IA_PD structure. */
4112 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
4113 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
4114 log_error("reply_process_ia_pd: no memory for ia.");
4115 status
= ISC_R_NOMEMORY
;
4118 reply
->ia
->ia_type
= D6O_IA_PD
;
4120 /* Cache pre-existing IA_PD, if any. */
4121 ia_hash_lookup(&reply
->old_ia
, ia_pd_active
,
4122 (unsigned char *)reply
->ia
->iaid_duid
.data
,
4123 reply
->ia
->iaid_duid
.len
, MDL
);
4126 * Create an option cache to carry the IA_PD option contents, and
4127 * execute any user-supplied values into it.
4129 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
4130 status
= ISC_R_NOMEMORY
;
4134 /* Check & count the fixed prefix host records. */
4135 reply
->static_prefixes
= 0;
4136 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_prefix
!= NULL
)) {
4137 struct iaddrcidrnetlist
*fp
;
4139 for (fp
= reply
->host
->fixed_prefix
; fp
!= NULL
;
4141 reply
->static_prefixes
+= 1;
4146 * Save the cursor position at the start of the IA_PD, so we can
4147 * set length and adjust t1/t2 values later. We write a temporary
4148 * header out now just in case we decide to adjust the packet
4149 * within sub-process functions.
4151 ia_cursor
= reply
->cursor
;
4153 /* Initialize the IA_PD header. First the code. */
4154 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_PD
);
4157 /* Then option length. */
4158 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
4161 /* Then IA_PD header contents; IAID. */
4162 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
4165 /* We store the client's t1 for now, and may over-ride it later. */
4166 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
4169 /* We store the client's t2 for now, and may over-ride it later. */
4170 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
4174 * For each prefix in this IA_PD, decide what to do about it.
4176 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAPREFIX
);
4177 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
4178 reply
->client_valid
= reply
->client_prefer
= 0;
4179 reply
->preflen
= -1;
4180 for (; oc
!= NULL
; oc
= oc
->next
) {
4181 status
= reply_process_prefix(reply
, oc
);
4184 * Canceled means we did not allocate prefixes to the
4185 * client, but we're "done" with this IA - we set a status
4186 * code. So transmit this reply, e.g., move on to the next
4189 if (status
== ISC_R_CANCELED
)
4192 if ((status
!= ISC_R_SUCCESS
) &&
4193 (status
!= ISC_R_ADDRINUSE
) &&
4194 (status
!= ISC_R_ADDRNOTAVAIL
))
4201 * If we fell through the above and never gave the client
4202 * a prefix, give it one now.
4204 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
4205 status
= find_client_prefix(reply
);
4207 if (status
== ISC_R_NORESOURCES
) {
4208 switch (reply
->packet
->dhcpv6_msg_type
) {
4209 case DHCPV6_SOLICIT
:
4211 * No prefix for any IA is handled
4216 case DHCPV6_REQUEST
:
4217 /* Same than for addresses. */
4218 option_state_dereference(&reply
->reply_ia
, MDL
);
4219 if (!option_state_allocate(&reply
->reply_ia
,
4222 log_error("reply_process_ia_pd: No "
4223 "memory for option state "
4225 status
= ISC_R_NOMEMORY
;
4229 if (!set_status_code(STATUS_NoPrefixAvail
,
4230 "No prefixes available "
4231 "for this interface.",
4233 log_error("reply_process_ia_pd: "
4235 "NoPrefixAvail status "
4237 status
= ISC_R_FAILURE
;
4241 status
= ISC_R_SUCCESS
;
4245 if (reply
->resources_included
)
4246 status
= ISC_R_SUCCESS
;
4253 if (status
!= ISC_R_SUCCESS
)
4258 * yes, goto's aren't the best but we also want to avoid extra
4261 if (status
== ISC_R_CANCELED
) {
4262 /* We're replying with a status code so we still need to
4263 * write it out in wire-format to the outbound buffer */
4264 write_to_packet(reply
, ia_cursor
);
4269 * Handle static prefixes, we always log stuff and if it's
4270 * a hard binding we run any commit statements that we have
4272 if (reply
->static_prefixes
!= 0) {
4273 char tmp_addr
[INET6_ADDRSTRLEN
];
4274 log_info("%s PD: address %s/%d to client with duid %s "
4276 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
4277 inet_ntop(AF_INET6
, reply
->fixed_pref
.lo_addr
.iabuf
,
4278 tmp_addr
, sizeof(tmp_addr
)),
4279 reply
->fixed_pref
.bits
,
4280 print_hex_1(reply
->client_id
.len
,
4281 reply
->client_id
.data
, 60),
4284 /* Write the lease out in wire-format to the outbound buffer */
4285 write_to_packet(reply
, ia_cursor
);
4287 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
4288 (reply
->on_star
.on_commit
!= NULL
)) {
4289 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
4290 reply
->packet
->options
,
4292 NULL
, reply
->on_star
.on_commit
,
4294 executable_statement_dereference
4295 (&reply
->on_star
.on_commit
, MDL
);
4301 * If we have any addresses log what we are doing.
4303 if (reply
->ia
->num_iasubopt
!= 0) {
4304 struct iasubopt
*tmp
;
4306 char tmp_addr
[INET6_ADDRSTRLEN
];
4308 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
4309 tmp
= reply
->ia
->iasubopt
[i
];
4311 log_info("%s PD: address %s/%d to client with duid %s"
4312 " iaid = %d valid for %u seconds",
4313 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
4314 inet_ntop(AF_INET6
, &tmp
->addr
,
4315 tmp_addr
, sizeof(tmp_addr
)),
4317 print_hex_1(reply
->client_id
.len
,
4318 reply
->client_id
.data
, 60),
4324 * If this is not a 'soft' binding, consume the new changes into
4325 * the database (if any have been attached to the ia_pd).
4327 * Loop through the assigned dynamic prefixes, referencing the
4328 * prefixes onto this IA_PD rather than any old ones, and updating
4329 * prefix pool timers for each (if any).
4331 * If a lease can be reused we skip renewing it or checking the
4332 * pool threshold. If it can't we flag that the IA must be commited
4333 * to the db and do the renewal and pool check.
4335 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
4336 (reply
->ia
->num_iasubopt
!= 0)) {
4337 int must_commit
= 0;
4338 struct iasubopt
*tmp
;
4339 struct data_string
*ia_id
;
4342 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
4343 tmp
= reply
->ia
->iasubopt
[i
];
4345 if (tmp
->ia
!= NULL
)
4346 ia_dereference(&tmp
->ia
, MDL
);
4347 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
4349 /* If we have anything to do on commit do it now */
4350 if (tmp
->on_star
.on_commit
!= NULL
) {
4351 execute_statements(NULL
, reply
->packet
,
4353 reply
->packet
->options
,
4356 tmp
->on_star
.on_commit
,
4358 executable_statement_dereference
4359 (&tmp
->on_star
.on_commit
, MDL
);
4362 if (!reuse_lease6(reply
, tmp
)) {
4363 /* Commit 'hard' bindings. */
4365 renew_lease6(tmp
->ipv6_pool
, tmp
);
4366 schedule_lease_timeout(tmp
->ipv6_pool
);
4368 /* Do our threshold check. */
4369 check_pool6_threshold(reply
, tmp
);
4373 /* write the IA_PD in wire-format to the outbound buffer */
4374 write_to_packet(reply
, ia_cursor
);
4376 /* Remove any old ia from the hash. */
4377 if (reply
->old_ia
!= NULL
) {
4378 if (!release_on_roam(reply
)) {
4379 ia_id
= &reply
->old_ia
->iaid_duid
;
4380 ia_hash_delete(ia_pd_active
,
4381 (unsigned char *)ia_id
->data
,
4385 ia_dereference(&reply
->old_ia
, MDL
);
4388 /* Put new ia into the hash. */
4389 reply
->ia
->cltt
= cur_time
;
4390 ia_id
= &reply
->ia
->iaid_duid
;
4391 ia_hash_add(ia_pd_active
, (unsigned char *)ia_id
->data
,
4392 ia_id
->len
, reply
->ia
, MDL
);
4394 /* If we couldn't reuse all of the iasubopts, we
4395 * must udpate the lease db */
4397 write_ia(reply
->ia
);
4400 /* write the IA_PD in wire-format to the outbound buffer */
4401 write_to_packet(reply
, ia_cursor
);
4402 schedule_lease_timeout_reply(reply
);
4406 if (packet_ia
!= NULL
)
4407 option_state_dereference(&packet_ia
, MDL
);
4408 if (reply
->reply_ia
!= NULL
)
4409 option_state_dereference(&reply
->reply_ia
, MDL
);
4410 if (ia_data
.data
!= NULL
)
4411 data_string_forget(&ia_data
, MDL
);
4412 if (data
.data
!= NULL
)
4413 data_string_forget(&data
, MDL
);
4414 if (reply
->ia
!= NULL
)
4415 ia_dereference(&reply
->ia
, MDL
);
4416 if (reply
->old_ia
!= NULL
)
4417 ia_dereference(&reply
->old_ia
, MDL
);
4418 if (reply
->lease
!= NULL
)
4419 iasubopt_dereference(&reply
->lease
, MDL
);
4420 if (reply
->on_star
.on_expiry
!= NULL
)
4421 executable_statement_dereference
4422 (&reply
->on_star
.on_expiry
, MDL
);
4423 if (reply
->on_star
.on_release
!= NULL
)
4424 executable_statement_dereference
4425 (&reply
->on_star
.on_release
, MDL
);
4428 * ISC_R_CANCELED is a status code used by the prefix processing to
4429 * indicate we're replying with a status code. This is still a
4430 * success at higher layers.
4432 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
4437 * \brief Find the proper scoping group for use with a v6 static prefix.
4439 * We start by trying to find a subnet based on the given prefix and
4440 * the shared network. If we don't find one then the prefix has been
4441 * declared outside of any subnets. If there is a static address
4442 * associated with the host we use it to try and find a subnet (this
4443 * should succeed). If there isn't a static address we fall back
4444 * to the shared subnet itself.
4445 * Once we have a subnet we extract the group from it and return it.
4447 * \param reply - the reply structure we use to collect information
4448 * we will use the fields shared, fixed_pref and host
4449 * from the structure
4451 * \return a pointer to the group structure to use for scoping
4454 static struct group
*
4455 find_group_by_prefix(struct reply_state
*reply
) {
4456 /* default group if we don't find anything better */
4457 struct group
*group
= reply
->shared
->group
;
4458 struct subnet
*subnet
= NULL
;
4459 struct iaddr tmp_addr
;
4460 struct data_string fixed_addr
;
4462 /* Try with the prefix first */
4463 if (find_grouped_subnet(&subnet
, reply
->shared
,
4464 reply
->fixed_pref
.lo_addr
, MDL
) != 0) {
4465 group
= subnet
->group
;
4466 subnet_dereference(&subnet
, MDL
);
4470 /* Didn't find a subnet via prefix, what about fixed address */
4471 /* The caller has already tested reply->host != NULL */
4473 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
4475 if ((reply
->host
->fixed_addr
!= NULL
) &&
4476 (evaluate_option_cache(&fixed_addr
, NULL
, NULL
, NULL
,
4477 NULL
, NULL
, &global_scope
,
4478 reply
->host
->fixed_addr
, MDL
))) {
4479 if (fixed_addr
.len
>= 16) {
4481 memcpy(tmp_addr
.iabuf
, fixed_addr
.data
, 16);
4482 if (find_grouped_subnet(&subnet
, reply
->shared
,
4483 tmp_addr
, MDL
) != 0) {
4484 group
= subnet
->group
;
4485 subnet_dereference(&subnet
, MDL
);
4488 data_string_forget(&fixed_addr
, MDL
);
4491 /* return whatever we got */
4496 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
4497 * contents into the reply's current ia_pd-scoped option cache. Returns
4498 * ISC_R_CANCELED in the event we are replying with a status code and do
4499 * not wish to process more IAPREFIXes within this IA_PD.
4502 reply_process_prefix(struct reply_state
*reply
, struct option_cache
*pref
) {
4503 u_int32_t pref_life
, valid_life
;
4504 struct binding_scope
**scope
;
4505 struct iaddrcidrnet tmp_pref
;
4506 struct option_cache
*oc
;
4507 struct data_string iapref
, data
;
4508 isc_result_t status
= ISC_R_SUCCESS
;
4509 struct group
*group
;
4511 /* Initializes values that will be cleaned up. */
4512 memset(&iapref
, 0, sizeof(iapref
));
4513 memset(&data
, 0, sizeof(data
));
4514 /* Note that reply->lease may be set by prefix_is_owned() */
4517 * There is no point trying to process an incoming prefix if there
4518 * is no room for an outgoing prefix.
4520 if ((reply
->cursor
+ 29) > sizeof(reply
->buf
)) {
4521 log_error("reply_process_prefix: Out of room for prefix.");
4522 return ISC_R_NOSPACE
;
4525 /* Extract this IAPREFIX option. */
4526 if (!evaluate_option_cache(&iapref
, reply
->packet
, NULL
, NULL
,
4527 reply
->packet
->options
, NULL
, &global_scope
,
4529 (iapref
.len
< IAPREFIX_OFFSET
)) {
4530 log_error("reply_process_prefix: error evaluating IAPREFIX.");
4531 status
= ISC_R_FAILURE
;
4536 * Layout: preferred and valid lifetimes followed by the prefix
4537 * length and the IPv6 address.
4539 pref_life
= getULong(iapref
.data
);
4540 valid_life
= getULong(iapref
.data
+ 4);
4542 if ((reply
->client_valid
== 0) ||
4543 (reply
->client_valid
> valid_life
))
4544 reply
->client_valid
= valid_life
;
4546 if ((reply
->client_prefer
== 0) ||
4547 (reply
->client_prefer
> pref_life
))
4548 reply
->client_prefer
= pref_life
;
4551 * Clients may choose to send ::/0 as a prefix, with the idea to give
4552 * hints about preferred-lifetime or valid-lifetime.
4554 tmp_pref
.lo_addr
.len
= 16;
4555 memset(tmp_pref
.lo_addr
.iabuf
, 0, 16);
4556 if ((iapref
.data
[8] == 0) &&
4557 (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0)) {
4558 /* Status remains success; we just ignore this one. */
4563 * Clients may choose to send ::/X as a prefix to specify a
4564 * preferred/requested prefix length. Note X is never zero here.
4566 tmp_pref
.bits
= (int) iapref
.data
[8];
4567 if (reply
->preflen
< 0) {
4568 /* Cache the first preferred prefix length. */
4569 reply
->preflen
= tmp_pref
.bits
;
4571 if (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0) {
4575 memcpy(tmp_pref
.lo_addr
.iabuf
, iapref
.data
+ 9, 16);
4577 /* Verify the prefix belongs to the client. */
4578 if (!prefix_is_owned(reply
, &tmp_pref
)) {
4579 /* Same than for addresses. */
4580 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
4581 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
4582 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
4583 status
= reply_process_try_prefix(reply
, &tmp_pref
);
4585 /* Either error out or skip this prefix. */
4586 if ((status
!= ISC_R_SUCCESS
) &&
4587 (status
!= ISC_R_ADDRINUSE
) &&
4588 (status
!= ISC_R_ADDRNOTAVAIL
))
4591 if (reply
->lease
== NULL
) {
4592 if (reply
->packet
->dhcpv6_msg_type
==
4594 reply
->send_prefer
= 0;
4595 reply
->send_valid
= 0;
4599 /* status remains success - ignore */
4603 * RFC3633 section 18.2.3:
4605 * If the delegating router cannot find a binding
4606 * for the requesting router's IA_PD the delegating
4607 * router returns the IA_PD containing no prefixes
4608 * with a Status Code option set to NoBinding in the
4611 * On mismatch we (ab)use this pretending we have not the IA
4612 * as soon as we have not a prefix.
4614 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
4615 /* Rewind the IA_PD to empty. */
4616 option_state_dereference(&reply
->reply_ia
, MDL
);
4617 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
4618 log_error("reply_process_prefix: No memory "
4619 "for option state wipe.");
4620 status
= ISC_R_NOMEMORY
;
4624 /* Append a NoBinding status code. */
4625 if (!set_status_code(STATUS_NoBinding
,
4626 "Prefix not bound to this "
4627 "interface.", reply
->reply_ia
)) {
4628 log_error("reply_process_prefix: Unable to "
4629 "attach status code.");
4630 status
= ISC_R_FAILURE
;
4634 /* Fin (no more IAPREFIXes). */
4635 status
= ISC_R_CANCELED
;
4638 log_error("It is impossible to lease a client that is "
4639 "not sending a solicit, request, renew, or "
4641 status
= ISC_R_FAILURE
;
4646 if (reply
->static_prefixes
> 0) {
4647 if (reply
->host
== NULL
)
4648 log_fatal("Impossible condition at %s:%d.", MDL
);
4650 scope
= &global_scope
;
4652 /* Copy the static prefix for logging and finding the group */
4653 memcpy(&reply
->fixed_pref
, &tmp_pref
, sizeof(tmp_pref
));
4655 /* Try to find a group for the static prefix */
4656 group
= find_group_by_prefix(reply
);
4658 if (reply
->lease
== NULL
)
4659 log_fatal("Impossible condition at %s:%d.", MDL
);
4661 scope
= &reply
->lease
->scope
;
4662 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4666 * If client_resources is nonzero, then the reply_process_is_prefixed
4667 * function has executed configuration state into the reply option
4668 * cache. We will use that valid cache to derive configuration for
4669 * whether or not to engage in additional prefixes, and similar.
4671 if (reply
->client_resources
!= 0) {
4675 * Does this client have "enough" prefixes already? Default
4676 * to one. Everybody gets one, and one should be enough for
4679 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4680 SV_LIMIT_PREFS_PER_IA
);
4682 if (!evaluate_option_cache(&data
, reply
->packet
,
4684 reply
->packet
->options
,
4688 log_error("reply_process_prefix: unable to "
4689 "evaluate prefs-per-ia value.");
4690 status
= ISC_R_FAILURE
;
4694 limit
= getULong(data
.data
);
4695 data_string_forget(&data
, MDL
);
4699 * If we wish to limit the client to a certain number of
4700 * prefixes, then omit the prefix from the reply.
4702 if (reply
->client_resources
>= limit
)
4706 status
= reply_process_is_prefixed(reply
, scope
, group
);
4707 if (status
!= ISC_R_SUCCESS
)
4711 status
= reply_process_send_prefix(reply
, &tmp_pref
);
4714 if (iapref
.data
!= NULL
)
4715 data_string_forget(&iapref
, MDL
);
4716 if (data
.data
!= NULL
)
4717 data_string_forget(&data
, MDL
);
4718 if (reply
->lease
!= NULL
)
4719 iasubopt_dereference(&reply
->lease
, MDL
);
4725 * Verify the prefix belongs to the client. If we've got a host
4726 * record with fixed prefixes, it has to be an assigned prefix
4727 * (fault out all else). Otherwise it's a dynamic prefix, so lookup
4728 * that prefix and make sure it belongs to this DUID:IAID pair.
4730 static isc_boolean_t
4731 prefix_is_owned(struct reply_state
*reply
, struct iaddrcidrnet
*pref
) {
4732 struct iaddrcidrnetlist
*l
;
4734 struct ipv6_pond
*pond
;
4737 * This faults out prefixes that don't match fixed prefixes.
4739 if (reply
->static_prefixes
> 0) {
4740 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4741 if ((pref
->bits
== l
->cidrnet
.bits
) &&
4742 (memcmp(pref
->lo_addr
.iabuf
,
4743 l
->cidrnet
.lo_addr
.iabuf
, 16) == 0))
4749 if ((reply
->old_ia
== NULL
) ||
4750 (reply
->old_ia
->num_iasubopt
== 0))
4753 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4754 struct iasubopt
*tmp
;
4756 tmp
= reply
->old_ia
->iasubopt
[i
];
4758 if ((pref
->bits
== (int) tmp
->plen
) &&
4759 (memcmp(pref
->lo_addr
.iabuf
, &tmp
->addr
, 16) == 0)) {
4760 if (lease6_usable(tmp
) == ISC_FALSE
) {
4764 pond
= tmp
->ipv6_pool
->ipv6_pond
;
4765 if (((pond
->prohibit_list
!= NULL
) &&
4766 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4767 ((pond
->permit_list
!= NULL
) &&
4768 (!permitted(reply
->packet
, pond
->permit_list
))))
4771 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
4780 * This function only returns failure on 'hard' failures. If it succeeds,
4781 * it will leave a prefix structure behind.
4784 reply_process_try_prefix(struct reply_state
*reply
,
4785 struct iaddrcidrnet
*pref
) {
4786 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
4787 struct ipv6_pool
*pool
= NULL
;
4788 struct ipv6_pond
*pond
= NULL
;
4790 struct data_string data_pref
;
4792 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
4793 (pref
== NULL
) || (reply
->lease
!= NULL
))
4794 return (DHCP_R_INVALIDARG
);
4797 * Do a quick walk through of the ponds and pools
4798 * to see if we have any prefix pools
4800 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4801 if (pond
->ipv6_pools
== NULL
)
4804 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4805 if (pool
->pool_type
== D6O_IA_PD
)
4812 /* If we get here and p is NULL we have no useful pools */
4814 return (ISC_R_ADDRNOTAVAIL
);
4817 memset(&data_pref
, 0, sizeof(data_pref
));
4819 if (!buffer_allocate(&data_pref
.buffer
, data_pref
.len
, MDL
)) {
4820 log_error("reply_process_try_prefix: out of memory.");
4821 return (ISC_R_NOMEMORY
);
4823 data_pref
.data
= data_pref
.buffer
->data
;
4824 data_pref
.buffer
->data
[0] = (u_int8_t
) pref
->bits
;
4825 memcpy(data_pref
.buffer
->data
+ 1, pref
->lo_addr
.iabuf
, 16);
4828 * We have at least one pool that could provide a prefix
4829 * Now we walk through the ponds and pools again and check
4830 * to see if the client is permitted and if an prefix is
4835 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4836 if (((pond
->prohibit_list
!= NULL
) &&
4837 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4838 ((pond
->permit_list
!= NULL
) &&
4839 (!permitted(reply
->packet
, pond
->permit_list
))))
4842 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4843 if (pool
->pool_type
!= D6O_IA_PD
) {
4847 status
= try_client_v6_prefix(&reply
->lease
, pool
,
4849 /* If we found it in this pool (either in use or available),
4850 there is no need to look further. */
4851 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4854 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4858 data_string_forget(&data_pref
, MDL
);
4859 /* Return just the most recent status... */
4863 /* Look around for a prefix to give the client. First, look through the old
4864 * IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
4865 * Finally, actually add that prefix into the current reply IA_PD.
4868 find_client_prefix(struct reply_state
*reply
) {
4869 struct iaddrcidrnet send_pref
;
4870 isc_result_t status
= ISC_R_NORESOURCES
;
4871 struct iasubopt
*prefix
, *best_prefix
= NULL
;
4872 struct binding_scope
**scope
;
4874 struct group
*group
;
4876 if (reply
->static_prefixes
> 0) {
4877 struct iaddrcidrnetlist
*l
;
4879 if (reply
->host
== NULL
)
4880 return DHCP_R_INVALIDARG
;
4882 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4883 if (l
->cidrnet
.bits
== reply
->preflen
)
4888 * If no fixed prefix has the preferred length,
4889 * get the first one.
4891 l
= reply
->host
->fixed_prefix
;
4893 memcpy(&send_pref
, &l
->cidrnet
, sizeof(send_pref
));
4895 scope
= &global_scope
;
4897 /* Copy the prefix for logging purposes */
4898 memcpy(&reply
->fixed_pref
, &l
->cidrnet
, sizeof(send_pref
));
4900 /* Try to find a group for the static prefix */
4901 group
= find_group_by_prefix(reply
);
4906 if (reply
->old_ia
!= NULL
) {
4907 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4908 struct shared_network
*candidate_shared
;
4909 struct ipv6_pond
*pond
;
4911 prefix
= reply
->old_ia
->iasubopt
[i
];
4912 candidate_shared
= prefix
->ipv6_pool
->shared_network
;
4913 pond
= prefix
->ipv6_pool
->ipv6_pond
;
4916 * Consider this prefix if it is in a global pool or
4917 * if it is scoped in a pool under the client's shared
4920 if (((candidate_shared
!= NULL
) &&
4921 (candidate_shared
!= reply
->shared
)) ||
4922 (lease6_usable(prefix
) != ISC_TRUE
))
4926 * And check if the prefix is still permitted
4929 if (((pond
->prohibit_list
!= NULL
) &&
4930 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4931 ((pond
->permit_list
!= NULL
) &&
4932 (!permitted(reply
->packet
, pond
->permit_list
))))
4935 best_prefix
= prefix_compare(reply
, prefix
,
4940 * If we have prefix length hint and we're not igoring them,
4941 * then toss the best match if it doesn't match the hint,
4942 * unless this is in response to a rebind. In the latter
4943 * case we're supposed to return it with zero lifetimes.
4945 if (best_prefix
&& (reply
->preflen
> 0)
4946 && (prefix_length_mode
!= PLM_IGNORE
)
4947 && (reply
->preflen
!= best_prefix
->plen
)
4948 && (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
4953 /* Try to pick a new prefix if we didn't find one, or if we found an
4956 if ((best_prefix
== NULL
) || (best_prefix
->state
== FTS_ABANDONED
)) {
4957 status
= pick_v6_prefix(reply
);
4958 } else if (best_prefix
!= NULL
) {
4959 iasubopt_reference(&reply
->lease
, best_prefix
, MDL
);
4960 status
= ISC_R_SUCCESS
;
4963 /* Pick the abandoned prefix as a last resort. */
4964 if ((status
== ISC_R_NORESOURCES
) && (best_prefix
!= NULL
)) {
4965 /* I don't see how this is supposed to be done right now. */
4966 log_error("Reclaiming abandoned prefixes is not yet "
4967 "supported. Treating this as an out of space "
4969 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
4972 /* Give up now if we didn't find a prefix. */
4973 if (status
!= ISC_R_SUCCESS
)
4976 if (reply
->lease
== NULL
)
4977 log_fatal("Impossible condition at %s:%d.", MDL
);
4979 scope
= &reply
->lease
->scope
;
4980 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4982 send_pref
.lo_addr
.len
= 16;
4983 memcpy(send_pref
.lo_addr
.iabuf
, &reply
->lease
->addr
, 16);
4984 send_pref
.bits
= (int) reply
->lease
->plen
;
4987 status
= reply_process_is_prefixed(reply
, scope
, group
);
4988 if (status
!= ISC_R_SUCCESS
)
4991 status
= reply_process_send_prefix(reply
, &send_pref
);
4995 /* Once a prefix is found for a client, perform several common functions;
4996 * Calculate and store valid and preferred prefix times, draw client options
4997 * into the option state.
5000 reply_process_is_prefixed(struct reply_state
*reply
,
5001 struct binding_scope
**scope
, struct group
*group
)
5003 isc_result_t status
= ISC_R_SUCCESS
;
5004 struct data_string data
;
5005 struct option_cache
*oc
;
5006 struct option_state
*tmp_options
= NULL
;
5007 struct on_star
*on_star
;
5010 /* Initialize values we will cleanup. */
5011 memset(&data
, 0, sizeof(data
));
5014 * Find the proper on_star block to use. We use the
5015 * one in the lease if we have a lease or the one in
5016 * the reply if we don't have a lease because this is
5020 on_star
= &reply
->lease
->on_star
;
5022 on_star
= &reply
->on_star
;
5026 * Bring in the root configuration. We only do this to bring
5027 * in the on * statements, as we didn't have the lease available
5028 * we we did it the first time.
5030 option_state_allocate(&tmp_options
, MDL
);
5031 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5032 reply
->packet
->options
, tmp_options
,
5033 &global_scope
, root_group
, NULL
,
5035 if (tmp_options
!= NULL
) {
5036 option_state_dereference(&tmp_options
, MDL
);
5040 * Bring configured options into the root packet level cache - start
5041 * with the lease's closest enclosing group (passed in by the caller
5044 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5045 reply
->packet
->options
, reply
->opt_state
,
5046 scope
, group
, root_group
, on_star
);
5048 /* Execute statements from class scopes. */
5049 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
5050 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5051 reply
->packet
->options
,
5052 reply
->opt_state
, scope
,
5053 reply
->packet
->classes
[i
- 1]->group
,
5058 * If there is a host record, over-ride with values configured there,
5059 * without re-evaluating configuration from the previously executed
5060 * group or its common enclosers.
5062 if (reply
->host
!= NULL
)
5063 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5064 reply
->packet
->options
,
5065 reply
->opt_state
, scope
,
5066 reply
->host
->group
, group
,
5069 /* Determine valid lifetime. */
5070 if (reply
->client_valid
== 0)
5071 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
5073 reply
->send_valid
= reply
->client_valid
;
5075 oc
= lookup_option(&server_universe
, reply
->opt_state
,
5076 SV_DEFAULT_LEASE_TIME
);
5078 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
5079 reply
->packet
->options
,
5083 log_error("reply_process_is_prefixed: unable to "
5084 "evaluate default prefix time");
5085 status
= ISC_R_FAILURE
;
5089 reply
->send_valid
= getULong(data
.data
);
5090 data_string_forget(&data
, MDL
);
5093 /* Check to see if the lease time would cause us to wrap
5094 * in which case we make it infinite.
5095 * The following doesn't work on at least some systems:
5096 * (cur_time + reply->send_valid < cur_time)
5098 if (reply
->send_valid
!= INFINITE_TIME
) {
5099 time_t test_time
= cur_time
+ reply
->send_valid
;
5100 if (test_time
< cur_time
)
5101 reply
->send_valid
= INFINITE_TIME
;
5104 if (reply
->client_prefer
== 0)
5105 reply
->send_prefer
= reply
->send_valid
;
5107 reply
->send_prefer
= reply
->client_prefer
;
5109 if ((reply
->send_prefer
>= reply
->send_valid
) &&
5110 (reply
->send_valid
!= INFINITE_TIME
))
5111 reply
->send_prefer
= (reply
->send_valid
/ 2) +
5112 (reply
->send_valid
/ 8);
5114 oc
= lookup_option(&server_universe
, reply
->opt_state
,
5115 SV_PREFER_LIFETIME
);
5117 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
5118 reply
->packet
->options
,
5122 log_error("reply_process_is_prefixed: unable to "
5123 "evaluate preferred prefix time");
5124 status
= ISC_R_FAILURE
;
5128 reply
->send_prefer
= getULong(data
.data
);
5129 data_string_forget(&data
, MDL
);
5132 /* Note lowest values for later calculation of renew/rebind times. */
5133 if (reply
->min_prefer
> reply
->send_prefer
)
5134 reply
->min_prefer
= reply
->send_prefer
;
5136 if (reply
->min_valid
> reply
->send_valid
)
5137 reply
->min_valid
= reply
->send_valid
;
5139 /* Perform dynamic prefix related update work. */
5140 if (reply
->lease
!= NULL
) {
5141 /* Cached lifetimes */
5142 reply
->lease
->prefer
= reply
->send_prefer
;
5143 reply
->lease
->valid
= reply
->send_valid
;
5145 /* Advance (or rewind) the valid lifetime.
5146 * In the protocol 0xFFFFFFFF is infinite
5147 * when connecting to the lease file MAX_TIME is
5149 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
5150 if (reply
->send_valid
== INFINITE_TIME
) {
5151 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
5153 reply
->lease
->soft_lifetime_end_time
=
5154 cur_time
+ reply
->send_valid
;
5156 /* Wait before renew! */
5159 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
5160 if (status
!= ISC_R_SUCCESS
) {
5161 log_fatal("reply_process_is_prefixed: Unable to "
5162 "attach prefix to new IA_PD: %s",
5163 isc_result_totext(status
));
5167 * If this is a new prefix, make sure it is attached somewhere.
5169 if (reply
->lease
->ia
== NULL
) {
5170 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
5174 /* Bring a copy of the relevant options into the IA_PD scope. */
5175 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5176 reply
->packet
->options
, reply
->reply_ia
,
5177 scope
, group
, root_group
, NULL
);
5179 /* Execute statements from class scopes. */
5180 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
5181 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5182 reply
->packet
->options
,
5183 reply
->reply_ia
, scope
,
5184 reply
->packet
->classes
[i
- 1]->group
,
5189 * And bring in host record configuration, if any, but not to overlap
5190 * the previous group or its common enclosers.
5192 if (reply
->host
!= NULL
)
5193 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5194 reply
->packet
->options
,
5195 reply
->reply_ia
, scope
,
5196 reply
->host
->group
, group
, NULL
);
5199 if (data
.data
!= NULL
)
5200 data_string_forget(&data
, MDL
);
5202 if (status
== ISC_R_SUCCESS
)
5203 reply
->client_resources
++;
5208 /* Simply send an IAPREFIX within the IA_PD scope as described. */
5210 reply_process_send_prefix(struct reply_state
*reply
,
5211 struct iaddrcidrnet
*pref
) {
5212 isc_result_t status
= ISC_R_SUCCESS
;
5213 struct data_string data
;
5215 memset(&data
, 0, sizeof(data
));
5217 /* Now append the prefix. */
5218 data
.len
= IAPREFIX_OFFSET
;
5219 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
5220 log_error("reply_process_send_prefix: out of memory"
5221 "allocating new IAPREFIX buffer.");
5222 status
= ISC_R_NOMEMORY
;
5225 data
.data
= data
.buffer
->data
;
5227 putULong(data
.buffer
->data
, reply
->send_prefer
);
5228 putULong(data
.buffer
->data
+ 4, reply
->send_valid
);
5229 data
.buffer
->data
[8] = pref
->bits
;
5230 memcpy(data
.buffer
->data
+ 9, pref
->lo_addr
.iabuf
, 16);
5232 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
5233 data
.buffer
, data
.buffer
->data
,
5234 data
.len
, D6O_IAPREFIX
, 0)) {
5235 log_error("reply_process_send_prefix: unable "
5236 "to save IAPREFIX option");
5237 status
= ISC_R_FAILURE
;
5241 reply
->resources_included
= ISC_TRUE
;
5244 if (data
.data
!= NULL
)
5245 data_string_forget(&data
, MDL
);
5250 /* Choose the better of two prefixes. */
5251 static struct iasubopt
*
5252 prefix_compare(struct reply_state
*reply
,
5253 struct iasubopt
*alpha
, struct iasubopt
*beta
) {
5259 if (reply
->preflen
>= 0) {
5260 if ((alpha
->plen
== reply
->preflen
) &&
5261 (beta
->plen
!= reply
->preflen
))
5263 if ((beta
->plen
== reply
->preflen
) &&
5264 (alpha
->plen
!= reply
->preflen
))
5268 switch(alpha
->state
) {
5270 switch(beta
->state
) {
5272 /* Choose the prefix with the longest lifetime (most
5273 * likely the most recently allocated).
5275 if (alpha
->hard_lifetime_end_time
<
5276 beta
->hard_lifetime_end_time
)
5286 log_fatal("Impossible condition at %s:%d.", MDL
);
5291 switch (beta
->state
) {
5296 /* Choose the most recently expired prefix. */
5297 if (alpha
->hard_lifetime_end_time
<
5298 beta
->hard_lifetime_end_time
)
5300 else if ((alpha
->hard_lifetime_end_time
==
5301 beta
->hard_lifetime_end_time
) &&
5302 (alpha
->soft_lifetime_end_time
<
5303 beta
->soft_lifetime_end_time
))
5312 log_fatal("Impossible condition at %s:%d.", MDL
);
5317 switch (beta
->state
) {
5323 /* Choose the prefix that was abandoned longest ago. */
5324 if (alpha
->hard_lifetime_end_time
<
5325 beta
->hard_lifetime_end_time
)
5331 log_fatal("Impossible condition at %s:%d.", MDL
);
5336 log_fatal("Impossible condition at %s:%d.", MDL
);
5339 log_fatal("Triple impossible condition at %s:%d.", MDL
);
5344 * Solicit is how a client starts requesting addresses.
5346 * If the client asks for rapid commit, and we support it, we will
5347 * allocate the addresses and reply.
5349 * Otherwise we will send an advertise message.
5353 dhcpv6_solicit(struct data_string
*reply_ret
, struct packet
*packet
) {
5354 struct data_string client_id
;
5357 * Validate our input.
5359 if (!valid_client_msg(packet
, &client_id
)) {
5363 lease_to_client(reply_ret
, packet
, &client_id
, NULL
);
5368 data_string_forget(&client_id
, MDL
);
5372 * Request is how a client actually requests addresses.
5374 * Very similar to Solicit handling, except the server DUID is required.
5378 dhcpv6_request(struct data_string
*reply_ret
, struct packet
*packet
) {
5379 struct data_string client_id
;
5380 struct data_string server_id
;
5383 * Validate our input.
5385 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5389 /* If the REQUEST arrived via unicast and unicast option isn't set,
5390 * reject it per RFC 3315, Sec 18.2.1 */
5391 if (packet
->unicast
== ISC_TRUE
&&
5392 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5393 unicast_reject(reply_ret
, packet
, &client_id
, &server_id
);
5398 lease_to_client(reply_ret
, packet
, &client_id
, &server_id
);
5404 data_string_forget(&client_id
, MDL
);
5405 data_string_forget(&server_id
, MDL
);
5408 /* Find a DHCPv6 packet's shared network from hints in the packet.
5411 shared_network_from_packet6(struct shared_network
**shared
,
5412 struct packet
*packet
)
5414 const struct packet
*chk_packet
;
5415 const struct in6_addr
*link_addr
, *first_link_addr
;
5416 struct iaddr tmp_addr
;
5417 struct subnet
*subnet
;
5418 isc_result_t status
;
5420 if ((shared
== NULL
) || (*shared
!= NULL
) || (packet
== NULL
))
5421 return DHCP_R_INVALIDARG
;
5424 * First, find the link address where the packet from the client
5425 * first appeared (if this packet was relayed).
5427 first_link_addr
= NULL
;
5428 chk_packet
= packet
->dhcpv6_container_packet
;
5429 while (chk_packet
!= NULL
) {
5430 link_addr
= &chk_packet
->dhcpv6_link_address
;
5431 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
5432 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
5433 first_link_addr
= link_addr
;
5436 chk_packet
= chk_packet
->dhcpv6_container_packet
;
5440 * If there is a relayed link address, find the subnet associated
5441 * with that, and use that to get the appropriate
5444 if (first_link_addr
!= NULL
) {
5445 tmp_addr
.len
= sizeof(*first_link_addr
);
5446 memcpy(tmp_addr
.iabuf
,
5447 first_link_addr
, sizeof(*first_link_addr
));
5449 if (!find_subnet(&subnet
, tmp_addr
, MDL
)) {
5450 log_debug("No subnet found for link-address %s.",
5452 return ISC_R_NOTFOUND
;
5454 status
= shared_network_reference(shared
,
5455 subnet
->shared_network
, MDL
);
5456 subnet_dereference(&subnet
, MDL
);
5459 * If there is no link address, we will use the interface
5460 * that this packet came in on to pick the shared_network.
5462 } else if (packet
->interface
!= NULL
) {
5463 status
= shared_network_reference(shared
,
5464 packet
->interface
->shared_network
,
5466 if (packet
->dhcpv6_container_packet
!= NULL
) {
5467 log_info("[L2 Relay] No link address in relay packet "
5468 "assuming L2 relay and using receiving "
5474 * We shouldn't be able to get here but if there is no link
5475 * address and no interface we don't know where to get the
5476 * pool from log an error and return an error.
5478 log_error("No interface and no link address "
5479 "can't determine pool");
5480 status
= DHCP_R_INVALIDARG
;
5487 * When a client thinks it might be on a new link, it sends a
5490 * From RFC3315 section 18.2.2:
5492 * When the server receives a Confirm message, the server determines
5493 * whether the addresses in the Confirm message are appropriate for the
5494 * link to which the client is attached. If all of the addresses in the
5495 * Confirm message pass this test, the server returns a status of
5496 * Success. If any of the addresses do not pass this test, the server
5497 * returns a status of NotOnLink. If the server is unable to perform
5498 * this test (for example, the server does not have information about
5499 * prefixes on the link to which the client is connected), or there were
5500 * no addresses in any of the IAs sent by the client, the server MUST
5501 * NOT send a reply to the client.
5505 dhcpv6_confirm(struct data_string
*reply_ret
, struct packet
*packet
) {
5506 struct shared_network
*shared
;
5507 struct subnet
*subnet
;
5508 struct option_cache
*ia
, *ta
, *oc
;
5509 struct data_string cli_enc_opt_data
, iaaddr
, client_id
, packet_oro
;
5510 struct option_state
*cli_enc_opt_state
, *opt_state
;
5511 struct iaddr cli_addr
;
5513 isc_boolean_t inappropriate
, has_addrs
;
5514 char reply_data
[65536];
5515 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5516 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5519 * Basic client message validation.
5521 memset(&client_id
, 0, sizeof(client_id
));
5522 if (!valid_client_msg(packet
, &client_id
)) {
5527 * Do not process Confirms that do not have IA's we do not recognize.
5529 ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5530 ta
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
5531 if ((ia
== NULL
) && (ta
== NULL
))
5535 * IA_PD's are simply ignored.
5537 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5540 * Bit of variable initialization.
5542 opt_state
= cli_enc_opt_state
= NULL
;
5543 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5544 memset(&iaaddr
, 0, sizeof(iaaddr
));
5545 memset(&packet_oro
, 0, sizeof(packet_oro
));
5547 /* Determine what shared network the client is connected to. We
5548 * must not respond if we don't have any information about the
5549 * network the client is on.
5552 if ((shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
) ||
5556 /* If there are no recorded subnets, then we have no
5557 * information about this subnet - ignore Confirms.
5559 subnet
= shared
->subnets
;
5563 /* Are the addresses in all the IA's appropriate for that link? */
5564 has_addrs
= inappropriate
= ISC_FALSE
;
5566 while(!inappropriate
) {
5567 /* If we've reached the end of the IA_NA pass, move to the
5570 if ((pass
== D6O_IA_NA
) && (ia
== NULL
)) {
5575 /* If we've reached the end of all passes, we're done. */
5579 if (((pass
== D6O_IA_NA
) &&
5580 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5582 packet
, ia
, IA_NA_OFFSET
)) ||
5583 ((pass
== D6O_IA_TA
) &&
5584 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5586 packet
, ia
, IA_TA_OFFSET
))) {
5590 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5593 for ( ; oc
!= NULL
; oc
= oc
->next
) {
5594 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5595 packet
->options
, NULL
,
5596 &global_scope
, oc
, MDL
) ||
5597 (iaaddr
.len
< IAADDR_OFFSET
)) {
5598 log_error("dhcpv6_confirm: "
5599 "error evaluating IAADDR.");
5603 /* Copy out the IPv6 address for processing. */
5605 memcpy(cli_addr
.iabuf
, iaaddr
.data
, 16);
5607 data_string_forget(&iaaddr
, MDL
);
5609 /* Record that we've processed at least one address. */
5610 has_addrs
= ISC_TRUE
;
5612 /* Find out if any subnets cover this address. */
5613 for (subnet
= shared
->subnets
; subnet
!= NULL
;
5614 subnet
= subnet
->next_sibling
) {
5615 if (addr_eq(subnet_number(cli_addr
,
5621 /* If we reach the end of the subnet list, and no
5622 * subnet matches the client address, then it must
5623 * be inappropriate to the link (so far as our
5624 * configuration says). Once we've found one
5625 * inappropriate address, there is no reason to
5626 * continue searching.
5628 if (subnet
== NULL
) {
5629 inappropriate
= ISC_TRUE
;
5634 option_state_dereference(&cli_enc_opt_state
, MDL
);
5635 data_string_forget(&cli_enc_opt_data
, MDL
);
5637 /* Advance to the next IA_*. */
5641 /* If the client supplied no addresses, do not reply. */
5648 if (!start_reply(packet
, &client_id
, NULL
, &opt_state
, reply
)) {
5655 if (inappropriate
) {
5656 if (!set_status_code(STATUS_NotOnLink
,
5657 "Some of the addresses are not on link.",
5662 if (!set_status_code(STATUS_Success
,
5663 "All addresses still on link.",
5670 * Only one option: add it.
5672 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5673 sizeof(reply_data
)-reply_ofs
,
5675 required_opts
, &packet_oro
);
5678 * Return our reply to the caller.
5680 reply_ret
->len
= reply_ofs
;
5681 reply_ret
->buffer
= NULL
;
5682 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5683 log_fatal("No memory to store reply.");
5685 reply_ret
->data
= reply_ret
->buffer
->data
;
5686 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5689 /* Cleanup any stale data strings. */
5690 if (cli_enc_opt_data
.buffer
!= NULL
)
5691 data_string_forget(&cli_enc_opt_data
, MDL
);
5692 if (iaaddr
.buffer
!= NULL
)
5693 data_string_forget(&iaaddr
, MDL
);
5694 if (client_id
.buffer
!= NULL
)
5695 data_string_forget(&client_id
, MDL
);
5696 if (packet_oro
.buffer
!= NULL
)
5697 data_string_forget(&packet_oro
, MDL
);
5699 /* Release any stale option states. */
5700 if (cli_enc_opt_state
!= NULL
)
5701 option_state_dereference(&cli_enc_opt_state
, MDL
);
5702 if (opt_state
!= NULL
)
5703 option_state_dereference(&opt_state
, MDL
);
5707 * Renew is when a client wants to extend its lease/prefix, at time T1.
5709 * We handle this the same as if the client wants a new lease/prefix,
5710 * except for the error code of when addresses don't match.
5714 dhcpv6_renew(struct data_string
*reply
, struct packet
*packet
) {
5715 struct data_string client_id
;
5716 struct data_string server_id
;
5719 * Validate the request.
5721 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5725 /* If the RENEW arrived via unicast and unicast option isn't set,
5726 * reject it per RFC 3315, Sec 18.2.3 */
5727 if (packet
->unicast
== ISC_TRUE
&&
5728 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5729 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5734 lease_to_client(reply
, packet
, &client_id
, &server_id
);
5740 data_string_forget(&server_id
, MDL
);
5741 data_string_forget(&client_id
, MDL
);
5745 * Rebind is when a client wants to extend its lease, at time T2.
5747 * We handle this the same as if the client wants a new lease, except
5748 * for the error code of when addresses don't match.
5752 dhcpv6_rebind(struct data_string
*reply
, struct packet
*packet
) {
5753 struct data_string client_id
;
5755 if (!valid_client_msg(packet
, &client_id
)) {
5759 lease_to_client(reply
, packet
, &client_id
, NULL
);
5761 data_string_forget(&client_id
, MDL
);
5765 ia_na_match_decline(const struct data_string
*client_id
,
5766 const struct data_string
*iaaddr
,
5767 struct iasubopt
*lease
)
5769 char tmp_addr
[INET6_ADDRSTRLEN
];
5771 log_error("Client %s reports address %s is "
5772 "already in use by another host!",
5773 print_hex_1(client_id
->len
, client_id
->data
, 60),
5774 inet_ntop(AF_INET6
, iaaddr
->data
,
5775 tmp_addr
, sizeof(tmp_addr
)));
5776 if (lease
!= NULL
) {
5777 decline_lease6(lease
->ipv6_pool
, lease
);
5778 lease
->ia
->cltt
= cur_time
;
5779 write_ia(lease
->ia
);
5784 ia_na_nomatch_decline(const struct data_string
*client_id
,
5785 const struct data_string
*iaaddr
,
5786 u_int32_t
*ia_na_id
,
5787 struct packet
*packet
,
5792 char tmp_addr
[INET6_ADDRSTRLEN
];
5793 struct option_state
*host_opt_state
;
5796 log_info("Client %s declines address %s, which is not offered to it.",
5797 print_hex_1(client_id
->len
, client_id
->data
, 60),
5798 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5801 * Create state for this IA_NA.
5803 host_opt_state
= NULL
;
5804 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5805 log_error("ia_na_nomatch_decline: out of memory "
5806 "allocating option_state.");
5810 if (!set_status_code(STATUS_NoBinding
, "Decline for unknown address.",
5816 * Insure we have enough space
5818 if (reply_len
< (*reply_ofs
+ 16)) {
5819 log_error("ia_na_nomatch_decline: "
5820 "out of space for reply packet.");
5825 * Put our status code into the reply packet.
5827 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5828 reply_len
-(*reply_ofs
)-16,
5829 host_opt_state
, packet
,
5830 required_opts_STATUS_CODE
, NULL
);
5833 * Store the non-encapsulated option data for this
5834 * IA_NA into our reply packet. Defined in RFC 3315,
5838 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5840 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5841 /* IA_NA, copied from the client */
5842 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5843 /* t1 and t2, odd that we need them, but here it is */
5844 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5845 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5848 * Get ready for next IA_NA.
5850 *reply_ofs
+= (len
+ 16);
5853 option_state_dereference(&host_opt_state
, MDL
);
5857 iterate_over_ia_na(struct data_string
*reply_ret
,
5858 struct packet
*packet
,
5859 const struct data_string
*client_id
,
5860 const struct data_string
*server_id
,
5861 const char *packet_type
,
5862 void (*ia_na_match
)(),
5863 void (*ia_na_nomatch
)())
5865 struct option_state
*opt_state
;
5866 struct host_decl
*packet_host
;
5867 struct option_cache
*ia
;
5868 struct option_cache
*oc
;
5869 /* cli_enc_... variables come from the IA_NA/IA_TA options */
5870 struct data_string cli_enc_opt_data
;
5871 struct option_state
*cli_enc_opt_state
;
5872 struct host_decl
*host
;
5873 struct data_string iaaddr
;
5874 struct data_string fixed_addr
;
5875 char reply_data
[65536];
5876 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5877 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5878 char status_msg
[32];
5879 struct iasubopt
*lease
;
5880 struct ia_xx
*existing_ia_na
;
5882 struct data_string key
;
5886 * Initialize to empty values, in case we have to exit early.
5889 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5890 cli_enc_opt_state
= NULL
;
5891 memset(&iaaddr
, 0, sizeof(iaaddr
));
5892 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
5896 * Find the host record that matches from the packet, if any.
5899 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
5902 * Set our reply information.
5904 reply
->msg_type
= DHCPV6_REPLY
;
5905 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
5906 sizeof(reply
->transaction_id
));
5909 * Build our option state for reply.
5912 if (!option_state_allocate(&opt_state
, MDL
)) {
5913 log_error("iterate_over_ia_na: no memory for option_state.");
5916 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5917 packet
->options
, opt_state
,
5918 &global_scope
, root_group
, NULL
, NULL
);
5921 * RFC 3315, section 18.2.7 tells us which options to include.
5923 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
5925 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5926 (unsigned char *)server_duid
.data
,
5927 server_duid
.len
, D6O_SERVERID
, 0)) {
5928 log_error("iterate_over_ia_na: "
5929 "error saving server identifier.");
5934 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
5936 (unsigned char *)client_id
->data
,
5939 log_error("iterate_over_ia_na: "
5940 "error saving client identifier.");
5944 snprintf(status_msg
, sizeof(status_msg
), "%s received.", packet_type
);
5945 if (!set_status_code(STATUS_Success
, status_msg
, opt_state
)) {
5950 * Add our options that are not associated with any IA_NA or IA_TA.
5952 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5953 sizeof(reply_data
)-reply_ofs
,
5955 required_opts
, NULL
);
5958 * Loop through the IA_NA reported by the client, and deal with
5959 * addresses reported as already in use.
5961 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5962 ia
!= NULL
; ia
= ia
->next
) {
5964 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
5966 packet
, ia
, IA_NA_OFFSET
)) {
5970 iaid
= getULong(cli_enc_opt_data
.data
);
5973 * XXX: It is possible that we can get multiple addresses
5974 * sent by the client. We don't send multiple
5975 * addresses, so this indicates a client error.
5976 * We should check for multiple IAADDR options, log
5977 * if found, and set as an error.
5979 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5982 /* no address given for this IA, ignore */
5983 option_state_dereference(&cli_enc_opt_state
, MDL
);
5984 data_string_forget(&cli_enc_opt_data
, MDL
);
5988 memset(&iaaddr
, 0, sizeof(iaaddr
));
5989 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5990 packet
->options
, NULL
,
5991 &global_scope
, oc
, MDL
)) {
5992 log_error("iterate_over_ia_na: "
5993 "error evaluating IAADDR.");
5998 * Now we need to figure out which host record matches
5999 * this IA_NA and IAADDR (encapsulated option contents
6000 * matching a host record by option).
6002 * XXX: We don't currently track IA_NA separately, but
6003 * we will need to do this!
6006 if (!find_hosts_by_option(&host
, packet
,
6007 cli_enc_opt_state
, MDL
)) {
6008 if (packet_host
!= NULL
) {
6014 while (host
!= NULL
) {
6015 if (host
->fixed_addr
!= NULL
) {
6016 if (!evaluate_option_cache(&fixed_addr
, NULL
,
6018 NULL
, &global_scope
,
6021 log_error("iterate_over_ia_na: error "
6022 "evaluating host address.");
6025 if ((iaaddr
.len
>= 16) &&
6026 !memcmp(fixed_addr
.data
, iaaddr
.data
, 16)) {
6027 data_string_forget(&fixed_addr
, MDL
);
6030 data_string_forget(&fixed_addr
, MDL
);
6032 host
= host
->n_ipaddr
;
6035 if ((host
== NULL
) && (iaaddr
.len
>= IAADDR_OFFSET
)) {
6037 * Find existing IA_NA.
6039 if (ia_make_key(&key
, iaid
,
6040 (char *)client_id
->data
,
6042 MDL
) != ISC_R_SUCCESS
) {
6043 log_fatal("iterate_over_ia_na: no memory for "
6047 existing_ia_na
= NULL
;
6048 if (ia_hash_lookup(&existing_ia_na
, ia_na_active
,
6049 (unsigned char *)key
.data
,
6052 * Make sure this address is in the IA_NA.
6054 for (i
=0; i
<existing_ia_na
->num_iasubopt
; i
++) {
6055 struct iasubopt
*tmp
;
6056 struct in6_addr
*in6_addr
;
6058 tmp
= existing_ia_na
->iasubopt
[i
];
6059 in6_addr
= &tmp
->addr
;
6060 if (memcmp(in6_addr
,
6061 iaaddr
.data
, 16) == 0) {
6062 iasubopt_reference(&lease
,
6069 data_string_forget(&key
, MDL
);
6072 if ((host
!= NULL
) || (lease
!= NULL
)) {
6073 ia_na_match(client_id
, &iaaddr
, lease
);
6075 ia_na_nomatch(client_id
, &iaaddr
,
6076 (u_int32_t
*)cli_enc_opt_data
.data
,
6077 packet
, reply_data
, &reply_ofs
,
6078 sizeof(reply_data
));
6081 if (lease
!= NULL
) {
6082 iasubopt_dereference(&lease
, MDL
);
6085 data_string_forget(&iaaddr
, MDL
);
6086 option_state_dereference(&cli_enc_opt_state
, MDL
);
6087 data_string_forget(&cli_enc_opt_data
, MDL
);
6091 * Return our reply to the caller.
6093 reply_ret
->len
= reply_ofs
;
6094 reply_ret
->buffer
= NULL
;
6095 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
6096 log_fatal("No memory to store reply.");
6098 reply_ret
->data
= reply_ret
->buffer
->data
;
6099 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
6102 if (lease
!= NULL
) {
6103 iasubopt_dereference(&lease
, MDL
);
6105 if (fixed_addr
.buffer
!= NULL
) {
6106 data_string_forget(&fixed_addr
, MDL
);
6108 if (iaaddr
.buffer
!= NULL
) {
6109 data_string_forget(&iaaddr
, MDL
);
6111 if (cli_enc_opt_state
!= NULL
) {
6112 option_state_dereference(&cli_enc_opt_state
, MDL
);
6114 if (cli_enc_opt_data
.buffer
!= NULL
) {
6115 data_string_forget(&cli_enc_opt_data
, MDL
);
6117 if (opt_state
!= NULL
) {
6118 option_state_dereference(&opt_state
, MDL
);
6123 * Decline means a client has detected that something else is using an
6124 * address we gave it.
6126 * Since we're only dealing with fixed leases for now, there's not
6127 * much we can do, other that log the occurrence.
6129 * When we start issuing addresses from pools, then we will have to
6130 * record our declined addresses and issue another. In general with
6131 * IPv6 there is no worry about DoS by clients exhausting space, but
6132 * we still need to be aware of this possibility.
6137 dhcpv6_decline(struct data_string
*reply
, struct packet
*packet
) {
6138 struct data_string client_id
;
6139 struct data_string server_id
;
6142 * Validate our input.
6144 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
6148 /* If the DECLINE arrived via unicast and unicast option isn't set,
6149 * reject it per RFC 3315, Sec 18.2.7 */
6150 if (packet
->unicast
== ISC_TRUE
&&
6151 is_unicast_option_defined(packet
) == ISC_FALSE
) {
6152 unicast_reject(reply
, packet
, &client_id
, &server_id
);
6155 * Undefined for IA_PD.
6157 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
6160 * And operate on each IA_NA in this packet.
6162 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
6163 "Decline", ia_na_match_decline
,
6164 ia_na_nomatch_decline
);
6168 data_string_forget(&server_id
, MDL
);
6169 data_string_forget(&client_id
, MDL
);
6173 ia_na_match_release(const struct data_string
*client_id
,
6174 const struct data_string
*iaaddr
,
6175 struct iasubopt
*lease
)
6177 char tmp_addr
[INET6_ADDRSTRLEN
];
6179 log_info("Client %s releases address %s",
6180 print_hex_1(client_id
->len
, client_id
->data
, 60),
6181 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
6182 if (lease
!= NULL
) {
6183 release_lease6(lease
->ipv6_pool
, lease
);
6184 lease
->ia
->cltt
= cur_time
;
6185 write_ia(lease
->ia
);
6190 ia_na_nomatch_release(const struct data_string
*client_id
,
6191 const struct data_string
*iaaddr
,
6192 u_int32_t
*ia_na_id
,
6193 struct packet
*packet
,
6198 char tmp_addr
[INET6_ADDRSTRLEN
];
6199 struct option_state
*host_opt_state
;
6202 log_info("Client %s releases address %s, which is not leased to it.",
6203 print_hex_1(client_id
->len
, client_id
->data
, 60),
6204 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
6207 * Create state for this IA_NA.
6209 host_opt_state
= NULL
;
6210 if (!option_state_allocate(&host_opt_state
, MDL
)) {
6211 log_error("ia_na_nomatch_release: out of memory "
6212 "allocating option_state.");
6216 if (!set_status_code(STATUS_NoBinding
,
6217 "Release for non-leased address.",
6223 * Insure we have enough space
6225 if (reply_len
< (*reply_ofs
+ 16)) {
6226 log_error("ia_na_nomatch_release: "
6227 "out of space for reply packet.");
6232 * Put our status code into the reply packet.
6234 len
= store_options6(reply_data
+(*reply_ofs
)+16,
6235 reply_len
-(*reply_ofs
)-16,
6236 host_opt_state
, packet
,
6237 required_opts_STATUS_CODE
, NULL
);
6240 * Store the non-encapsulated option data for this
6241 * IA_NA into our reply packet. Defined in RFC 3315,
6245 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
6247 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
6248 /* IA_NA, copied from the client */
6249 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
6250 /* t1 and t2, odd that we need them, but here it is */
6251 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
6252 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
6255 * Get ready for next IA_NA.
6257 *reply_ofs
+= (len
+ 16);
6260 option_state_dereference(&host_opt_state
, MDL
);
6264 ia_pd_match_release(const struct data_string
*client_id
,
6265 const struct data_string
*iapref
,
6266 struct iasubopt
*prefix
)
6268 char tmp_addr
[INET6_ADDRSTRLEN
];
6270 log_info("Client %s releases prefix %s/%u",
6271 print_hex_1(client_id
->len
, client_id
->data
, 60),
6272 inet_ntop(AF_INET6
, iapref
->data
+ 9,
6273 tmp_addr
, sizeof(tmp_addr
)),
6274 (unsigned) getUChar(iapref
->data
+ 8));
6275 if (prefix
!= NULL
) {
6276 release_lease6(prefix
->ipv6_pool
, prefix
);
6277 prefix
->ia
->cltt
= cur_time
;
6278 write_ia(prefix
->ia
);
6283 ia_pd_nomatch_release(const struct data_string
*client_id
,
6284 const struct data_string
*iapref
,
6285 u_int32_t
*ia_pd_id
,
6286 struct packet
*packet
,
6291 char tmp_addr
[INET6_ADDRSTRLEN
];
6292 struct option_state
*host_opt_state
;
6295 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
6296 print_hex_1(client_id
->len
, client_id
->data
, 60),
6297 inet_ntop(AF_INET6
, iapref
->data
+ 9,
6298 tmp_addr
, sizeof(tmp_addr
)),
6299 (unsigned) getUChar(iapref
->data
+ 8));
6302 * Create state for this IA_PD.
6304 host_opt_state
= NULL
;
6305 if (!option_state_allocate(&host_opt_state
, MDL
)) {
6306 log_error("ia_pd_nomatch_release: out of memory "
6307 "allocating option_state.");
6311 if (!set_status_code(STATUS_NoBinding
,
6312 "Release for non-leased prefix.",
6318 * Insure we have enough space
6320 if (reply_len
< (*reply_ofs
+ 16)) {
6321 log_error("ia_pd_nomatch_release: "
6322 "out of space for reply packet.");
6327 * Put our status code into the reply packet.
6329 len
= store_options6(reply_data
+(*reply_ofs
)+16,
6330 reply_len
-(*reply_ofs
)-16,
6331 host_opt_state
, packet
,
6332 required_opts_STATUS_CODE
, NULL
);
6335 * Store the non-encapsulated option data for this
6336 * IA_PD into our reply packet. Defined in RFC 3315,
6340 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_PD
);
6342 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
6343 /* IA_PD, copied from the client */
6344 memcpy(reply_data
+(*reply_ofs
)+4, ia_pd_id
, 4);
6345 /* t1 and t2, odd that we need them, but here it is */
6346 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
6347 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
6350 * Get ready for next IA_PD.
6352 *reply_ofs
+= (len
+ 16);
6355 option_state_dereference(&host_opt_state
, MDL
);
6359 iterate_over_ia_pd(struct data_string
*reply_ret
,
6360 struct packet
*packet
,
6361 const struct data_string
*client_id
,
6362 const struct data_string
*server_id
,
6363 const char *packet_type
,
6364 void (*ia_pd_match
)(),
6365 void (*ia_pd_nomatch
)())
6367 struct data_string reply_new
;
6369 struct option_state
*opt_state
;
6370 struct host_decl
*packet_host
;
6371 struct option_cache
*ia
;
6372 struct option_cache
*oc
;
6373 /* cli_enc_... variables come from the IA_PD options */
6374 struct data_string cli_enc_opt_data
;
6375 struct option_state
*cli_enc_opt_state
;
6376 struct host_decl
*host
;
6377 struct data_string iaprefix
;
6378 char reply_data
[65536];
6380 struct iasubopt
*prefix
;
6381 struct ia_xx
*existing_ia_pd
;
6383 struct data_string key
;
6387 * Initialize to empty values, in case we have to exit early.
6389 memset(&reply_new
, 0, sizeof(reply_new
));
6391 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
6392 cli_enc_opt_state
= NULL
;
6393 memset(&iaprefix
, 0, sizeof(iaprefix
));
6397 * Compute the available length for the reply.
6399 reply_len
= sizeof(reply_data
) - reply_ret
->len
;
6403 * Find the host record that matches from the packet, if any.
6406 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
6409 * Build our option state for reply.
6412 if (!option_state_allocate(&opt_state
, MDL
)) {
6413 log_error("iterate_over_ia_pd: no memory for option_state.");
6416 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
6417 packet
->options
, opt_state
,
6418 &global_scope
, root_group
, NULL
, NULL
);
6421 * Loop through the IA_PD reported by the client, and deal with
6422 * prefixes reported as already in use.
6424 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
6425 ia
!= NULL
; ia
= ia
->next
) {
6427 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
6429 packet
, ia
, IA_PD_OFFSET
)) {
6433 iaid
= getULong(cli_enc_opt_data
.data
);
6435 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
6438 /* no prefix given for this IA_PD, ignore */
6439 option_state_dereference(&cli_enc_opt_state
, MDL
);
6440 data_string_forget(&cli_enc_opt_data
, MDL
);
6444 for (; oc
!= NULL
; oc
= oc
->next
) {
6445 memset(&iaprefix
, 0, sizeof(iaprefix
));
6446 if (!evaluate_option_cache(&iaprefix
, packet
, NULL
, NULL
,
6447 packet
->options
, NULL
,
6448 &global_scope
, oc
, MDL
)) {
6449 log_error("iterate_over_ia_pd: "
6450 "error evaluating IAPREFIX.");
6455 * Now we need to figure out which host record matches
6456 * this IA_PD and IAPREFIX (encapsulated option contents
6457 * matching a host record by option).
6459 * XXX: We don't currently track IA_PD separately, but
6460 * we will need to do this!
6463 if (!find_hosts_by_option(&host
, packet
,
6464 cli_enc_opt_state
, MDL
)) {
6465 if (packet_host
!= NULL
) {
6471 while (host
!= NULL
) {
6472 if (host
->fixed_prefix
!= NULL
) {
6473 struct iaddrcidrnetlist
*l
;
6474 int plen
= (int) getUChar(iaprefix
.data
+ 8);
6476 for (l
= host
->fixed_prefix
; l
!= NULL
;
6478 if (plen
!= l
->cidrnet
.bits
)
6480 if (memcmp(iaprefix
.data
+ 9,
6481 l
->cidrnet
.lo_addr
.iabuf
,
6485 if ((l
!= NULL
) && (iaprefix
.len
>= 17))
6488 host
= host
->n_ipaddr
;
6491 if ((host
== NULL
) && (iaprefix
.len
>= IAPREFIX_OFFSET
)) {
6493 * Find existing IA_PD.
6495 if (ia_make_key(&key
, iaid
,
6496 (char *)client_id
->data
,
6498 MDL
) != ISC_R_SUCCESS
) {
6499 log_fatal("iterate_over_ia_pd: no memory for "
6503 existing_ia_pd
= NULL
;
6504 if (ia_hash_lookup(&existing_ia_pd
, ia_pd_active
,
6505 (unsigned char *)key
.data
,
6508 * Make sure this prefix is in the IA_PD.
6511 i
< existing_ia_pd
->num_iasubopt
;
6513 struct iasubopt
*tmp
;
6516 plen
= getUChar(iaprefix
.data
+ 8);
6517 tmp
= existing_ia_pd
->iasubopt
[i
];
6518 if ((tmp
->plen
== plen
) &&
6522 iasubopt_reference(&prefix
,
6529 data_string_forget(&key
, MDL
);
6532 if ((host
!= NULL
) || (prefix
!= NULL
)) {
6533 ia_pd_match(client_id
, &iaprefix
, prefix
);
6535 ia_pd_nomatch(client_id
, &iaprefix
,
6536 (u_int32_t
*)cli_enc_opt_data
.data
,
6537 packet
, reply_data
, &reply_ofs
,
6538 reply_len
- reply_ofs
);
6541 if (prefix
!= NULL
) {
6542 iasubopt_dereference(&prefix
, MDL
);
6545 data_string_forget(&iaprefix
, MDL
);
6548 option_state_dereference(&cli_enc_opt_state
, MDL
);
6549 data_string_forget(&cli_enc_opt_data
, MDL
);
6553 * Return our reply to the caller.
6554 * The IA_NA routine has already filled at least the header.
6556 reply_new
.len
= reply_ret
->len
+ reply_ofs
;
6557 if (!buffer_allocate(&reply_new
.buffer
, reply_new
.len
, MDL
)) {
6558 log_fatal("No memory to store reply.");
6560 reply_new
.data
= reply_new
.buffer
->data
;
6561 memcpy(reply_new
.buffer
->data
,
6562 reply_ret
->buffer
->data
, reply_ret
->len
);
6563 memcpy(reply_new
.buffer
->data
+ reply_ret
->len
,
6564 reply_data
, reply_ofs
);
6565 data_string_forget(reply_ret
, MDL
);
6566 data_string_copy(reply_ret
, &reply_new
, MDL
);
6567 data_string_forget(&reply_new
, MDL
);
6570 if (prefix
!= NULL
) {
6571 iasubopt_dereference(&prefix
, MDL
);
6573 if (iaprefix
.buffer
!= NULL
) {
6574 data_string_forget(&iaprefix
, MDL
);
6576 if (cli_enc_opt_state
!= NULL
) {
6577 option_state_dereference(&cli_enc_opt_state
, MDL
);
6579 if (cli_enc_opt_data
.buffer
!= NULL
) {
6580 data_string_forget(&cli_enc_opt_data
, MDL
);
6582 if (opt_state
!= NULL
) {
6583 option_state_dereference(&opt_state
, MDL
);
6588 * Release means a client is done with the leases.
6592 dhcpv6_release(struct data_string
*reply
, struct packet
*packet
) {
6593 struct data_string client_id
;
6594 struct data_string server_id
;
6597 * Validate our input.
6599 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
6603 /* If the RELEASE arrived via unicast and unicast option isn't set,
6604 * reject it per RFC 3315, Sec 18.2.6 */
6605 if (packet
->unicast
== ISC_TRUE
&&
6606 is_unicast_option_defined(packet
) == ISC_FALSE
) {
6607 unicast_reject(reply
, packet
, &client_id
, &server_id
);
6610 * And operate on each IA_NA in this packet.
6612 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
6613 "Release", ia_na_match_release
,
6614 ia_na_nomatch_release
);
6617 * And operate on each IA_PD in this packet.
6619 iterate_over_ia_pd(reply
, packet
, &client_id
, &server_id
,
6620 "Release", ia_pd_match_release
,
6621 ia_pd_nomatch_release
);
6624 data_string_forget(&server_id
, MDL
);
6625 data_string_forget(&client_id
, MDL
);
6629 * Information-Request is used by clients who have obtained an address
6630 * from other means, but want configuration information from the server.
6634 dhcpv6_information_request(struct data_string
*reply
, struct packet
*packet
) {
6635 struct data_string client_id
;
6636 struct data_string server_id
;
6639 * Validate our input.
6641 if (!valid_client_info_req(packet
, &server_id
)) {
6646 * Get our client ID, if there is one.
6648 memset(&client_id
, 0, sizeof(client_id
));
6649 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
) {
6650 data_string_forget(&client_id
, MDL
);
6654 * Use the lease_to_client() function. This will work fine,
6655 * because the valid_client_info_req() insures that we
6656 * don't have any IA that would cause us to allocate
6657 * resources to the client.
6659 lease_to_client(reply
, packet
, &client_id
,
6660 server_id
.data
!= NULL
? &server_id
: NULL
);
6665 if (client_id
.data
!= NULL
) {
6666 data_string_forget(&client_id
, MDL
);
6668 data_string_forget(&server_id
, MDL
);
6672 * The Relay-forw message is sent by relays. It typically contains a
6673 * single option, which encapsulates an entire packet.
6675 * We need to build an encapsulated reply.
6678 /* XXX: this is very, very similar to do_packet6(), and should probably
6679 be combined in a clever way */
6680 /* DHCPv6 server side */
6682 dhcpv6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
6683 struct option_cache
*oc
;
6684 struct data_string enc_opt_data
;
6685 struct packet
*enc_packet
;
6686 unsigned char msg_type
;
6687 const struct dhcpv6_packet
*msg
;
6688 const struct dhcpv6_relay_packet
*relay
;
6689 struct data_string enc_reply
;
6690 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6691 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6692 struct data_string a_opt
, packet_ero
;
6693 struct option_state
*opt_state
;
6694 static char reply_data
[65536];
6695 struct dhcpv6_relay_packet
*reply
;
6699 * Initialize variables for early exit.
6702 memset(&a_opt
, 0, sizeof(a_opt
));
6703 memset(&packet_ero
, 0, sizeof(packet_ero
));
6704 memset(&enc_reply
, 0, sizeof(enc_reply
));
6705 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6709 * Get our encapsulated relay message.
6711 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
6713 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
6714 link_addr
, sizeof(link_addr
));
6715 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
6716 peer_addr
, sizeof(peer_addr
));
6717 log_info("Relay-forward from %s with link address=%s and "
6718 "peer address=%s missing Relay Message option.",
6719 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
6723 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
6724 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
6725 /* should be dhcpv6_relay_forw */
6726 log_error("dhcpv6_forw_relay: error evaluating "
6727 "relayed message.");
6731 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
6732 /* should be dhcpv6_relay_forw */
6733 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
6738 * Build a packet structure from this encapsulated packet.
6741 if (!packet_allocate(&enc_packet
, MDL
)) {
6742 /* should be dhcpv6_relay_forw */
6743 log_error("dhcpv6_forw_relay: "
6744 "no memory for encapsulated packet.");
6748 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
6749 /* should be dhcpv6_relay_forw */
6750 log_error("dhcpv6_forw_relay: "
6751 "no memory for encapsulated packet's options.");
6755 enc_packet
->client_port
= packet
->client_port
;
6756 enc_packet
->client_addr
= packet
->client_addr
;
6757 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
6758 enc_packet
->dhcpv6_container_packet
= packet
;
6760 msg_type
= enc_opt_data
.data
[0];
6761 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
6762 (msg_type
== DHCPV6_RELAY_REPL
)) {
6763 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6764 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
6765 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
6767 /* relay-specific data */
6768 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
6769 memcpy(&enc_packet
->dhcpv6_link_address
,
6770 relay
->link_address
, sizeof(relay
->link_address
));
6771 memcpy(&enc_packet
->dhcpv6_peer_address
,
6772 relay
->peer_address
, sizeof(relay
->peer_address
));
6774 if (!parse_option_buffer(enc_packet
->options
,
6776 enc_opt_data
.len
- relaylen
,
6777 &dhcpv6_universe
)) {
6778 /* no logging here, as parse_option_buffer() logs all
6779 cases where it fails */
6782 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
6783 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6785 if (!dhcpv4_over_dhcpv6
||
6786 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6787 log_error("dhcpv6_relay_forw: "
6788 "unsupported %s message type.",
6789 dhcpv6_type_names
[msg_type
]);
6792 forw_dhcpv4_query(packet
);
6795 log_error("dhcpv6_relay_forw: unsupported %s message type.",
6796 dhcpv6_type_names
[msg_type
]);
6798 #endif /* DHCP4o6 */
6800 int msglen
= (int)(offsetof(struct dhcpv6_packet
, options
));
6801 msg
= (struct dhcpv6_packet
*)enc_opt_data
.data
;
6802 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
6804 /* message-specific data */
6805 memcpy(enc_packet
->dhcpv6_transaction_id
,
6806 msg
->transaction_id
,
6807 sizeof(enc_packet
->dhcpv6_transaction_id
));
6809 if (!parse_option_buffer(enc_packet
->options
,
6811 enc_opt_data
.len
- msglen
,
6812 &dhcpv6_universe
)) {
6813 /* no logging here, as parse_option_buffer() logs all
6814 cases where it fails */
6820 * This is recursive. It is possible to exceed maximum packet size.
6821 * XXX: This will cause the packet send to fail.
6823 build_dhcpv6_reply(&enc_reply
, enc_packet
);
6826 * If we got no encapsulated data, then it is discarded, and
6827 * our reply-forw is also discarded.
6829 if (enc_reply
.data
== NULL
) {
6834 * Now we can use the reply_data buffer.
6835 * Packet header stuff all comes from the forward message.
6837 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
6838 reply
->msg_type
= DHCPV6_RELAY_REPL
;
6839 reply
->hop_count
= packet
->dhcpv6_hop_count
;
6840 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
6841 sizeof(reply
->link_address
));
6842 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
6843 sizeof(reply
->peer_address
));
6844 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6847 * Get the reply option state.
6850 if (!option_state_allocate(&opt_state
, MDL
)) {
6851 log_error("dhcpv6_relay_forw: no memory for option state.");
6856 * Append the interface-id if present.
6858 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6861 if (!evaluate_option_cache(&a_opt
, packet
,
6863 packet
->options
, NULL
,
6864 &global_scope
, oc
, MDL
)) {
6865 log_error("dhcpv6_relay_forw: error evaluating "
6869 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6870 (unsigned char *)a_opt
.data
,
6872 D6O_INTERFACE_ID
, 0)) {
6873 log_error("dhcpv6_relay_forw: error saving "
6877 data_string_forget(&a_opt
, MDL
);
6880 #if defined(RELAY_PORT)
6882 * Append the relay_source_port option if present.
6884 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6885 D6O_RELAY_SOURCE_PORT
);
6887 if (!evaluate_option_cache(&a_opt
, packet
,
6889 packet
->options
, NULL
,
6890 &global_scope
, oc
, MDL
)) {
6891 log_error("dhcpv6_relay_forw: error evaluating "
6892 "Relay Source Port.");
6895 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6896 (unsigned char *)a_opt
.data
,
6898 D6O_RELAY_SOURCE_PORT
, 0)) {
6899 log_error("dhcpv6_relay_forw: error saving "
6900 "Relay Source Port.");
6903 data_string_forget(&a_opt
, MDL
);
6905 packet
->relay_source_port
= ISC_TRUE
;
6910 * Append our encapsulated stuff for caller.
6912 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6913 (unsigned char *)enc_reply
.data
,
6915 D6O_RELAY_MSG
, 0)) {
6916 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
6921 * Get the ERO if any.
6923 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
6928 if (!evaluate_option_cache(&packet_ero
, packet
,
6930 packet
->options
, NULL
,
6931 &global_scope
, oc
, MDL
) ||
6932 (packet_ero
.len
& 1)) {
6933 log_error("dhcpv6_relay_forw: error evaluating ERO.");
6937 /* Decode and apply the ERO. */
6938 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
6939 req
= getUShort(packet_ero
.data
+ i
);
6940 /* Already in the reply? */
6941 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
6944 /* Get it from the packet if present. */
6945 oc
= lookup_option(&dhcpv6_universe
,
6950 if (!evaluate_option_cache(&a_opt
, packet
,
6952 packet
->options
, NULL
,
6953 &global_scope
, oc
, MDL
)) {
6954 log_error("dhcpv6_relay_forw: error "
6955 "evaluating option %u.", req
);
6958 if (!save_option_buffer(&dhcpv6_universe
,
6961 (unsigned char *)a_opt
.data
,
6965 log_error("dhcpv6_relay_forw: error saving "
6969 data_string_forget(&a_opt
, MDL
);
6973 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
6974 sizeof(reply_data
) - reply_ofs
,
6976 required_opts_agent
, &packet_ero
);
6979 * Return our reply to the caller.
6981 reply_ret
->len
= reply_ofs
;
6982 reply_ret
->buffer
= NULL
;
6983 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
6984 log_fatal("No memory to store reply.");
6986 reply_ret
->data
= reply_ret
->buffer
->data
;
6987 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
6990 if (opt_state
!= NULL
)
6991 option_state_dereference(&opt_state
, MDL
);
6992 if (a_opt
.data
!= NULL
) {
6993 data_string_forget(&a_opt
, MDL
);
6995 if (packet_ero
.data
!= NULL
) {
6996 data_string_forget(&packet_ero
, MDL
);
6998 if (enc_reply
.data
!= NULL
) {
6999 data_string_forget(&enc_reply
, MDL
);
7001 if (enc_opt_data
.data
!= NULL
) {
7002 data_string_forget(&enc_opt_data
, MDL
);
7004 if (enc_packet
!= NULL
) {
7005 packet_dereference(&enc_packet
, MDL
);
7010 /* \brief Internal processing of a relayed DHCPv4-query
7011 * (DHCPv4 server side)
7013 * Code copied from \ref dhcpv6_relay_forw() which itself is
7014 * from \ref do_packet6().
7016 * \param reply_ret pointer to the response
7017 * \param packet the query
7020 dhcp4o6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
7021 struct option_cache
*oc
;
7022 struct data_string enc_opt_data
;
7023 struct packet
*enc_packet
;
7024 unsigned char msg_type
;
7025 const struct dhcpv6_relay_packet
*relay
;
7026 const struct dhcpv4_over_dhcpv6_packet
*msg
;
7027 struct data_string enc_reply
;
7028 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
7029 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
7030 struct data_string a_opt
, packet_ero
;
7031 struct option_state
*opt_state
;
7032 static char reply_data
[65536];
7033 struct dhcpv6_relay_packet
*reply
;
7037 * Initialize variables for early exit.
7040 memset(&a_opt
, 0, sizeof(a_opt
));
7041 memset(&packet_ero
, 0, sizeof(packet_ero
));
7042 memset(&enc_reply
, 0, sizeof(enc_reply
));
7043 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
7047 * Get our encapsulated relay message.
7049 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
7051 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
7052 link_addr
, sizeof(link_addr
));
7053 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
7054 peer_addr
, sizeof(peer_addr
));
7055 log_info("Relay-forward from %s with link address=%s and "
7056 "peer address=%s missing Relay Message option.",
7057 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
7061 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
7062 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
7063 log_error("dhcp4o6_relay_forw: error evaluating "
7064 "relayed message.");
7068 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
7069 log_error("dhcp4o6_relay_forw: "
7070 "encapsulated packet too short.");
7075 * Build a packet structure from this encapsulated packet.
7077 if (!packet_allocate(&enc_packet
, MDL
)) {
7078 log_error("dhcp4o6_relay_forw: "
7079 "no memory for encapsulated packet.");
7083 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
7084 log_error("dhcp4o6_relay_forw: "
7085 "no memory for encapsulated packet's options.");
7089 enc_packet
->client_port
= packet
->client_port
;
7090 enc_packet
->client_addr
= packet
->client_addr
;
7091 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
7092 enc_packet
->dhcpv6_container_packet
= packet
;
7094 msg_type
= enc_opt_data
.data
[0];
7095 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
7096 (msg_type
== DHCPV6_RELAY_REPL
)) {
7097 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
7098 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
7099 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
7101 /* relay-specific data */
7102 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
7103 memcpy(&enc_packet
->dhcpv6_link_address
,
7104 relay
->link_address
, sizeof(relay
->link_address
));
7105 memcpy(&enc_packet
->dhcpv6_peer_address
,
7106 relay
->peer_address
, sizeof(relay
->peer_address
));
7108 if (!parse_option_buffer(enc_packet
->options
,
7110 enc_opt_data
.len
- relaylen
,
7111 &dhcpv6_universe
)) {
7112 /* no logging here, as parse_option_buffer() logs all
7113 cases where it fails */
7116 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
7117 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
7119 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7120 msg
= (struct dhcpv4_over_dhcpv6_packet
*)enc_opt_data
.data
;
7121 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
7123 /* message-specific data */
7124 memcpy(enc_packet
->dhcp4o6_flags
,
7126 sizeof(enc_packet
->dhcp4o6_flags
));
7128 if (!parse_option_buffer(enc_packet
->options
,
7130 enc_opt_data
.len
- msglen
,
7131 &dhcpv6_universe
)) {
7132 /* no logging here, as parse_option_buffer() logs all
7133 cases where it fails */
7137 log_error("dhcp4o6_relay_forw: unexpected message of type %d.",
7143 * This is recursive. It is possible to exceed maximum packet size.
7144 * XXX: This will cause the packet send to fail.
7146 build_dhcpv6_reply(&enc_reply
, enc_packet
);
7149 * If we got no encapsulated data, then it is discarded, and
7150 * our reply-forw is also discarded.
7152 if (enc_reply
.data
== NULL
) {
7157 * Now we can use the reply_data buffer.
7158 * Packet header stuff all comes from the forward message.
7160 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
7161 reply
->msg_type
= DHCPV6_RELAY_REPL
;
7162 reply
->hop_count
= packet
->dhcpv6_hop_count
;
7163 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
7164 sizeof(reply
->link_address
));
7165 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
7166 sizeof(reply
->peer_address
));
7167 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
7170 * Get the reply option state.
7172 if (!option_state_allocate(&opt_state
, MDL
)) {
7173 log_error("dhcp4o6_relay_forw: no memory for option state.");
7178 * Append the interface-id if present.
7180 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
7183 if (!evaluate_option_cache(&a_opt
, packet
,
7185 packet
->options
, NULL
,
7186 &global_scope
, oc
, MDL
)) {
7187 log_error("dhcp4o6_relay_forw: error evaluating "
7191 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7192 (unsigned char *)a_opt
.data
,
7194 D6O_INTERFACE_ID
, 0)) {
7195 log_error("dhcp4o6_relay_forw: error saving "
7199 data_string_forget(&a_opt
, MDL
);
7202 #if defined(RELAY_PORT)
7204 * Append the relay_source_port option if present.
7206 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
7207 D6O_RELAY_SOURCE_PORT
);
7209 if (!evaluate_option_cache(&a_opt
, packet
,
7211 packet
->options
, NULL
,
7212 &global_scope
, oc
, MDL
)) {
7213 log_error("dhcpv4o6_relay_forw: error evaluating "
7214 "Relay Source Port.");
7217 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7218 (unsigned char *)a_opt
.data
,
7220 D6O_RELAY_SOURCE_PORT
, 0)) {
7221 log_error("dhcpv4o6_relay_forw: error saving "
7222 "Relay Source Port.");
7225 data_string_forget(&a_opt
, MDL
);
7227 packet
->relay_source_port
= ISC_TRUE
;
7232 * Append our encapsulated stuff for caller.
7234 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7235 (unsigned char *)enc_reply
.data
,
7237 D6O_RELAY_MSG
, 0)) {
7238 log_error("dhcp4o6_relay_forw: error saving Relay MSG.");
7243 * Get the ERO if any.
7245 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
7250 if (!evaluate_option_cache(&packet_ero
, packet
,
7252 packet
->options
, NULL
,
7253 &global_scope
, oc
, MDL
) ||
7254 (packet_ero
.len
& 1)) {
7255 log_error("dhcp4o6_relay_forw: error evaluating ERO.");
7259 /* Decode and apply the ERO. */
7260 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
7261 req
= getUShort(packet_ero
.data
+ i
);
7262 /* Already in the reply? */
7263 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
7266 /* Get it from the packet if present. */
7267 oc
= lookup_option(&dhcpv6_universe
,
7272 if (!evaluate_option_cache(&a_opt
, packet
,
7274 packet
->options
, NULL
,
7275 &global_scope
, oc
, MDL
)) {
7276 log_error("dhcp4o6_relay_forw: error "
7277 "evaluating option %u.", req
);
7280 if (!save_option_buffer(&dhcpv6_universe
,
7283 (unsigned char *)a_opt
.data
,
7287 log_error("dhcp4o6_relay_forw: error saving "
7291 data_string_forget(&a_opt
, MDL
);
7295 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
7296 sizeof(reply_data
) - reply_ofs
,
7298 required_opts_agent
, &packet_ero
);
7301 * Return our reply to the caller.
7303 reply_ret
->len
= reply_ofs
;
7304 reply_ret
->buffer
= NULL
;
7305 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
7306 log_fatal("No memory to store reply.");
7308 reply_ret
->data
= reply_ret
->buffer
->data
;
7309 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
7312 if (opt_state
!= NULL
)
7313 option_state_dereference(&opt_state
, MDL
);
7314 if (a_opt
.data
!= NULL
) {
7315 data_string_forget(&a_opt
, MDL
);
7317 if (packet_ero
.data
!= NULL
) {
7318 data_string_forget(&packet_ero
, MDL
);
7320 if (enc_reply
.data
!= NULL
) {
7321 data_string_forget(&enc_reply
, MDL
);
7323 if (enc_opt_data
.data
!= NULL
) {
7324 data_string_forget(&enc_opt_data
, MDL
);
7326 if (enc_packet
!= NULL
) {
7327 packet_dereference(&enc_packet
, MDL
);
7332 * \brief Internal processing of a DHCPv4-query
7333 * (DHCPv4 server function)
7335 * Code copied from \ref do_packet().
7337 * \param reply_ret pointer to the response
7338 * \param packet the query
7341 dhcp4o6_dhcpv4_query(struct data_string
*reply_ret
, struct packet
*packet
) {
7342 struct option_cache
*oc
;
7343 struct data_string enc_opt_data
;
7344 struct packet
*enc_packet
;
7345 struct data_string enc_response
;
7346 struct option_state
*opt_state
;
7347 static char response_data
[65536];
7348 struct dhcpv4_over_dhcpv6_packet
*response
;
7352 * Initialize variables for early exit.
7355 memset(&enc_response
, 0, sizeof(enc_response
));
7356 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
7360 * Get our encapsulated relay message.
7362 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_DHCPV4_MSG
);
7364 log_info("DHCPv4-query from %s missing DHCPv4 Message option.",
7365 piaddr(packet
->client_addr
));
7369 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
7370 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
7371 log_error("dhcp4o6_dhcpv4_query: error evaluating "
7376 if (enc_opt_data
.len
< DHCP_FIXED_NON_UDP
) {
7377 log_error("dhcp4o6_dhcpv4_query: DHCPv4 packet too short.");
7382 * Build a packet structure from this encapsulated packet.
7384 if (!packet_allocate(&enc_packet
, MDL
)) {
7385 log_error("dhcp4o6_dhcpv4_query: "
7386 "no memory for encapsulated packet.");
7390 enc_packet
->raw
= (struct dhcp_packet
*)enc_opt_data
.data
;
7391 enc_packet
->packet_length
= enc_opt_data
.len
;
7392 enc_packet
->dhcp4o6_response
= &enc_response
;
7393 enc_packet
->client_port
= packet
->client_port
;
7394 enc_packet
->client_addr
= packet
->client_addr
;
7395 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
7396 enc_packet
->dhcpv6_container_packet
= packet
;
7397 if (packet
->dhcp4o6_flags
[0] & DHCP4O6_QUERY_UNICAST
)
7398 enc_packet
->unicast
= 1;
7400 if (enc_packet
->raw
->hlen
> sizeof(enc_packet
->raw
->chaddr
)) {
7401 log_info("dhcp4o6_dhcpv4_query: "
7402 "discarding packet with bogus hlen.");
7406 /* Allocate packet->options now so it is non-null for all packets */
7407 if (!option_state_allocate (&enc_packet
->options
, MDL
)) {
7408 log_error("dhcp4o6_dhcpv4_query: no memory for options.");
7412 /* If there's an option buffer, try to parse it. */
7413 if (enc_packet
->packet_length
>= DHCP_FIXED_NON_UDP
+ 4) {
7414 struct option_cache
*op
;
7415 if (!parse_options(enc_packet
)) {
7416 if (enc_packet
->options
)
7417 option_state_dereference
7418 (&enc_packet
->options
, MDL
);
7419 packet_dereference (&enc_packet
, MDL
);
7423 if (enc_packet
->options_valid
&&
7424 (op
= lookup_option(&dhcp_universe
,
7425 enc_packet
->options
,
7426 DHO_DHCP_MESSAGE_TYPE
))) {
7427 struct data_string dp
;
7428 memset(&dp
, 0, sizeof dp
);
7429 evaluate_option_cache(&dp
, enc_packet
, NULL
, NULL
,
7430 enc_packet
->options
, NULL
,
7433 enc_packet
->packet_type
= dp
.data
[0];
7435 enc_packet
->packet_type
= 0;
7436 data_string_forget(&dp
, MDL
);
7440 if (validate_packet(enc_packet
) != 0) {
7441 if (enc_packet
->packet_type
)
7447 /* If the caller kept the packet, they'll have upped the refcnt. */
7448 packet_dereference(&enc_packet
, MDL
);
7451 * If we got no response data, then it is discarded, and
7452 * our DHCPv4-response is also discarded.
7454 if (enc_response
.data
== NULL
) {
7459 * Now we can use the response_data buffer.
7461 response
= (struct dhcpv4_over_dhcpv6_packet
*)response_data
;
7462 response
->msg_type
= DHCPV6_DHCPV4_RESPONSE
;
7463 response
->flags
[0] = response
->flags
[1] = response
->flags
[2] = 0;
7465 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7468 * Get the response option state.
7470 if (!option_state_allocate(&opt_state
, MDL
)) {
7471 log_error("dhcp4o6_dhcpv4_query: no memory for option state.");
7476 * Append our encapsulated stuff for caller.
7478 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7479 (unsigned char *)enc_response
.data
,
7481 D6O_DHCPV4_MSG
, 0)) {
7482 log_error("dhcp4o6_dhcpv4_query: error saving DHCPv4 MSG.");
7486 response_ofs
+= store_options6(response_data
+ response_ofs
,
7487 sizeof(response_data
) - response_ofs
,
7489 required_opts_4o6
, NULL
);
7492 * Return our response to the caller.
7494 reply_ret
->len
= response_ofs
;
7495 reply_ret
->buffer
= NULL
;
7496 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
7497 log_fatal("dhcp4o6_dhcpv4_query: no memory to store reply.");
7499 reply_ret
->data
= reply_ret
->buffer
->data
;
7500 memcpy(reply_ret
->buffer
->data
, response_data
, response_ofs
);
7503 if (opt_state
!= NULL
)
7504 option_state_dereference(&opt_state
, MDL
);
7505 if (enc_response
.data
!= NULL
) {
7506 data_string_forget(&enc_response
, MDL
);
7508 if (enc_opt_data
.data
!= NULL
) {
7509 data_string_forget(&enc_opt_data
, MDL
);
7511 if (enc_packet
!= NULL
) {
7512 packet_dereference(&enc_packet
, MDL
);
7517 * \brief Forward a DHCPv4-query message to the DHCPv4 side
7518 * (DHCPv6 server function)
7520 * Format: interface:16 + address:16 + udp:4 + DHCPv6 DHCPv4-query message
7522 * \brief packet the DHCPv6 DHCPv4-query message
7524 static void forw_dhcpv4_query(struct packet
*packet
) {
7525 struct data_string ds
;
7526 struct udp_data4o6 udp_data
;
7530 /* Get the initial message. */
7531 while (packet
->dhcpv6_container_packet
!= NULL
)
7532 packet
= packet
->dhcpv6_container_packet
;
7534 /* Check the initial message. */
7535 if ((packet
->raw
== NULL
) ||
7536 (packet
->client_addr
.len
!= 16) ||
7537 (packet
->interface
== NULL
)) {
7538 log_error("forw_dhcpv4_query: can't find initial message.");
7543 len
= packet
->packet_length
+ 36;
7544 memset(&ds
, 0, sizeof(ds
));
7545 if (!buffer_allocate(&ds
.buffer
, len
, MDL
)) {
7546 log_error("forw_dhcpv4_query: "
7547 "no memory for encapsulating packet.");
7550 ds
.data
= ds
.buffer
->data
;
7553 /* Fill the buffer. */
7554 strncpy((char *)ds
.buffer
->data
, packet
->interface
->name
, 16);
7555 memcpy(ds
.buffer
->data
+ 16,
7556 packet
->client_addr
.iabuf
, 16);
7557 memset(&udp_data
, 0, sizeof(udp_data
));
7558 udp_data
.src_port
= packet
->client_port
;
7559 memcpy(ds
.buffer
->data
+ 32, &udp_data
, 4);
7560 memcpy(ds
.buffer
->data
+ 36,
7561 (unsigned char *)packet
->raw
,
7562 packet
->packet_length
);
7564 /* Forward to the DHCPv4 server. */
7565 cc
= send(dhcp4o6_fd
, ds
.data
, ds
.len
, 0);
7567 log_error("forw_dhcpv4_query: send(): %m");
7568 data_string_forget(&ds
, MDL
);
7573 dhcpv6_discard(struct packet
*packet
) {
7574 /* INSIST(packet->msg_type > 0); */
7575 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
7577 log_debug("Discarding %s from %s; message type not handled by server",
7578 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7579 piaddr(packet
->client_addr
));
7583 build_dhcpv6_reply(struct data_string
*reply
, struct packet
*packet
) {
7584 memset(reply
, 0, sizeof(*reply
));
7586 /* I would like to classify the client once here, but
7587 * as I don't want to classify all of the incoming packets
7588 * I need to do it before handling specific types.
7589 * We don't need to classify if we are tossing the packet
7590 * or if it is a relay - the classification step will get
7591 * done when we process the inner client packet.
7594 switch (packet
->dhcpv6_msg_type
) {
7595 case DHCPV6_SOLICIT
:
7596 classify_client(packet
);
7597 dhcpv6_solicit(reply
, packet
);
7599 case DHCPV6_ADVERTISE
:
7600 dhcpv6_discard(packet
);
7602 case DHCPV6_REQUEST
:
7603 classify_client(packet
);
7604 dhcpv6_request(reply
, packet
);
7606 case DHCPV6_CONFIRM
:
7607 classify_client(packet
);
7608 dhcpv6_confirm(reply
, packet
);
7611 classify_client(packet
);
7612 dhcpv6_renew(reply
, packet
);
7615 classify_client(packet
);
7616 dhcpv6_rebind(reply
, packet
);
7619 dhcpv6_discard(packet
);
7621 case DHCPV6_RELEASE
:
7622 classify_client(packet
);
7623 dhcpv6_release(reply
, packet
);
7625 case DHCPV6_DECLINE
:
7626 classify_client(packet
);
7627 dhcpv6_decline(reply
, packet
);
7629 case DHCPV6_RECONFIGURE
:
7630 dhcpv6_discard(packet
);
7632 case DHCPV6_INFORMATION_REQUEST
:
7633 classify_client(packet
);
7634 dhcpv6_information_request(reply
, packet
);
7636 case DHCPV6_RELAY_FORW
:
7638 if (dhcpv4_over_dhcpv6
&& (local_family
== AF_INET
))
7639 dhcp4o6_relay_forw(reply
, packet
);
7641 #endif /* DHCP4o6 */
7642 dhcpv6_relay_forw(reply
, packet
);
7644 case DHCPV6_RELAY_REPL
:
7645 dhcpv6_discard(packet
);
7647 case DHCPV6_LEASEQUERY
:
7648 classify_client(packet
);
7649 dhcpv6_leasequery(reply
, packet
);
7651 case DHCPV6_LEASEQUERY_REPLY
:
7652 dhcpv6_discard(packet
);
7654 case DHCPV6_DHCPV4_QUERY
:
7656 if (dhcpv4_over_dhcpv6
) {
7657 if (local_family
== AF_INET6
) {
7658 forw_dhcpv4_query(packet
);
7660 dhcp4o6_dhcpv4_query(reply
, packet
);
7663 #endif /* DHCP4o6 */
7664 dhcpv6_discard(packet
);
7666 case DHCPV6_DHCPV4_RESPONSE
:
7667 dhcpv6_discard(packet
);
7670 /* XXX: would be nice if we had "notice" level,
7671 as syslog, for this */
7672 log_info("Discarding unknown DHCPv6 message type %d "
7673 "from %s", packet
->dhcpv6_msg_type
,
7674 piaddr(packet
->client_addr
));
7679 log_packet_in(const struct packet
*packet
) {
7680 struct data_string s
;
7682 char tmp_addr
[INET6_ADDRSTRLEN
];
7685 memset(&s
, 0, sizeof(s
));
7687 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
7688 data_string_sprintfa(&s
, "%s message from %s port %d",
7689 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7690 piaddr(packet
->client_addr
),
7691 ntohs(packet
->client_port
));
7693 data_string_sprintfa(&s
,
7694 "Unknown message type %d from %s port %d",
7695 packet
->dhcpv6_msg_type
,
7696 piaddr(packet
->client_addr
),
7697 ntohs(packet
->client_port
));
7699 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7700 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7701 addr
= &packet
->dhcpv6_link_address
;
7702 data_string_sprintfa(&s
, ", link address %s",
7703 inet_ntop(AF_INET6
, addr
,
7704 tmp_addr
, sizeof(tmp_addr
)));
7705 addr
= &packet
->dhcpv6_peer_address
;
7706 data_string_sprintfa(&s
, ", peer address %s",
7707 inet_ntop(AF_INET6
, addr
,
7708 tmp_addr
, sizeof(tmp_addr
)));
7709 } else if ((packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_QUERY
) &&
7710 (packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_RESPONSE
)) {
7712 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
7713 data_string_sprintfa(&s
, ", transaction ID 0x%06X", tid
);
7716 oc = lookup_option(&dhcpv6_universe, packet->options,
7719 memset(&tmp_ds, 0, sizeof(tmp_ds_));
7720 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
7721 packet->options, NULL,
7722 &global_scope, oc, MDL)) {
7723 log_error("Error evaluating Client Identifier");
7725 data_strint_sprintf(&s, ", client ID %s",
7727 data_string_forget(&tmp_ds, MDL);
7733 log_info("%s", s
.data
);
7735 data_string_forget(&s
, MDL
);
7739 dhcpv6(struct packet
*packet
) {
7740 struct data_string reply
;
7741 struct sockaddr_in6 to_addr
;
7745 * Log a message that we received this packet.
7747 log_packet_in(packet
);
7750 * Build our reply packet.
7752 build_dhcpv6_reply(&reply
, packet
);
7754 if (reply
.data
!= NULL
) {
7756 * Send our reply, if we have one.
7758 memset(&to_addr
, 0, sizeof(to_addr
));
7759 to_addr
.sin6_family
= AF_INET6
;
7760 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7761 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7762 to_addr
.sin6_port
= local_port
;
7764 to_addr
.sin6_port
= remote_port
;
7767 #if defined (REPLY_TO_SOURCE_PORT)
7769 * This appears to have been included for testing so we would
7770 * not need a root client, but was accidently left in the
7771 * final code. We continue to include it in case
7772 * some users have come to rely upon it, but leave
7773 * it off by default as it's a bad idea.
7775 to_addr
.sin6_port
= packet
->client_port
;
7778 #if defined(RELAY_PORT)
7780 * Check relay source port.
7782 if (packet
->relay_source_port
) {
7783 to_addr
.sin6_port
= packet
->client_port
;
7787 memcpy(&to_addr
.sin6_addr
, packet
->client_addr
.iabuf
,
7788 sizeof(to_addr
.sin6_addr
));
7790 log_info("Sending %s to %s port %d",
7791 dhcpv6_type_names
[reply
.data
[0]],
7792 piaddr(packet
->client_addr
),
7793 ntohs(to_addr
.sin6_port
));
7795 send_ret
= send_packet6(packet
->interface
,
7796 reply
.data
, reply
.len
, &to_addr
);
7797 if (send_ret
!= reply
.len
) {
7798 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
7799 send_ret
, reply
.len
);
7801 data_string_forget(&reply
, MDL
);
7807 * \brief Receive a DHCPv4-query message from the DHCPv6 side
7808 * (DHCPv4 server function)
7810 * Receive a message with a DHCPv4-query inside from the DHCPv6 server.
7811 * (code copied from \ref do_packet6() \ref and dhcpv6())
7813 * Format: interface:16 + address:16 + udp:4 + DHCPv6 DHCPv4-query message
7815 * \param raw the DHCPv6 DHCPv4-query message raw content
7817 static void recv_dhcpv4_query(struct data_string
*raw
) {
7818 struct interface_info
*ip
;
7821 struct packet
*packet
;
7822 unsigned char msg_type
;
7823 const struct dhcpv6_relay_packet
*relay
;
7824 const struct dhcpv4_over_dhcpv6_packet
*msg
;
7825 struct data_string reply
;
7826 struct data_string ds
;
7827 struct udp_data4o6 udp_data
;
7831 memset(name
, 0, sizeof(name
));
7832 memcpy(name
, raw
->data
, 16);
7833 for (ip
= interfaces
; ip
!= NULL
; ip
= ip
->next
) {
7834 if (!strcmp(name
, ip
->name
))
7838 log_error("recv_dhcpv4_query: can't find interface %s.",
7844 memcpy(iaddr
.iabuf
, raw
->data
+ 16, 16);
7846 memset(&udp_data
, 0, sizeof(udp_data
));
7847 memcpy(&udp_data
, raw
->data
+ 32, 4);
7850 * From do_packet6().
7853 if (!packet6_len_okay((char *)raw
->data
+ 36, raw
->len
- 36)) {
7854 log_error("recv_dhcpv4_query: "
7855 "short packet from %s, len %d, dropped",
7856 piaddr(iaddr
), raw
->len
- 36);
7861 * Build a packet structure.
7864 if (!packet_allocate(&packet
, MDL
)) {
7865 log_error("recv_dhcpv4_query: no memory for packet.");
7869 if (!option_state_allocate(&packet
->options
, MDL
)) {
7870 log_error("recv_dhcpv4_query: no memory for options.");
7871 packet_dereference(&packet
, MDL
);
7875 packet
->raw
= (struct dhcp_packet
*)(raw
->data
+ 36);
7876 packet
->packet_length
= raw
->len
- 36;
7877 packet
->client_port
= udp_data
.src_port
;
7878 packet
->client_addr
= iaddr
;
7879 interface_reference(&packet
->interface
, ip
, MDL
);
7881 msg_type
= raw
->data
[36];
7882 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
7883 (msg_type
== DHCPV6_RELAY_REPL
)) {
7885 (int)(offsetof(struct dhcpv6_relay_packet
, options
));
7886 relay
= (const struct dhcpv6_relay_packet
*)(raw
->data
+ 36);
7887 packet
->dhcpv6_msg_type
= relay
->msg_type
;
7889 /* relay-specific data */
7890 packet
->dhcpv6_hop_count
= relay
->hop_count
;
7891 memcpy(&packet
->dhcpv6_link_address
,
7892 relay
->link_address
, sizeof(relay
->link_address
));
7893 memcpy(&packet
->dhcpv6_peer_address
,
7894 relay
->peer_address
, sizeof(relay
->peer_address
));
7896 if (!parse_option_buffer(packet
->options
,
7898 raw
->len
- 36 - relaylen
,
7899 &dhcpv6_universe
)) {
7900 /* no logging here, as parse_option_buffer() logs all
7901 cases where it fails */
7902 packet_dereference(&packet
, MDL
);
7905 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
7906 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
7908 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7909 msg
= (struct dhcpv4_over_dhcpv6_packet
*)(raw
->data
+ 36);
7910 packet
->dhcpv6_msg_type
= msg
->msg_type
;
7912 /* message-specific data */
7913 memcpy(packet
->dhcp4o6_flags
, msg
->flags
,
7914 sizeof(packet
->dhcp4o6_flags
));
7916 if (!parse_option_buffer(packet
->options
,
7918 raw
->len
- 36 - msglen
,
7919 &dhcpv6_universe
)) {
7920 /* no logging here, as parse_option_buffer() logs all
7921 cases where it fails */
7922 packet_dereference(&packet
, MDL
);
7926 log_error("recv_dhcpv4_query: unexpected message of type %d.",
7928 packet_dereference(&packet
, MDL
);
7937 * Log a message that we received this packet.
7939 /* log_packet_in(packet); */
7940 memset(&ds
, 0, sizeof(ds
));
7941 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
7942 data_string_sprintfa(&ds
, "%s message from %s",
7943 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7944 piaddr(packet
->client_addr
));
7946 data_string_sprintfa(&ds
,
7947 "Unknown message type %d from %s",
7948 packet
->dhcpv6_msg_type
,
7949 piaddr(packet
->client_addr
));
7951 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7952 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7953 char tmp_addr
[INET6_ADDRSTRLEN
];
7956 addr
= &packet
->dhcpv6_link_address
;
7957 data_string_sprintfa(&ds
, ", link address %s",
7958 inet_ntop(AF_INET6
, addr
,
7959 tmp_addr
, sizeof(tmp_addr
)));
7960 addr
= &packet
->dhcpv6_peer_address
;
7961 data_string_sprintfa(&ds
, ", peer address %s",
7962 inet_ntop(AF_INET6
, addr
,
7963 tmp_addr
, sizeof(tmp_addr
)));
7964 } else if ((packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_QUERY
) &&
7965 (packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_RESPONSE
)) {
7968 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
7969 data_string_sprintfa(&ds
, ", transaction ID 0x%06X", tid
);
7971 log_info("%s", ds
.data
);
7972 data_string_forget(&ds
, MDL
);
7975 * Build our reply packet.
7977 build_dhcpv6_reply(&reply
, packet
);
7979 if (reply
.data
== NULL
) {
7980 packet_dereference(&packet
, MDL
);
7985 * Forward the response.
7987 len
= reply
.len
+ 36;
7988 memset(&ds
, 0, sizeof(ds
));
7989 if (!buffer_allocate(&ds
.buffer
, len
, MDL
)) {
7990 log_error("recv_dhcpv4_query: no memory.");
7991 packet_dereference(&packet
, MDL
);
7994 ds
.data
= ds
.buffer
->data
;
7997 memcpy(ds
.buffer
->data
, name
, 16);
7998 memcpy(ds
.buffer
->data
+ 16, iaddr
.iabuf
, 16);
7999 udp_data
.rsp_opt_exist
= packet
->relay_source_port
? 1 : 0;
8000 memcpy(ds
.buffer
->data
+ 32, &udp_data
, 4);
8001 memcpy(ds
.buffer
->data
+ 36, reply
.data
, reply
.len
);
8004 * Now we can release the packet.
8006 packet_dereference(&packet
, MDL
);
8008 cc
= send(dhcp4o6_fd
, ds
.data
, ds
.len
, 0);
8010 log_error("recv_dhcpv4_query: send(): %m");
8011 data_string_forget(&ds
, MDL
);
8013 #endif /* DHCP4o6 */
8016 seek_shared_host(struct host_decl
**hp
, struct shared_network
*shared
) {
8017 struct host_decl
*nofixed
= NULL
;
8018 struct host_decl
*seek
, *hold
= NULL
;
8021 * Seek forward through fixed addresses for the right link.
8023 * Note: how to do this for fixed prefixes???
8025 host_reference(&hold
, *hp
, MDL
);
8026 host_dereference(hp
, MDL
);
8028 while (seek
!= NULL
) {
8029 if (seek
->fixed_addr
== NULL
)
8031 else if (fixed_matches_shared(seek
, shared
))
8034 seek
= seek
->n_ipaddr
;
8037 if ((seek
== NULL
) && (nofixed
!= NULL
))
8041 host_reference(hp
, seek
, MDL
);
8044 static isc_boolean_t
8045 fixed_matches_shared(struct host_decl
*host
, struct shared_network
*shared
) {
8046 struct subnet
*subnet
;
8047 struct data_string addr
;
8048 isc_boolean_t matched
;
8051 if (host
->fixed_addr
== NULL
)
8054 memset(&addr
, 0, sizeof(addr
));
8055 if (!evaluate_option_cache(&addr
, NULL
, NULL
, NULL
, NULL
, NULL
,
8056 &global_scope
, host
->fixed_addr
, MDL
))
8059 if (addr
.len
< 16) {
8060 data_string_forget(&addr
, MDL
);
8065 memcpy(fixed
.iabuf
, addr
.data
, 16);
8067 matched
= ISC_FALSE
;
8068 for (subnet
= shared
->subnets
; subnet
!= NULL
;
8069 subnet
= subnet
->next_sibling
) {
8070 if (addr_eq(subnet_number(fixed
, subnet
->netmask
),
8077 data_string_forget(&addr
, MDL
);
8083 * \brief Constructs a REPLY with status of UseMulticast to a given packet
8085 * Per RFC 3315 Secs 18.2.1,3,6 & 7, when a server rejects a client's
8086 * unicast-sent packet, the response must only contain the client id,
8087 * server id, and a status code option of 5 (UseMulticast). This function
8088 * constructs such a packet and returns it as a data_string.
8090 * \param reply_ret = data_string which will receive the newly constructed
8092 * \param packet = client request which is being rejected
8093 * \param client_id = data_string which contains the client id
8094 * \param server_id = data_string which which contains the server id
8098 unicast_reject(struct data_string
*reply_ret
,
8099 struct packet
*packet
,
8100 const struct data_string
*client_id
,
8101 const struct data_string
*server_id
)
8103 struct reply_state reply
;
8104 memset(&reply
, 0x0, sizeof(struct reply_state
));
8106 /* Locate the client. */
8107 if (shared_network_from_packet6(&reply
.shared
, packet
)
8109 log_error("unicast_reject: could not locate client.");
8113 /* Initialize the reply. */
8114 packet_reference(&reply
.packet
, packet
, MDL
);
8115 data_string_copy(&reply
.client_id
, client_id
, MDL
);
8117 if (start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
8118 &reply
.buf
.reply
)) {
8119 /* Set the UseMulticast status code. */
8120 if (!set_status_code(STATUS_UseMulticast
,
8121 "Unicast not allowed by server.",
8123 log_error("unicast_reject: Unable to set status code.");
8125 /* Set write cursor to just past the reply header. */
8126 reply
.cursor
= REPLY_OPTIONS_INDEX
;
8127 reply
.cursor
+= store_options6(((char *)reply
.buf
.data
8133 unicast_reject_opts
,
8136 /* Return our reply to the caller. */
8137 reply_ret
->len
= reply
.cursor
;
8138 reply_ret
->buffer
= NULL
;
8139 if (!buffer_allocate(&reply_ret
->buffer
,
8140 reply
.cursor
, MDL
)) {
8141 log_fatal("unicast_reject:"
8142 "No memory to store Reply.");
8145 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
,
8147 reply_ret
->data
= reply_ret
->buffer
->data
;
8153 if (reply
.shared
!= NULL
)
8154 shared_network_dereference(&reply
.shared
, MDL
);
8155 if (reply
.opt_state
!= NULL
)
8156 option_state_dereference(&reply
.opt_state
, MDL
);
8157 if (reply
.packet
!= NULL
)
8158 packet_dereference(&reply
.packet
, MDL
);
8159 if (reply
.client_id
.data
!= NULL
)
8160 data_string_forget(&reply
.client_id
, MDL
);
8165 * \brief Checks if the dhcp6.unicast option has been defined
8167 * Scans the option space for the presence of the dhcp6.unicast option. The
8168 * function attempts to map the inbound packet to a shared network first
8169 * by an ip address specified via an D6O_IA_XX option and if that fails then
8170 * by the packet's source information (e.g. relay link, link, or interace).
8171 * Once the packet is mapped to a shared network, the function executes all
8172 * statements from the network's group outward into a local option cache.
8173 * The option cache is then scanned for the presence of unicast option. If
8174 * the packet cannot be mapped to a shared network, the function returns
8176 * \param packet inbound packet from the client
8178 * \return ISC_TRUE if the dhcp6.unicast option is defined, false otherwise.
8182 is_unicast_option_defined(struct packet
*packet
) {
8183 isc_boolean_t is_defined
= ISC_FALSE
;
8184 struct option_state
*opt_state
= NULL
;
8185 struct option_cache
*oc
= NULL
;
8186 struct shared_network
*shared
= NULL
;
8188 if (!option_state_allocate(&opt_state
, MDL
)) {
8189 log_fatal("is_unicast_option_defined:"
8190 "No memory for option state.");
8193 /* We try to map the packet to a network first by an IA_XX value.
8194 * If that fails, we try by packet source. */
8195 if (((shared_network_from_requested_addr(&shared
, packet
)
8196 != ISC_R_SUCCESS
) &&
8197 (shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
))
8198 || (shared
== NULL
)) {
8199 /* @todo what would this really mean? I think wrong network
8200 * logic will catch it */
8201 log_error("is_unicast_option_defined:"
8202 "cannot attribute packet to a network.");
8206 /* Now that we've mapped it to a network, execute statments to that
8207 * scope, looking for the unicast option. We don't care about the
8208 * value of the option, only whether or not it is defined. */
8209 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
, opt_state
,
8210 &global_scope
, shared
->group
, NULL
, NULL
);
8212 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_UNICAST
);
8213 is_defined
= (oc
!= NULL
? ISC_TRUE
: ISC_FALSE
);
8214 log_debug("is_unicast_option_defined: option found : %d", is_defined
);
8216 if (shared
!= NULL
) {
8217 shared_network_dereference(&shared
, MDL
);
8220 if (opt_state
!= NULL
) {
8221 option_state_dereference(&opt_state
, MDL
);
8224 return (is_defined
);
8229 * \brief Maps a packet to a shared network based on the requested IP address
8231 * The function attempts to find a subnet that matches the first requested IP
8232 * address contained within the given packet. Note that it looks first for
8233 * D6O_IA_NAs, then D6O_IA_PDs and lastly D6O_IA_TAs. If a matching network is
8234 * found, a reference to it is returned in the parameter, shared.
8236 * \param shared shared_network pointer which will receive the matching network
8237 * \param packet inbound packet from the client
8239 * \return ISC_R_SUCCESS if the packet can be mapped to a shared_network.
8243 shared_network_from_requested_addr (struct shared_network
**shared
,
8244 struct packet
* packet
) {
8246 struct subnet
* subnet
= NULL
;
8247 isc_result_t status
= ISC_R_FAILURE
;
8249 /* Try to match first IA_ address or prefix we find to a subnet. In
8250 * theory all IA_ values in a given request are supposed to be in the
8251 * same subnet so we only need to try one right? */
8252 if ((get_first_ia_addr_val(packet
, D6O_IA_NA
, &iaddr
) != ISC_R_SUCCESS
)
8253 && (get_first_ia_addr_val(packet
, D6O_IA_PD
, &iaddr
)
8255 && (get_first_ia_addr_val(packet
, D6O_IA_TA
, &iaddr
)
8256 != ISC_R_SUCCESS
)) {
8257 /* we found nothing to match against */
8258 log_debug("share_network_from_request_addr: nothing to match");
8259 return (ISC_R_FAILURE
);
8262 if (!find_subnet(&subnet
, iaddr
, MDL
)) {
8263 log_debug("shared_network_from_requested_addr:"
8264 "No subnet found for addr %s.", piaddr(iaddr
));
8266 status
= shared_network_reference(shared
,
8267 subnet
->shared_network
, MDL
);
8268 subnet_dereference(&subnet
, MDL
);
8269 log_debug("shared_network_from_requested_addr:"
8270 " found shared network %s for address %s.",
8271 ((*shared
)->name
? (*shared
)->name
: "unnamed"),
8276 return (ISC_R_FAILURE
);
8281 * \brief Retrieves the first IP address from a given packet of a given type
8283 * Search a packet for options of a given type (D6O_IA_AN, D6O_IA_PD, or
8284 * D6O_IA_TA) for the first non-blank IA_XX value and return its IP address
8287 * \param packet packet received from the client
8288 * \param addr_type the address option type (D6O_IA_NA , D6O_IA_PD, or
8289 * D6O_IP_TA) to look for within the packet.
8290 * \param iaddr pointer to the iaddr structure which will receive the extracted
8293 * \return ISC_R_SUCCESS if an address was succesfully extracted, ISC_R_FALURE
8298 get_first_ia_addr_val (struct packet
* packet
, int addr_type
,
8299 struct iaddr
* iaddr
) {
8300 struct option_cache
*ia
;
8301 struct option_cache
*oc
= NULL
;
8302 struct data_string cli_enc_opt_data
;
8303 struct option_state
*cli_enc_opt_state
;
8304 int addr_opt_offset
;
8306 int addr_opt_data_len
;
8309 isc_result_t status
= ISC_R_FAILURE
;
8310 memset(iaddr
, 0, sizeof(struct iaddr
));
8312 /* Set up address type specifics */
8313 switch (addr_type
) {
8315 addr_opt_offset
= IA_NA_OFFSET
;
8316 addr_opt
= D6O_IAADDR
;
8317 addr_opt_data_len
= 24;
8321 addr_opt_offset
= IA_TA_OFFSET
;
8322 addr_opt
= D6O_IAADDR
;
8323 addr_opt_data_len
= 24;
8327 addr_opt_offset
= IA_PD_OFFSET
;
8328 addr_opt
= D6O_IAPREFIX
;
8329 addr_opt_data_len
= 25;
8333 /* shouldn't be here */
8334 log_error ("get_first_ia_addr_val: invalid opt type %d",
8336 return (ISC_R_FAILURE
);
8339 /* Find the first, non-blank IA_XX value within an D6O_IA_XX option. */
8340 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, addr_type
);
8341 ia
!= NULL
&& oc
== NULL
; ia
= ia
->next
) {
8342 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
8344 packet
, ia
, addr_opt_offset
)) {
8345 log_debug ("get_first_ia_addr_val:"
8346 " couldn't unroll enclosing option");
8347 return (ISC_R_FAILURE
);
8350 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
8353 /* no address given for this IA, ignore */
8354 option_state_dereference(&cli_enc_opt_state
, MDL
);
8355 data_string_forget(&cli_enc_opt_data
, MDL
);
8359 /* If we found a non-blank IA_XX then extract its ip address. */
8361 struct data_string iaddr_str
;
8363 memset(&iaddr_str
, 0, sizeof(iaddr_str
));
8364 if (!evaluate_option_cache(&iaddr_str
, packet
, NULL
, NULL
,
8365 packet
->options
, NULL
, &global_scope
,
8367 log_error("get_first_ia_addr_val: "
8368 "error evaluating IA_XX option.");
8370 if (iaddr_str
.len
!= addr_opt_data_len
) {
8371 log_error("shared_network_from_requested_addr:"
8372 " invalid length %d, expected %d",
8373 iaddr_str
.len
, addr_opt_data_len
);
8376 memcpy (iaddr
->iabuf
,
8377 iaddr_str
.data
+ ip_addr_offset
, 16);
8378 status
= ISC_R_SUCCESS
;
8380 data_string_forget(&iaddr_str
, MDL
);
8383 option_state_dereference(&cli_enc_opt_state
, MDL
);
8384 data_string_forget(&cli_enc_opt_data
, MDL
);
8391 * \brief Calculates the reply T1/T2 times and stuffs them in outbound buffer
8393 * T1/T2 time selection is kind of weird. We actually use DHCP * (v4) scoped
8394 * options, dhcp-renewal-time and dhcp-rebinding-time, as handy existing places
8395 * where these can be configured by an administrator. A value of zero tells the
8396 * client it may choose its own value.
8398 * When those options are not defined, the values will be set to zero unless
8399 * the global option, dhcpv6-set-tee-times is enabled. When this option is
8400 * enabled the values are calculated as recommended by RFC 3315, Section 22.4:
8402 * T1 will be set to 0.5 times the shortest preferred lifetime
8403 * in the IA_XX option. If the "shortest" preferred lifetime is
8404 * 0xFFFFFFFF, T1 will set to 0xFFFFFFFF.
8406 * T2 will be set to 0.8 times the shortest preferred lifetime
8407 * in the IA_XX option. If the "shortest" preferred lifetime is
8408 * 0xFFFFFFFF, T2 will set to 0xFFFFFFFF.
8410 * Note that dhcpv6-set-tee-times is intended to be transitional and will
8411 * likely be removed in 4.4.0, leaving the behavior as getting the values
8412 * either from the configured parameters (if you want zeros, define them as
8413 * zeros) or by calculating them per the RFC.
8415 * \param reply - pointer to the reply_state structure
8416 * \param ia_cursor - offset of the beginning of the IA_XX option within the
8417 * reply's outbound data buffer
8420 set_reply_tee_times(struct reply_state
* reply
, unsigned ia_cursor
)
8422 struct option_cache
*oc
;
8425 /* Found out if calculated values are enabled. */
8426 oc
= lookup_option(&server_universe
, reply
->opt_state
,
8427 SV_DHCPV6_SET_TEE_TIMES
);
8428 set_tee_times
= (oc
&&
8429 evaluate_boolean_option_cache(NULL
, reply
->packet
,
8431 reply
->packet
->options
,
8433 &global_scope
, oc
, MDL
));
8435 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
8436 DHO_DHCP_RENEWAL_TIME
);
8438 /* dhcp-renewal-time is defined, use it */
8439 struct data_string data
;
8440 memset(&data
, 0x00, sizeof(data
));
8442 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
8443 reply
->packet
->options
,
8444 reply
->opt_state
, &global_scope
,
8447 log_error("Invalid renewal time.");
8450 reply
->renew
= getULong(data
.data
);
8453 if (data
.data
!= NULL
)
8454 data_string_forget(&data
, MDL
);
8455 } else if (set_tee_times
) {
8456 /* Setting them is enabled so T1 is either infinite or
8457 * 0.5 * the shortest preferred lifetime in the IA_XX */
8458 if (reply
->min_prefer
== INFINITE_TIME
)
8459 reply
->renew
= INFINITE_TIME
;
8461 reply
->renew
= reply
->min_prefer
/ 2;
8463 /* Default is to let the client choose */
8467 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
8470 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
8471 DHO_DHCP_REBINDING_TIME
);
8473 /* dhcp-rebinding-time is defined, use it */
8474 struct data_string data
;
8475 memset(&data
, 0x00, sizeof(data
));
8477 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
8478 reply
->packet
->options
,
8479 reply
->opt_state
, &global_scope
,
8482 log_error("Invalid rebinding time.");
8485 reply
->rebind
= getULong(data
.data
);
8488 if (data
.data
!= NULL
)
8489 data_string_forget(&data
, MDL
);
8490 } else if (set_tee_times
) {
8491 /* Setting them is enabled so T2 is either infinite or
8492 * 0.8 * the shortest preferred lifetime in the reply */
8493 if (reply
->min_prefer
== INFINITE_TIME
)
8494 reply
->rebind
= INFINITE_TIME
;
8496 reply
->rebind
= (reply
->min_prefer
/ 5) * 4;
8498 /* Default is to let the client choose */
8502 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
8506 * Releases the iasubopts in the pre-existing IA, if they are not in
8507 * the same shared-network as the new IA.
8509 * returns 1 if the release was done, 0 otherwise
8512 release_on_roam(struct reply_state
* reply
) {
8513 struct ia_xx
* old_ia
= reply
->old_ia
;
8514 struct iasubopt
*lease
= NULL
;
8517 if ((!do_release_on_roam
) || old_ia
== NULL
8518 || old_ia
->num_iasubopt
<= 0) {
8522 /* If the old shared-network and new are the same, client hasn't
8523 * roamed, nothing to do. We only check the first one because you
8524 * cannot have iasubopts on different shared-networks within a
8526 lease
= old_ia
->iasubopt
[0];
8527 if (lease
->ipv6_pool
->shared_network
== reply
->shared
) {
8531 /* Old and new are on different shared networks so the client must
8532 * roamed. Release the old leases. */
8533 for (i
= 0; i
< old_ia
->num_iasubopt
; i
++) {
8534 lease
= old_ia
->iasubopt
[i
];
8536 log_info("Client: %s roamed to new network,"
8537 " releasing lease: %s%s",
8538 print_hex_1(reply
->client_id
.len
,
8539 reply
->client_id
.data
, 60),
8540 pin6_addr(&lease
->addr
), iasubopt_plen_str(lease
));
8542 release_lease6(lease
->ipv6_pool
, lease
);
8543 lease
->ia
->cltt
= cur_time
;
8544 write_ia(lease
->ia
);
8551 * Convenience function which returns a string (static buffer)
8552 * containing either a "/" followed by the prefix length or an
8553 * empty string depending on the lease type
8555 const char *iasubopt_plen_str(struct iasubopt
*lease
) {
8556 static char prefix_buf
[16];
8558 if ((lease
->ia
) && (lease
->ia
->ia_type
== D6O_IA_PD
)) {
8559 sprintf(prefix_buf
, "/%-d", lease
->plen
);
8562 return (prefix_buf
);
8567 * Initiates DDNS updates for static v6 leases if configured to do so.
8569 * The function, which must be called after the IA has been written to the
8570 * packet, adds an iasubopt to the IA for static lease. This is done so we
8571 * have an iasubopt to pass into ddns_updates(). A reference to the IA is
8572 * added to the DDNS control block to ensure it and it's iasubopt remain in
8573 * scope until the update is complete.
8576 void ddns_update_static6(struct reply_state
* reply
) {
8577 struct iasubopt
*iasub
= NULL
;
8578 struct binding_scope
*scope
= NULL
;
8579 struct option_cache
*oc
= NULL
;
8581 oc
= lookup_option(&server_universe
, reply
->opt_state
, SV_DDNS_UPDATES
);
8583 (evaluate_boolean_option_cache(NULL
, reply
->packet
, NULL
, NULL
,
8584 reply
->packet
->options
,
8585 reply
->opt_state
, NULL
,
8590 oc
= lookup_option(&server_universe
, reply
->opt_state
,
8591 SV_UPDATE_STATIC_LEASES
);
8593 (evaluate_boolean_option_cache(NULL
, reply
->packet
,
8595 reply
->packet
->options
,
8596 reply
->opt_state
, NULL
,
8601 if (iasubopt_allocate(&iasub
, MDL
) != ISC_R_SUCCESS
) {
8602 log_fatal("No memory for iasubopt.");
8605 if (ia_add_iasubopt(reply
->ia
, iasub
, MDL
) != ISC_R_SUCCESS
) {
8606 log_fatal("Could not add iasubopt.");
8609 ia_reference(&iasub
->ia
, reply
->ia
, MDL
);
8611 memcpy(iasub
->addr
.s6_addr
, reply
->fixed
.data
, 16);
8613 iasub
->prefer
= MAX_TIME
;
8614 iasub
->valid
= MAX_TIME
;
8615 iasub
->static_lease
= 1;
8617 if (!binding_scope_allocate(&scope
, MDL
)) {
8618 log_fatal("Out of memory for binding scope.");
8621 binding_scope_reference(&iasub
->scope
, scope
, MDL
);
8623 ddns_updates(reply
->packet
, NULL
, NULL
, iasub
, NULL
, reply
->opt_state
);
8625 #endif /* NSUPDATE */