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
)),
1042 /* find the high threshold */
1043 if (get_option_int(&poolhigh
, &server_universe
, reply
->packet
, NULL
,
1044 NULL
, reply
->packet
->options
, reply
->opt_state
,
1045 reply
->opt_state
, &lease
->scope
,
1046 SV_LOG_THRESHOLD_HIGH
, MDL
) == 0) {
1047 /* no threshold bail out */
1051 /* We do have a threshold for this pool, see if its valid */
1052 if ((poolhigh
<= 0) || (poolhigh
> 100)) {
1057 /* we have a valid value, have we exceeded it */
1058 high_threshold
= FIND_POND6_PERCENT(count
, poolhigh
);
1059 if (used
< high_threshold
) {
1060 /* nope, no more to do */
1064 /* we've exceeded it, output a message */
1065 log_error("Pool threshold exceeded - shared subnet: %s; "
1066 "address: %s; high threshold %d%% %llu/%llu.",
1068 inet_ntop(AF_INET6
, &lease
->addr
, tmp_addr
, sizeof(tmp_addr
)),
1069 poolhigh
, used
, count
);
1071 /* handle the low threshold now, if we don't
1072 * have one we default to 0. */
1073 if ((get_option_int(&poollow
, &server_universe
, reply
->packet
, NULL
,
1074 NULL
, reply
->packet
->options
, reply
->opt_state
,
1075 reply
->opt_state
, &lease
->scope
,
1076 SV_LOG_THRESHOLD_LOW
, MDL
) == 0) ||
1082 * If the low theshold is higher than the high threshold we continue to log
1083 * If it isn't then we set the flag saying we already logged and determine
1084 * what the reset threshold is.
1086 if (poollow
< poolhigh
) {
1088 pond
->low_threshold
= FIND_POND6_PERCENT(count
, poollow
);
1093 * We have a set of operations we do to set up the reply packet, which
1094 * is the same for many message types.
1097 start_reply(struct packet
*packet
,
1098 const struct data_string
*client_id
,
1099 const struct data_string
*server_id
,
1100 struct option_state
**opt_state
,
1101 struct dhcpv6_packet
*reply
)
1103 struct option_cache
*oc
;
1104 const unsigned char *server_id_data
;
1108 * Build our option state for reply.
1111 if (!option_state_allocate(opt_state
, MDL
)) {
1112 log_error("start_reply: no memory for option_state.");
1115 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1116 packet
->options
, *opt_state
,
1117 &global_scope
, root_group
, NULL
, NULL
);
1120 * A small bit of special handling for Solicit messages.
1122 * We could move the logic into a flag, but for now just check
1125 if (packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
1126 reply
->msg_type
= DHCPV6_ADVERTISE
;
1130 * - this message type supports rapid commit (Solicit), and
1131 * - the server is configured to supply a rapid commit, and
1132 * - the client requests a rapid commit,
1133 * Then we add a rapid commit option, and send Reply (instead
1136 oc
= lookup_option(&dhcpv6_universe
,
1137 *opt_state
, D6O_RAPID_COMMIT
);
1139 oc
= lookup_option(&dhcpv6_universe
,
1140 packet
->options
, D6O_RAPID_COMMIT
);
1142 /* Rapid-commit in action. */
1143 reply
->msg_type
= DHCPV6_REPLY
;
1145 /* Don't want a rapid-commit in advertise. */
1146 delete_option(&dhcpv6_universe
,
1147 *opt_state
, D6O_RAPID_COMMIT
);
1151 reply
->msg_type
= DHCPV6_REPLY
;
1152 /* Delete the rapid-commit from the sent options. */
1153 oc
= lookup_option(&dhcpv6_universe
,
1154 *opt_state
, D6O_RAPID_COMMIT
);
1156 delete_option(&dhcpv6_universe
,
1157 *opt_state
, D6O_RAPID_COMMIT
);
1162 * Use the client's transaction identifier for the reply.
1164 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
1165 sizeof(reply
->transaction_id
));
1168 * RFC 3315, section 18.2 says we need server identifier and
1169 * client identifier.
1171 * If the server ID is defined via the configuration file, then
1172 * it will already be present in the option state at this point,
1173 * so we don't need to set it.
1175 * If we have a server ID passed in from the caller,
1176 * use that, otherwise use the global DUID.
1178 oc
= lookup_option(&dhcpv6_universe
, *opt_state
, D6O_SERVERID
);
1180 if (server_id
== NULL
) {
1181 server_id_data
= server_duid
.data
;
1182 server_id_len
= server_duid
.len
;
1184 server_id_data
= server_id
->data
;
1185 server_id_len
= server_id
->len
;
1187 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1188 NULL
, (unsigned char *)server_id_data
,
1189 server_id_len
, D6O_SERVERID
, 0)) {
1190 log_error("start_reply: "
1191 "error saving server identifier.");
1196 if (client_id
->buffer
!= NULL
) {
1197 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1199 (unsigned char *)client_id
->data
,
1202 log_error("start_reply: error saving "
1203 "client identifier.");
1209 * If the client accepts reconfiguration, let it know that we
1212 * Note: we don't actually do this yet, but DOCSIS requires we
1215 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
1218 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1219 NULL
, (unsigned char *)"", 0,
1220 D6O_RECONF_ACCEPT
, 0)) {
1221 log_error("start_reply: "
1222 "error saving RECONF_ACCEPT option.");
1223 option_state_dereference(opt_state
, MDL
);
1232 * Try to get the IPv6 address the client asked for from the
1235 * addr is the result (should be a pointer to NULL on entry)
1236 * pool is the pool to search in
1237 * requested_addr is the address the client wants
1240 try_client_v6_address(struct iasubopt
**addr
,
1241 struct ipv6_pool
*pool
,
1242 const struct data_string
*requested_addr
)
1244 struct in6_addr tmp_addr
;
1245 isc_result_t result
;
1247 if (requested_addr
->len
< sizeof(tmp_addr
)) {
1248 return DHCP_R_INVALIDARG
;
1250 memcpy(&tmp_addr
, requested_addr
->data
, sizeof(tmp_addr
));
1251 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
)) {
1252 return ISC_R_FAILURE
;
1256 * The address is not covered by this (or possibly any) dynamic
1259 if (!ipv6_in_pool(&tmp_addr
, pool
)) {
1260 return ISC_R_ADDRNOTAVAIL
;
1263 if (lease6_exists(pool
, &tmp_addr
)) {
1264 return ISC_R_ADDRINUSE
;
1267 result
= iasubopt_allocate(addr
, MDL
);
1268 if (result
!= ISC_R_SUCCESS
) {
1271 (*addr
)->addr
= tmp_addr
;
1274 /* Default is soft binding for 2 minutes. */
1275 result
= add_lease6(pool
, *addr
, cur_time
+ 120);
1276 if (result
!= ISC_R_SUCCESS
) {
1277 iasubopt_dereference(addr
, MDL
);
1284 * \brief Get an IPv6 address for the client.
1286 * Attempt to find a usable address for the client. We walk through
1287 * the ponds checking for permit and deny then through the pools
1288 * seeing if they have an available address.
1290 * \param reply = the state structure for the current work on this request
1291 * if we create a lease we return it using reply->lease
1294 * ISC_R_SUCCESS = we were able to find an address and are returning a
1295 * pointer to the lease
1296 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1297 * is probabalistic. We don't exhaustively try the
1298 * address range, instead we hash the duid and if
1299 * the address derived from the hash is in use we
1300 * hash the address. After a number of failures we
1301 * conclude the pool is basically full.
1304 pick_v6_address(struct reply_state
*reply
)
1306 struct ipv6_pool
*p
= NULL
;
1307 struct ipv6_pond
*pond
;
1310 unsigned int attempts
;
1311 char tmp_buf
[INET6_ADDRSTRLEN
];
1312 struct iasubopt
**addr
= &reply
->lease
;
1313 isc_uint64_t total
= 0;
1314 isc_uint64_t active
= 0;
1315 isc_uint64_t abandoned
= 0;
1316 int jumbo_range
= 0;
1317 char *shared_name
= (reply
->shared
->name
?
1318 reply
->shared
->name
: "(no name)");
1321 * Do a quick walk through of the ponds and pools
1322 * to see if we have any NA address pools
1324 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1325 if (pond
->ipv6_pools
== NULL
)
1328 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1329 if (p
->pool_type
== D6O_IA_NA
)
1336 /* If we get here and p is NULL we have no useful pools */
1338 log_debug("Unable to pick client address: "
1339 "no IPv6 pools on this shared network");
1340 return ISC_R_NORESOURCES
;
1344 * We have at least one pool that could provide an address
1345 * Now we walk through the ponds and pools again and check
1346 * to see if the client is permitted and if an address is
1349 * Within a given pond we start looking at the last pool we
1350 * allocated from, unless it had a collision trying to allocate
1351 * an address. This will tend to move us into less-filled pools.
1354 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1355 isc_result_t result
= ISC_R_FAILURE
;
1357 if (((pond
->prohibit_list
!= NULL
) &&
1358 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1359 ((pond
->permit_list
!= NULL
) &&
1360 (!permitted(reply
->packet
, pond
->permit_list
))))
1364 /* If pond is EUI-64 but client duid isn't a valid EUI-64
1365 * id, then skip this pond */
1366 if (pond
->use_eui_64
&&
1367 !valid_eui_64_duid(&reply
->ia
->iaid_duid
, IAID_LEN
)) {
1372 start_pool
= pond
->last_ipv6_pool
;
1375 p
= pond
->ipv6_pools
[i
];
1376 if (p
->pool_type
== D6O_IA_NA
) {
1378 if (pond
->use_eui_64
) {
1380 create_lease6_eui_64(p
, addr
,
1381 &reply
->ia
->iaid_duid
,
1388 create_lease6(p
, addr
, &attempts
,
1389 &reply
->ia
->iaid_duid
,
1394 if (result
== ISC_R_SUCCESS
) {
1396 * Record the pool used (or next one if
1397 * there was a collision).
1401 if (pond
->ipv6_pools
[i
]
1407 pond
->last_ipv6_pool
= i
;
1409 log_debug("Picking pool address %s",
1412 tmp_buf
, sizeof(tmp_buf
)));
1413 return (ISC_R_SUCCESS
);
1418 if (pond
->ipv6_pools
[i
] == NULL
) {
1421 } while (i
!= start_pool
);
1423 if (result
== ISC_R_NORESOURCES
) {
1424 jumbo_range
+= pond
->jumbo_range
;
1425 total
+= pond
->num_total
;
1426 active
+= pond
->num_active
;
1427 abandoned
+= pond
->num_abandoned
;
1432 * If we failed to pick an IPv6 address from any of the subnets.
1433 * Presumably that means we have no addresses for the client.
1435 if (jumbo_range
!= 0) {
1436 log_debug("Unable to pick client address: "
1437 "no addresses available - shared network %s: "
1438 " 2^64-1 < total, %llu active, %llu abandoned",
1439 shared_name
, active
- abandoned
, abandoned
);
1441 log_debug("Unable to pick client address: "
1442 "no addresses available - shared network %s: "
1443 "%llu total, %llu active, %llu abandoned",
1444 shared_name
, total
, active
- abandoned
, abandoned
);
1447 return ISC_R_NORESOURCES
;
1451 * Try to get the IPv6 prefix the client asked for from the
1454 * pref is the result (should be a pointer to NULL on entry)
1455 * pool is the prefix pool to search in
1456 * requested_pref is the address the client wants
1459 try_client_v6_prefix(struct iasubopt
**pref
,
1460 struct ipv6_pool
*pool
,
1461 const struct data_string
*requested_pref
)
1464 struct in6_addr tmp_pref
;
1466 isc_result_t result
;
1468 if (requested_pref
->len
< sizeof(tmp_plen
) + sizeof(tmp_pref
)) {
1469 return DHCP_R_INVALIDARG
;
1472 tmp_plen
= (int) requested_pref
->data
[0];
1473 if ((tmp_plen
< 3) || (tmp_plen
> 128)) {
1474 return ISC_R_FAILURE
;
1477 memcpy(&tmp_pref
, requested_pref
->data
+ 1, sizeof(tmp_pref
));
1478 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref
)) {
1479 return ISC_R_FAILURE
;
1483 memcpy(&ia
.iabuf
, &tmp_pref
, 16);
1484 if (!is_cidr_mask_valid(&ia
, (int) tmp_plen
)) {
1485 return ISC_R_FAILURE
;
1488 if (!ipv6_in_pool(&tmp_pref
, pool
) ||
1489 ((int)tmp_plen
!= pool
->units
)) {
1490 return ISC_R_ADDRNOTAVAIL
;
1493 if (prefix6_exists(pool
, &tmp_pref
, tmp_plen
)) {
1494 return ISC_R_ADDRINUSE
;
1497 result
= iasubopt_allocate(pref
, MDL
);
1498 if (result
!= ISC_R_SUCCESS
) {
1502 (*pref
)->addr
= tmp_pref
;
1503 (*pref
)->plen
= tmp_plen
;
1505 /* Default is soft binding for 2 minutes. */
1506 result
= add_lease6(pool
, *pref
, cur_time
+ 120);
1507 if (result
!= ISC_R_SUCCESS
) {
1508 iasubopt_dereference(pref
, MDL
);
1516 * \brief Get an IPv6 prefix for the client.
1518 * Attempt to find a usable prefix for the client. Based upon the prefix
1519 * length mode and the plen supplied by the client (if one), we make one
1520 * or more calls to pick_v6_prefix_helper() to find a prefix as follows:
1522 * PLM_IGNORE or client specifies a plen of zero, use the first available
1523 * prefix regardless of it's length.
1525 * PLM_PREFER – look for an exact match to client's plen first, if none
1526 * found, use the first available prefix of any length
1528 * PLM_EXACT – look for an exact match first, if none found then fail. This
1529 * is the default behavior.
1531 * PLM_MAXIMUM - look for an exact match first, then the first available whose
1532 * prefix length is less than client's plen, otherwise fail.
1534 * PLM_MINIMUM - look for an exact match first, then the first available whose
1535 * prefix length is greater than client's plen, otherwise fail.
1537 * Note that the selection mode is configurable at the global scope only via
1540 * \param reply = the state structure for the current work on this request
1541 * if we create a lease we return it using reply->lease
1544 * ISC_R_SUCCESS = we were able to find an prefix and are returning a
1545 * pointer to the lease
1546 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1547 * is probabalistic. We don't exhaustively try the
1548 * address range, instead we hash the duid and if
1549 * the address derived from the hash is in use we
1550 * hash the address. After a number of failures we
1551 * conclude the pool is basically full.
1554 pick_v6_prefix(struct reply_state
*reply
) {
1555 struct ipv6_pool
*p
= NULL
;
1556 struct ipv6_pond
*pond
;
1558 isc_result_t result
;
1561 * Do a quick walk through of the ponds and pools
1562 * to see if we have any prefix pools
1564 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1565 if (pond
->ipv6_pools
== NULL
)
1568 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1569 if (p
->pool_type
== D6O_IA_PD
)
1576 /* If we get here and p is NULL we have no useful pools */
1578 log_debug("Unable to pick client prefix: "
1579 "no IPv6 pools on this shared network");
1580 return ISC_R_NORESOURCES
;
1583 if (reply
->preflen
<= 0) {
1584 /* If we didn't get a plen (-1) or client plen is 0, then just
1585 * select first available (same as PLM_INGORE) */
1586 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1588 switch (prefix_length_mode
) {
1590 /* First we look for an exact match, if not found
1591 * then first available */
1592 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1593 if (result
!= ISC_R_SUCCESS
) {
1594 result
= pick_v6_prefix_helper(reply
,
1600 /* Match exactly or fail */
1601 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1606 /* First we look for an exact match, if not found
1607 * then first available by mode */
1608 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1609 if (result
!= ISC_R_SUCCESS
) {
1610 result
= pick_v6_prefix_helper(reply
,
1611 prefix_length_mode
);
1616 /* First available */
1617 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1622 if (result
== ISC_R_SUCCESS
) {
1623 char tmp_buf
[INET6_ADDRSTRLEN
];
1625 log_debug("Picking pool prefix %s/%u",
1626 inet_ntop(AF_INET6
, &(reply
->lease
->addr
),
1627 tmp_buf
, sizeof(tmp_buf
)),
1628 (unsigned)(reply
->lease
->plen
));
1629 return (ISC_R_SUCCESS
);
1633 * If we failed to pick an IPv6 prefix
1634 * Presumably that means we have no prefixes for the client.
1636 log_debug("Unable to pick client prefix: no prefixes available");
1637 return ISC_R_NORESOURCES
;
1642 * \brief Get an IPv6 prefix for the client based upon selection mode.
1644 * We walk through the ponds checking for permit and deny. If a pond is
1645 * permissable to use, loop through its PD pools checking prefix lengths
1646 * against the client plen based on the prefix length mode, looking for
1647 * available prefixes.
1649 * \param reply = the state structure for the current work on this request
1650 * if we create a lease we return it using reply->lease
1651 * \prefix_mode = selection mode to use
1654 * ISC_R_SUCCESS = we were able to find a prefix and are returning a
1655 * pointer to the lease
1656 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1657 * is probabalistic. We don't exhaustively try the
1658 * address range, instead we hash the duid and if
1659 * the address derived from the hash is in use we
1660 * hash the address. After a number of failures we
1661 * conclude the pool is basically full.
1664 pick_v6_prefix_helper(struct reply_state
*reply
, int prefix_mode
) {
1665 struct ipv6_pool
*p
= NULL
;
1666 struct ipv6_pond
*pond
;
1668 unsigned int attempts
;
1669 struct iasubopt
**pref
= &reply
->lease
;
1671 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1672 if (((pond
->prohibit_list
!= NULL
) &&
1673 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1674 ((pond
->permit_list
!= NULL
) &&
1675 (!permitted(reply
->packet
, pond
->permit_list
))))
1678 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1679 if ((p
->pool_type
== D6O_IA_PD
) &&
1680 (eval_prefix_mode(p
->units
, reply
->preflen
,
1681 prefix_mode
) == 1) &&
1682 (create_prefix6(p
, pref
, &attempts
,
1683 &reply
->ia
->iaid_duid
,
1684 cur_time
+ 120) == ISC_R_SUCCESS
)) {
1685 return (ISC_R_SUCCESS
);
1690 return ISC_R_NORESOURCES
;
1695 * \brief Test a prefix length against another based on prefix length mode
1697 * \param len - prefix length to test
1698 * \param preflen - preferred prefix length against which to test
1699 * \param prefix_mode - prefix selection mode with which to test
1701 * Note that the case of preferred length of 0 is not short-cut here as it
1702 * is assumed to be done at a higher level.
1704 * \return 1 if the given length is usable based upon mode and a preferred
1708 eval_prefix_mode(int len
, int preflen
, int prefix_mode
) {
1710 switch (prefix_mode
) {
1712 use_it
= (len
== preflen
);
1715 /* they asked for a prefix length no "shorter" than preflen */
1716 use_it
= (len
>= preflen
);
1719 /* they asked for a prefix length no "longer" than preflen */
1720 use_it
= (len
<= preflen
);
1723 /* otherwise use it */
1731 *! \file server/dhcpv6.c
1733 * \brief construct a reply containing information about a client's lease
1735 * lease_to_client() is called from several messages to construct a
1736 * reply that contains all that we know about the client's correct lease
1737 * (or projected lease).
1739 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1740 * send what we "may" give them on a request.
1742 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1743 * the client should really use).
1745 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1746 * Rebind out any "wrong" addresses the client sends. This means we send
1747 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1748 * possibly send the address with zeroed lifetimes.
1750 * Information-Request - No binding.
1752 * The basic structure is to traverse the client-supplied data first, and
1753 * validate and echo back any contents that can be. If the client-supplied
1754 * data does not error out (on renew/rebind as above), but we did not send
1755 * any addresses, attempt to allocate one.
1757 * At the end of the this function we call commit_leases_timed() to
1758 * fsync and rotate the file as necessary. commit_leases_timed() will
1759 * check that we have written at least one lease to the file and that
1760 * some time has passed before doing any fsync or file rewrite so we
1761 * don't bother tracking if we did a write_ia during this function.
1763 /* TODO: look at client hints for lease times */
1766 lease_to_client(struct data_string
*reply_ret
,
1767 struct packet
*packet
,
1768 const struct data_string
*client_id
,
1769 const struct data_string
*server_id
)
1771 static struct reply_state reply
;
1772 struct option_cache
*oc
;
1773 struct data_string packet_oro
;
1776 memset(&packet_oro
, 0, sizeof(packet_oro
));
1778 /* Locate the client. */
1779 if (shared_network_from_packet6(&reply
.shared
,
1780 packet
) != ISC_R_SUCCESS
)
1784 * Initialize the reply.
1786 packet_reference(&reply
.packet
, packet
, MDL
);
1787 data_string_copy(&reply
.client_id
, client_id
, MDL
);
1789 if (!start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
1793 /* Set the write cursor to just past the reply header. */
1794 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1797 * Get the ORO from the packet, if any.
1799 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ORO
);
1801 if (!evaluate_option_cache(&packet_oro
, packet
,
1803 packet
->options
, NULL
,
1804 &global_scope
, oc
, MDL
)) {
1805 log_error("lease_to_client: error evaluating ORO.");
1811 * Find a host record that matches the packet, if any, and is
1812 * valid for the shared network the client is on.
1814 if (find_hosts6(&reply
.host
, packet
, client_id
, MDL
)) {
1816 seek_shared_host(&reply
.host
, reply
.shared
);
1819 /* Process the client supplied IA's onto the reply buffer. */
1821 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
1823 for (; oc
!= NULL
; oc
= oc
->next
) {
1824 isc_result_t status
;
1826 /* Start counting resources (addresses) offered. */
1827 reply
.client_resources
= 0;
1828 reply
.resources_included
= ISC_FALSE
;
1830 status
= reply_process_ia_na(&reply
, oc
);
1833 * We continue to try other IA's whether we can address
1834 * this one or not. Any other result is an immediate fail.
1836 if ((status
!= ISC_R_SUCCESS
) &&
1837 (status
!= ISC_R_NORESOURCES
))
1840 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
1841 for (; oc
!= NULL
; oc
= oc
->next
) {
1842 isc_result_t status
;
1844 /* Start counting resources (addresses) offered. */
1845 reply
.client_resources
= 0;
1846 reply
.resources_included
= ISC_FALSE
;
1848 status
= reply_process_ia_ta(&reply
, oc
);
1851 * We continue to try other IA's whether we can address
1852 * this one or not. Any other result is an immediate fail.
1854 if ((status
!= ISC_R_SUCCESS
) &&
1855 (status
!= ISC_R_NORESOURCES
))
1859 /* Same for IA_PD's. */
1861 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
1862 for (; oc
!= NULL
; oc
= oc
->next
) {
1863 isc_result_t status
;
1865 /* Start counting resources (prefixes) offered. */
1866 reply
.client_resources
= 0;
1867 reply
.resources_included
= ISC_FALSE
;
1869 status
= reply_process_ia_pd(&reply
, oc
);
1872 * We continue to try other IA_PD's whether we can address
1873 * this one or not. Any other result is an immediate fail.
1875 if ((status
!= ISC_R_SUCCESS
) &&
1876 (status
!= ISC_R_NORESOURCES
))
1881 * Make no reply if we gave no resources and is not
1882 * for Information-Request.
1884 if ((reply
.ia_count
== 0) && (reply
.pd_count
== 0)) {
1885 if (reply
.packet
->dhcpv6_msg_type
!=
1886 DHCPV6_INFORMATION_REQUEST
)
1890 * Because we only execute statements on a per-IA basis,
1891 * we need to execute statements in any non-IA reply to
1892 * source configuration.
1894 execute_statements_in_scope(NULL
, reply
.packet
, NULL
, NULL
,
1895 reply
.packet
->options
,
1896 reply
.opt_state
, &global_scope
,
1897 reply
.shared
->group
, root_group
,
1900 /* Execute statements from class scopes. */
1901 for (i
= reply
.packet
->class_count
; i
> 0; i
--) {
1902 execute_statements_in_scope(NULL
, reply
.packet
,
1904 reply
.packet
->options
,
1907 reply
.packet
->classes
[i
- 1]->group
,
1908 reply
.shared
->group
, NULL
);
1911 /* Bring in any configuration from a host record. */
1912 if (reply
.host
!= NULL
)
1913 execute_statements_in_scope(NULL
, reply
.packet
,
1915 reply
.packet
->options
,
1919 reply
.shared
->group
, NULL
);
1923 * RFC3315 section 17.2.2 (Solicit):
1925 * If the server will not assign any addresses to any IAs in a
1926 * subsequent Request from the client, the server MUST send an
1927 * Advertise message to the client that includes only a Status
1928 * Code option with code NoAddrsAvail and a status message for
1929 * the user, a Server Identifier option with the server's DUID,
1930 * and a Client Identifier option with the client's DUID.
1932 * This has been updated by an errata such that the server
1933 * can always send an IA.
1935 * Section 18.2.1 (Request):
1937 * If the server cannot assign any addresses to an IA in the
1938 * message from the client, the server MUST include the IA in
1939 * the Reply message with no addresses in the IA and a Status
1940 * Code option in the IA containing status code NoAddrsAvail.
1942 * Section 18.1.8 (Client Behavior):
1944 * Leave unchanged any information about addresses the client has
1945 * recorded in the IA but that were not included in the IA from
1947 * Sends a Renew/Rebind if the IA is not in the Reply message.
1951 * Having stored the client's IA's, store any options that
1952 * will fit in the remaining space.
1954 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+ reply
.cursor
,
1955 sizeof(reply
.buf
) - reply
.cursor
,
1956 reply
.opt_state
, reply
.packet
,
1957 required_opts_solicit
,
1960 /* Return our reply to the caller. */
1961 reply_ret
->len
= reply
.cursor
;
1962 reply_ret
->buffer
= NULL
;
1963 if (!buffer_allocate(&reply_ret
->buffer
, reply
.cursor
, MDL
)) {
1964 log_fatal("No memory to store Reply.");
1966 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
, reply
.cursor
);
1967 reply_ret
->data
= reply_ret
->buffer
->data
;
1969 /* If appropriate commit and rotate the lease file */
1970 (void) commit_leases_timed();
1974 if (reply
.shared
!= NULL
)
1975 shared_network_dereference(&reply
.shared
, MDL
);
1976 if (reply
.host
!= NULL
)
1977 host_dereference(&reply
.host
, MDL
);
1978 if (reply
.opt_state
!= NULL
)
1979 option_state_dereference(&reply
.opt_state
, MDL
);
1980 if (reply
.packet
!= NULL
)
1981 packet_dereference(&reply
.packet
, MDL
);
1982 if (reply
.client_id
.data
!= NULL
)
1983 data_string_forget(&reply
.client_id
, MDL
);
1984 if (packet_oro
.buffer
!= NULL
)
1985 data_string_forget(&packet_oro
, MDL
);
1986 reply
.renew
= reply
.rebind
= reply
.min_prefer
= reply
.min_valid
= 0;
1990 /* Process a client-supplied IA_NA. This may append options to the tail of
1991 * the reply packet being built in the reply_state structure.
1994 reply_process_ia_na(struct reply_state
*reply
, struct option_cache
*ia
) {
1995 isc_result_t status
= ISC_R_SUCCESS
;
1998 struct option_state
*packet_ia
;
1999 struct option_cache
*oc
;
2000 struct data_string ia_data
, data
;
2002 /* Initialize values that will get cleaned up on return. */
2004 memset(&ia_data
, 0, sizeof(ia_data
));
2005 memset(&data
, 0, sizeof(data
));
2007 * Note that find_client_address() may set reply->lease.
2010 /* Make sure there is at least room for the header. */
2011 if ((reply
->cursor
+ IA_NA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2012 log_error("reply_process_ia_na: Reply too long for IA.");
2013 return ISC_R_NOSPACE
;
2017 /* Fetch the IA_NA contents. */
2018 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2019 ia
, IA_NA_OFFSET
)) {
2020 log_error("reply_process_ia_na: error evaluating ia");
2021 status
= ISC_R_FAILURE
;
2025 /* Extract IA_NA header contents. */
2026 iaid
= getULong(ia_data
.data
);
2027 reply
->renew
= getULong(ia_data
.data
+ 4);
2028 reply
->rebind
= getULong(ia_data
.data
+ 8);
2030 /* Create an IA_NA structure. */
2031 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2032 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2033 log_error("reply_process_ia_na: no memory for ia.");
2034 status
= ISC_R_NOMEMORY
;
2037 reply
->ia
->ia_type
= D6O_IA_NA
;
2039 /* Cache pre-existing IA, if any. */
2040 ia_hash_lookup(&reply
->old_ia
, ia_na_active
,
2041 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2042 reply
->ia
->iaid_duid
.len
, MDL
);
2045 * Create an option cache to carry the IA_NA option contents, and
2046 * execute any user-supplied values into it.
2048 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2049 status
= ISC_R_NOMEMORY
;
2053 /* Check & cache the fixed host record. */
2054 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_addr
!= NULL
)) {
2055 struct iaddr tmp_addr
;
2057 if (!evaluate_option_cache(&reply
->fixed
, NULL
, NULL
, NULL
,
2058 NULL
, NULL
, &global_scope
,
2059 reply
->host
->fixed_addr
, MDL
)) {
2060 log_error("reply_process_ia_na: unable to evaluate "
2062 status
= ISC_R_FAILURE
;
2066 if (reply
->fixed
.len
< 16) {
2067 log_error("reply_process_ia_na: invalid fixed address.");
2068 status
= DHCP_R_INVALIDARG
;
2072 /* Find the static lease's subnet. */
2074 memcpy(tmp_addr
.iabuf
, reply
->fixed
.data
, 16);
2076 if (find_grouped_subnet(&reply
->subnet
, reply
->shared
,
2077 tmp_addr
, MDL
) == 0)
2078 log_fatal("Impossible condition at %s:%d.", MDL
);
2080 reply
->static_lease
= ISC_TRUE
;
2082 reply
->static_lease
= ISC_FALSE
;
2085 * Save the cursor position at the start of the IA, so we can
2086 * set length and adjust t1/t2 values later. We write a temporary
2087 * header out now just in case we decide to adjust the packet
2088 * within sub-process functions.
2090 ia_cursor
= reply
->cursor
;
2092 /* Initialize the IA_NA header. First the code. */
2093 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_NA
);
2096 /* Then option length. */
2097 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
2100 /* Then IA_NA header contents; IAID. */
2101 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2104 /* We store the client's t1 for now, and may over-ride it later. */
2105 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
2108 /* We store the client's t2 for now, and may over-ride it later. */
2109 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
2113 * For each address in this IA_NA, decide what to do about it.
2117 * The client leaves unchanged any information about addresses
2118 * it has recorded but are not included ("cancel/break" below).
2119 * A not included IA ("cleanup" below) could give a Renew/Rebind.
2121 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2122 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
2123 reply
->client_valid
= reply
->client_prefer
= 0;
2124 for (; oc
!= NULL
; oc
= oc
->next
) {
2125 status
= reply_process_addr(reply
, oc
);
2128 * Canceled means we did not allocate addresses to the
2129 * client, but we're "done" with this IA - we set a status
2130 * code. So transmit this reply, e.g., move on to the next
2133 if (status
== ISC_R_CANCELED
)
2136 if ((status
!= ISC_R_SUCCESS
) &&
2137 (status
!= ISC_R_ADDRINUSE
) &&
2138 (status
!= ISC_R_ADDRNOTAVAIL
))
2145 * If we fell through the above and never gave the client
2146 * an address, give it one now.
2148 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
2149 status
= find_client_address(reply
);
2151 if (status
== ISC_R_NORESOURCES
) {
2152 switch (reply
->packet
->dhcpv6_msg_type
) {
2153 case DHCPV6_SOLICIT
:
2155 * No address for any IA is handled
2160 case DHCPV6_REQUEST
:
2161 /* Section 18.2.1 (Request):
2163 * If the server cannot assign any addresses to
2164 * an IA in the message from the client, the
2165 * server MUST include the IA in the Reply
2166 * message with no addresses in the IA and a
2167 * Status Code option in the IA containing
2168 * status code NoAddrsAvail.
2170 option_state_dereference(&reply
->reply_ia
, MDL
);
2171 if (!option_state_allocate(&reply
->reply_ia
,
2174 log_error("reply_process_ia_na: No "
2175 "memory for option state "
2177 status
= ISC_R_NOMEMORY
;
2181 if (!set_status_code(STATUS_NoAddrsAvail
,
2182 "No addresses available "
2183 "for this interface.",
2185 log_error("reply_process_ia_na: Unable "
2186 "to set NoAddrsAvail status "
2188 status
= ISC_R_FAILURE
;
2192 status
= ISC_R_SUCCESS
;
2197 * RFC 3315 does not tell us to emit a status
2198 * code in this condition, or anything else.
2200 * If we included non-allocated addresses
2201 * (zeroed lifetimes) in an IA, then the client
2202 * will deconfigure them.
2204 * So we want to include the IA even if we
2205 * can't give it a new address if it includes
2206 * zeroed lifetime addresses.
2208 * We don't want to include the IA if we
2209 * provide zero addresses including zeroed
2212 if (reply
->resources_included
)
2213 status
= ISC_R_SUCCESS
;
2220 if (status
!= ISC_R_SUCCESS
)
2225 * yes, goto's aren't the best but we also want to avoid extra
2228 if (status
== ISC_R_CANCELED
) {
2229 /* We're replying with a status code so we still need to
2230 * write it out in wire-format to the outbound buffer */
2231 write_to_packet(reply
, ia_cursor
);
2236 * Handle static leases, we always log stuff and if it's
2237 * a hard binding we run any commit statements that we have
2239 if (reply
->static_lease
) {
2240 char tmp_addr
[INET6_ADDRSTRLEN
];
2241 log_info("%s NA: address %s to client with duid %s iaid = %d "
2243 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2244 inet_ntop(AF_INET6
, reply
->fixed
.data
, tmp_addr
,
2246 print_hex_1(reply
->client_id
.len
,
2247 reply
->client_id
.data
, 60),
2250 /* Write the lease out in wire-format to the outbound buffer */
2251 write_to_packet(reply
, ia_cursor
);
2253 /* Performs DDNS updates if we're configured to do them */
2254 ddns_update_static6(reply
);
2256 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
2257 (reply
->on_star
.on_commit
!= NULL
)) {
2258 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
2259 reply
->packet
->options
,
2260 reply
->opt_state
, NULL
,
2261 reply
->on_star
.on_commit
, NULL
);
2262 executable_statement_dereference
2263 (&reply
->on_star
.on_commit
, MDL
);
2269 * If we have any addresses log what we are doing.
2271 if (reply
->ia
->num_iasubopt
!= 0) {
2272 struct iasubopt
*tmp
;
2274 char tmp_addr
[INET6_ADDRSTRLEN
];
2276 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2277 tmp
= reply
->ia
->iasubopt
[i
];
2279 log_info("%s NA: address %s to client with duid %s "
2280 "iaid = %d valid for %u seconds",
2281 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2282 inet_ntop(AF_INET6
, &tmp
->addr
,
2283 tmp_addr
, sizeof(tmp_addr
)),
2284 print_hex_1(reply
->client_id
.len
,
2285 reply
->client_id
.data
, 60),
2291 * If this is not a 'soft' binding, consume the new changes into
2292 * the database (if any have been attached to the ia_na).
2294 * Loop through the assigned dynamic addresses, referencing the
2295 * leases onto this IA_NA rather than any old ones, and updating
2296 * pool timers for each (if any).
2298 * Note that we must do ddns_updates() before we test for lease
2299 * reuse (so we'll know if DNS entries are different). To ensure
2300 * we don't break any configs, we run on_commit statements before
2301 * we do ddns_updates() just in case the former affects the later.
2302 * This is symetrical with v4 logic. We always run on_commit and
2303 * ddns_udpates() whether a lease is reused or renewed.
2305 if ((reply
->ia
->num_iasubopt
!= 0) &&
2306 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
2307 int must_commit
= 0;
2308 struct iasubopt
*tmp
;
2309 struct data_string
*ia_id
;
2312 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2313 tmp
= reply
->ia
->iasubopt
[i
];
2314 if (tmp
->ia
!= NULL
) {
2315 ia_dereference(&tmp
->ia
, MDL
);
2318 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2320 /* If we have anything to do on commit do it now */
2321 if (tmp
->on_star
.on_commit
!= NULL
) {
2322 execute_statements(NULL
, reply
->packet
,
2324 reply
->packet
->options
,
2327 tmp
->on_star
.on_commit
,
2329 executable_statement_dereference
2330 (&tmp
->on_star
.on_commit
, MDL
);
2333 #if defined (NSUPDATE)
2335 /* Perform ddns updates */
2336 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2339 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2341 reply
->packet
->options
,
2345 ddns_updates(reply
->packet
, NULL
, NULL
,
2346 tmp
, NULL
, reply
->opt_state
);
2349 if (!reuse_lease6(reply
, tmp
)) {
2350 /* Commit 'hard' bindings. */
2352 renew_lease6(tmp
->ipv6_pool
, tmp
);
2353 schedule_lease_timeout(tmp
->ipv6_pool
);
2355 /* Do our threshold check. */
2356 check_pool6_threshold(reply
, tmp
);
2360 /* write the IA_NA in wire-format to the outbound buffer */
2361 write_to_packet(reply
, ia_cursor
);
2363 /* Remove any old ia from the hash. */
2364 if (reply
->old_ia
!= NULL
) {
2365 if (!release_on_roam(reply
)) {
2366 ia_id
= &reply
->old_ia
->iaid_duid
;
2367 ia_hash_delete(ia_na_active
,
2368 (unsigned char *)ia_id
->data
,
2372 ia_dereference(&reply
->old_ia
, MDL
);
2375 /* Put new ia into the hash. */
2376 reply
->ia
->cltt
= cur_time
;
2377 ia_id
= &reply
->ia
->iaid_duid
;
2378 ia_hash_add(ia_na_active
, (unsigned char *)ia_id
->data
,
2379 ia_id
->len
, reply
->ia
, MDL
);
2381 /* If we couldn't reuse all of the iasubopts, we
2382 * must update udpate the lease db */
2384 write_ia(reply
->ia
);
2387 /* write the IA_NA in wire-format to the outbound buffer */
2388 write_to_packet(reply
, ia_cursor
);
2389 schedule_lease_timeout_reply(reply
);
2393 if (packet_ia
!= NULL
)
2394 option_state_dereference(&packet_ia
, MDL
);
2395 if (reply
->reply_ia
!= NULL
)
2396 option_state_dereference(&reply
->reply_ia
, MDL
);
2397 if (ia_data
.data
!= NULL
)
2398 data_string_forget(&ia_data
, MDL
);
2399 if (data
.data
!= NULL
)
2400 data_string_forget(&data
, MDL
);
2401 if (reply
->ia
!= NULL
)
2402 ia_dereference(&reply
->ia
, MDL
);
2403 if (reply
->old_ia
!= NULL
)
2404 ia_dereference(&reply
->old_ia
, MDL
);
2405 if (reply
->lease
!= NULL
)
2406 iasubopt_dereference(&reply
->lease
, MDL
);
2407 if (reply
->fixed
.data
!= NULL
)
2408 data_string_forget(&reply
->fixed
, MDL
);
2409 if (reply
->subnet
!= NULL
)
2410 subnet_dereference(&reply
->subnet
, MDL
);
2411 if (reply
->on_star
.on_expiry
!= NULL
)
2412 executable_statement_dereference
2413 (&reply
->on_star
.on_expiry
, MDL
);
2414 if (reply
->on_star
.on_release
!= NULL
)
2415 executable_statement_dereference
2416 (&reply
->on_star
.on_release
, MDL
);
2419 * ISC_R_CANCELED is a status code used by the addr processing to
2420 * indicate we're replying with a status code. This is still a
2421 * success at higher layers.
2423 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2427 * Writes the populated IA_xx in wire format to the reply buffer
2430 write_to_packet(struct reply_state
*reply
, unsigned ia_cursor
) {
2431 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2432 sizeof(reply
->buf
) - reply
->cursor
,
2433 reply
->reply_ia
, reply
->packet
,
2434 (reply
->ia
->ia_type
!= D6O_IA_PD
?
2435 required_opts_IA
: required_opts_IA_PD
),
2438 /* Reset the length of this IA to match what was just written. */
2439 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2440 reply
->cursor
- (ia_cursor
+ 4));
2442 if (reply
->ia
->ia_type
!= D6O_IA_TA
) {
2443 /* Calculate T1/T2 and stuff them in the reply */
2444 set_reply_tee_times(reply
, ia_cursor
);
2449 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
2450 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
2451 * in the event we are replying with a status code and do not wish to process
2452 * more IAADDRs within this IA.
2455 reply_process_addr(struct reply_state
*reply
, struct option_cache
*addr
) {
2456 u_int32_t pref_life
, valid_life
;
2457 struct binding_scope
**scope
;
2458 struct group
*group
;
2459 struct subnet
*subnet
;
2460 struct iaddr tmp_addr
;
2461 struct option_cache
*oc
;
2462 struct data_string iaaddr
, data
;
2463 isc_result_t status
= ISC_R_SUCCESS
;
2465 int invalid_for_eui_64
= 0;
2468 /* Initializes values that will be cleaned up. */
2469 memset(&iaaddr
, 0, sizeof(iaaddr
));
2470 memset(&data
, 0, sizeof(data
));
2471 /* Note that reply->lease may be set by address_is_owned() */
2474 * There is no point trying to process an incoming address if there
2475 * is no room for an outgoing address.
2477 if ((reply
->cursor
+ 28) > sizeof(reply
->buf
)) {
2478 log_error("reply_process_addr: Out of room for address.");
2479 return ISC_R_NOSPACE
;
2482 /* Extract this IAADDR option. */
2483 if (!evaluate_option_cache(&iaaddr
, reply
->packet
, NULL
, NULL
,
2484 reply
->packet
->options
, NULL
, &global_scope
,
2486 (iaaddr
.len
< IAADDR_OFFSET
)) {
2487 log_error("reply_process_addr: error evaluating IAADDR.");
2488 status
= ISC_R_FAILURE
;
2492 /* The first 16 bytes are the IPv6 address. */
2493 pref_life
= getULong(iaaddr
.data
+ 16);
2494 valid_life
= getULong(iaaddr
.data
+ 20);
2496 if ((reply
->client_valid
== 0) ||
2497 (reply
->client_valid
> valid_life
))
2498 reply
->client_valid
= valid_life
;
2500 if ((reply
->client_prefer
== 0) ||
2501 (reply
->client_prefer
> pref_life
))
2502 reply
->client_prefer
= pref_life
;
2505 * Clients may choose to send :: as an address, with the idea to give
2506 * hints about preferred-lifetime or valid-lifetime.
2509 memset(tmp_addr
.iabuf
, 0, 16);
2510 if (!memcmp(iaaddr
.data
, tmp_addr
.iabuf
, 16)) {
2511 /* Status remains success; we just ignore this one. */
2515 /* tmp_addr len remains 16 */
2516 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2519 * Verify that this address is on the client's network.
2521 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
2522 subnet
= subnet
->next_sibling
) {
2523 if (addr_eq(subnet_number(tmp_addr
, subnet
->netmask
),
2530 /* If the requested address falls into an EUI-64 pool, then
2531 * we need to verify if it has EUI-64 duid AND the requested
2532 * address is correct for that duid. If not we treat it just
2533 * like an not-on-link request. */
2534 struct ipv6_pool
* pool
= NULL
;
2535 struct in6_addr
* addr
= (struct in6_addr
*)(iaaddr
.data
);
2536 if ((find_ipv6_pool(&pool
, D6O_IA_NA
, addr
) == ISC_R_SUCCESS
)
2537 && (pool
->ipv6_pond
->use_eui_64
) &&
2538 (!valid_for_eui_64_pool(pool
, &reply
->client_id
, 0, addr
))) {
2539 log_debug ("Requested address: %s,"
2540 " not valid for EUI-64 pool",
2542 invalid_for_eui_64
= 1;
2547 /* Address not found on shared network. */
2549 if ((subnet
== NULL
) || invalid_for_eui_64
) {
2551 if (subnet
== NULL
) {
2553 /* Ignore this address on 'soft' bindings. */
2554 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
2555 /* disable rapid commit */
2556 reply
->buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
2557 delete_option(&dhcpv6_universe
,
2560 /* status remains success */
2565 * RFC3315 section 18.2.1:
2567 * If the server finds that the prefix on one or more IP
2568 * addresses in any IA in the message from the client is not
2569 * appropriate for the link to which the client is connected,
2570 * the server MUST return the IA to the client with a Status
2571 * Code option with the value NotOnLink.
2573 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) {
2574 /* Rewind the IA_NA to empty. */
2575 option_state_dereference(&reply
->reply_ia
, MDL
);
2576 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2577 log_error("reply_process_addr: No memory for "
2578 "option state wipe.");
2579 status
= ISC_R_NOMEMORY
;
2583 /* Append a NotOnLink status code. */
2584 if (!set_status_code(STATUS_NotOnLink
,
2585 "Address not for use on this "
2586 "link.", reply
->reply_ia
)) {
2587 log_error("reply_process_addr: Failure "
2588 "setting status code.");
2589 status
= ISC_R_FAILURE
;
2593 /* Fin (no more IAADDRs). */
2594 status
= ISC_R_CANCELED
;
2599 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2601 * If the server finds that any of the addresses are not
2602 * appropriate for the link to which the client is attached,
2603 * the server returns the address to the client with lifetimes
2606 if ((reply
->packet
->dhcpv6_msg_type
!= DHCPV6_RENEW
) &&
2607 (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
2608 log_error("It is impossible to lease a client that is "
2609 "not sending a solicit, request, renew, or "
2611 status
= ISC_R_FAILURE
;
2615 reply
->send_prefer
= reply
->send_valid
= 0;
2620 /* Verify the address belongs to the client. */
2621 if (!address_is_owned(reply
, &tmp_addr
)) {
2623 * For solicit and request, any addresses included are
2624 * 'requested' addresses. For rebind, we actually have
2625 * no direction on what to do from 3315 section 18.2.4!
2626 * So I think the best bet is to try and give it out, and if
2627 * we can't, zero lifetimes.
2629 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
2630 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
2631 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
2632 status
= reply_process_try_addr(reply
, &tmp_addr
);
2635 * If the address is in use, or isn't in any dynamic
2636 * range, continue as normal. If any other error was
2639 if ((status
!= ISC_R_SUCCESS
) &&
2640 (status
!= ISC_R_ADDRINUSE
) &&
2641 (status
!= ISC_R_ADDRNOTAVAIL
))
2645 * If we didn't honor this lease, for solicit and
2646 * request we simply omit it from our answer. For
2647 * rebind, we send it with zeroed lifetimes.
2649 if (reply
->lease
== NULL
) {
2650 if (reply
->packet
->dhcpv6_msg_type
==
2652 reply
->send_prefer
= 0;
2653 reply
->send_valid
= 0;
2657 /* status remains success - ignore */
2661 * RFC3315 section 18.2.3:
2663 * If the server cannot find a client entry for the IA the
2664 * server returns the IA containing no addresses with a Status
2665 * Code option set to NoBinding in the Reply message.
2667 * On mismatch we (ab)use this pretending we have not the IA
2668 * as soon as we have not an address.
2670 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
2671 /* Rewind the IA_NA to empty. */
2672 option_state_dereference(&reply
->reply_ia
, MDL
);
2673 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2674 log_error("reply_process_addr: No memory for "
2675 "option state wipe.");
2676 status
= ISC_R_NOMEMORY
;
2680 /* Append a NoBinding status code. */
2681 if (!set_status_code(STATUS_NoBinding
,
2682 "Address not bound to this "
2683 "interface.", reply
->reply_ia
)) {
2684 log_error("reply_process_addr: Unable to "
2685 "attach status code.");
2686 status
= ISC_R_FAILURE
;
2690 /* Fin (no more IAADDRs). */
2691 status
= ISC_R_CANCELED
;
2694 log_error("It is impossible to lease a client that is "
2695 "not sending a solicit, request, renew, or "
2697 status
= ISC_R_FAILURE
;
2702 if (reply
->static_lease
) {
2703 if (reply
->host
== NULL
)
2704 log_fatal("Impossible condition at %s:%d.", MDL
);
2706 scope
= &global_scope
;
2707 group
= reply
->subnet
->group
;
2709 if (reply
->lease
== NULL
)
2710 log_fatal("Impossible condition at %s:%d.", MDL
);
2712 scope
= &reply
->lease
->scope
;
2713 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
2717 * If client_resources is nonzero, then the reply_process_is_addressed
2718 * function has executed configuration state into the reply option
2719 * cache. We will use that valid cache to derive configuration for
2720 * whether or not to engage in additional addresses, and similar.
2722 if (reply
->client_resources
!= 0) {
2726 * Does this client have "enough" addresses already? Default
2727 * to one. Everybody gets one, and one should be enough for
2730 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2731 SV_LIMIT_ADDRS_PER_IA
);
2733 if (!evaluate_option_cache(&data
, reply
->packet
,
2735 reply
->packet
->options
,
2739 log_error("reply_process_addr: unable to "
2740 "evaluate addrs-per-ia value.");
2741 status
= ISC_R_FAILURE
;
2745 limit
= getULong(data
.data
);
2746 data_string_forget(&data
, MDL
);
2750 * If we wish to limit the client to a certain number of
2751 * addresses, then omit the address from the reply.
2753 if (reply
->client_resources
>= limit
)
2757 status
= reply_process_is_addressed(reply
, scope
, group
);
2758 if (status
!= ISC_R_SUCCESS
)
2762 status
= reply_process_send_addr(reply
, &tmp_addr
);
2765 if (iaaddr
.data
!= NULL
)
2766 data_string_forget(&iaaddr
, MDL
);
2767 if (data
.data
!= NULL
)
2768 data_string_forget(&data
, MDL
);
2769 if (reply
->lease
!= NULL
)
2770 iasubopt_dereference(&reply
->lease
, MDL
);
2776 * Verify the address belongs to the client. If we've got a host
2777 * record with a fixed address, it has to be the assigned address
2778 * (fault out all else). Otherwise it's a dynamic address, so lookup
2779 * that address and make sure it belongs to this DUID:IAID pair.
2781 static isc_boolean_t
2782 address_is_owned(struct reply_state
*reply
, struct iaddr
*addr
) {
2784 struct ipv6_pond
*pond
;
2787 * This faults out addresses that don't match fixed addresses.
2789 if (reply
->static_lease
) {
2790 if (reply
->fixed
.data
== NULL
)
2791 log_fatal("Impossible condition at %s:%d.", MDL
);
2793 if (memcmp(addr
->iabuf
, reply
->fixed
.data
, 16) == 0)
2799 if ((reply
->old_ia
== NULL
) || (reply
->old_ia
->num_iasubopt
== 0))
2802 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2803 struct iasubopt
*tmp
;
2805 tmp
= reply
->old_ia
->iasubopt
[i
];
2807 if (memcmp(addr
->iabuf
, &tmp
->addr
, 16) == 0) {
2808 if (lease6_usable(tmp
) == ISC_FALSE
) {
2812 pond
= tmp
->ipv6_pool
->ipv6_pond
;
2813 if (((pond
->prohibit_list
!= NULL
) &&
2814 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
2815 ((pond
->permit_list
!= NULL
) &&
2816 (!permitted(reply
->packet
, pond
->permit_list
))))
2819 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
2828 /* Process a client-supplied IA_TA. This may append options to the tail of
2829 * the reply packet being built in the reply_state structure.
2832 reply_process_ia_ta(struct reply_state
*reply
, struct option_cache
*ia
) {
2833 isc_result_t status
= ISC_R_SUCCESS
;
2836 struct option_state
*packet_ia
;
2837 struct option_cache
*oc
;
2838 struct data_string ia_data
, data
;
2839 struct data_string iaaddr
;
2840 u_int32_t pref_life
, valid_life
;
2841 struct iaddr tmp_addr
;
2843 /* Initialize values that will get cleaned up on return. */
2845 memset(&ia_data
, 0, sizeof(ia_data
));
2846 memset(&data
, 0, sizeof(data
));
2847 memset(&iaaddr
, 0, sizeof(iaaddr
));
2849 /* Make sure there is at least room for the header. */
2850 if ((reply
->cursor
+ IA_TA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2851 log_error("reply_process_ia_ta: Reply too long for IA.");
2852 return ISC_R_NOSPACE
;
2856 /* Fetch the IA_TA contents. */
2857 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2858 ia
, IA_TA_OFFSET
)) {
2859 log_error("reply_process_ia_ta: error evaluating ia");
2860 status
= ISC_R_FAILURE
;
2864 /* Extract IA_TA header contents. */
2865 iaid
= getULong(ia_data
.data
);
2867 /* Create an IA_TA structure. */
2868 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2869 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2870 log_error("reply_process_ia_ta: no memory for ia.");
2871 status
= ISC_R_NOMEMORY
;
2874 reply
->ia
->ia_type
= D6O_IA_TA
;
2876 /* Cache pre-existing IA, if any. */
2877 ia_hash_lookup(&reply
->old_ia
, ia_ta_active
,
2878 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2879 reply
->ia
->iaid_duid
.len
, MDL
);
2882 * Create an option cache to carry the IA_TA option contents, and
2883 * execute any user-supplied values into it.
2885 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2886 status
= ISC_R_NOMEMORY
;
2891 * Temporary leases are dynamic by definition.
2893 reply
->static_lease
= ISC_FALSE
;
2896 * Save the cursor position at the start of the IA, so we can
2897 * set length later. We write a temporary
2898 * header out now just in case we decide to adjust the packet
2899 * within sub-process functions.
2901 ia_cursor
= reply
->cursor
;
2903 /* Initialize the IA_TA header. First the code. */
2904 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_TA
);
2907 /* Then option length. */
2908 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x04u
);
2911 /* Then IA_TA header contents; IAID. */
2912 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2916 * Deal with an IAADDR for lifetimes.
2917 * For all or none, process IAADDRs as hints.
2919 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
2920 reply
->client_valid
= reply
->client_prefer
= 0;
2921 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2922 for (; oc
!= NULL
; oc
= oc
->next
) {
2923 memset(&iaaddr
, 0, sizeof(iaaddr
));
2924 if (!evaluate_option_cache(&iaaddr
, reply
->packet
,
2926 reply
->packet
->options
, NULL
,
2927 &global_scope
, oc
, MDL
) ||
2928 (iaaddr
.len
< IAADDR_OFFSET
)) {
2929 log_error("reply_process_ia_ta: error "
2930 "evaluating IAADDR.");
2931 status
= ISC_R_FAILURE
;
2934 /* The first 16 bytes are the IPv6 address. */
2935 pref_life
= getULong(iaaddr
.data
+ 16);
2936 valid_life
= getULong(iaaddr
.data
+ 20);
2938 if ((reply
->client_valid
== 0) ||
2939 (reply
->client_valid
> valid_life
))
2940 reply
->client_valid
= valid_life
;
2942 if ((reply
->client_prefer
== 0) ||
2943 (reply
->client_prefer
> pref_life
))
2944 reply
->client_prefer
= pref_life
;
2946 /* Nothing more if something has failed. */
2947 if (status
== ISC_R_CANCELED
)
2951 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2952 if (!temporary_is_available(reply
, &tmp_addr
))
2954 status
= reply_process_is_addressed(reply
,
2955 &reply
->lease
->scope
,
2956 reply
->lease
->ipv6_pool
->ipv6_pond
->group
);
2957 if (status
!= ISC_R_SUCCESS
)
2959 status
= reply_process_send_addr(reply
, &tmp_addr
);
2960 if (status
!= ISC_R_SUCCESS
)
2962 if (reply
->lease
!= NULL
)
2963 iasubopt_dereference(&reply
->lease
, MDL
);
2967 /* Rewind the IA_TA to empty. */
2968 option_state_dereference(&reply
->reply_ia
, MDL
);
2969 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2970 status
= ISC_R_NOMEMORY
;
2973 status
= ISC_R_CANCELED
;
2974 reply
->client_resources
= 0;
2975 reply
->resources_included
= ISC_FALSE
;
2976 if (reply
->lease
!= NULL
)
2977 iasubopt_dereference(&reply
->lease
, MDL
);
2982 * Give the client temporary addresses.
2984 if (reply
->client_resources
!= 0)
2986 status
= find_client_temporaries(reply
);
2987 if (status
== ISC_R_NORESOURCES
) {
2988 switch (reply
->packet
->dhcpv6_msg_type
) {
2989 case DHCPV6_SOLICIT
:
2991 * No address for any IA is handled
2996 case DHCPV6_REQUEST
:
2997 /* Section 18.2.1 (Request):
2999 * If the server cannot assign any addresses to
3000 * an IA in the message from the client, the
3001 * server MUST include the IA in the Reply
3002 * message with no addresses in the IA and a
3003 * Status Code option in the IA containing
3004 * status code NoAddrsAvail.
3006 option_state_dereference(&reply
->reply_ia
, MDL
);
3007 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
3008 log_error("reply_process_ia_ta: No "
3009 "memory for option state wipe.");
3010 status
= ISC_R_NOMEMORY
;
3014 if (!set_status_code(STATUS_NoAddrsAvail
,
3015 "No addresses available "
3016 "for this interface.",
3018 log_error("reply_process_ia_ta: Unable "
3019 "to set NoAddrsAvail status code.");
3020 status
= ISC_R_FAILURE
;
3024 status
= ISC_R_SUCCESS
;
3029 * We don't want to include the IA if we
3030 * provide zero addresses including zeroed
3033 if (reply
->resources_included
)
3034 status
= ISC_R_SUCCESS
;
3039 } else if (status
!= ISC_R_SUCCESS
)
3045 * yes, goto's aren't the best but we also want to avoid extra
3048 if (status
== ISC_R_CANCELED
) {
3049 /* We're replying with a status code so we still need to
3050 * write it out in wire-format to the outbound buffer */
3051 write_to_packet(reply
, ia_cursor
);
3056 * If we have any addresses log what we are doing.
3058 if (reply
->ia
->num_iasubopt
!= 0) {
3059 struct iasubopt
*tmp
;
3061 char tmp_addr
[INET6_ADDRSTRLEN
];
3063 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3064 tmp
= reply
->ia
->iasubopt
[i
];
3066 log_info("%s TA: address %s to client with duid %s "
3067 "iaid = %d valid for %u seconds",
3068 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
3069 inet_ntop(AF_INET6
, &tmp
->addr
,
3070 tmp_addr
, sizeof(tmp_addr
)),
3071 print_hex_1(reply
->client_id
.len
,
3072 reply
->client_id
.data
, 60),
3079 * For hard bindings we consume the new changes into
3080 * the database (if any have been attached to the ia_ta).
3082 * Loop through the assigned dynamic addresses, referencing the
3083 * leases onto this IA_TA rather than any old ones, and updating
3084 * pool timers for each (if any).
3086 if ((reply
->ia
->num_iasubopt
!= 0) &&
3087 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
3088 int must_commit
= 0;
3089 struct iasubopt
*tmp
;
3090 struct data_string
*ia_id
;
3093 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3094 tmp
= reply
->ia
->iasubopt
[i
];
3096 if (tmp
->ia
!= NULL
)
3097 ia_dereference(&tmp
->ia
, MDL
);
3098 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
3100 /* If we have anything to do on commit do it now */
3101 if (tmp
->on_star
.on_commit
!= NULL
) {
3102 execute_statements(NULL
, reply
->packet
,
3104 reply
->packet
->options
,
3107 tmp
->on_star
.on_commit
,
3109 executable_statement_dereference
3110 (&tmp
->on_star
.on_commit
, MDL
);
3113 #if defined (NSUPDATE)
3115 * Perform ddns updates.
3117 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3120 evaluate_boolean_option_cache(NULL
, reply
->packet
,
3122 reply
->packet
->options
,
3126 ddns_updates(reply
->packet
, NULL
, NULL
,
3127 tmp
, NULL
, reply
->opt_state
);
3131 if (!reuse_lease6(reply
, tmp
)) {
3132 /* Commit 'hard' bindings. */
3134 renew_lease6(tmp
->ipv6_pool
, tmp
);
3135 schedule_lease_timeout(tmp
->ipv6_pool
);
3137 /* Do our threshold check. */
3138 check_pool6_threshold(reply
, tmp
);
3142 /* write the IA_TA in wire-format to the outbound buffer */
3143 write_to_packet(reply
, ia_cursor
);
3145 /* Remove any old ia from the hash. */
3146 if (reply
->old_ia
!= NULL
) {
3147 if (!release_on_roam(reply
)) {
3148 ia_id
= &reply
->old_ia
->iaid_duid
;
3149 ia_hash_delete(ia_ta_active
,
3150 (unsigned char *)ia_id
->data
,
3154 ia_dereference(&reply
->old_ia
, MDL
);
3157 /* Put new ia into the hash. */
3158 reply
->ia
->cltt
= cur_time
;
3159 ia_id
= &reply
->ia
->iaid_duid
;
3160 ia_hash_add(ia_ta_active
, (unsigned char *)ia_id
->data
,
3161 ia_id
->len
, reply
->ia
, MDL
);
3163 /* If we couldn't reuse all of the iasubopts, we
3164 * must update udpate the lease db */
3166 write_ia(reply
->ia
);
3169 /* write the IA_TA in wire-format to the outbound buffer */
3170 write_to_packet(reply
, ia_cursor
);
3171 schedule_lease_timeout_reply(reply
);
3175 if (packet_ia
!= NULL
)
3176 option_state_dereference(&packet_ia
, MDL
);
3177 if (iaaddr
.data
!= NULL
)
3178 data_string_forget(&iaaddr
, MDL
);
3179 if (reply
->reply_ia
!= NULL
)
3180 option_state_dereference(&reply
->reply_ia
, MDL
);
3181 if (ia_data
.data
!= NULL
)
3182 data_string_forget(&ia_data
, MDL
);
3183 if (data
.data
!= NULL
)
3184 data_string_forget(&data
, MDL
);
3185 if (reply
->ia
!= NULL
)
3186 ia_dereference(&reply
->ia
, MDL
);
3187 if (reply
->old_ia
!= NULL
)
3188 ia_dereference(&reply
->old_ia
, MDL
);
3189 if (reply
->lease
!= NULL
)
3190 iasubopt_dereference(&reply
->lease
, MDL
);
3193 * ISC_R_CANCELED is a status code used by the addr processing to
3194 * indicate we're replying with other addresses. This is still a
3195 * success at higher layers.
3197 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
3200 * Determines if a lease (iasubopt) can be reused without extending it.
3201 * If dhcp-cache-threshold is greater than zero (i.e enabled) then
3202 * a lease may be reused without going through a full renewal if
3203 * it meets all the requirements. In short it must be active, younger
3204 * than the threshold, and not have DNS changes.
3206 * If it is determined that it can be reused, that a call to
3207 * shorten_lifetimes() is made to reduce the valid and preferred lifetimes
3208 * sent to the client by the age of the lease.
3210 * Returns 1 if lease can be reused, 0 otherwise
3213 reuse_lease6(struct reply_state
*reply
, struct iasubopt
*lease
) {
3214 int threshold
= DEFAULT_CACHE_THRESHOLD
;
3215 struct option_cache
* oc
= NULL
;
3216 struct data_string d1
;
3221 /* In order to even qualify for reuse consideration:
3222 * 1. Lease must be active
3223 * 2. It must have been accepted at least once
3224 * 3. DNS info must not have changed */
3225 if ((lease
->state
!= FTS_ACTIVE
) ||
3226 (lease
->hard_lifetime_end_time
== 0) ||
3227 (lease
->ddns_cb
!= NULL
)) {
3231 /* Look up threshold value */
3232 memset(&d1
, 0, sizeof(struct data_string
));
3233 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3234 SV_CACHE_THRESHOLD
);
3236 evaluate_option_cache(&d1
, reply
->packet
, NULL
, NULL
,
3237 reply
->packet
->options
, reply
->opt_state
,
3238 &lease
->scope
, oc
, MDL
)) {
3239 if (d1
.len
== 1 && (d1
.data
[0] < 100)) {
3240 threshold
= d1
.data
[0];
3243 data_string_forget(&d1
, MDL
);
3246 if (threshold
<= 0) {
3250 if (lease
->valid
>= MAX_TIME
) {
3251 /* Infinite leases are always reused. We have to make
3252 * a choice because we cannot determine when they actually
3253 * began, so we either always reuse them or we never do. */
3254 log_debug ("reusing infinite lease for: %s%s",
3255 pin6_addr(&lease
->addr
), iasubopt_plen_str(lease
));
3259 age
= cur_tv
.tv_sec
- (lease
->hard_lifetime_end_time
- lease
->valid
);
3260 if (lease
->valid
<= (INT_MAX
/ threshold
))
3261 limit
= lease
->valid
* threshold
/ 100;
3263 limit
= lease
->valid
/ 100 * threshold
;
3266 /* Reduce valid/preferred going to the client by age */
3267 shorten_lifetimes(reply
, lease
, age
, threshold
);
3275 * Reduces the valid and preferred lifetimes for a given lease (iasubopt)
3277 * We cannot determine until after a iasubopt has been added to
3278 * the reply if the lease can be reused. Therefore, when we do reuse a
3279 * lease we need a way to alter the lifetimes that will be sent to the client.
3280 * That's where this function comes in handy:
3282 * Locate the iasubopt by it's address within the reply the reduce both
3283 * the preferred and valid lifetimes by the given number of seconds.
3285 * Note that this function, by necessity, works directly with the
3286 * option_cache data. Sort of a no-no but I don't have any better ideas.
3288 void shorten_lifetimes(struct reply_state
*reply
, struct iasubopt
*lease
,
3289 time_t age
, int threshold
) {
3290 struct option_cache
* oc
= NULL
;
3297 if (reply
->ia
->ia_type
!= D6O_IA_PD
) {
3298 subopt_type
= D6O_IAADDR
;
3299 addr_offset
= IASUBOPT_NA_ADDR_OFFSET
;
3300 pref_offset
= IASUBOPT_NA_PREF_OFFSET
;
3301 val_offset
= IASUBOPT_NA_VALID_OFFSET
;
3302 exp_length
= IASUBOPT_NA_LEN
;
3305 subopt_type
= D6O_IAPREFIX
;
3306 addr_offset
= IASUBOPT_PD_PREFIX_OFFSET
;
3307 pref_offset
= IASUBOPT_PD_PREF_OFFSET
;
3308 val_offset
= IASUBOPT_PD_VALID_OFFSET
;
3309 exp_length
= IASUBOPT_PD_LEN
;
3312 // loop through the iasubopts for the one that matches this lease
3313 oc
= lookup_option(&dhcpv6_universe
, reply
->reply_ia
, subopt_type
);
3314 for (; oc
!= NULL
; oc
= oc
->next
) {
3315 if (oc
->data
.data
== NULL
|| oc
->data
.len
!= exp_length
) {
3316 /* shouldn't happen */
3320 /* If address matches (and for PDs the prefix len matches)
3321 * we assume this is our subopt, so update the lifetimes */
3322 if (!memcmp(oc
->data
.data
+ addr_offset
, &lease
->addr
, 16) &&
3323 (subopt_type
!= D6O_IAPREFIX
||
3324 (oc
->data
.data
[IASUBOPT_PD_PREFLEN_OFFSET
] ==
3326 u_int32_t pref_life
= getULong(oc
->data
.data
+
3328 u_int32_t valid_life
= getULong(oc
->data
.data
+
3331 if (pref_life
< MAX_TIME
&& pref_life
> age
) {
3333 putULong((unsigned char*)(oc
->data
.data
) +
3334 pref_offset
, pref_life
);
3336 if (reply
->min_prefer
> pref_life
) {
3337 reply
->min_prefer
= pref_life
;
3341 if (valid_life
< MAX_TIME
&& valid_life
> age
) {
3343 putULong((unsigned char*)(oc
->data
.data
) +
3344 val_offset
, valid_life
);
3346 if (reply
->min_valid
> reply
->send_valid
) {
3347 reply
->min_valid
= valid_life
;
3351 log_debug ("Reusing lease for: %s%s, "
3352 "age %ld secs < %d%%,"
3353 " sending shortened lifetimes -"
3354 " preferred: %u, valid %u",
3355 pin6_addr(&lease
->addr
),
3356 iasubopt_plen_str(lease
),
3357 (long)age
, threshold
,
3358 pref_life
, valid_life
);
3365 * Verify the temporary address is available.
3367 static isc_boolean_t
3368 temporary_is_available(struct reply_state
*reply
, struct iaddr
*addr
) {
3369 struct in6_addr tmp_addr
;
3370 struct subnet
*subnet
;
3371 struct ipv6_pool
*pool
= NULL
;
3372 struct ipv6_pond
*pond
= NULL
;
3375 memcpy(&tmp_addr
, addr
->iabuf
, sizeof(tmp_addr
));
3377 * Clients may choose to send :: as an address, with the idea to give
3378 * hints about preferred-lifetime or valid-lifetime.
3379 * So this is not a request for this address.
3381 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
))
3385 * Verify that this address is on the client's network.
3387 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
3388 subnet
= subnet
->next_sibling
) {
3389 if (addr_eq(subnet_number(*addr
, subnet
->netmask
),
3394 /* Address not found on shared network. */
3399 * Check if this address is owned (must be before next step).
3401 if (address_is_owned(reply
, addr
))
3405 * Verify that this address is in a temporary pool and try to get it.
3407 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3408 if (((pond
->prohibit_list
!= NULL
) &&
3409 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3410 ((pond
->permit_list
!= NULL
) &&
3411 (!permitted(reply
->packet
, pond
->permit_list
))))
3414 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3415 if (pool
->pool_type
!= D6O_IA_TA
)
3418 if (ipv6_in_pool(&tmp_addr
, pool
))
3428 if (lease6_exists(pool
, &tmp_addr
))
3430 if (iasubopt_allocate(&reply
->lease
, MDL
) != ISC_R_SUCCESS
)
3432 reply
->lease
->addr
= tmp_addr
;
3433 reply
->lease
->plen
= 0;
3434 /* Default is soft binding for 2 minutes. */
3435 if (add_lease6(pool
, reply
->lease
, cur_time
+ 120) != ISC_R_SUCCESS
)
3442 * Get a temporary address per prefix.
3445 find_client_temporaries(struct reply_state
*reply
) {
3447 struct ipv6_pool
*p
= NULL
;
3448 struct ipv6_pond
*pond
;
3449 isc_result_t status
= ISC_R_NORESOURCES
;;
3450 unsigned int attempts
;
3451 struct iaddr send_addr
;
3454 * Do a quick walk through of the ponds and pools
3455 * to see if we have any prefix pools
3457 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3458 if (pond
->ipv6_pools
== NULL
)
3461 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3462 if (p
->pool_type
== D6O_IA_TA
)
3469 /* If we get here and p is NULL we have no useful pools */
3471 log_debug("Unable to get client addresses: "
3472 "no IPv6 pools on this shared network");
3473 return ISC_R_NORESOURCES
;
3477 * We have at least one pool that could provide an address
3478 * Now we walk through the ponds and pools again and check
3479 * to see if the client is permitted and if an address is
3483 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3484 if (((pond
->prohibit_list
!= NULL
) &&
3485 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3486 ((pond
->permit_list
!= NULL
) &&
3487 (!permitted(reply
->packet
, pond
->permit_list
))))
3490 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3491 if (p
->pool_type
!= D6O_IA_TA
) {
3496 * Get an address in this temporary pool.
3498 status
= create_lease6(p
, &reply
->lease
, &attempts
,
3502 if (status
!= ISC_R_SUCCESS
) {
3503 log_debug("Unable to get a temporary address.");
3507 status
= reply_process_is_addressed(reply
,
3508 &reply
->lease
->scope
,
3510 if (status
!= ISC_R_SUCCESS
) {
3514 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3515 status
= reply_process_send_addr(reply
, &send_addr
);
3516 if (status
!= ISC_R_SUCCESS
) {
3520 * reply->lease can't be null as we use it above
3521 * add check if that changes
3523 iasubopt_dereference(&reply
->lease
, MDL
);
3528 if (reply
->lease
!= NULL
) {
3529 iasubopt_dereference(&reply
->lease
, MDL
);
3535 * This function only returns failure on 'hard' failures. If it succeeds,
3536 * it will leave a lease structure behind.
3539 reply_process_try_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3540 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
3541 struct ipv6_pool
*pool
= NULL
;
3542 struct ipv6_pond
*pond
= NULL
;
3544 struct data_string data_addr
;
3546 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
3547 (addr
== NULL
) || (reply
->lease
!= NULL
))
3548 return (DHCP_R_INVALIDARG
);
3551 * Do a quick walk through of the ponds and pools
3552 * to see if we have any NA address pools
3554 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3555 if (pond
->ipv6_pools
== NULL
)
3558 for (i
= 0; ; i
++) {
3559 pool
= pond
->ipv6_pools
[i
];
3560 if ((pool
== NULL
) ||
3561 (pool
->pool_type
== D6O_IA_NA
))
3568 /* If we get here and p is NULL we have no useful pools */
3570 return (ISC_R_ADDRNOTAVAIL
);
3573 memset(&data_addr
, 0, sizeof(data_addr
));
3574 data_addr
.len
= addr
->len
;
3575 data_addr
.data
= addr
->iabuf
;
3578 * We have at least one pool that could provide an address
3579 * Now we walk through the ponds and pools again and check
3580 * to see if the client is permitted and if an address is
3583 * Within a given pond we start looking at the last pool we
3584 * allocated from, unless it had a collision trying to allocate
3585 * an address. This will tend to move us into less-filled pools.
3588 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3589 if (((pond
->prohibit_list
!= NULL
) &&
3590 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3591 ((pond
->permit_list
!= NULL
) &&
3592 (!permitted(reply
->packet
, pond
->permit_list
))))
3595 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3596 if (pool
->pool_type
!= D6O_IA_NA
)
3599 status
= try_client_v6_address(&reply
->lease
, pool
,
3601 if (status
== ISC_R_SUCCESS
)
3605 if (status
== ISC_R_SUCCESS
)
3609 /* Note that this is just pedantry. There is no allocation to free. */
3610 data_string_forget(&data_addr
, MDL
);
3611 /* Return just the most recent status... */
3615 /* Look around for an address to give the client. First, look through the
3616 * old IA for addresses we can extend. Second, try to allocate a new address.
3617 * Finally, actually add that address into the current reply IA.
3620 find_client_address(struct reply_state
*reply
) {
3621 struct iaddr send_addr
;
3622 isc_result_t status
= ISC_R_NORESOURCES
;
3623 struct iasubopt
*lease
, *best_lease
= NULL
;
3624 struct binding_scope
**scope
;
3625 struct group
*group
;
3628 if (reply
->static_lease
) {
3629 if (reply
->host
== NULL
)
3630 return DHCP_R_INVALIDARG
;
3633 memcpy(send_addr
.iabuf
, reply
->fixed
.data
, 16);
3635 scope
= &global_scope
;
3636 group
= reply
->subnet
->group
;
3640 if (reply
->old_ia
!= NULL
) {
3641 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3642 struct shared_network
*candidate_shared
;
3643 struct ipv6_pond
*pond
;
3645 lease
= reply
->old_ia
->iasubopt
[i
];
3646 candidate_shared
= lease
->ipv6_pool
->shared_network
;
3647 pond
= lease
->ipv6_pool
->ipv6_pond
;
3650 * Look for the best lease on the client's shared
3651 * network, that is still permitted
3654 if ((candidate_shared
!= reply
->shared
) ||
3655 (lease6_usable(lease
) != ISC_TRUE
))
3658 if (((pond
->prohibit_list
!= NULL
) &&
3659 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3660 ((pond
->permit_list
!= NULL
) &&
3661 (!permitted(reply
->packet
, pond
->permit_list
))))
3664 best_lease
= lease_compare(lease
, best_lease
);
3668 /* Try to pick a new address if we didn't find one, or if we found an
3671 if ((best_lease
== NULL
) || (best_lease
->state
== FTS_ABANDONED
)) {
3672 status
= pick_v6_address(reply
);
3673 } else if (best_lease
!= NULL
) {
3674 iasubopt_reference(&reply
->lease
, best_lease
, MDL
);
3675 status
= ISC_R_SUCCESS
;
3678 /* Pick the abandoned lease as a last resort. */
3679 if ((status
== ISC_R_NORESOURCES
) && (best_lease
!= NULL
)) {
3680 /* I don't see how this is supposed to be done right now. */
3681 log_error("Best match for DUID %s is an abandoned address,"
3682 " This may be a result of multiple clients attempting"
3683 " to use this DUID",
3684 print_hex_1(reply
->client_id
.len
,
3685 reply
->client_id
.data
, 60));
3686 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
3689 /* Give up now if we didn't find a lease. */
3690 if (status
!= ISC_R_SUCCESS
)
3693 if (reply
->lease
== NULL
)
3694 log_fatal("Impossible condition at %s:%d.", MDL
);
3696 /* Draw binding scopes from the lease's binding scope, and config
3697 * from the lease's containing subnet and higher. Note that it may
3698 * be desirable to place the group attachment directly in the pool.
3700 scope
= &reply
->lease
->scope
;
3701 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
3704 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3707 status
= reply_process_is_addressed(reply
, scope
, group
);
3708 if (status
!= ISC_R_SUCCESS
)
3711 status
= reply_process_send_addr(reply
, &send_addr
);
3715 /* Once an address is found for a client, perform several common functions;
3716 * Calculate and store valid and preferred lease times, draw client options
3717 * into the option state.
3720 reply_process_is_addressed(struct reply_state
*reply
,
3721 struct binding_scope
**scope
, struct group
*group
)
3723 isc_result_t status
= ISC_R_SUCCESS
;
3724 struct data_string data
;
3725 struct option_cache
*oc
;
3726 struct option_state
*tmp_options
= NULL
;
3727 struct on_star
*on_star
;
3730 /* Initialize values we will cleanup. */
3731 memset(&data
, 0, sizeof(data
));
3734 * Find the proper on_star block to use. We use the
3735 * one in the lease if we have a lease or the one in
3736 * the reply if we don't have a lease because this is
3740 on_star
= &reply
->lease
->on_star
;
3742 on_star
= &reply
->on_star
;
3746 * Bring in the root configuration. We only do this to bring
3747 * in the on * statements, as we didn't have the lease available
3748 * we did it the first time.
3750 option_state_allocate(&tmp_options
, MDL
);
3751 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3752 reply
->packet
->options
, tmp_options
,
3753 &global_scope
, root_group
, NULL
,
3755 if (tmp_options
!= NULL
) {
3756 option_state_dereference(&tmp_options
, MDL
);
3760 * Bring configured options into the root packet level cache - start
3761 * with the lease's closest enclosing group (passed in by the caller
3764 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3765 reply
->packet
->options
, reply
->opt_state
,
3766 scope
, group
, root_group
, on_star
);
3768 /* Execute statements from class scopes. */
3769 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3770 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3771 reply
->packet
->options
,
3772 reply
->opt_state
, scope
,
3773 reply
->packet
->classes
[i
- 1]->group
,
3778 * If there is a host record, over-ride with values configured there,
3779 * without re-evaluating configuration from the previously executed
3780 * group or its common enclosers.
3782 if (reply
->host
!= NULL
)
3783 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3784 reply
->packet
->options
,
3785 reply
->opt_state
, scope
,
3786 reply
->host
->group
, group
,
3789 /* Determine valid lifetime. */
3790 if (reply
->client_valid
== 0)
3791 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
3793 reply
->send_valid
= reply
->client_valid
;
3795 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3796 SV_DEFAULT_LEASE_TIME
);
3798 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3799 reply
->packet
->options
,
3803 log_error("reply_process_is_addressed: unable to "
3804 "evaluate default lease time");
3805 status
= ISC_R_FAILURE
;
3809 reply
->send_valid
= getULong(data
.data
);
3810 data_string_forget(&data
, MDL
);
3813 /* Check to see if the lease time would cause us to wrap
3814 * in which case we make it infinite.
3815 * The following doesn't work on at least some systems:
3816 * (cur_time + reply->send_valid < cur_time)
3818 if (reply
->send_valid
!= INFINITE_TIME
) {
3819 time_t test_time
= cur_time
+ reply
->send_valid
;
3820 if (test_time
< cur_time
)
3821 reply
->send_valid
= INFINITE_TIME
;
3824 if (reply
->client_prefer
== 0)
3825 reply
->send_prefer
= reply
->send_valid
;
3827 reply
->send_prefer
= reply
->client_prefer
;
3829 if ((reply
->send_prefer
>= reply
->send_valid
) &&
3830 (reply
->send_valid
!= INFINITE_TIME
))
3831 reply
->send_prefer
= (reply
->send_valid
/ 2) +
3832 (reply
->send_valid
/ 8);
3834 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3835 SV_PREFER_LIFETIME
);
3837 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3838 reply
->packet
->options
,
3842 log_error("reply_process_is_addressed: unable to "
3843 "evaluate preferred lease time");
3844 status
= ISC_R_FAILURE
;
3848 reply
->send_prefer
= getULong(data
.data
);
3849 data_string_forget(&data
, MDL
);
3852 /* Note lowest values for later calculation of renew/rebind times. */
3853 if (reply
->min_prefer
> reply
->send_prefer
)
3854 reply
->min_prefer
= reply
->send_prefer
;
3856 if (reply
->min_valid
> reply
->send_valid
)
3857 reply
->min_valid
= reply
->send_valid
;
3861 * XXX: Old 4.0.0 alpha code would change the host {} record
3862 * XXX: uid upon lease assignment. This was intended to cover the
3863 * XXX: case where a client first identifies itself using vendor
3864 * XXX: options in a solicit, or request, but later neglects to include
3865 * XXX: these options in a Renew or Rebind. It is not clear that this
3866 * XXX: is required, and has some startling ramifications (such as
3867 * XXX: how to recover this dynamic host {} state across restarts).
3869 if (reply
->host
!= NULL
)
3870 change_host_uid(host
, reply
->client_id
->data
,
3871 reply
->client_id
->len
);
3874 /* Perform dynamic lease related update work. */
3875 if (reply
->lease
!= NULL
) {
3876 /* Cached lifetimes */
3877 reply
->lease
->prefer
= reply
->send_prefer
;
3878 reply
->lease
->valid
= reply
->send_valid
;
3880 /* Advance (or rewind) the valid lifetime.
3881 * In the protocol 0xFFFFFFFF is infinite
3882 * when connecting to the lease file MAX_TIME is
3884 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
3885 if (reply
->send_valid
== INFINITE_TIME
) {
3886 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
3888 reply
->lease
->soft_lifetime_end_time
=
3889 cur_time
+ reply
->send_valid
;
3891 /* Wait before renew! */
3894 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
3895 if (status
!= ISC_R_SUCCESS
) {
3896 log_fatal("reply_process_is_addressed: Unable to "
3897 "attach lease to new IA: %s",
3898 isc_result_totext(status
));
3902 * If this is a new lease, make sure it is attached somewhere.
3904 if (reply
->lease
->ia
== NULL
) {
3905 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
3909 /* Bring a copy of the relevant options into the IA scope. */
3910 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3911 reply
->packet
->options
, reply
->reply_ia
,
3912 scope
, group
, root_group
, NULL
);
3914 /* Execute statements from class scopes. */
3915 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3916 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3917 reply
->packet
->options
,
3918 reply
->reply_ia
, scope
,
3919 reply
->packet
->classes
[i
- 1]->group
,
3924 * And bring in host record configuration, if any, but not to overlap
3925 * the previous group or its common enclosers.
3927 if (reply
->host
!= NULL
)
3928 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3929 reply
->packet
->options
,
3930 reply
->reply_ia
, scope
,
3931 reply
->host
->group
, group
, NULL
);
3934 if (data
.data
!= NULL
)
3935 data_string_forget(&data
, MDL
);
3937 if (status
== ISC_R_SUCCESS
)
3938 reply
->client_resources
++;
3943 /* Simply send an IAADDR within the IA scope as described. */
3945 reply_process_send_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3946 isc_result_t status
= ISC_R_SUCCESS
;
3947 struct data_string data
;
3949 memset(&data
, 0, sizeof(data
));
3951 /* Now append the lease. */
3952 data
.len
= IAADDR_OFFSET
;
3953 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
3954 log_error("reply_process_send_addr: out of memory"
3955 "allocating new IAADDR buffer.");
3956 status
= ISC_R_NOMEMORY
;
3959 data
.data
= data
.buffer
->data
;
3961 memcpy(data
.buffer
->data
, addr
->iabuf
, 16);
3962 putULong(data
.buffer
->data
+ 16, reply
->send_prefer
);
3963 putULong(data
.buffer
->data
+ 20, reply
->send_valid
);
3965 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
3966 data
.buffer
, data
.buffer
->data
,
3967 data
.len
, D6O_IAADDR
, 0)) {
3968 log_error("reply_process_send_addr: unable "
3969 "to save IAADDR option");
3970 status
= ISC_R_FAILURE
;
3974 reply
->resources_included
= ISC_TRUE
;
3977 if (data
.data
!= NULL
)
3978 data_string_forget(&data
, MDL
);
3983 /* Choose the better of two leases. */
3984 static struct iasubopt
*
3985 lease_compare(struct iasubopt
*alpha
, struct iasubopt
*beta
) {
3991 switch(alpha
->state
) {
3993 switch(beta
->state
) {
3995 /* Choose the lease with the longest lifetime (most
3996 * likely the most recently allocated).
3998 if (alpha
->hard_lifetime_end_time
<
3999 beta
->hard_lifetime_end_time
)
4009 log_fatal("Impossible condition at %s:%d.", MDL
);
4014 switch (beta
->state
) {
4019 /* Choose the most recently expired lease. */
4020 if (alpha
->hard_lifetime_end_time
<
4021 beta
->hard_lifetime_end_time
)
4023 else if ((alpha
->hard_lifetime_end_time
==
4024 beta
->hard_lifetime_end_time
) &&
4025 (alpha
->soft_lifetime_end_time
<
4026 beta
->soft_lifetime_end_time
))
4035 log_fatal("Impossible condition at %s:%d.", MDL
);
4040 switch (beta
->state
) {
4046 /* Choose the lease that was abandoned longest ago. */
4047 if (alpha
->hard_lifetime_end_time
<
4048 beta
->hard_lifetime_end_time
)
4054 log_fatal("Impossible condition at %s:%d.", MDL
);
4059 log_fatal("Impossible condition at %s:%d.", MDL
);
4062 log_fatal("Triple impossible condition at %s:%d.", MDL
);
4066 /* Process a client-supplied IA_PD. This may append options to the tail of
4067 * the reply packet being built in the reply_state structure.
4070 reply_process_ia_pd(struct reply_state
*reply
, struct option_cache
*ia
) {
4071 isc_result_t status
= ISC_R_SUCCESS
;
4074 struct option_state
*packet_ia
;
4075 struct option_cache
*oc
;
4076 struct data_string ia_data
, data
;
4078 /* Initialize values that will get cleaned up on return. */
4080 memset(&ia_data
, 0, sizeof(ia_data
));
4081 memset(&data
, 0, sizeof(data
));
4083 * Note that find_client_prefix() may set reply->lease.
4086 /* Make sure there is at least room for the header. */
4087 if ((reply
->cursor
+ IA_PD_OFFSET
+ 4) > sizeof(reply
->buf
)) {
4088 log_error("reply_process_ia_pd: Reply too long for IA.");
4089 return ISC_R_NOSPACE
;
4093 /* Fetch the IA_PD contents. */
4094 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
4095 ia
, IA_PD_OFFSET
)) {
4096 log_error("reply_process_ia_pd: error evaluating ia");
4097 status
= ISC_R_FAILURE
;
4101 /* Extract IA_PD header contents. */
4102 iaid
= getULong(ia_data
.data
);
4103 reply
->renew
= getULong(ia_data
.data
+ 4);
4104 reply
->rebind
= getULong(ia_data
.data
+ 8);
4106 /* Create an IA_PD structure. */
4107 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
4108 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
4109 log_error("reply_process_ia_pd: no memory for ia.");
4110 status
= ISC_R_NOMEMORY
;
4113 reply
->ia
->ia_type
= D6O_IA_PD
;
4115 /* Cache pre-existing IA_PD, if any. */
4116 ia_hash_lookup(&reply
->old_ia
, ia_pd_active
,
4117 (unsigned char *)reply
->ia
->iaid_duid
.data
,
4118 reply
->ia
->iaid_duid
.len
, MDL
);
4121 * Create an option cache to carry the IA_PD option contents, and
4122 * execute any user-supplied values into it.
4124 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
4125 status
= ISC_R_NOMEMORY
;
4129 /* Check & count the fixed prefix host records. */
4130 reply
->static_prefixes
= 0;
4131 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_prefix
!= NULL
)) {
4132 struct iaddrcidrnetlist
*fp
;
4134 for (fp
= reply
->host
->fixed_prefix
; fp
!= NULL
;
4136 reply
->static_prefixes
+= 1;
4141 * Save the cursor position at the start of the IA_PD, so we can
4142 * set length and adjust t1/t2 values later. We write a temporary
4143 * header out now just in case we decide to adjust the packet
4144 * within sub-process functions.
4146 ia_cursor
= reply
->cursor
;
4148 /* Initialize the IA_PD header. First the code. */
4149 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_PD
);
4152 /* Then option length. */
4153 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
4156 /* Then IA_PD header contents; IAID. */
4157 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
4160 /* We store the client's t1 for now, and may over-ride it later. */
4161 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
4164 /* We store the client's t2 for now, and may over-ride it later. */
4165 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
4169 * For each prefix in this IA_PD, decide what to do about it.
4171 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAPREFIX
);
4172 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
4173 reply
->client_valid
= reply
->client_prefer
= 0;
4174 reply
->preflen
= -1;
4175 for (; oc
!= NULL
; oc
= oc
->next
) {
4176 status
= reply_process_prefix(reply
, oc
);
4179 * Canceled means we did not allocate prefixes to the
4180 * client, but we're "done" with this IA - we set a status
4181 * code. So transmit this reply, e.g., move on to the next
4184 if (status
== ISC_R_CANCELED
)
4187 if ((status
!= ISC_R_SUCCESS
) &&
4188 (status
!= ISC_R_ADDRINUSE
) &&
4189 (status
!= ISC_R_ADDRNOTAVAIL
))
4196 * If we fell through the above and never gave the client
4197 * a prefix, give it one now.
4199 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
4200 status
= find_client_prefix(reply
);
4202 if (status
== ISC_R_NORESOURCES
) {
4203 switch (reply
->packet
->dhcpv6_msg_type
) {
4204 case DHCPV6_SOLICIT
:
4206 * No prefix for any IA is handled
4211 case DHCPV6_REQUEST
:
4212 /* Same than for addresses. */
4213 option_state_dereference(&reply
->reply_ia
, MDL
);
4214 if (!option_state_allocate(&reply
->reply_ia
,
4217 log_error("reply_process_ia_pd: No "
4218 "memory for option state "
4220 status
= ISC_R_NOMEMORY
;
4224 if (!set_status_code(STATUS_NoPrefixAvail
,
4225 "No prefixes available "
4226 "for this interface.",
4228 log_error("reply_process_ia_pd: "
4230 "NoPrefixAvail status "
4232 status
= ISC_R_FAILURE
;
4236 status
= ISC_R_SUCCESS
;
4240 if (reply
->resources_included
)
4241 status
= ISC_R_SUCCESS
;
4248 if (status
!= ISC_R_SUCCESS
)
4253 * yes, goto's aren't the best but we also want to avoid extra
4256 if (status
== ISC_R_CANCELED
) {
4257 /* We're replying with a status code so we still need to
4258 * write it out in wire-format to the outbound buffer */
4259 write_to_packet(reply
, ia_cursor
);
4264 * Handle static prefixes, we always log stuff and if it's
4265 * a hard binding we run any commit statements that we have
4267 if (reply
->static_prefixes
!= 0) {
4268 char tmp_addr
[INET6_ADDRSTRLEN
];
4269 log_info("%s PD: address %s/%d to client with duid %s "
4271 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
4272 inet_ntop(AF_INET6
, reply
->fixed_pref
.lo_addr
.iabuf
,
4273 tmp_addr
, sizeof(tmp_addr
)),
4274 reply
->fixed_pref
.bits
,
4275 print_hex_1(reply
->client_id
.len
,
4276 reply
->client_id
.data
, 60),
4279 /* Write the lease out in wire-format to the outbound buffer */
4280 write_to_packet(reply
, ia_cursor
);
4282 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
4283 (reply
->on_star
.on_commit
!= NULL
)) {
4284 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
4285 reply
->packet
->options
,
4287 NULL
, reply
->on_star
.on_commit
,
4289 executable_statement_dereference
4290 (&reply
->on_star
.on_commit
, MDL
);
4296 * If we have any addresses log what we are doing.
4298 if (reply
->ia
->num_iasubopt
!= 0) {
4299 struct iasubopt
*tmp
;
4301 char tmp_addr
[INET6_ADDRSTRLEN
];
4303 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
4304 tmp
= reply
->ia
->iasubopt
[i
];
4306 log_info("%s PD: address %s/%d to client with duid %s"
4307 " iaid = %d valid for %u seconds",
4308 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
4309 inet_ntop(AF_INET6
, &tmp
->addr
,
4310 tmp_addr
, sizeof(tmp_addr
)),
4312 print_hex_1(reply
->client_id
.len
,
4313 reply
->client_id
.data
, 60),
4319 * If this is not a 'soft' binding, consume the new changes into
4320 * the database (if any have been attached to the ia_pd).
4322 * Loop through the assigned dynamic prefixes, referencing the
4323 * prefixes onto this IA_PD rather than any old ones, and updating
4324 * prefix pool timers for each (if any).
4326 * If a lease can be reused we skip renewing it or checking the
4327 * pool threshold. If it can't we flag that the IA must be commited
4328 * to the db and do the renewal and pool check.
4330 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
4331 (reply
->ia
->num_iasubopt
!= 0)) {
4332 int must_commit
= 0;
4333 struct iasubopt
*tmp
;
4334 struct data_string
*ia_id
;
4337 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
4338 tmp
= reply
->ia
->iasubopt
[i
];
4340 if (tmp
->ia
!= NULL
)
4341 ia_dereference(&tmp
->ia
, MDL
);
4342 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
4344 /* If we have anything to do on commit do it now */
4345 if (tmp
->on_star
.on_commit
!= NULL
) {
4346 execute_statements(NULL
, reply
->packet
,
4348 reply
->packet
->options
,
4351 tmp
->on_star
.on_commit
,
4353 executable_statement_dereference
4354 (&tmp
->on_star
.on_commit
, MDL
);
4357 if (!reuse_lease6(reply
, tmp
)) {
4358 /* Commit 'hard' bindings. */
4360 renew_lease6(tmp
->ipv6_pool
, tmp
);
4361 schedule_lease_timeout(tmp
->ipv6_pool
);
4363 /* Do our threshold check. */
4364 check_pool6_threshold(reply
, tmp
);
4368 /* write the IA_PD in wire-format to the outbound buffer */
4369 write_to_packet(reply
, ia_cursor
);
4371 /* Remove any old ia from the hash. */
4372 if (reply
->old_ia
!= NULL
) {
4373 if (!release_on_roam(reply
)) {
4374 ia_id
= &reply
->old_ia
->iaid_duid
;
4375 ia_hash_delete(ia_pd_active
,
4376 (unsigned char *)ia_id
->data
,
4380 ia_dereference(&reply
->old_ia
, MDL
);
4383 /* Put new ia into the hash. */
4384 reply
->ia
->cltt
= cur_time
;
4385 ia_id
= &reply
->ia
->iaid_duid
;
4386 ia_hash_add(ia_pd_active
, (unsigned char *)ia_id
->data
,
4387 ia_id
->len
, reply
->ia
, MDL
);
4389 /* If we couldn't reuse all of the iasubopts, we
4390 * must udpate the lease db */
4392 write_ia(reply
->ia
);
4395 /* write the IA_PD in wire-format to the outbound buffer */
4396 write_to_packet(reply
, ia_cursor
);
4397 schedule_lease_timeout_reply(reply
);
4401 if (packet_ia
!= NULL
)
4402 option_state_dereference(&packet_ia
, MDL
);
4403 if (reply
->reply_ia
!= NULL
)
4404 option_state_dereference(&reply
->reply_ia
, MDL
);
4405 if (ia_data
.data
!= NULL
)
4406 data_string_forget(&ia_data
, MDL
);
4407 if (data
.data
!= NULL
)
4408 data_string_forget(&data
, MDL
);
4409 if (reply
->ia
!= NULL
)
4410 ia_dereference(&reply
->ia
, MDL
);
4411 if (reply
->old_ia
!= NULL
)
4412 ia_dereference(&reply
->old_ia
, MDL
);
4413 if (reply
->lease
!= NULL
)
4414 iasubopt_dereference(&reply
->lease
, MDL
);
4415 if (reply
->on_star
.on_expiry
!= NULL
)
4416 executable_statement_dereference
4417 (&reply
->on_star
.on_expiry
, MDL
);
4418 if (reply
->on_star
.on_release
!= NULL
)
4419 executable_statement_dereference
4420 (&reply
->on_star
.on_release
, MDL
);
4423 * ISC_R_CANCELED is a status code used by the prefix processing to
4424 * indicate we're replying with a status code. This is still a
4425 * success at higher layers.
4427 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
4432 * \brief Find the proper scoping group for use with a v6 static prefix.
4434 * We start by trying to find a subnet based on the given prefix and
4435 * the shared network. If we don't find one then the prefix has been
4436 * declared outside of any subnets. If there is a static address
4437 * associated with the host we use it to try and find a subnet (this
4438 * should succeed). If there isn't a static address we fall back
4439 * to the shared subnet itself.
4440 * Once we have a subnet we extract the group from it and return it.
4442 * \param reply - the reply structure we use to collect information
4443 * we will use the fields shared, fixed_pref and host
4444 * from the structure
4446 * \return a pointer to the group structure to use for scoping
4449 static struct group
*
4450 find_group_by_prefix(struct reply_state
*reply
) {
4451 /* default group if we don't find anything better */
4452 struct group
*group
= reply
->shared
->group
;
4453 struct subnet
*subnet
= NULL
;
4454 struct iaddr tmp_addr
;
4455 struct data_string fixed_addr
;
4457 /* Try with the prefix first */
4458 if (find_grouped_subnet(&subnet
, reply
->shared
,
4459 reply
->fixed_pref
.lo_addr
, MDL
) != 0) {
4460 group
= subnet
->group
;
4461 subnet_dereference(&subnet
, MDL
);
4465 /* Didn't find a subnet via prefix, what about fixed address */
4466 /* The caller has already tested reply->host != NULL */
4468 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
4470 if ((reply
->host
->fixed_addr
!= NULL
) &&
4471 (evaluate_option_cache(&fixed_addr
, NULL
, NULL
, NULL
,
4472 NULL
, NULL
, &global_scope
,
4473 reply
->host
->fixed_addr
, MDL
))) {
4474 if (fixed_addr
.len
>= 16) {
4476 memcpy(tmp_addr
.iabuf
, fixed_addr
.data
, 16);
4477 if (find_grouped_subnet(&subnet
, reply
->shared
,
4478 tmp_addr
, MDL
) != 0) {
4479 group
= subnet
->group
;
4480 subnet_dereference(&subnet
, MDL
);
4483 data_string_forget(&fixed_addr
, MDL
);
4486 /* return whatever we got */
4491 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
4492 * contents into the reply's current ia_pd-scoped option cache. Returns
4493 * ISC_R_CANCELED in the event we are replying with a status code and do
4494 * not wish to process more IAPREFIXes within this IA_PD.
4497 reply_process_prefix(struct reply_state
*reply
, struct option_cache
*pref
) {
4498 u_int32_t pref_life
, valid_life
;
4499 struct binding_scope
**scope
;
4500 struct iaddrcidrnet tmp_pref
;
4501 struct option_cache
*oc
;
4502 struct data_string iapref
, data
;
4503 isc_result_t status
= ISC_R_SUCCESS
;
4504 struct group
*group
;
4506 /* Initializes values that will be cleaned up. */
4507 memset(&iapref
, 0, sizeof(iapref
));
4508 memset(&data
, 0, sizeof(data
));
4509 /* Note that reply->lease may be set by prefix_is_owned() */
4512 * There is no point trying to process an incoming prefix if there
4513 * is no room for an outgoing prefix.
4515 if ((reply
->cursor
+ 29) > sizeof(reply
->buf
)) {
4516 log_error("reply_process_prefix: Out of room for prefix.");
4517 return ISC_R_NOSPACE
;
4520 /* Extract this IAPREFIX option. */
4521 if (!evaluate_option_cache(&iapref
, reply
->packet
, NULL
, NULL
,
4522 reply
->packet
->options
, NULL
, &global_scope
,
4524 (iapref
.len
< IAPREFIX_OFFSET
)) {
4525 log_error("reply_process_prefix: error evaluating IAPREFIX.");
4526 status
= ISC_R_FAILURE
;
4531 * Layout: preferred and valid lifetimes followed by the prefix
4532 * length and the IPv6 address.
4534 pref_life
= getULong(iapref
.data
);
4535 valid_life
= getULong(iapref
.data
+ 4);
4537 if ((reply
->client_valid
== 0) ||
4538 (reply
->client_valid
> valid_life
))
4539 reply
->client_valid
= valid_life
;
4541 if ((reply
->client_prefer
== 0) ||
4542 (reply
->client_prefer
> pref_life
))
4543 reply
->client_prefer
= pref_life
;
4546 * Clients may choose to send ::/0 as a prefix, with the idea to give
4547 * hints about preferred-lifetime or valid-lifetime.
4549 tmp_pref
.lo_addr
.len
= 16;
4550 memset(tmp_pref
.lo_addr
.iabuf
, 0, 16);
4551 if ((iapref
.data
[8] == 0) &&
4552 (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0)) {
4553 /* Status remains success; we just ignore this one. */
4558 * Clients may choose to send ::/X as a prefix to specify a
4559 * preferred/requested prefix length. Note X is never zero here.
4561 tmp_pref
.bits
= (int) iapref
.data
[8];
4562 if (reply
->preflen
< 0) {
4563 /* Cache the first preferred prefix length. */
4564 reply
->preflen
= tmp_pref
.bits
;
4566 if (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0) {
4570 memcpy(tmp_pref
.lo_addr
.iabuf
, iapref
.data
+ 9, 16);
4572 /* Verify the prefix belongs to the client. */
4573 if (!prefix_is_owned(reply
, &tmp_pref
)) {
4574 /* Same than for addresses. */
4575 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
4576 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
4577 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
4578 status
= reply_process_try_prefix(reply
, &tmp_pref
);
4580 /* Either error out or skip this prefix. */
4581 if ((status
!= ISC_R_SUCCESS
) &&
4582 (status
!= ISC_R_ADDRINUSE
) &&
4583 (status
!= ISC_R_ADDRNOTAVAIL
))
4586 if (reply
->lease
== NULL
) {
4587 if (reply
->packet
->dhcpv6_msg_type
==
4589 reply
->send_prefer
= 0;
4590 reply
->send_valid
= 0;
4594 /* status remains success - ignore */
4598 * RFC3633 section 18.2.3:
4600 * If the delegating router cannot find a binding
4601 * for the requesting router's IA_PD the delegating
4602 * router returns the IA_PD containing no prefixes
4603 * with a Status Code option set to NoBinding in the
4606 * On mismatch we (ab)use this pretending we have not the IA
4607 * as soon as we have not a prefix.
4609 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
4610 /* Rewind the IA_PD to empty. */
4611 option_state_dereference(&reply
->reply_ia
, MDL
);
4612 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
4613 log_error("reply_process_prefix: No memory "
4614 "for option state wipe.");
4615 status
= ISC_R_NOMEMORY
;
4619 /* Append a NoBinding status code. */
4620 if (!set_status_code(STATUS_NoBinding
,
4621 "Prefix not bound to this "
4622 "interface.", reply
->reply_ia
)) {
4623 log_error("reply_process_prefix: Unable to "
4624 "attach status code.");
4625 status
= ISC_R_FAILURE
;
4629 /* Fin (no more IAPREFIXes). */
4630 status
= ISC_R_CANCELED
;
4633 log_error("It is impossible to lease a client that is "
4634 "not sending a solicit, request, renew, or "
4636 status
= ISC_R_FAILURE
;
4641 if (reply
->static_prefixes
> 0) {
4642 if (reply
->host
== NULL
)
4643 log_fatal("Impossible condition at %s:%d.", MDL
);
4645 scope
= &global_scope
;
4647 /* Copy the static prefix for logging and finding the group */
4648 memcpy(&reply
->fixed_pref
, &tmp_pref
, sizeof(tmp_pref
));
4650 /* Try to find a group for the static prefix */
4651 group
= find_group_by_prefix(reply
);
4653 if (reply
->lease
== NULL
)
4654 log_fatal("Impossible condition at %s:%d.", MDL
);
4656 scope
= &reply
->lease
->scope
;
4657 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4661 * If client_resources is nonzero, then the reply_process_is_prefixed
4662 * function has executed configuration state into the reply option
4663 * cache. We will use that valid cache to derive configuration for
4664 * whether or not to engage in additional prefixes, and similar.
4666 if (reply
->client_resources
!= 0) {
4670 * Does this client have "enough" prefixes already? Default
4671 * to one. Everybody gets one, and one should be enough for
4674 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4675 SV_LIMIT_PREFS_PER_IA
);
4677 if (!evaluate_option_cache(&data
, reply
->packet
,
4679 reply
->packet
->options
,
4683 log_error("reply_process_prefix: unable to "
4684 "evaluate prefs-per-ia value.");
4685 status
= ISC_R_FAILURE
;
4689 limit
= getULong(data
.data
);
4690 data_string_forget(&data
, MDL
);
4694 * If we wish to limit the client to a certain number of
4695 * prefixes, then omit the prefix from the reply.
4697 if (reply
->client_resources
>= limit
)
4701 status
= reply_process_is_prefixed(reply
, scope
, group
);
4702 if (status
!= ISC_R_SUCCESS
)
4706 status
= reply_process_send_prefix(reply
, &tmp_pref
);
4709 if (iapref
.data
!= NULL
)
4710 data_string_forget(&iapref
, MDL
);
4711 if (data
.data
!= NULL
)
4712 data_string_forget(&data
, MDL
);
4713 if (reply
->lease
!= NULL
)
4714 iasubopt_dereference(&reply
->lease
, MDL
);
4720 * Verify the prefix belongs to the client. If we've got a host
4721 * record with fixed prefixes, it has to be an assigned prefix
4722 * (fault out all else). Otherwise it's a dynamic prefix, so lookup
4723 * that prefix and make sure it belongs to this DUID:IAID pair.
4725 static isc_boolean_t
4726 prefix_is_owned(struct reply_state
*reply
, struct iaddrcidrnet
*pref
) {
4727 struct iaddrcidrnetlist
*l
;
4729 struct ipv6_pond
*pond
;
4732 * This faults out prefixes that don't match fixed prefixes.
4734 if (reply
->static_prefixes
> 0) {
4735 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4736 if ((pref
->bits
== l
->cidrnet
.bits
) &&
4737 (memcmp(pref
->lo_addr
.iabuf
,
4738 l
->cidrnet
.lo_addr
.iabuf
, 16) == 0))
4744 if ((reply
->old_ia
== NULL
) ||
4745 (reply
->old_ia
->num_iasubopt
== 0))
4748 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4749 struct iasubopt
*tmp
;
4751 tmp
= reply
->old_ia
->iasubopt
[i
];
4753 if ((pref
->bits
== (int) tmp
->plen
) &&
4754 (memcmp(pref
->lo_addr
.iabuf
, &tmp
->addr
, 16) == 0)) {
4755 if (lease6_usable(tmp
) == ISC_FALSE
) {
4759 pond
= tmp
->ipv6_pool
->ipv6_pond
;
4760 if (((pond
->prohibit_list
!= NULL
) &&
4761 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4762 ((pond
->permit_list
!= NULL
) &&
4763 (!permitted(reply
->packet
, pond
->permit_list
))))
4766 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
4775 * This function only returns failure on 'hard' failures. If it succeeds,
4776 * it will leave a prefix structure behind.
4779 reply_process_try_prefix(struct reply_state
*reply
,
4780 struct iaddrcidrnet
*pref
) {
4781 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
4782 struct ipv6_pool
*pool
= NULL
;
4783 struct ipv6_pond
*pond
= NULL
;
4785 struct data_string data_pref
;
4787 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
4788 (pref
== NULL
) || (reply
->lease
!= NULL
))
4789 return (DHCP_R_INVALIDARG
);
4792 * Do a quick walk through of the ponds and pools
4793 * to see if we have any prefix pools
4795 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4796 if (pond
->ipv6_pools
== NULL
)
4799 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4800 if (pool
->pool_type
== D6O_IA_PD
)
4807 /* If we get here and p is NULL we have no useful pools */
4809 return (ISC_R_ADDRNOTAVAIL
);
4812 memset(&data_pref
, 0, sizeof(data_pref
));
4814 if (!buffer_allocate(&data_pref
.buffer
, data_pref
.len
, MDL
)) {
4815 log_error("reply_process_try_prefix: out of memory.");
4816 return (ISC_R_NOMEMORY
);
4818 data_pref
.data
= data_pref
.buffer
->data
;
4819 data_pref
.buffer
->data
[0] = (u_int8_t
) pref
->bits
;
4820 memcpy(data_pref
.buffer
->data
+ 1, pref
->lo_addr
.iabuf
, 16);
4823 * We have at least one pool that could provide a prefix
4824 * Now we walk through the ponds and pools again and check
4825 * to see if the client is permitted and if an prefix is
4830 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4831 if (((pond
->prohibit_list
!= NULL
) &&
4832 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4833 ((pond
->permit_list
!= NULL
) &&
4834 (!permitted(reply
->packet
, pond
->permit_list
))))
4837 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4838 if (pool
->pool_type
!= D6O_IA_PD
) {
4842 status
= try_client_v6_prefix(&reply
->lease
, pool
,
4844 /* If we found it in this pool (either in use or available),
4845 there is no need to look further. */
4846 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4849 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4853 data_string_forget(&data_pref
, MDL
);
4854 /* Return just the most recent status... */
4858 /* Look around for a prefix to give the client. First, look through the old
4859 * IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
4860 * Finally, actually add that prefix into the current reply IA_PD.
4863 find_client_prefix(struct reply_state
*reply
) {
4864 struct iaddrcidrnet send_pref
;
4865 isc_result_t status
= ISC_R_NORESOURCES
;
4866 struct iasubopt
*prefix
, *best_prefix
= NULL
;
4867 struct binding_scope
**scope
;
4869 struct group
*group
;
4871 if (reply
->static_prefixes
> 0) {
4872 struct iaddrcidrnetlist
*l
;
4874 if (reply
->host
== NULL
)
4875 return DHCP_R_INVALIDARG
;
4877 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4878 if (l
->cidrnet
.bits
== reply
->preflen
)
4883 * If no fixed prefix has the preferred length,
4884 * get the first one.
4886 l
= reply
->host
->fixed_prefix
;
4888 memcpy(&send_pref
, &l
->cidrnet
, sizeof(send_pref
));
4890 scope
= &global_scope
;
4892 /* Copy the prefix for logging purposes */
4893 memcpy(&reply
->fixed_pref
, &l
->cidrnet
, sizeof(send_pref
));
4895 /* Try to find a group for the static prefix */
4896 group
= find_group_by_prefix(reply
);
4901 if (reply
->old_ia
!= NULL
) {
4902 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4903 struct shared_network
*candidate_shared
;
4904 struct ipv6_pond
*pond
;
4906 prefix
= reply
->old_ia
->iasubopt
[i
];
4907 candidate_shared
= prefix
->ipv6_pool
->shared_network
;
4908 pond
= prefix
->ipv6_pool
->ipv6_pond
;
4911 * Consider this prefix if it is in a global pool or
4912 * if it is scoped in a pool under the client's shared
4915 if (((candidate_shared
!= NULL
) &&
4916 (candidate_shared
!= reply
->shared
)) ||
4917 (lease6_usable(prefix
) != ISC_TRUE
))
4921 * And check if the prefix is still permitted
4924 if (((pond
->prohibit_list
!= NULL
) &&
4925 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4926 ((pond
->permit_list
!= NULL
) &&
4927 (!permitted(reply
->packet
, pond
->permit_list
))))
4930 best_prefix
= prefix_compare(reply
, prefix
,
4935 * If we have prefix length hint and we're not igoring them,
4936 * then toss the best match if it doesn't match the hint,
4937 * unless this is in response to a rebind. In the latter
4938 * case we're supposed to return it with zero lifetimes.
4940 if (best_prefix
&& (reply
->preflen
> 0)
4941 && (prefix_length_mode
!= PLM_IGNORE
)
4942 && (reply
->preflen
!= best_prefix
->plen
)
4943 && (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
4948 /* Try to pick a new prefix if we didn't find one, or if we found an
4951 if ((best_prefix
== NULL
) || (best_prefix
->state
== FTS_ABANDONED
)) {
4952 status
= pick_v6_prefix(reply
);
4953 } else if (best_prefix
!= NULL
) {
4954 iasubopt_reference(&reply
->lease
, best_prefix
, MDL
);
4955 status
= ISC_R_SUCCESS
;
4958 /* Pick the abandoned prefix as a last resort. */
4959 if ((status
== ISC_R_NORESOURCES
) && (best_prefix
!= NULL
)) {
4960 /* I don't see how this is supposed to be done right now. */
4961 log_error("Reclaiming abandoned prefixes is not yet "
4962 "supported. Treating this as an out of space "
4964 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
4967 /* Give up now if we didn't find a prefix. */
4968 if (status
!= ISC_R_SUCCESS
)
4971 if (reply
->lease
== NULL
)
4972 log_fatal("Impossible condition at %s:%d.", MDL
);
4974 scope
= &reply
->lease
->scope
;
4975 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4977 send_pref
.lo_addr
.len
= 16;
4978 memcpy(send_pref
.lo_addr
.iabuf
, &reply
->lease
->addr
, 16);
4979 send_pref
.bits
= (int) reply
->lease
->plen
;
4982 status
= reply_process_is_prefixed(reply
, scope
, group
);
4983 if (status
!= ISC_R_SUCCESS
)
4986 status
= reply_process_send_prefix(reply
, &send_pref
);
4990 /* Once a prefix is found for a client, perform several common functions;
4991 * Calculate and store valid and preferred prefix times, draw client options
4992 * into the option state.
4995 reply_process_is_prefixed(struct reply_state
*reply
,
4996 struct binding_scope
**scope
, struct group
*group
)
4998 isc_result_t status
= ISC_R_SUCCESS
;
4999 struct data_string data
;
5000 struct option_cache
*oc
;
5001 struct option_state
*tmp_options
= NULL
;
5002 struct on_star
*on_star
;
5005 /* Initialize values we will cleanup. */
5006 memset(&data
, 0, sizeof(data
));
5009 * Find the proper on_star block to use. We use the
5010 * one in the lease if we have a lease or the one in
5011 * the reply if we don't have a lease because this is
5015 on_star
= &reply
->lease
->on_star
;
5017 on_star
= &reply
->on_star
;
5021 * Bring in the root configuration. We only do this to bring
5022 * in the on * statements, as we didn't have the lease available
5023 * we we did it the first time.
5025 option_state_allocate(&tmp_options
, MDL
);
5026 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5027 reply
->packet
->options
, tmp_options
,
5028 &global_scope
, root_group
, NULL
,
5030 if (tmp_options
!= NULL
) {
5031 option_state_dereference(&tmp_options
, MDL
);
5035 * Bring configured options into the root packet level cache - start
5036 * with the lease's closest enclosing group (passed in by the caller
5039 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5040 reply
->packet
->options
, reply
->opt_state
,
5041 scope
, group
, root_group
, on_star
);
5043 /* Execute statements from class scopes. */
5044 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
5045 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5046 reply
->packet
->options
,
5047 reply
->opt_state
, scope
,
5048 reply
->packet
->classes
[i
- 1]->group
,
5053 * If there is a host record, over-ride with values configured there,
5054 * without re-evaluating configuration from the previously executed
5055 * group or its common enclosers.
5057 if (reply
->host
!= NULL
)
5058 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5059 reply
->packet
->options
,
5060 reply
->opt_state
, scope
,
5061 reply
->host
->group
, group
,
5064 /* Determine valid lifetime. */
5065 if (reply
->client_valid
== 0)
5066 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
5068 reply
->send_valid
= reply
->client_valid
;
5070 oc
= lookup_option(&server_universe
, reply
->opt_state
,
5071 SV_DEFAULT_LEASE_TIME
);
5073 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
5074 reply
->packet
->options
,
5078 log_error("reply_process_is_prefixed: unable to "
5079 "evaluate default prefix time");
5080 status
= ISC_R_FAILURE
;
5084 reply
->send_valid
= getULong(data
.data
);
5085 data_string_forget(&data
, MDL
);
5088 /* Check to see if the lease time would cause us to wrap
5089 * in which case we make it infinite.
5090 * The following doesn't work on at least some systems:
5091 * (cur_time + reply->send_valid < cur_time)
5093 if (reply
->send_valid
!= INFINITE_TIME
) {
5094 time_t test_time
= cur_time
+ reply
->send_valid
;
5095 if (test_time
< cur_time
)
5096 reply
->send_valid
= INFINITE_TIME
;
5099 if (reply
->client_prefer
== 0)
5100 reply
->send_prefer
= reply
->send_valid
;
5102 reply
->send_prefer
= reply
->client_prefer
;
5104 if ((reply
->send_prefer
>= reply
->send_valid
) &&
5105 (reply
->send_valid
!= INFINITE_TIME
))
5106 reply
->send_prefer
= (reply
->send_valid
/ 2) +
5107 (reply
->send_valid
/ 8);
5109 oc
= lookup_option(&server_universe
, reply
->opt_state
,
5110 SV_PREFER_LIFETIME
);
5112 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
5113 reply
->packet
->options
,
5117 log_error("reply_process_is_prefixed: unable to "
5118 "evaluate preferred prefix time");
5119 status
= ISC_R_FAILURE
;
5123 reply
->send_prefer
= getULong(data
.data
);
5124 data_string_forget(&data
, MDL
);
5127 /* Note lowest values for later calculation of renew/rebind times. */
5128 if (reply
->min_prefer
> reply
->send_prefer
)
5129 reply
->min_prefer
= reply
->send_prefer
;
5131 if (reply
->min_valid
> reply
->send_valid
)
5132 reply
->min_valid
= reply
->send_valid
;
5134 /* Perform dynamic prefix related update work. */
5135 if (reply
->lease
!= NULL
) {
5136 /* Cached lifetimes */
5137 reply
->lease
->prefer
= reply
->send_prefer
;
5138 reply
->lease
->valid
= reply
->send_valid
;
5140 /* Advance (or rewind) the valid lifetime.
5141 * In the protocol 0xFFFFFFFF is infinite
5142 * when connecting to the lease file MAX_TIME is
5144 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
5145 if (reply
->send_valid
== INFINITE_TIME
) {
5146 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
5148 reply
->lease
->soft_lifetime_end_time
=
5149 cur_time
+ reply
->send_valid
;
5151 /* Wait before renew! */
5154 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
5155 if (status
!= ISC_R_SUCCESS
) {
5156 log_fatal("reply_process_is_prefixed: Unable to "
5157 "attach prefix to new IA_PD: %s",
5158 isc_result_totext(status
));
5162 * If this is a new prefix, make sure it is attached somewhere.
5164 if (reply
->lease
->ia
== NULL
) {
5165 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
5169 /* Bring a copy of the relevant options into the IA_PD scope. */
5170 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5171 reply
->packet
->options
, reply
->reply_ia
,
5172 scope
, group
, root_group
, NULL
);
5174 /* Execute statements from class scopes. */
5175 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
5176 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5177 reply
->packet
->options
,
5178 reply
->reply_ia
, scope
,
5179 reply
->packet
->classes
[i
- 1]->group
,
5184 * And bring in host record configuration, if any, but not to overlap
5185 * the previous group or its common enclosers.
5187 if (reply
->host
!= NULL
)
5188 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
5189 reply
->packet
->options
,
5190 reply
->reply_ia
, scope
,
5191 reply
->host
->group
, group
, NULL
);
5194 if (data
.data
!= NULL
)
5195 data_string_forget(&data
, MDL
);
5197 if (status
== ISC_R_SUCCESS
)
5198 reply
->client_resources
++;
5203 /* Simply send an IAPREFIX within the IA_PD scope as described. */
5205 reply_process_send_prefix(struct reply_state
*reply
,
5206 struct iaddrcidrnet
*pref
) {
5207 isc_result_t status
= ISC_R_SUCCESS
;
5208 struct data_string data
;
5210 memset(&data
, 0, sizeof(data
));
5212 /* Now append the prefix. */
5213 data
.len
= IAPREFIX_OFFSET
;
5214 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
5215 log_error("reply_process_send_prefix: out of memory"
5216 "allocating new IAPREFIX buffer.");
5217 status
= ISC_R_NOMEMORY
;
5220 data
.data
= data
.buffer
->data
;
5222 putULong(data
.buffer
->data
, reply
->send_prefer
);
5223 putULong(data
.buffer
->data
+ 4, reply
->send_valid
);
5224 data
.buffer
->data
[8] = pref
->bits
;
5225 memcpy(data
.buffer
->data
+ 9, pref
->lo_addr
.iabuf
, 16);
5227 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
5228 data
.buffer
, data
.buffer
->data
,
5229 data
.len
, D6O_IAPREFIX
, 0)) {
5230 log_error("reply_process_send_prefix: unable "
5231 "to save IAPREFIX option");
5232 status
= ISC_R_FAILURE
;
5236 reply
->resources_included
= ISC_TRUE
;
5239 if (data
.data
!= NULL
)
5240 data_string_forget(&data
, MDL
);
5245 /* Choose the better of two prefixes. */
5246 static struct iasubopt
*
5247 prefix_compare(struct reply_state
*reply
,
5248 struct iasubopt
*alpha
, struct iasubopt
*beta
) {
5254 if (reply
->preflen
>= 0) {
5255 if ((alpha
->plen
== reply
->preflen
) &&
5256 (beta
->plen
!= reply
->preflen
))
5258 if ((beta
->plen
== reply
->preflen
) &&
5259 (alpha
->plen
!= reply
->preflen
))
5263 switch(alpha
->state
) {
5265 switch(beta
->state
) {
5267 /* Choose the prefix with the longest lifetime (most
5268 * likely the most recently allocated).
5270 if (alpha
->hard_lifetime_end_time
<
5271 beta
->hard_lifetime_end_time
)
5281 log_fatal("Impossible condition at %s:%d.", MDL
);
5286 switch (beta
->state
) {
5291 /* Choose the most recently expired prefix. */
5292 if (alpha
->hard_lifetime_end_time
<
5293 beta
->hard_lifetime_end_time
)
5295 else if ((alpha
->hard_lifetime_end_time
==
5296 beta
->hard_lifetime_end_time
) &&
5297 (alpha
->soft_lifetime_end_time
<
5298 beta
->soft_lifetime_end_time
))
5307 log_fatal("Impossible condition at %s:%d.", MDL
);
5312 switch (beta
->state
) {
5318 /* Choose the prefix that was abandoned longest ago. */
5319 if (alpha
->hard_lifetime_end_time
<
5320 beta
->hard_lifetime_end_time
)
5326 log_fatal("Impossible condition at %s:%d.", MDL
);
5331 log_fatal("Impossible condition at %s:%d.", MDL
);
5334 log_fatal("Triple impossible condition at %s:%d.", MDL
);
5339 * Solicit is how a client starts requesting addresses.
5341 * If the client asks for rapid commit, and we support it, we will
5342 * allocate the addresses and reply.
5344 * Otherwise we will send an advertise message.
5348 dhcpv6_solicit(struct data_string
*reply_ret
, struct packet
*packet
) {
5349 struct data_string client_id
;
5352 * Validate our input.
5354 if (!valid_client_msg(packet
, &client_id
)) {
5358 lease_to_client(reply_ret
, packet
, &client_id
, NULL
);
5363 data_string_forget(&client_id
, MDL
);
5367 * Request is how a client actually requests addresses.
5369 * Very similar to Solicit handling, except the server DUID is required.
5373 dhcpv6_request(struct data_string
*reply_ret
, struct packet
*packet
) {
5374 struct data_string client_id
;
5375 struct data_string server_id
;
5378 * Validate our input.
5380 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5384 /* If the REQUEST arrived via unicast and unicast option isn't set,
5385 * reject it per RFC 3315, Sec 18.2.1 */
5386 if (packet
->unicast
== ISC_TRUE
&&
5387 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5388 unicast_reject(reply_ret
, packet
, &client_id
, &server_id
);
5393 lease_to_client(reply_ret
, packet
, &client_id
, &server_id
);
5399 data_string_forget(&client_id
, MDL
);
5400 data_string_forget(&server_id
, MDL
);
5403 /* Find a DHCPv6 packet's shared network from hints in the packet.
5406 shared_network_from_packet6(struct shared_network
**shared
,
5407 struct packet
*packet
)
5409 const struct packet
*chk_packet
;
5410 const struct in6_addr
*link_addr
, *first_link_addr
;
5411 struct iaddr tmp_addr
;
5412 struct subnet
*subnet
;
5413 isc_result_t status
;
5415 if ((shared
== NULL
) || (*shared
!= NULL
) || (packet
== NULL
))
5416 return DHCP_R_INVALIDARG
;
5419 * First, find the link address where the packet from the client
5420 * first appeared (if this packet was relayed).
5422 first_link_addr
= NULL
;
5423 chk_packet
= packet
->dhcpv6_container_packet
;
5424 while (chk_packet
!= NULL
) {
5425 link_addr
= &chk_packet
->dhcpv6_link_address
;
5426 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
5427 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
5428 first_link_addr
= link_addr
;
5431 chk_packet
= chk_packet
->dhcpv6_container_packet
;
5435 * If there is a relayed link address, find the subnet associated
5436 * with that, and use that to get the appropriate
5439 if (first_link_addr
!= NULL
) {
5440 tmp_addr
.len
= sizeof(*first_link_addr
);
5441 memcpy(tmp_addr
.iabuf
,
5442 first_link_addr
, sizeof(*first_link_addr
));
5444 if (!find_subnet(&subnet
, tmp_addr
, MDL
)) {
5445 log_debug("No subnet found for link-address %s.",
5447 return ISC_R_NOTFOUND
;
5449 status
= shared_network_reference(shared
,
5450 subnet
->shared_network
, MDL
);
5451 subnet_dereference(&subnet
, MDL
);
5454 * If there is no link address, we will use the interface
5455 * that this packet came in on to pick the shared_network.
5457 } else if (packet
->interface
!= NULL
) {
5458 status
= shared_network_reference(shared
,
5459 packet
->interface
->shared_network
,
5461 if (packet
->dhcpv6_container_packet
!= NULL
) {
5462 log_info("[L2 Relay] No link address in relay packet "
5463 "assuming L2 relay and using receiving "
5469 * We shouldn't be able to get here but if there is no link
5470 * address and no interface we don't know where to get the
5471 * pool from log an error and return an error.
5473 log_error("No interface and no link address "
5474 "can't determine pool");
5475 status
= DHCP_R_INVALIDARG
;
5482 * When a client thinks it might be on a new link, it sends a
5485 * From RFC3315 section 18.2.2:
5487 * When the server receives a Confirm message, the server determines
5488 * whether the addresses in the Confirm message are appropriate for the
5489 * link to which the client is attached. If all of the addresses in the
5490 * Confirm message pass this test, the server returns a status of
5491 * Success. If any of the addresses do not pass this test, the server
5492 * returns a status of NotOnLink. If the server is unable to perform
5493 * this test (for example, the server does not have information about
5494 * prefixes on the link to which the client is connected), or there were
5495 * no addresses in any of the IAs sent by the client, the server MUST
5496 * NOT send a reply to the client.
5500 dhcpv6_confirm(struct data_string
*reply_ret
, struct packet
*packet
) {
5501 struct shared_network
*shared
;
5502 struct subnet
*subnet
;
5503 struct option_cache
*ia
, *ta
, *oc
;
5504 struct data_string cli_enc_opt_data
, iaaddr
, client_id
, packet_oro
;
5505 struct option_state
*cli_enc_opt_state
, *opt_state
;
5506 struct iaddr cli_addr
;
5508 isc_boolean_t inappropriate
, has_addrs
;
5509 char reply_data
[65536];
5510 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5511 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5514 * Basic client message validation.
5516 memset(&client_id
, 0, sizeof(client_id
));
5517 if (!valid_client_msg(packet
, &client_id
)) {
5522 * Do not process Confirms that do not have IA's we do not recognize.
5524 ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5525 ta
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
5526 if ((ia
== NULL
) && (ta
== NULL
))
5530 * IA_PD's are simply ignored.
5532 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5535 * Bit of variable initialization.
5537 opt_state
= cli_enc_opt_state
= NULL
;
5538 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5539 memset(&iaaddr
, 0, sizeof(iaaddr
));
5540 memset(&packet_oro
, 0, sizeof(packet_oro
));
5542 /* Determine what shared network the client is connected to. We
5543 * must not respond if we don't have any information about the
5544 * network the client is on.
5547 if ((shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
) ||
5551 /* If there are no recorded subnets, then we have no
5552 * information about this subnet - ignore Confirms.
5554 subnet
= shared
->subnets
;
5558 /* Are the addresses in all the IA's appropriate for that link? */
5559 has_addrs
= inappropriate
= ISC_FALSE
;
5561 while(!inappropriate
) {
5562 /* If we've reached the end of the IA_NA pass, move to the
5565 if ((pass
== D6O_IA_NA
) && (ia
== NULL
)) {
5570 /* If we've reached the end of all passes, we're done. */
5574 if (((pass
== D6O_IA_NA
) &&
5575 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5577 packet
, ia
, IA_NA_OFFSET
)) ||
5578 ((pass
== D6O_IA_TA
) &&
5579 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5581 packet
, ia
, IA_TA_OFFSET
))) {
5585 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5588 for ( ; oc
!= NULL
; oc
= oc
->next
) {
5589 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5590 packet
->options
, NULL
,
5591 &global_scope
, oc
, MDL
) ||
5592 (iaaddr
.len
< IAADDR_OFFSET
)) {
5593 log_error("dhcpv6_confirm: "
5594 "error evaluating IAADDR.");
5598 /* Copy out the IPv6 address for processing. */
5600 memcpy(cli_addr
.iabuf
, iaaddr
.data
, 16);
5602 data_string_forget(&iaaddr
, MDL
);
5604 /* Record that we've processed at least one address. */
5605 has_addrs
= ISC_TRUE
;
5607 /* Find out if any subnets cover this address. */
5608 for (subnet
= shared
->subnets
; subnet
!= NULL
;
5609 subnet
= subnet
->next_sibling
) {
5610 if (addr_eq(subnet_number(cli_addr
,
5616 /* If we reach the end of the subnet list, and no
5617 * subnet matches the client address, then it must
5618 * be inappropriate to the link (so far as our
5619 * configuration says). Once we've found one
5620 * inappropriate address, there is no reason to
5621 * continue searching.
5623 if (subnet
== NULL
) {
5624 inappropriate
= ISC_TRUE
;
5629 option_state_dereference(&cli_enc_opt_state
, MDL
);
5630 data_string_forget(&cli_enc_opt_data
, MDL
);
5632 /* Advance to the next IA_*. */
5636 /* If the client supplied no addresses, do not reply. */
5643 if (!start_reply(packet
, &client_id
, NULL
, &opt_state
, reply
)) {
5650 if (inappropriate
) {
5651 if (!set_status_code(STATUS_NotOnLink
,
5652 "Some of the addresses are not on link.",
5657 if (!set_status_code(STATUS_Success
,
5658 "All addresses still on link.",
5665 * Only one option: add it.
5667 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5668 sizeof(reply_data
)-reply_ofs
,
5670 required_opts
, &packet_oro
);
5673 * Return our reply to the caller.
5675 reply_ret
->len
= reply_ofs
;
5676 reply_ret
->buffer
= NULL
;
5677 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5678 log_fatal("No memory to store reply.");
5680 reply_ret
->data
= reply_ret
->buffer
->data
;
5681 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5684 /* Cleanup any stale data strings. */
5685 if (cli_enc_opt_data
.buffer
!= NULL
)
5686 data_string_forget(&cli_enc_opt_data
, MDL
);
5687 if (iaaddr
.buffer
!= NULL
)
5688 data_string_forget(&iaaddr
, MDL
);
5689 if (client_id
.buffer
!= NULL
)
5690 data_string_forget(&client_id
, MDL
);
5691 if (packet_oro
.buffer
!= NULL
)
5692 data_string_forget(&packet_oro
, MDL
);
5694 /* Release any stale option states. */
5695 if (cli_enc_opt_state
!= NULL
)
5696 option_state_dereference(&cli_enc_opt_state
, MDL
);
5697 if (opt_state
!= NULL
)
5698 option_state_dereference(&opt_state
, MDL
);
5702 * Renew is when a client wants to extend its lease/prefix, at time T1.
5704 * We handle this the same as if the client wants a new lease/prefix,
5705 * except for the error code of when addresses don't match.
5709 dhcpv6_renew(struct data_string
*reply
, struct packet
*packet
) {
5710 struct data_string client_id
;
5711 struct data_string server_id
;
5714 * Validate the request.
5716 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5720 /* If the RENEW arrived via unicast and unicast option isn't set,
5721 * reject it per RFC 3315, Sec 18.2.3 */
5722 if (packet
->unicast
== ISC_TRUE
&&
5723 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5724 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5729 lease_to_client(reply
, packet
, &client_id
, &server_id
);
5735 data_string_forget(&server_id
, MDL
);
5736 data_string_forget(&client_id
, MDL
);
5740 * Rebind is when a client wants to extend its lease, at time T2.
5742 * We handle this the same as if the client wants a new lease, except
5743 * for the error code of when addresses don't match.
5747 dhcpv6_rebind(struct data_string
*reply
, struct packet
*packet
) {
5748 struct data_string client_id
;
5750 if (!valid_client_msg(packet
, &client_id
)) {
5754 lease_to_client(reply
, packet
, &client_id
, NULL
);
5756 data_string_forget(&client_id
, MDL
);
5760 ia_na_match_decline(const struct data_string
*client_id
,
5761 const struct data_string
*iaaddr
,
5762 struct iasubopt
*lease
)
5764 char tmp_addr
[INET6_ADDRSTRLEN
];
5766 log_error("Client %s reports address %s is "
5767 "already in use by another host!",
5768 print_hex_1(client_id
->len
, client_id
->data
, 60),
5769 inet_ntop(AF_INET6
, iaaddr
->data
,
5770 tmp_addr
, sizeof(tmp_addr
)));
5771 if (lease
!= NULL
) {
5772 decline_lease6(lease
->ipv6_pool
, lease
);
5773 lease
->ia
->cltt
= cur_time
;
5774 write_ia(lease
->ia
);
5779 ia_na_nomatch_decline(const struct data_string
*client_id
,
5780 const struct data_string
*iaaddr
,
5781 u_int32_t
*ia_na_id
,
5782 struct packet
*packet
,
5787 char tmp_addr
[INET6_ADDRSTRLEN
];
5788 struct option_state
*host_opt_state
;
5791 log_info("Client %s declines address %s, which is not offered to it.",
5792 print_hex_1(client_id
->len
, client_id
->data
, 60),
5793 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5796 * Create state for this IA_NA.
5798 host_opt_state
= NULL
;
5799 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5800 log_error("ia_na_nomatch_decline: out of memory "
5801 "allocating option_state.");
5805 if (!set_status_code(STATUS_NoBinding
, "Decline for unknown address.",
5811 * Insure we have enough space
5813 if (reply_len
< (*reply_ofs
+ 16)) {
5814 log_error("ia_na_nomatch_decline: "
5815 "out of space for reply packet.");
5820 * Put our status code into the reply packet.
5822 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5823 reply_len
-(*reply_ofs
)-16,
5824 host_opt_state
, packet
,
5825 required_opts_STATUS_CODE
, NULL
);
5828 * Store the non-encapsulated option data for this
5829 * IA_NA into our reply packet. Defined in RFC 3315,
5833 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5835 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5836 /* IA_NA, copied from the client */
5837 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5838 /* t1 and t2, odd that we need them, but here it is */
5839 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5840 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5843 * Get ready for next IA_NA.
5845 *reply_ofs
+= (len
+ 16);
5848 option_state_dereference(&host_opt_state
, MDL
);
5852 iterate_over_ia_na(struct data_string
*reply_ret
,
5853 struct packet
*packet
,
5854 const struct data_string
*client_id
,
5855 const struct data_string
*server_id
,
5856 const char *packet_type
,
5857 void (*ia_na_match
)(),
5858 void (*ia_na_nomatch
)())
5860 struct option_state
*opt_state
;
5861 struct host_decl
*packet_host
;
5862 struct option_cache
*ia
;
5863 struct option_cache
*oc
;
5864 /* cli_enc_... variables come from the IA_NA/IA_TA options */
5865 struct data_string cli_enc_opt_data
;
5866 struct option_state
*cli_enc_opt_state
;
5867 struct host_decl
*host
;
5868 struct data_string iaaddr
;
5869 struct data_string fixed_addr
;
5870 char reply_data
[65536];
5871 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5872 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5873 char status_msg
[32];
5874 struct iasubopt
*lease
;
5875 struct ia_xx
*existing_ia_na
;
5877 struct data_string key
;
5881 * Initialize to empty values, in case we have to exit early.
5884 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5885 cli_enc_opt_state
= NULL
;
5886 memset(&iaaddr
, 0, sizeof(iaaddr
));
5887 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
5891 * Find the host record that matches from the packet, if any.
5894 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
5897 * Set our reply information.
5899 reply
->msg_type
= DHCPV6_REPLY
;
5900 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
5901 sizeof(reply
->transaction_id
));
5904 * Build our option state for reply.
5907 if (!option_state_allocate(&opt_state
, MDL
)) {
5908 log_error("iterate_over_ia_na: no memory for option_state.");
5911 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5912 packet
->options
, opt_state
,
5913 &global_scope
, root_group
, NULL
, NULL
);
5916 * RFC 3315, section 18.2.7 tells us which options to include.
5918 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
5920 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5921 (unsigned char *)server_duid
.data
,
5922 server_duid
.len
, D6O_SERVERID
, 0)) {
5923 log_error("iterate_over_ia_na: "
5924 "error saving server identifier.");
5929 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
5931 (unsigned char *)client_id
->data
,
5934 log_error("iterate_over_ia_na: "
5935 "error saving client identifier.");
5939 snprintf(status_msg
, sizeof(status_msg
), "%s received.", packet_type
);
5940 if (!set_status_code(STATUS_Success
, status_msg
, opt_state
)) {
5945 * Add our options that are not associated with any IA_NA or IA_TA.
5947 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5948 sizeof(reply_data
)-reply_ofs
,
5950 required_opts
, NULL
);
5953 * Loop through the IA_NA reported by the client, and deal with
5954 * addresses reported as already in use.
5956 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5957 ia
!= NULL
; ia
= ia
->next
) {
5959 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
5961 packet
, ia
, IA_NA_OFFSET
)) {
5965 iaid
= getULong(cli_enc_opt_data
.data
);
5968 * XXX: It is possible that we can get multiple addresses
5969 * sent by the client. We don't send multiple
5970 * addresses, so this indicates a client error.
5971 * We should check for multiple IAADDR options, log
5972 * if found, and set as an error.
5974 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5977 /* no address given for this IA, ignore */
5978 option_state_dereference(&cli_enc_opt_state
, MDL
);
5979 data_string_forget(&cli_enc_opt_data
, MDL
);
5983 memset(&iaaddr
, 0, sizeof(iaaddr
));
5984 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5985 packet
->options
, NULL
,
5986 &global_scope
, oc
, MDL
)) {
5987 log_error("iterate_over_ia_na: "
5988 "error evaluating IAADDR.");
5993 * Now we need to figure out which host record matches
5994 * this IA_NA and IAADDR (encapsulated option contents
5995 * matching a host record by option).
5997 * XXX: We don't currently track IA_NA separately, but
5998 * we will need to do this!
6001 if (!find_hosts_by_option(&host
, packet
,
6002 cli_enc_opt_state
, MDL
)) {
6003 if (packet_host
!= NULL
) {
6009 while (host
!= NULL
) {
6010 if (host
->fixed_addr
!= NULL
) {
6011 if (!evaluate_option_cache(&fixed_addr
, NULL
,
6013 NULL
, &global_scope
,
6016 log_error("iterate_over_ia_na: error "
6017 "evaluating host address.");
6020 if ((iaaddr
.len
>= 16) &&
6021 !memcmp(fixed_addr
.data
, iaaddr
.data
, 16)) {
6022 data_string_forget(&fixed_addr
, MDL
);
6025 data_string_forget(&fixed_addr
, MDL
);
6027 host
= host
->n_ipaddr
;
6030 if ((host
== NULL
) && (iaaddr
.len
>= IAADDR_OFFSET
)) {
6032 * Find existing IA_NA.
6034 if (ia_make_key(&key
, iaid
,
6035 (char *)client_id
->data
,
6037 MDL
) != ISC_R_SUCCESS
) {
6038 log_fatal("iterate_over_ia_na: no memory for "
6042 existing_ia_na
= NULL
;
6043 if (ia_hash_lookup(&existing_ia_na
, ia_na_active
,
6044 (unsigned char *)key
.data
,
6047 * Make sure this address is in the IA_NA.
6049 for (i
=0; i
<existing_ia_na
->num_iasubopt
; i
++) {
6050 struct iasubopt
*tmp
;
6051 struct in6_addr
*in6_addr
;
6053 tmp
= existing_ia_na
->iasubopt
[i
];
6054 in6_addr
= &tmp
->addr
;
6055 if (memcmp(in6_addr
,
6056 iaaddr
.data
, 16) == 0) {
6057 iasubopt_reference(&lease
,
6064 data_string_forget(&key
, MDL
);
6067 if ((host
!= NULL
) || (lease
!= NULL
)) {
6068 ia_na_match(client_id
, &iaaddr
, lease
);
6070 ia_na_nomatch(client_id
, &iaaddr
,
6071 (u_int32_t
*)cli_enc_opt_data
.data
,
6072 packet
, reply_data
, &reply_ofs
,
6073 sizeof(reply_data
));
6076 if (lease
!= NULL
) {
6077 iasubopt_dereference(&lease
, MDL
);
6080 data_string_forget(&iaaddr
, MDL
);
6081 option_state_dereference(&cli_enc_opt_state
, MDL
);
6082 data_string_forget(&cli_enc_opt_data
, MDL
);
6086 * Return our reply to the caller.
6088 reply_ret
->len
= reply_ofs
;
6089 reply_ret
->buffer
= NULL
;
6090 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
6091 log_fatal("No memory to store reply.");
6093 reply_ret
->data
= reply_ret
->buffer
->data
;
6094 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
6097 if (lease
!= NULL
) {
6098 iasubopt_dereference(&lease
, MDL
);
6100 if (fixed_addr
.buffer
!= NULL
) {
6101 data_string_forget(&fixed_addr
, MDL
);
6103 if (iaaddr
.buffer
!= NULL
) {
6104 data_string_forget(&iaaddr
, MDL
);
6106 if (cli_enc_opt_state
!= NULL
) {
6107 option_state_dereference(&cli_enc_opt_state
, MDL
);
6109 if (cli_enc_opt_data
.buffer
!= NULL
) {
6110 data_string_forget(&cli_enc_opt_data
, MDL
);
6112 if (opt_state
!= NULL
) {
6113 option_state_dereference(&opt_state
, MDL
);
6118 * Decline means a client has detected that something else is using an
6119 * address we gave it.
6121 * Since we're only dealing with fixed leases for now, there's not
6122 * much we can do, other that log the occurrence.
6124 * When we start issuing addresses from pools, then we will have to
6125 * record our declined addresses and issue another. In general with
6126 * IPv6 there is no worry about DoS by clients exhausting space, but
6127 * we still need to be aware of this possibility.
6132 dhcpv6_decline(struct data_string
*reply
, struct packet
*packet
) {
6133 struct data_string client_id
;
6134 struct data_string server_id
;
6137 * Validate our input.
6139 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
6143 /* If the DECLINE arrived via unicast and unicast option isn't set,
6144 * reject it per RFC 3315, Sec 18.2.7 */
6145 if (packet
->unicast
== ISC_TRUE
&&
6146 is_unicast_option_defined(packet
) == ISC_FALSE
) {
6147 unicast_reject(reply
, packet
, &client_id
, &server_id
);
6150 * Undefined for IA_PD.
6152 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
6155 * And operate on each IA_NA in this packet.
6157 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
6158 "Decline", ia_na_match_decline
,
6159 ia_na_nomatch_decline
);
6163 data_string_forget(&server_id
, MDL
);
6164 data_string_forget(&client_id
, MDL
);
6168 ia_na_match_release(const struct data_string
*client_id
,
6169 const struct data_string
*iaaddr
,
6170 struct iasubopt
*lease
)
6172 char tmp_addr
[INET6_ADDRSTRLEN
];
6174 log_info("Client %s releases address %s",
6175 print_hex_1(client_id
->len
, client_id
->data
, 60),
6176 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
6177 if (lease
!= NULL
) {
6178 release_lease6(lease
->ipv6_pool
, lease
);
6179 lease
->ia
->cltt
= cur_time
;
6180 write_ia(lease
->ia
);
6185 ia_na_nomatch_release(const struct data_string
*client_id
,
6186 const struct data_string
*iaaddr
,
6187 u_int32_t
*ia_na_id
,
6188 struct packet
*packet
,
6193 char tmp_addr
[INET6_ADDRSTRLEN
];
6194 struct option_state
*host_opt_state
;
6197 log_info("Client %s releases address %s, which is not leased to it.",
6198 print_hex_1(client_id
->len
, client_id
->data
, 60),
6199 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
6202 * Create state for this IA_NA.
6204 host_opt_state
= NULL
;
6205 if (!option_state_allocate(&host_opt_state
, MDL
)) {
6206 log_error("ia_na_nomatch_release: out of memory "
6207 "allocating option_state.");
6211 if (!set_status_code(STATUS_NoBinding
,
6212 "Release for non-leased address.",
6218 * Insure we have enough space
6220 if (reply_len
< (*reply_ofs
+ 16)) {
6221 log_error("ia_na_nomatch_release: "
6222 "out of space for reply packet.");
6227 * Put our status code into the reply packet.
6229 len
= store_options6(reply_data
+(*reply_ofs
)+16,
6230 reply_len
-(*reply_ofs
)-16,
6231 host_opt_state
, packet
,
6232 required_opts_STATUS_CODE
, NULL
);
6235 * Store the non-encapsulated option data for this
6236 * IA_NA into our reply packet. Defined in RFC 3315,
6240 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
6242 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
6243 /* IA_NA, copied from the client */
6244 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
6245 /* t1 and t2, odd that we need them, but here it is */
6246 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
6247 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
6250 * Get ready for next IA_NA.
6252 *reply_ofs
+= (len
+ 16);
6255 option_state_dereference(&host_opt_state
, MDL
);
6259 ia_pd_match_release(const struct data_string
*client_id
,
6260 const struct data_string
*iapref
,
6261 struct iasubopt
*prefix
)
6263 char tmp_addr
[INET6_ADDRSTRLEN
];
6265 log_info("Client %s releases prefix %s/%u",
6266 print_hex_1(client_id
->len
, client_id
->data
, 60),
6267 inet_ntop(AF_INET6
, iapref
->data
+ 9,
6268 tmp_addr
, sizeof(tmp_addr
)),
6269 (unsigned) getUChar(iapref
->data
+ 8));
6270 if (prefix
!= NULL
) {
6271 release_lease6(prefix
->ipv6_pool
, prefix
);
6272 prefix
->ia
->cltt
= cur_time
;
6273 write_ia(prefix
->ia
);
6278 ia_pd_nomatch_release(const struct data_string
*client_id
,
6279 const struct data_string
*iapref
,
6280 u_int32_t
*ia_pd_id
,
6281 struct packet
*packet
,
6286 char tmp_addr
[INET6_ADDRSTRLEN
];
6287 struct option_state
*host_opt_state
;
6290 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
6291 print_hex_1(client_id
->len
, client_id
->data
, 60),
6292 inet_ntop(AF_INET6
, iapref
->data
+ 9,
6293 tmp_addr
, sizeof(tmp_addr
)),
6294 (unsigned) getUChar(iapref
->data
+ 8));
6297 * Create state for this IA_PD.
6299 host_opt_state
= NULL
;
6300 if (!option_state_allocate(&host_opt_state
, MDL
)) {
6301 log_error("ia_pd_nomatch_release: out of memory "
6302 "allocating option_state.");
6306 if (!set_status_code(STATUS_NoBinding
,
6307 "Release for non-leased prefix.",
6313 * Insure we have enough space
6315 if (reply_len
< (*reply_ofs
+ 16)) {
6316 log_error("ia_pd_nomatch_release: "
6317 "out of space for reply packet.");
6322 * Put our status code into the reply packet.
6324 len
= store_options6(reply_data
+(*reply_ofs
)+16,
6325 reply_len
-(*reply_ofs
)-16,
6326 host_opt_state
, packet
,
6327 required_opts_STATUS_CODE
, NULL
);
6330 * Store the non-encapsulated option data for this
6331 * IA_PD into our reply packet. Defined in RFC 3315,
6335 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_PD
);
6337 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
6338 /* IA_PD, copied from the client */
6339 memcpy(reply_data
+(*reply_ofs
)+4, ia_pd_id
, 4);
6340 /* t1 and t2, odd that we need them, but here it is */
6341 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
6342 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
6345 * Get ready for next IA_PD.
6347 *reply_ofs
+= (len
+ 16);
6350 option_state_dereference(&host_opt_state
, MDL
);
6354 iterate_over_ia_pd(struct data_string
*reply_ret
,
6355 struct packet
*packet
,
6356 const struct data_string
*client_id
,
6357 const struct data_string
*server_id
,
6358 const char *packet_type
,
6359 void (*ia_pd_match
)(),
6360 void (*ia_pd_nomatch
)())
6362 struct data_string reply_new
;
6364 struct option_state
*opt_state
;
6365 struct host_decl
*packet_host
;
6366 struct option_cache
*ia
;
6367 struct option_cache
*oc
;
6368 /* cli_enc_... variables come from the IA_PD options */
6369 struct data_string cli_enc_opt_data
;
6370 struct option_state
*cli_enc_opt_state
;
6371 struct host_decl
*host
;
6372 struct data_string iaprefix
;
6373 char reply_data
[65536];
6375 struct iasubopt
*prefix
;
6376 struct ia_xx
*existing_ia_pd
;
6378 struct data_string key
;
6382 * Initialize to empty values, in case we have to exit early.
6384 memset(&reply_new
, 0, sizeof(reply_new
));
6386 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
6387 cli_enc_opt_state
= NULL
;
6388 memset(&iaprefix
, 0, sizeof(iaprefix
));
6392 * Compute the available length for the reply.
6394 reply_len
= sizeof(reply_data
) - reply_ret
->len
;
6398 * Find the host record that matches from the packet, if any.
6401 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
6404 * Build our option state for reply.
6407 if (!option_state_allocate(&opt_state
, MDL
)) {
6408 log_error("iterate_over_ia_pd: no memory for option_state.");
6411 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
6412 packet
->options
, opt_state
,
6413 &global_scope
, root_group
, NULL
, NULL
);
6416 * Loop through the IA_PD reported by the client, and deal with
6417 * prefixes reported as already in use.
6419 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
6420 ia
!= NULL
; ia
= ia
->next
) {
6422 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
6424 packet
, ia
, IA_PD_OFFSET
)) {
6428 iaid
= getULong(cli_enc_opt_data
.data
);
6430 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
6433 /* no prefix given for this IA_PD, ignore */
6434 option_state_dereference(&cli_enc_opt_state
, MDL
);
6435 data_string_forget(&cli_enc_opt_data
, MDL
);
6439 for (; oc
!= NULL
; oc
= oc
->next
) {
6440 memset(&iaprefix
, 0, sizeof(iaprefix
));
6441 if (!evaluate_option_cache(&iaprefix
, packet
, NULL
, NULL
,
6442 packet
->options
, NULL
,
6443 &global_scope
, oc
, MDL
)) {
6444 log_error("iterate_over_ia_pd: "
6445 "error evaluating IAPREFIX.");
6450 * Now we need to figure out which host record matches
6451 * this IA_PD and IAPREFIX (encapsulated option contents
6452 * matching a host record by option).
6454 * XXX: We don't currently track IA_PD separately, but
6455 * we will need to do this!
6458 if (!find_hosts_by_option(&host
, packet
,
6459 cli_enc_opt_state
, MDL
)) {
6460 if (packet_host
!= NULL
) {
6466 while (host
!= NULL
) {
6467 if (host
->fixed_prefix
!= NULL
) {
6468 struct iaddrcidrnetlist
*l
;
6469 int plen
= (int) getUChar(iaprefix
.data
+ 8);
6471 for (l
= host
->fixed_prefix
; l
!= NULL
;
6473 if (plen
!= l
->cidrnet
.bits
)
6475 if (memcmp(iaprefix
.data
+ 9,
6476 l
->cidrnet
.lo_addr
.iabuf
,
6480 if ((l
!= NULL
) && (iaprefix
.len
>= 17))
6483 host
= host
->n_ipaddr
;
6486 if ((host
== NULL
) && (iaprefix
.len
>= IAPREFIX_OFFSET
)) {
6488 * Find existing IA_PD.
6490 if (ia_make_key(&key
, iaid
,
6491 (char *)client_id
->data
,
6493 MDL
) != ISC_R_SUCCESS
) {
6494 log_fatal("iterate_over_ia_pd: no memory for "
6498 existing_ia_pd
= NULL
;
6499 if (ia_hash_lookup(&existing_ia_pd
, ia_pd_active
,
6500 (unsigned char *)key
.data
,
6503 * Make sure this prefix is in the IA_PD.
6506 i
< existing_ia_pd
->num_iasubopt
;
6508 struct iasubopt
*tmp
;
6511 plen
= getUChar(iaprefix
.data
+ 8);
6512 tmp
= existing_ia_pd
->iasubopt
[i
];
6513 if ((tmp
->plen
== plen
) &&
6517 iasubopt_reference(&prefix
,
6524 data_string_forget(&key
, MDL
);
6527 if ((host
!= NULL
) || (prefix
!= NULL
)) {
6528 ia_pd_match(client_id
, &iaprefix
, prefix
);
6530 ia_pd_nomatch(client_id
, &iaprefix
,
6531 (u_int32_t
*)cli_enc_opt_data
.data
,
6532 packet
, reply_data
, &reply_ofs
,
6533 reply_len
- reply_ofs
);
6536 if (prefix
!= NULL
) {
6537 iasubopt_dereference(&prefix
, MDL
);
6540 data_string_forget(&iaprefix
, MDL
);
6543 option_state_dereference(&cli_enc_opt_state
, MDL
);
6544 data_string_forget(&cli_enc_opt_data
, MDL
);
6548 * Return our reply to the caller.
6549 * The IA_NA routine has already filled at least the header.
6551 reply_new
.len
= reply_ret
->len
+ reply_ofs
;
6552 if (!buffer_allocate(&reply_new
.buffer
, reply_new
.len
, MDL
)) {
6553 log_fatal("No memory to store reply.");
6555 reply_new
.data
= reply_new
.buffer
->data
;
6556 memcpy(reply_new
.buffer
->data
,
6557 reply_ret
->buffer
->data
, reply_ret
->len
);
6558 memcpy(reply_new
.buffer
->data
+ reply_ret
->len
,
6559 reply_data
, reply_ofs
);
6560 data_string_forget(reply_ret
, MDL
);
6561 data_string_copy(reply_ret
, &reply_new
, MDL
);
6562 data_string_forget(&reply_new
, MDL
);
6565 if (prefix
!= NULL
) {
6566 iasubopt_dereference(&prefix
, MDL
);
6568 if (iaprefix
.buffer
!= NULL
) {
6569 data_string_forget(&iaprefix
, MDL
);
6571 if (cli_enc_opt_state
!= NULL
) {
6572 option_state_dereference(&cli_enc_opt_state
, MDL
);
6574 if (cli_enc_opt_data
.buffer
!= NULL
) {
6575 data_string_forget(&cli_enc_opt_data
, MDL
);
6577 if (opt_state
!= NULL
) {
6578 option_state_dereference(&opt_state
, MDL
);
6583 * Release means a client is done with the leases.
6587 dhcpv6_release(struct data_string
*reply
, struct packet
*packet
) {
6588 struct data_string client_id
;
6589 struct data_string server_id
;
6592 * Validate our input.
6594 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
6598 /* If the RELEASE arrived via unicast and unicast option isn't set,
6599 * reject it per RFC 3315, Sec 18.2.6 */
6600 if (packet
->unicast
== ISC_TRUE
&&
6601 is_unicast_option_defined(packet
) == ISC_FALSE
) {
6602 unicast_reject(reply
, packet
, &client_id
, &server_id
);
6605 * And operate on each IA_NA in this packet.
6607 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
6608 "Release", ia_na_match_release
,
6609 ia_na_nomatch_release
);
6612 * And operate on each IA_PD in this packet.
6614 iterate_over_ia_pd(reply
, packet
, &client_id
, &server_id
,
6615 "Release", ia_pd_match_release
,
6616 ia_pd_nomatch_release
);
6619 data_string_forget(&server_id
, MDL
);
6620 data_string_forget(&client_id
, MDL
);
6624 * Information-Request is used by clients who have obtained an address
6625 * from other means, but want configuration information from the server.
6629 dhcpv6_information_request(struct data_string
*reply
, struct packet
*packet
) {
6630 struct data_string client_id
;
6631 struct data_string server_id
;
6634 * Validate our input.
6636 if (!valid_client_info_req(packet
, &server_id
)) {
6641 * Get our client ID, if there is one.
6643 memset(&client_id
, 0, sizeof(client_id
));
6644 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
) {
6645 data_string_forget(&client_id
, MDL
);
6649 * Use the lease_to_client() function. This will work fine,
6650 * because the valid_client_info_req() insures that we
6651 * don't have any IA that would cause us to allocate
6652 * resources to the client.
6654 lease_to_client(reply
, packet
, &client_id
,
6655 server_id
.data
!= NULL
? &server_id
: NULL
);
6660 if (client_id
.data
!= NULL
) {
6661 data_string_forget(&client_id
, MDL
);
6663 data_string_forget(&server_id
, MDL
);
6667 * The Relay-forw message is sent by relays. It typically contains a
6668 * single option, which encapsulates an entire packet.
6670 * We need to build an encapsulated reply.
6673 /* XXX: this is very, very similar to do_packet6(), and should probably
6674 be combined in a clever way */
6675 /* DHCPv6 server side */
6677 dhcpv6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
6678 struct option_cache
*oc
;
6679 struct data_string enc_opt_data
;
6680 struct packet
*enc_packet
;
6681 unsigned char msg_type
;
6682 const struct dhcpv6_packet
*msg
;
6683 const struct dhcpv6_relay_packet
*relay
;
6684 struct data_string enc_reply
;
6685 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6686 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6687 struct data_string a_opt
, packet_ero
;
6688 struct option_state
*opt_state
;
6689 static char reply_data
[65536];
6690 struct dhcpv6_relay_packet
*reply
;
6694 * Initialize variables for early exit.
6697 memset(&a_opt
, 0, sizeof(a_opt
));
6698 memset(&packet_ero
, 0, sizeof(packet_ero
));
6699 memset(&enc_reply
, 0, sizeof(enc_reply
));
6700 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6704 * Get our encapsulated relay message.
6706 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
6708 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
6709 link_addr
, sizeof(link_addr
));
6710 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
6711 peer_addr
, sizeof(peer_addr
));
6712 log_info("Relay-forward from %s with link address=%s and "
6713 "peer address=%s missing Relay Message option.",
6714 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
6718 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
6719 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
6720 /* should be dhcpv6_relay_forw */
6721 log_error("dhcpv6_forw_relay: error evaluating "
6722 "relayed message.");
6726 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
6727 /* should be dhcpv6_relay_forw */
6728 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
6733 * Build a packet structure from this encapsulated packet.
6736 if (!packet_allocate(&enc_packet
, MDL
)) {
6737 /* should be dhcpv6_relay_forw */
6738 log_error("dhcpv6_forw_relay: "
6739 "no memory for encapsulated packet.");
6743 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
6744 /* should be dhcpv6_relay_forw */
6745 log_error("dhcpv6_forw_relay: "
6746 "no memory for encapsulated packet's options.");
6750 enc_packet
->client_port
= packet
->client_port
;
6751 enc_packet
->client_addr
= packet
->client_addr
;
6752 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
6753 enc_packet
->dhcpv6_container_packet
= packet
;
6755 msg_type
= enc_opt_data
.data
[0];
6756 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
6757 (msg_type
== DHCPV6_RELAY_REPL
)) {
6758 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6759 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
6760 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
6762 /* relay-specific data */
6763 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
6764 memcpy(&enc_packet
->dhcpv6_link_address
,
6765 relay
->link_address
, sizeof(relay
->link_address
));
6766 memcpy(&enc_packet
->dhcpv6_peer_address
,
6767 relay
->peer_address
, sizeof(relay
->peer_address
));
6769 if (!parse_option_buffer(enc_packet
->options
,
6771 enc_opt_data
.len
- relaylen
,
6772 &dhcpv6_universe
)) {
6773 /* no logging here, as parse_option_buffer() logs all
6774 cases where it fails */
6777 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
6778 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6780 if (!dhcpv4_over_dhcpv6
||
6781 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6782 log_error("dhcpv6_relay_forw: "
6783 "unsupported %s message type.",
6784 dhcpv6_type_names
[msg_type
]);
6787 forw_dhcpv4_query(packet
);
6790 log_error("dhcpv6_relay_forw: unsupported %s message type.",
6791 dhcpv6_type_names
[msg_type
]);
6793 #endif /* DHCP4o6 */
6795 int msglen
= (int)(offsetof(struct dhcpv6_packet
, options
));
6796 msg
= (struct dhcpv6_packet
*)enc_opt_data
.data
;
6797 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
6799 /* message-specific data */
6800 memcpy(enc_packet
->dhcpv6_transaction_id
,
6801 msg
->transaction_id
,
6802 sizeof(enc_packet
->dhcpv6_transaction_id
));
6804 if (!parse_option_buffer(enc_packet
->options
,
6806 enc_opt_data
.len
- msglen
,
6807 &dhcpv6_universe
)) {
6808 /* no logging here, as parse_option_buffer() logs all
6809 cases where it fails */
6815 * This is recursive. It is possible to exceed maximum packet size.
6816 * XXX: This will cause the packet send to fail.
6818 build_dhcpv6_reply(&enc_reply
, enc_packet
);
6821 * If we got no encapsulated data, then it is discarded, and
6822 * our reply-forw is also discarded.
6824 if (enc_reply
.data
== NULL
) {
6829 * Now we can use the reply_data buffer.
6830 * Packet header stuff all comes from the forward message.
6832 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
6833 reply
->msg_type
= DHCPV6_RELAY_REPL
;
6834 reply
->hop_count
= packet
->dhcpv6_hop_count
;
6835 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
6836 sizeof(reply
->link_address
));
6837 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
6838 sizeof(reply
->peer_address
));
6839 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6842 * Get the reply option state.
6845 if (!option_state_allocate(&opt_state
, MDL
)) {
6846 log_error("dhcpv6_relay_forw: no memory for option state.");
6851 * Append the interface-id if present.
6853 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6856 if (!evaluate_option_cache(&a_opt
, packet
,
6858 packet
->options
, NULL
,
6859 &global_scope
, oc
, MDL
)) {
6860 log_error("dhcpv6_relay_forw: error evaluating "
6864 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6865 (unsigned char *)a_opt
.data
,
6867 D6O_INTERFACE_ID
, 0)) {
6868 log_error("dhcpv6_relay_forw: error saving "
6872 data_string_forget(&a_opt
, MDL
);
6875 #if defined(RELAY_PORT)
6877 * Append the relay_source_port option if present.
6879 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6880 D6O_RELAY_SOURCE_PORT
);
6882 if (!evaluate_option_cache(&a_opt
, packet
,
6884 packet
->options
, NULL
,
6885 &global_scope
, oc
, MDL
)) {
6886 log_error("dhcpv6_relay_forw: error evaluating "
6887 "Relay Source Port.");
6890 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6891 (unsigned char *)a_opt
.data
,
6893 D6O_RELAY_SOURCE_PORT
, 0)) {
6894 log_error("dhcpv6_relay_forw: error saving "
6895 "Relay Source Port.");
6898 data_string_forget(&a_opt
, MDL
);
6900 packet
->relay_source_port
= ISC_TRUE
;
6905 * Append our encapsulated stuff for caller.
6907 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6908 (unsigned char *)enc_reply
.data
,
6910 D6O_RELAY_MSG
, 0)) {
6911 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
6916 * Get the ERO if any.
6918 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
6923 if (!evaluate_option_cache(&packet_ero
, packet
,
6925 packet
->options
, NULL
,
6926 &global_scope
, oc
, MDL
) ||
6927 (packet_ero
.len
& 1)) {
6928 log_error("dhcpv6_relay_forw: error evaluating ERO.");
6932 /* Decode and apply the ERO. */
6933 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
6934 req
= getUShort(packet_ero
.data
+ i
);
6935 /* Already in the reply? */
6936 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
6939 /* Get it from the packet if present. */
6940 oc
= lookup_option(&dhcpv6_universe
,
6945 if (!evaluate_option_cache(&a_opt
, packet
,
6947 packet
->options
, NULL
,
6948 &global_scope
, oc
, MDL
)) {
6949 log_error("dhcpv6_relay_forw: error "
6950 "evaluating option %u.", req
);
6953 if (!save_option_buffer(&dhcpv6_universe
,
6956 (unsigned char *)a_opt
.data
,
6960 log_error("dhcpv6_relay_forw: error saving "
6964 data_string_forget(&a_opt
, MDL
);
6968 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
6969 sizeof(reply_data
) - reply_ofs
,
6971 required_opts_agent
, &packet_ero
);
6974 * Return our reply to the caller.
6976 reply_ret
->len
= reply_ofs
;
6977 reply_ret
->buffer
= NULL
;
6978 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
6979 log_fatal("No memory to store reply.");
6981 reply_ret
->data
= reply_ret
->buffer
->data
;
6982 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
6985 if (opt_state
!= NULL
)
6986 option_state_dereference(&opt_state
, MDL
);
6987 if (a_opt
.data
!= NULL
) {
6988 data_string_forget(&a_opt
, MDL
);
6990 if (packet_ero
.data
!= NULL
) {
6991 data_string_forget(&packet_ero
, MDL
);
6993 if (enc_reply
.data
!= NULL
) {
6994 data_string_forget(&enc_reply
, MDL
);
6996 if (enc_opt_data
.data
!= NULL
) {
6997 data_string_forget(&enc_opt_data
, MDL
);
6999 if (enc_packet
!= NULL
) {
7000 packet_dereference(&enc_packet
, MDL
);
7005 /* \brief Internal processing of a relayed DHCPv4-query
7006 * (DHCPv4 server side)
7008 * Code copied from \ref dhcpv6_relay_forw() which itself is
7009 * from \ref do_packet6().
7011 * \param reply_ret pointer to the response
7012 * \param packet the query
7015 dhcp4o6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
7016 struct option_cache
*oc
;
7017 struct data_string enc_opt_data
;
7018 struct packet
*enc_packet
;
7019 unsigned char msg_type
;
7020 const struct dhcpv6_relay_packet
*relay
;
7021 const struct dhcpv4_over_dhcpv6_packet
*msg
;
7022 struct data_string enc_reply
;
7023 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
7024 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
7025 struct data_string a_opt
, packet_ero
;
7026 struct option_state
*opt_state
;
7027 static char reply_data
[65536];
7028 struct dhcpv6_relay_packet
*reply
;
7032 * Initialize variables for early exit.
7035 memset(&a_opt
, 0, sizeof(a_opt
));
7036 memset(&packet_ero
, 0, sizeof(packet_ero
));
7037 memset(&enc_reply
, 0, sizeof(enc_reply
));
7038 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
7042 * Get our encapsulated relay message.
7044 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
7046 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
7047 link_addr
, sizeof(link_addr
));
7048 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
7049 peer_addr
, sizeof(peer_addr
));
7050 log_info("Relay-forward from %s with link address=%s and "
7051 "peer address=%s missing Relay Message option.",
7052 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
7056 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
7057 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
7058 log_error("dhcp4o6_relay_forw: error evaluating "
7059 "relayed message.");
7063 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
7064 log_error("dhcp4o6_relay_forw: "
7065 "encapsulated packet too short.");
7070 * Build a packet structure from this encapsulated packet.
7072 if (!packet_allocate(&enc_packet
, MDL
)) {
7073 log_error("dhcp4o6_relay_forw: "
7074 "no memory for encapsulated packet.");
7078 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
7079 log_error("dhcp4o6_relay_forw: "
7080 "no memory for encapsulated packet's options.");
7084 enc_packet
->client_port
= packet
->client_port
;
7085 enc_packet
->client_addr
= packet
->client_addr
;
7086 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
7087 enc_packet
->dhcpv6_container_packet
= packet
;
7089 msg_type
= enc_opt_data
.data
[0];
7090 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
7091 (msg_type
== DHCPV6_RELAY_REPL
)) {
7092 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
7093 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
7094 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
7096 /* relay-specific data */
7097 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
7098 memcpy(&enc_packet
->dhcpv6_link_address
,
7099 relay
->link_address
, sizeof(relay
->link_address
));
7100 memcpy(&enc_packet
->dhcpv6_peer_address
,
7101 relay
->peer_address
, sizeof(relay
->peer_address
));
7103 if (!parse_option_buffer(enc_packet
->options
,
7105 enc_opt_data
.len
- relaylen
,
7106 &dhcpv6_universe
)) {
7107 /* no logging here, as parse_option_buffer() logs all
7108 cases where it fails */
7111 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
7112 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
7114 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7115 msg
= (struct dhcpv4_over_dhcpv6_packet
*)enc_opt_data
.data
;
7116 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
7118 /* message-specific data */
7119 memcpy(enc_packet
->dhcp4o6_flags
,
7121 sizeof(enc_packet
->dhcp4o6_flags
));
7123 if (!parse_option_buffer(enc_packet
->options
,
7125 enc_opt_data
.len
- msglen
,
7126 &dhcpv6_universe
)) {
7127 /* no logging here, as parse_option_buffer() logs all
7128 cases where it fails */
7132 log_error("dhcp4o6_relay_forw: unexpected message of type %d.",
7138 * This is recursive. It is possible to exceed maximum packet size.
7139 * XXX: This will cause the packet send to fail.
7141 build_dhcpv6_reply(&enc_reply
, enc_packet
);
7144 * If we got no encapsulated data, then it is discarded, and
7145 * our reply-forw is also discarded.
7147 if (enc_reply
.data
== NULL
) {
7152 * Now we can use the reply_data buffer.
7153 * Packet header stuff all comes from the forward message.
7155 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
7156 reply
->msg_type
= DHCPV6_RELAY_REPL
;
7157 reply
->hop_count
= packet
->dhcpv6_hop_count
;
7158 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
7159 sizeof(reply
->link_address
));
7160 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
7161 sizeof(reply
->peer_address
));
7162 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
7165 * Get the reply option state.
7167 if (!option_state_allocate(&opt_state
, MDL
)) {
7168 log_error("dhcp4o6_relay_forw: no memory for option state.");
7173 * Append the interface-id if present.
7175 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
7178 if (!evaluate_option_cache(&a_opt
, packet
,
7180 packet
->options
, NULL
,
7181 &global_scope
, oc
, MDL
)) {
7182 log_error("dhcp4o6_relay_forw: error evaluating "
7186 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7187 (unsigned char *)a_opt
.data
,
7189 D6O_INTERFACE_ID
, 0)) {
7190 log_error("dhcp4o6_relay_forw: error saving "
7194 data_string_forget(&a_opt
, MDL
);
7197 #if defined(RELAY_PORT)
7199 * Append the relay_source_port option if present.
7201 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
7202 D6O_RELAY_SOURCE_PORT
);
7204 if (!evaluate_option_cache(&a_opt
, packet
,
7206 packet
->options
, NULL
,
7207 &global_scope
, oc
, MDL
)) {
7208 log_error("dhcpv4o6_relay_forw: error evaluating "
7209 "Relay Source Port.");
7212 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7213 (unsigned char *)a_opt
.data
,
7215 D6O_RELAY_SOURCE_PORT
, 0)) {
7216 log_error("dhcpv4o6_relay_forw: error saving "
7217 "Relay Source Port.");
7220 data_string_forget(&a_opt
, MDL
);
7222 packet
->relay_source_port
= ISC_TRUE
;
7227 * Append our encapsulated stuff for caller.
7229 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7230 (unsigned char *)enc_reply
.data
,
7232 D6O_RELAY_MSG
, 0)) {
7233 log_error("dhcp4o6_relay_forw: error saving Relay MSG.");
7238 * Get the ERO if any.
7240 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
7245 if (!evaluate_option_cache(&packet_ero
, packet
,
7247 packet
->options
, NULL
,
7248 &global_scope
, oc
, MDL
) ||
7249 (packet_ero
.len
& 1)) {
7250 log_error("dhcp4o6_relay_forw: error evaluating ERO.");
7254 /* Decode and apply the ERO. */
7255 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
7256 req
= getUShort(packet_ero
.data
+ i
);
7257 /* Already in the reply? */
7258 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
7261 /* Get it from the packet if present. */
7262 oc
= lookup_option(&dhcpv6_universe
,
7267 if (!evaluate_option_cache(&a_opt
, packet
,
7269 packet
->options
, NULL
,
7270 &global_scope
, oc
, MDL
)) {
7271 log_error("dhcp4o6_relay_forw: error "
7272 "evaluating option %u.", req
);
7275 if (!save_option_buffer(&dhcpv6_universe
,
7278 (unsigned char *)a_opt
.data
,
7282 log_error("dhcp4o6_relay_forw: error saving "
7286 data_string_forget(&a_opt
, MDL
);
7290 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
7291 sizeof(reply_data
) - reply_ofs
,
7293 required_opts_agent
, &packet_ero
);
7296 * Return our reply to the caller.
7298 reply_ret
->len
= reply_ofs
;
7299 reply_ret
->buffer
= NULL
;
7300 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
7301 log_fatal("No memory to store reply.");
7303 reply_ret
->data
= reply_ret
->buffer
->data
;
7304 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
7307 if (opt_state
!= NULL
)
7308 option_state_dereference(&opt_state
, MDL
);
7309 if (a_opt
.data
!= NULL
) {
7310 data_string_forget(&a_opt
, MDL
);
7312 if (packet_ero
.data
!= NULL
) {
7313 data_string_forget(&packet_ero
, MDL
);
7315 if (enc_reply
.data
!= NULL
) {
7316 data_string_forget(&enc_reply
, MDL
);
7318 if (enc_opt_data
.data
!= NULL
) {
7319 data_string_forget(&enc_opt_data
, MDL
);
7321 if (enc_packet
!= NULL
) {
7322 packet_dereference(&enc_packet
, MDL
);
7327 * \brief Internal processing of a DHCPv4-query
7328 * (DHCPv4 server function)
7330 * Code copied from \ref do_packet().
7332 * \param reply_ret pointer to the response
7333 * \param packet the query
7336 dhcp4o6_dhcpv4_query(struct data_string
*reply_ret
, struct packet
*packet
) {
7337 struct option_cache
*oc
;
7338 struct data_string enc_opt_data
;
7339 struct packet
*enc_packet
;
7340 struct data_string enc_response
;
7341 struct option_state
*opt_state
;
7342 static char response_data
[65536];
7343 struct dhcpv4_over_dhcpv6_packet
*response
;
7347 * Initialize variables for early exit.
7350 memset(&enc_response
, 0, sizeof(enc_response
));
7351 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
7355 * Get our encapsulated relay message.
7357 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_DHCPV4_MSG
);
7359 log_info("DHCPv4-query from %s missing DHCPv4 Message option.",
7360 piaddr(packet
->client_addr
));
7364 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
7365 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
7366 log_error("dhcp4o6_dhcpv4_query: error evaluating "
7371 if (enc_opt_data
.len
< DHCP_FIXED_NON_UDP
) {
7372 log_error("dhcp4o6_dhcpv4_query: DHCPv4 packet too short.");
7377 * Build a packet structure from this encapsulated packet.
7379 if (!packet_allocate(&enc_packet
, MDL
)) {
7380 log_error("dhcp4o6_dhcpv4_query: "
7381 "no memory for encapsulated packet.");
7385 enc_packet
->raw
= (struct dhcp_packet
*)enc_opt_data
.data
;
7386 enc_packet
->packet_length
= enc_opt_data
.len
;
7387 enc_packet
->dhcp4o6_response
= &enc_response
;
7388 enc_packet
->client_port
= packet
->client_port
;
7389 enc_packet
->client_addr
= packet
->client_addr
;
7390 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
7391 enc_packet
->dhcpv6_container_packet
= packet
;
7392 if (packet
->dhcp4o6_flags
[0] & DHCP4O6_QUERY_UNICAST
)
7393 enc_packet
->unicast
= 1;
7395 if (enc_packet
->raw
->hlen
> sizeof(enc_packet
->raw
->chaddr
)) {
7396 log_info("dhcp4o6_dhcpv4_query: "
7397 "discarding packet with bogus hlen.");
7401 /* Allocate packet->options now so it is non-null for all packets */
7402 if (!option_state_allocate (&enc_packet
->options
, MDL
)) {
7403 log_error("dhcp4o6_dhcpv4_query: no memory for options.");
7407 /* If there's an option buffer, try to parse it. */
7408 if (enc_packet
->packet_length
>= DHCP_FIXED_NON_UDP
+ 4) {
7409 struct option_cache
*op
;
7410 if (!parse_options(enc_packet
)) {
7411 if (enc_packet
->options
)
7412 option_state_dereference
7413 (&enc_packet
->options
, MDL
);
7414 packet_dereference (&enc_packet
, MDL
);
7418 if (enc_packet
->options_valid
&&
7419 (op
= lookup_option(&dhcp_universe
,
7420 enc_packet
->options
,
7421 DHO_DHCP_MESSAGE_TYPE
))) {
7422 struct data_string dp
;
7423 memset(&dp
, 0, sizeof dp
);
7424 evaluate_option_cache(&dp
, enc_packet
, NULL
, NULL
,
7425 enc_packet
->options
, NULL
,
7428 enc_packet
->packet_type
= dp
.data
[0];
7430 enc_packet
->packet_type
= 0;
7431 data_string_forget(&dp
, MDL
);
7435 if (validate_packet(enc_packet
) != 0) {
7436 if (enc_packet
->packet_type
)
7442 /* If the caller kept the packet, they'll have upped the refcnt. */
7443 packet_dereference(&enc_packet
, MDL
);
7446 * If we got no response data, then it is discarded, and
7447 * our DHCPv4-response is also discarded.
7449 if (enc_response
.data
== NULL
) {
7454 * Now we can use the response_data buffer.
7456 response
= (struct dhcpv4_over_dhcpv6_packet
*)response_data
;
7457 response
->msg_type
= DHCPV6_DHCPV4_RESPONSE
;
7458 response
->flags
[0] = response
->flags
[1] = response
->flags
[2] = 0;
7460 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7463 * Get the response option state.
7465 if (!option_state_allocate(&opt_state
, MDL
)) {
7466 log_error("dhcp4o6_dhcpv4_query: no memory for option state.");
7471 * Append our encapsulated stuff for caller.
7473 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7474 (unsigned char *)enc_response
.data
,
7476 D6O_DHCPV4_MSG
, 0)) {
7477 log_error("dhcp4o6_dhcpv4_query: error saving DHCPv4 MSG.");
7481 response_ofs
+= store_options6(response_data
+ response_ofs
,
7482 sizeof(response_data
) - response_ofs
,
7484 required_opts_4o6
, NULL
);
7487 * Return our response to the caller.
7489 reply_ret
->len
= response_ofs
;
7490 reply_ret
->buffer
= NULL
;
7491 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
7492 log_fatal("dhcp4o6_dhcpv4_query: no memory to store reply.");
7494 reply_ret
->data
= reply_ret
->buffer
->data
;
7495 memcpy(reply_ret
->buffer
->data
, response_data
, response_ofs
);
7498 if (opt_state
!= NULL
)
7499 option_state_dereference(&opt_state
, MDL
);
7500 if (enc_response
.data
!= NULL
) {
7501 data_string_forget(&enc_response
, MDL
);
7503 if (enc_opt_data
.data
!= NULL
) {
7504 data_string_forget(&enc_opt_data
, MDL
);
7506 if (enc_packet
!= NULL
) {
7507 packet_dereference(&enc_packet
, MDL
);
7512 * \brief Forward a DHCPv4-query message to the DHCPv4 side
7513 * (DHCPv6 server function)
7515 * Format: interface:16 + address:16 + udp:4 + DHCPv6 DHCPv4-query message
7517 * \brief packet the DHCPv6 DHCPv4-query message
7519 static void forw_dhcpv4_query(struct packet
*packet
) {
7520 struct data_string ds
;
7521 struct udp_data4o6 udp_data
;
7525 /* Get the initial message. */
7526 while (packet
->dhcpv6_container_packet
!= NULL
)
7527 packet
= packet
->dhcpv6_container_packet
;
7529 /* Check the initial message. */
7530 if ((packet
->raw
== NULL
) ||
7531 (packet
->client_addr
.len
!= 16) ||
7532 (packet
->interface
== NULL
)) {
7533 log_error("forw_dhcpv4_query: can't find initial message.");
7538 len
= packet
->packet_length
+ 36;
7539 memset(&ds
, 0, sizeof(ds
));
7540 if (!buffer_allocate(&ds
.buffer
, len
, MDL
)) {
7541 log_error("forw_dhcpv4_query: "
7542 "no memory for encapsulating packet.");
7545 ds
.data
= ds
.buffer
->data
;
7548 /* Fill the buffer. */
7549 strncpy((char *)ds
.buffer
->data
, packet
->interface
->name
, 16);
7550 memcpy(ds
.buffer
->data
+ 16,
7551 packet
->client_addr
.iabuf
, 16);
7552 memset(&udp_data
, 0, sizeof(udp_data
));
7553 udp_data
.src_port
= packet
->client_port
;
7554 memcpy(ds
.buffer
->data
+ 32, &udp_data
, 4);
7555 memcpy(ds
.buffer
->data
+ 36,
7556 (unsigned char *)packet
->raw
,
7557 packet
->packet_length
);
7559 /* Forward to the DHCPv4 server. */
7560 cc
= send(dhcp4o6_fd
, ds
.data
, ds
.len
, 0);
7562 log_error("forw_dhcpv4_query: send(): %m");
7563 data_string_forget(&ds
, MDL
);
7568 dhcpv6_discard(struct packet
*packet
) {
7569 /* INSIST(packet->msg_type > 0); */
7570 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
7572 log_debug("Discarding %s from %s; message type not handled by server",
7573 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7574 piaddr(packet
->client_addr
));
7578 build_dhcpv6_reply(struct data_string
*reply
, struct packet
*packet
) {
7579 memset(reply
, 0, sizeof(*reply
));
7581 /* I would like to classify the client once here, but
7582 * as I don't want to classify all of the incoming packets
7583 * I need to do it before handling specific types.
7584 * We don't need to classify if we are tossing the packet
7585 * or if it is a relay - the classification step will get
7586 * done when we process the inner client packet.
7589 switch (packet
->dhcpv6_msg_type
) {
7590 case DHCPV6_SOLICIT
:
7591 classify_client(packet
);
7592 dhcpv6_solicit(reply
, packet
);
7594 case DHCPV6_ADVERTISE
:
7595 dhcpv6_discard(packet
);
7597 case DHCPV6_REQUEST
:
7598 classify_client(packet
);
7599 dhcpv6_request(reply
, packet
);
7601 case DHCPV6_CONFIRM
:
7602 classify_client(packet
);
7603 dhcpv6_confirm(reply
, packet
);
7606 classify_client(packet
);
7607 dhcpv6_renew(reply
, packet
);
7610 classify_client(packet
);
7611 dhcpv6_rebind(reply
, packet
);
7614 dhcpv6_discard(packet
);
7616 case DHCPV6_RELEASE
:
7617 classify_client(packet
);
7618 dhcpv6_release(reply
, packet
);
7620 case DHCPV6_DECLINE
:
7621 classify_client(packet
);
7622 dhcpv6_decline(reply
, packet
);
7624 case DHCPV6_RECONFIGURE
:
7625 dhcpv6_discard(packet
);
7627 case DHCPV6_INFORMATION_REQUEST
:
7628 classify_client(packet
);
7629 dhcpv6_information_request(reply
, packet
);
7631 case DHCPV6_RELAY_FORW
:
7633 if (dhcpv4_over_dhcpv6
&& (local_family
== AF_INET
))
7634 dhcp4o6_relay_forw(reply
, packet
);
7636 #endif /* DHCP4o6 */
7637 dhcpv6_relay_forw(reply
, packet
);
7639 case DHCPV6_RELAY_REPL
:
7640 dhcpv6_discard(packet
);
7642 case DHCPV6_LEASEQUERY
:
7643 classify_client(packet
);
7644 dhcpv6_leasequery(reply
, packet
);
7646 case DHCPV6_LEASEQUERY_REPLY
:
7647 dhcpv6_discard(packet
);
7649 case DHCPV6_DHCPV4_QUERY
:
7651 if (dhcpv4_over_dhcpv6
) {
7652 if (local_family
== AF_INET6
) {
7653 forw_dhcpv4_query(packet
);
7655 dhcp4o6_dhcpv4_query(reply
, packet
);
7658 #endif /* DHCP4o6 */
7659 dhcpv6_discard(packet
);
7661 case DHCPV6_DHCPV4_RESPONSE
:
7662 dhcpv6_discard(packet
);
7665 /* XXX: would be nice if we had "notice" level,
7666 as syslog, for this */
7667 log_info("Discarding unknown DHCPv6 message type %d "
7668 "from %s", packet
->dhcpv6_msg_type
,
7669 piaddr(packet
->client_addr
));
7674 log_packet_in(const struct packet
*packet
) {
7675 struct data_string s
;
7677 char tmp_addr
[INET6_ADDRSTRLEN
];
7680 memset(&s
, 0, sizeof(s
));
7682 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
7683 data_string_sprintfa(&s
, "%s message from %s port %d",
7684 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7685 piaddr(packet
->client_addr
),
7686 ntohs(packet
->client_port
));
7688 data_string_sprintfa(&s
,
7689 "Unknown message type %d from %s port %d",
7690 packet
->dhcpv6_msg_type
,
7691 piaddr(packet
->client_addr
),
7692 ntohs(packet
->client_port
));
7694 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7695 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7696 addr
= &packet
->dhcpv6_link_address
;
7697 data_string_sprintfa(&s
, ", link address %s",
7698 inet_ntop(AF_INET6
, addr
,
7699 tmp_addr
, sizeof(tmp_addr
)));
7700 addr
= &packet
->dhcpv6_peer_address
;
7701 data_string_sprintfa(&s
, ", peer address %s",
7702 inet_ntop(AF_INET6
, addr
,
7703 tmp_addr
, sizeof(tmp_addr
)));
7704 } else if ((packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_QUERY
) &&
7705 (packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_RESPONSE
)) {
7707 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
7708 data_string_sprintfa(&s
, ", transaction ID 0x%06X", tid
);
7711 oc = lookup_option(&dhcpv6_universe, packet->options,
7714 memset(&tmp_ds, 0, sizeof(tmp_ds_));
7715 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
7716 packet->options, NULL,
7717 &global_scope, oc, MDL)) {
7718 log_error("Error evaluating Client Identifier");
7720 data_strint_sprintf(&s, ", client ID %s",
7722 data_string_forget(&tmp_ds, MDL);
7728 log_info("%s", s
.data
);
7730 data_string_forget(&s
, MDL
);
7734 dhcpv6(struct packet
*packet
) {
7735 struct data_string reply
;
7736 struct sockaddr_in6 to_addr
;
7740 * Log a message that we received this packet.
7742 log_packet_in(packet
);
7745 * Build our reply packet.
7747 build_dhcpv6_reply(&reply
, packet
);
7749 if (reply
.data
!= NULL
) {
7751 * Send our reply, if we have one.
7753 memset(&to_addr
, 0, sizeof(to_addr
));
7754 to_addr
.sin6_family
= AF_INET6
;
7755 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7756 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7757 to_addr
.sin6_port
= local_port
;
7759 to_addr
.sin6_port
= remote_port
;
7762 #if defined (REPLY_TO_SOURCE_PORT)
7764 * This appears to have been included for testing so we would
7765 * not need a root client, but was accidently left in the
7766 * final code. We continue to include it in case
7767 * some users have come to rely upon it, but leave
7768 * it off by default as it's a bad idea.
7770 to_addr
.sin6_port
= packet
->client_port
;
7773 #if defined(RELAY_PORT)
7775 * Check relay source port.
7777 if (packet
->relay_source_port
) {
7778 to_addr
.sin6_port
= packet
->client_port
;
7782 memcpy(&to_addr
.sin6_addr
, packet
->client_addr
.iabuf
,
7783 sizeof(to_addr
.sin6_addr
));
7785 log_info("Sending %s to %s port %d",
7786 dhcpv6_type_names
[reply
.data
[0]],
7787 piaddr(packet
->client_addr
),
7788 ntohs(to_addr
.sin6_port
));
7790 send_ret
= send_packet6(packet
->interface
,
7791 reply
.data
, reply
.len
, &to_addr
);
7792 if (send_ret
!= reply
.len
) {
7793 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
7794 send_ret
, reply
.len
);
7796 data_string_forget(&reply
, MDL
);
7802 * \brief Receive a DHCPv4-query message from the DHCPv6 side
7803 * (DHCPv4 server function)
7805 * Receive a message with a DHCPv4-query inside from the DHCPv6 server.
7806 * (code copied from \ref do_packet6() \ref and dhcpv6())
7808 * Format: interface:16 + address:16 + udp:4 + DHCPv6 DHCPv4-query message
7810 * \param raw the DHCPv6 DHCPv4-query message raw content
7812 static void recv_dhcpv4_query(struct data_string
*raw
) {
7813 struct interface_info
*ip
;
7816 struct packet
*packet
;
7817 unsigned char msg_type
;
7818 const struct dhcpv6_relay_packet
*relay
;
7819 const struct dhcpv4_over_dhcpv6_packet
*msg
;
7820 struct data_string reply
;
7821 struct data_string ds
;
7822 struct udp_data4o6 udp_data
;
7826 memset(name
, 0, sizeof(name
));
7827 memcpy(name
, raw
->data
, 16);
7828 for (ip
= interfaces
; ip
!= NULL
; ip
= ip
->next
) {
7829 if (!strcmp(name
, ip
->name
))
7833 log_error("recv_dhcpv4_query: can't find interface %s.",
7839 memcpy(iaddr
.iabuf
, raw
->data
+ 16, 16);
7841 memset(&udp_data
, 0, sizeof(udp_data
));
7842 memcpy(&udp_data
, raw
->data
+ 32, 4);
7845 * From do_packet6().
7848 if (!packet6_len_okay((char *)raw
->data
+ 36, raw
->len
- 36)) {
7849 log_error("recv_dhcpv4_query: "
7850 "short packet from %s, len %d, dropped",
7851 piaddr(iaddr
), raw
->len
- 36);
7856 * Build a packet structure.
7859 if (!packet_allocate(&packet
, MDL
)) {
7860 log_error("recv_dhcpv4_query: no memory for packet.");
7864 if (!option_state_allocate(&packet
->options
, MDL
)) {
7865 log_error("recv_dhcpv4_query: no memory for options.");
7866 packet_dereference(&packet
, MDL
);
7870 packet
->raw
= (struct dhcp_packet
*)(raw
->data
+ 36);
7871 packet
->packet_length
= raw
->len
- 36;
7872 packet
->client_port
= udp_data
.src_port
;
7873 packet
->client_addr
= iaddr
;
7874 interface_reference(&packet
->interface
, ip
, MDL
);
7876 msg_type
= raw
->data
[36];
7877 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
7878 (msg_type
== DHCPV6_RELAY_REPL
)) {
7880 (int)(offsetof(struct dhcpv6_relay_packet
, options
));
7881 relay
= (const struct dhcpv6_relay_packet
*)(raw
->data
+ 36);
7882 packet
->dhcpv6_msg_type
= relay
->msg_type
;
7884 /* relay-specific data */
7885 packet
->dhcpv6_hop_count
= relay
->hop_count
;
7886 memcpy(&packet
->dhcpv6_link_address
,
7887 relay
->link_address
, sizeof(relay
->link_address
));
7888 memcpy(&packet
->dhcpv6_peer_address
,
7889 relay
->peer_address
, sizeof(relay
->peer_address
));
7891 if (!parse_option_buffer(packet
->options
,
7893 raw
->len
- 36 - relaylen
,
7894 &dhcpv6_universe
)) {
7895 /* no logging here, as parse_option_buffer() logs all
7896 cases where it fails */
7897 packet_dereference(&packet
, MDL
);
7900 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
7901 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
7903 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7904 msg
= (struct dhcpv4_over_dhcpv6_packet
*)(raw
->data
+ 36);
7905 packet
->dhcpv6_msg_type
= msg
->msg_type
;
7907 /* message-specific data */
7908 memcpy(packet
->dhcp4o6_flags
, msg
->flags
,
7909 sizeof(packet
->dhcp4o6_flags
));
7911 if (!parse_option_buffer(packet
->options
,
7913 raw
->len
- 36 - msglen
,
7914 &dhcpv6_universe
)) {
7915 /* no logging here, as parse_option_buffer() logs all
7916 cases where it fails */
7917 packet_dereference(&packet
, MDL
);
7921 log_error("recv_dhcpv4_query: unexpected message of type %d.",
7923 packet_dereference(&packet
, MDL
);
7932 * Log a message that we received this packet.
7934 /* log_packet_in(packet); */
7935 memset(&ds
, 0, sizeof(ds
));
7936 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
7937 data_string_sprintfa(&ds
, "%s message from %s",
7938 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7939 piaddr(packet
->client_addr
));
7941 data_string_sprintfa(&ds
,
7942 "Unknown message type %d from %s",
7943 packet
->dhcpv6_msg_type
,
7944 piaddr(packet
->client_addr
));
7946 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7947 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7948 char tmp_addr
[INET6_ADDRSTRLEN
];
7951 addr
= &packet
->dhcpv6_link_address
;
7952 data_string_sprintfa(&ds
, ", link address %s",
7953 inet_ntop(AF_INET6
, addr
,
7954 tmp_addr
, sizeof(tmp_addr
)));
7955 addr
= &packet
->dhcpv6_peer_address
;
7956 data_string_sprintfa(&ds
, ", peer address %s",
7957 inet_ntop(AF_INET6
, addr
,
7958 tmp_addr
, sizeof(tmp_addr
)));
7959 } else if ((packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_QUERY
) &&
7960 (packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_RESPONSE
)) {
7963 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
7964 data_string_sprintfa(&ds
, ", transaction ID 0x%06X", tid
);
7966 log_info("%s", ds
.data
);
7967 data_string_forget(&ds
, MDL
);
7970 * Build our reply packet.
7972 build_dhcpv6_reply(&reply
, packet
);
7974 if (reply
.data
== NULL
) {
7975 packet_dereference(&packet
, MDL
);
7980 * Forward the response.
7982 len
= reply
.len
+ 36;
7983 memset(&ds
, 0, sizeof(ds
));
7984 if (!buffer_allocate(&ds
.buffer
, len
, MDL
)) {
7985 log_error("recv_dhcpv4_query: no memory.");
7986 packet_dereference(&packet
, MDL
);
7989 ds
.data
= ds
.buffer
->data
;
7992 memcpy(ds
.buffer
->data
, name
, 16);
7993 memcpy(ds
.buffer
->data
+ 16, iaddr
.iabuf
, 16);
7994 udp_data
.rsp_opt_exist
= packet
->relay_source_port
? 1 : 0;
7995 memcpy(ds
.buffer
->data
+ 32, &udp_data
, 4);
7996 memcpy(ds
.buffer
->data
+ 36, reply
.data
, reply
.len
);
7999 * Now we can release the packet.
8001 packet_dereference(&packet
, MDL
);
8003 cc
= send(dhcp4o6_fd
, ds
.data
, ds
.len
, 0);
8005 log_error("recv_dhcpv4_query: send(): %m");
8006 data_string_forget(&ds
, MDL
);
8008 #endif /* DHCP4o6 */
8011 seek_shared_host(struct host_decl
**hp
, struct shared_network
*shared
) {
8012 struct host_decl
*nofixed
= NULL
;
8013 struct host_decl
*seek
, *hold
= NULL
;
8016 * Seek forward through fixed addresses for the right link.
8018 * Note: how to do this for fixed prefixes???
8020 host_reference(&hold
, *hp
, MDL
);
8021 host_dereference(hp
, MDL
);
8023 while (seek
!= NULL
) {
8024 if (seek
->fixed_addr
== NULL
)
8026 else if (fixed_matches_shared(seek
, shared
))
8029 seek
= seek
->n_ipaddr
;
8032 if ((seek
== NULL
) && (nofixed
!= NULL
))
8036 host_reference(hp
, seek
, MDL
);
8039 static isc_boolean_t
8040 fixed_matches_shared(struct host_decl
*host
, struct shared_network
*shared
) {
8041 struct subnet
*subnet
;
8042 struct data_string addr
;
8043 isc_boolean_t matched
;
8046 if (host
->fixed_addr
== NULL
)
8049 memset(&addr
, 0, sizeof(addr
));
8050 if (!evaluate_option_cache(&addr
, NULL
, NULL
, NULL
, NULL
, NULL
,
8051 &global_scope
, host
->fixed_addr
, MDL
))
8054 if (addr
.len
< 16) {
8055 data_string_forget(&addr
, MDL
);
8060 memcpy(fixed
.iabuf
, addr
.data
, 16);
8062 matched
= ISC_FALSE
;
8063 for (subnet
= shared
->subnets
; subnet
!= NULL
;
8064 subnet
= subnet
->next_sibling
) {
8065 if (addr_eq(subnet_number(fixed
, subnet
->netmask
),
8072 data_string_forget(&addr
, MDL
);
8078 * \brief Constructs a REPLY with status of UseMulticast to a given packet
8080 * Per RFC 3315 Secs 18.2.1,3,6 & 7, when a server rejects a client's
8081 * unicast-sent packet, the response must only contain the client id,
8082 * server id, and a status code option of 5 (UseMulticast). This function
8083 * constructs such a packet and returns it as a data_string.
8085 * \param reply_ret = data_string which will receive the newly constructed
8087 * \param packet = client request which is being rejected
8088 * \param client_id = data_string which contains the client id
8089 * \param server_id = data_string which which contains the server id
8093 unicast_reject(struct data_string
*reply_ret
,
8094 struct packet
*packet
,
8095 const struct data_string
*client_id
,
8096 const struct data_string
*server_id
)
8098 struct reply_state reply
;
8099 memset(&reply
, 0x0, sizeof(struct reply_state
));
8101 /* Locate the client. */
8102 if (shared_network_from_packet6(&reply
.shared
, packet
)
8104 log_error("unicast_reject: could not locate client.");
8108 /* Initialize the reply. */
8109 packet_reference(&reply
.packet
, packet
, MDL
);
8110 data_string_copy(&reply
.client_id
, client_id
, MDL
);
8112 if (start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
8113 &reply
.buf
.reply
)) {
8114 /* Set the UseMulticast status code. */
8115 if (!set_status_code(STATUS_UseMulticast
,
8116 "Unicast not allowed by server.",
8118 log_error("unicast_reject: Unable to set status code.");
8120 /* Set write cursor to just past the reply header. */
8121 reply
.cursor
= REPLY_OPTIONS_INDEX
;
8122 reply
.cursor
+= store_options6(((char *)reply
.buf
.data
8128 unicast_reject_opts
,
8131 /* Return our reply to the caller. */
8132 reply_ret
->len
= reply
.cursor
;
8133 reply_ret
->buffer
= NULL
;
8134 if (!buffer_allocate(&reply_ret
->buffer
,
8135 reply
.cursor
, MDL
)) {
8136 log_fatal("unicast_reject:"
8137 "No memory to store Reply.");
8140 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
,
8142 reply_ret
->data
= reply_ret
->buffer
->data
;
8148 if (reply
.shared
!= NULL
)
8149 shared_network_dereference(&reply
.shared
, MDL
);
8150 if (reply
.opt_state
!= NULL
)
8151 option_state_dereference(&reply
.opt_state
, MDL
);
8152 if (reply
.packet
!= NULL
)
8153 packet_dereference(&reply
.packet
, MDL
);
8154 if (reply
.client_id
.data
!= NULL
)
8155 data_string_forget(&reply
.client_id
, MDL
);
8160 * \brief Checks if the dhcp6.unicast option has been defined
8162 * Scans the option space for the presence of the dhcp6.unicast option. The
8163 * function attempts to map the inbound packet to a shared network first
8164 * by an ip address specified via an D6O_IA_XX option and if that fails then
8165 * by the packet's source information (e.g. relay link, link, or interace).
8166 * Once the packet is mapped to a shared network, the function executes all
8167 * statements from the network's group outward into a local option cache.
8168 * The option cache is then scanned for the presence of unicast option. If
8169 * the packet cannot be mapped to a shared network, the function returns
8171 * \param packet inbound packet from the client
8173 * \return ISC_TRUE if the dhcp6.unicast option is defined, false otherwise.
8177 is_unicast_option_defined(struct packet
*packet
) {
8178 isc_boolean_t is_defined
= ISC_FALSE
;
8179 struct option_state
*opt_state
= NULL
;
8180 struct option_cache
*oc
= NULL
;
8181 struct shared_network
*shared
= NULL
;
8183 if (!option_state_allocate(&opt_state
, MDL
)) {
8184 log_fatal("is_unicast_option_defined:"
8185 "No memory for option state.");
8188 /* We try to map the packet to a network first by an IA_XX value.
8189 * If that fails, we try by packet source. */
8190 if (((shared_network_from_requested_addr(&shared
, packet
)
8191 != ISC_R_SUCCESS
) &&
8192 (shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
))
8193 || (shared
== NULL
)) {
8194 /* @todo what would this really mean? I think wrong network
8195 * logic will catch it */
8196 log_error("is_unicast_option_defined:"
8197 "cannot attribute packet to a network.");
8201 /* Now that we've mapped it to a network, execute statments to that
8202 * scope, looking for the unicast option. We don't care about the
8203 * value of the option, only whether or not it is defined. */
8204 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
, opt_state
,
8205 &global_scope
, shared
->group
, NULL
, NULL
);
8207 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_UNICAST
);
8208 is_defined
= (oc
!= NULL
? ISC_TRUE
: ISC_FALSE
);
8209 log_debug("is_unicast_option_defined: option found : %d", is_defined
);
8211 if (shared
!= NULL
) {
8212 shared_network_dereference(&shared
, MDL
);
8215 if (opt_state
!= NULL
) {
8216 option_state_dereference(&opt_state
, MDL
);
8219 return (is_defined
);
8224 * \brief Maps a packet to a shared network based on the requested IP address
8226 * The function attempts to find a subnet that matches the first requested IP
8227 * address contained within the given packet. Note that it looks first for
8228 * D6O_IA_NAs, then D6O_IA_PDs and lastly D6O_IA_TAs. If a matching network is
8229 * found, a reference to it is returned in the parameter, shared.
8231 * \param shared shared_network pointer which will receive the matching network
8232 * \param packet inbound packet from the client
8234 * \return ISC_R_SUCCESS if the packet can be mapped to a shared_network.
8238 shared_network_from_requested_addr (struct shared_network
**shared
,
8239 struct packet
* packet
) {
8241 struct subnet
* subnet
= NULL
;
8242 isc_result_t status
= ISC_R_FAILURE
;
8244 /* Try to match first IA_ address or prefix we find to a subnet. In
8245 * theory all IA_ values in a given request are supposed to be in the
8246 * same subnet so we only need to try one right? */
8247 if ((get_first_ia_addr_val(packet
, D6O_IA_NA
, &iaddr
) != ISC_R_SUCCESS
)
8248 && (get_first_ia_addr_val(packet
, D6O_IA_PD
, &iaddr
)
8250 && (get_first_ia_addr_val(packet
, D6O_IA_TA
, &iaddr
)
8251 != ISC_R_SUCCESS
)) {
8252 /* we found nothing to match against */
8253 log_debug("share_network_from_request_addr: nothing to match");
8254 return (ISC_R_FAILURE
);
8257 if (!find_subnet(&subnet
, iaddr
, MDL
)) {
8258 log_debug("shared_network_from_requested_addr:"
8259 "No subnet found for addr %s.", piaddr(iaddr
));
8261 status
= shared_network_reference(shared
,
8262 subnet
->shared_network
, MDL
);
8263 subnet_dereference(&subnet
, MDL
);
8264 log_debug("shared_network_from_requested_addr:"
8265 " found shared network %s for address %s.",
8266 ((*shared
)->name
? (*shared
)->name
: "unnamed"),
8271 return (ISC_R_FAILURE
);
8276 * \brief Retrieves the first IP address from a given packet of a given type
8278 * Search a packet for options of a given type (D6O_IA_AN, D6O_IA_PD, or
8279 * D6O_IA_TA) for the first non-blank IA_XX value and return its IP address
8282 * \param packet packet received from the client
8283 * \param addr_type the address option type (D6O_IA_NA , D6O_IA_PD, or
8284 * D6O_IP_TA) to look for within the packet.
8285 * \param iaddr pointer to the iaddr structure which will receive the extracted
8288 * \return ISC_R_SUCCESS if an address was succesfully extracted, ISC_R_FALURE
8293 get_first_ia_addr_val (struct packet
* packet
, int addr_type
,
8294 struct iaddr
* iaddr
) {
8295 struct option_cache
*ia
;
8296 struct option_cache
*oc
= NULL
;
8297 struct data_string cli_enc_opt_data
;
8298 struct option_state
*cli_enc_opt_state
;
8299 int addr_opt_offset
;
8301 int addr_opt_data_len
;
8304 isc_result_t status
= ISC_R_FAILURE
;
8305 memset(iaddr
, 0, sizeof(struct iaddr
));
8307 /* Set up address type specifics */
8308 switch (addr_type
) {
8310 addr_opt_offset
= IA_NA_OFFSET
;
8311 addr_opt
= D6O_IAADDR
;
8312 addr_opt_data_len
= 24;
8316 addr_opt_offset
= IA_TA_OFFSET
;
8317 addr_opt
= D6O_IAADDR
;
8318 addr_opt_data_len
= 24;
8322 addr_opt_offset
= IA_PD_OFFSET
;
8323 addr_opt
= D6O_IAPREFIX
;
8324 addr_opt_data_len
= 25;
8328 /* shouldn't be here */
8329 log_error ("get_first_ia_addr_val: invalid opt type %d",
8331 return (ISC_R_FAILURE
);
8334 /* Find the first, non-blank IA_XX value within an D6O_IA_XX option. */
8335 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, addr_type
);
8336 ia
!= NULL
&& oc
== NULL
; ia
= ia
->next
) {
8337 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
8339 packet
, ia
, addr_opt_offset
)) {
8340 log_debug ("get_first_ia_addr_val:"
8341 " couldn't unroll enclosing option");
8342 return (ISC_R_FAILURE
);
8345 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
8348 /* no address given for this IA, ignore */
8349 option_state_dereference(&cli_enc_opt_state
, MDL
);
8350 data_string_forget(&cli_enc_opt_data
, MDL
);
8354 /* If we found a non-blank IA_XX then extract its ip address. */
8356 struct data_string iaddr_str
;
8358 memset(&iaddr_str
, 0, sizeof(iaddr_str
));
8359 if (!evaluate_option_cache(&iaddr_str
, packet
, NULL
, NULL
,
8360 packet
->options
, NULL
, &global_scope
,
8362 log_error("get_first_ia_addr_val: "
8363 "error evaluating IA_XX option.");
8365 if (iaddr_str
.len
!= addr_opt_data_len
) {
8366 log_error("shared_network_from_requested_addr:"
8367 " invalid length %d, expected %d",
8368 iaddr_str
.len
, addr_opt_data_len
);
8371 memcpy (iaddr
->iabuf
,
8372 iaddr_str
.data
+ ip_addr_offset
, 16);
8373 status
= ISC_R_SUCCESS
;
8375 data_string_forget(&iaddr_str
, MDL
);
8378 option_state_dereference(&cli_enc_opt_state
, MDL
);
8379 data_string_forget(&cli_enc_opt_data
, MDL
);
8386 * \brief Calculates the reply T1/T2 times and stuffs them in outbound buffer
8388 * T1/T2 time selection is kind of weird. We actually use DHCP * (v4) scoped
8389 * options, dhcp-renewal-time and dhcp-rebinding-time, as handy existing places
8390 * where these can be configured by an administrator. A value of zero tells the
8391 * client it may choose its own value.
8393 * When those options are not defined, the values will be set to zero unless
8394 * the global option, dhcpv6-set-tee-times is enabled. When this option is
8395 * enabled the values are calculated as recommended by RFC 3315, Section 22.4:
8397 * T1 will be set to 0.5 times the shortest preferred lifetime
8398 * in the IA_XX option. If the "shortest" preferred lifetime is
8399 * 0xFFFFFFFF, T1 will set to 0xFFFFFFFF.
8401 * T2 will be set to 0.8 times the shortest preferred lifetime
8402 * in the IA_XX option. If the "shortest" preferred lifetime is
8403 * 0xFFFFFFFF, T2 will set to 0xFFFFFFFF.
8405 * Note that dhcpv6-set-tee-times is intended to be transitional and will
8406 * likely be removed in 4.4.0, leaving the behavior as getting the values
8407 * either from the configured parameters (if you want zeros, define them as
8408 * zeros) or by calculating them per the RFC.
8410 * \param reply - pointer to the reply_state structure
8411 * \param ia_cursor - offset of the beginning of the IA_XX option within the
8412 * reply's outbound data buffer
8415 set_reply_tee_times(struct reply_state
* reply
, unsigned ia_cursor
)
8417 struct option_cache
*oc
;
8420 /* Found out if calculated values are enabled. */
8421 oc
= lookup_option(&server_universe
, reply
->opt_state
,
8422 SV_DHCPV6_SET_TEE_TIMES
);
8423 set_tee_times
= (oc
&&
8424 evaluate_boolean_option_cache(NULL
, reply
->packet
,
8426 reply
->packet
->options
,
8428 &global_scope
, oc
, MDL
));
8430 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
8431 DHO_DHCP_RENEWAL_TIME
);
8433 /* dhcp-renewal-time is defined, use it */
8434 struct data_string data
;
8435 memset(&data
, 0x00, sizeof(data
));
8437 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
8438 reply
->packet
->options
,
8439 reply
->opt_state
, &global_scope
,
8442 log_error("Invalid renewal time.");
8445 reply
->renew
= getULong(data
.data
);
8448 if (data
.data
!= NULL
)
8449 data_string_forget(&data
, MDL
);
8450 } else if (set_tee_times
) {
8451 /* Setting them is enabled so T1 is either infinite or
8452 * 0.5 * the shortest preferred lifetime in the IA_XX */
8453 if (reply
->min_prefer
== INFINITE_TIME
)
8454 reply
->renew
= INFINITE_TIME
;
8456 reply
->renew
= reply
->min_prefer
/ 2;
8458 /* Default is to let the client choose */
8462 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
8465 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
8466 DHO_DHCP_REBINDING_TIME
);
8468 /* dhcp-rebinding-time is defined, use it */
8469 struct data_string data
;
8470 memset(&data
, 0x00, sizeof(data
));
8472 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
8473 reply
->packet
->options
,
8474 reply
->opt_state
, &global_scope
,
8477 log_error("Invalid rebinding time.");
8480 reply
->rebind
= getULong(data
.data
);
8483 if (data
.data
!= NULL
)
8484 data_string_forget(&data
, MDL
);
8485 } else if (set_tee_times
) {
8486 /* Setting them is enabled so T2 is either infinite or
8487 * 0.8 * the shortest preferred lifetime in the reply */
8488 if (reply
->min_prefer
== INFINITE_TIME
)
8489 reply
->rebind
= INFINITE_TIME
;
8491 reply
->rebind
= (reply
->min_prefer
/ 5) * 4;
8493 /* Default is to let the client choose */
8497 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
8501 * Releases the iasubopts in the pre-existing IA, if they are not in
8502 * the same shared-network as the new IA.
8504 * returns 1 if the release was done, 0 otherwise
8507 release_on_roam(struct reply_state
* reply
) {
8508 struct ia_xx
* old_ia
= reply
->old_ia
;
8509 struct iasubopt
*lease
= NULL
;
8512 if ((!do_release_on_roam
) || old_ia
== NULL
8513 || old_ia
->num_iasubopt
<= 0) {
8517 /* If the old shared-network and new are the same, client hasn't
8518 * roamed, nothing to do. We only check the first one because you
8519 * cannot have iasubopts on different shared-networks within a
8521 lease
= old_ia
->iasubopt
[0];
8522 if (lease
->ipv6_pool
->shared_network
== reply
->shared
) {
8526 /* Old and new are on different shared networks so the client must
8527 * roamed. Release the old leases. */
8528 for (i
= 0; i
< old_ia
->num_iasubopt
; i
++) {
8529 lease
= old_ia
->iasubopt
[i
];
8531 log_info("Client: %s roamed to new network,"
8532 " releasing lease: %s%s",
8533 print_hex_1(reply
->client_id
.len
,
8534 reply
->client_id
.data
, 60),
8535 pin6_addr(&lease
->addr
), iasubopt_plen_str(lease
));
8537 release_lease6(lease
->ipv6_pool
, lease
);
8538 lease
->ia
->cltt
= cur_time
;
8539 write_ia(lease
->ia
);
8546 * Convenience function which returns a string (static buffer)
8547 * containing either a "/" followed by the prefix length or an
8548 * empty string depending on the lease type
8550 const char *iasubopt_plen_str(struct iasubopt
*lease
) {
8551 static char prefix_buf
[16];
8553 if ((lease
->ia
) && (lease
->ia
->ia_type
== D6O_IA_PD
)) {
8554 sprintf(prefix_buf
, "/%-d", lease
->plen
);
8557 return (prefix_buf
);
8562 * Initiates DDNS updates for static v6 leases if configured to do so.
8564 * The function, which must be called after the IA has been written to the
8565 * packet, adds an iasubopt to the IA for static lease. This is done so we
8566 * have an iasubopt to pass into ddns_updates(). A reference to the IA is
8567 * added to the DDNS control block to ensure it and it's iasubopt remain in
8568 * scope until the update is complete.
8571 void ddns_update_static6(struct reply_state
* reply
) {
8572 struct iasubopt
*iasub
= NULL
;
8573 struct binding_scope
*scope
= NULL
;
8574 struct option_cache
*oc
= NULL
;
8576 oc
= lookup_option(&server_universe
, reply
->opt_state
, SV_DDNS_UPDATES
);
8578 (evaluate_boolean_option_cache(NULL
, reply
->packet
, NULL
, NULL
,
8579 reply
->packet
->options
,
8580 reply
->opt_state
, NULL
,
8585 oc
= lookup_option(&server_universe
, reply
->opt_state
,
8586 SV_UPDATE_STATIC_LEASES
);
8588 (evaluate_boolean_option_cache(NULL
, reply
->packet
,
8590 reply
->packet
->options
,
8591 reply
->opt_state
, NULL
,
8596 if (iasubopt_allocate(&iasub
, MDL
) != ISC_R_SUCCESS
) {
8597 log_fatal("No memory for iasubopt.");
8600 if (ia_add_iasubopt(reply
->ia
, iasub
, MDL
) != ISC_R_SUCCESS
) {
8601 log_fatal("Could not add iasubopt.");
8604 ia_reference(&iasub
->ia
, reply
->ia
, MDL
);
8606 memcpy(iasub
->addr
.s6_addr
, reply
->fixed
.data
, 16);
8608 iasub
->prefer
= MAX_TIME
;
8609 iasub
->valid
= MAX_TIME
;
8610 iasub
->static_lease
= 1;
8612 if (!binding_scope_allocate(&scope
, MDL
)) {
8613 log_fatal("Out of memory for binding scope.");
8616 binding_scope_reference(&iasub
->scope
, scope
, MDL
);
8618 ddns_updates(reply
->packet
, NULL
, NULL
, iasub
, NULL
, reply
->opt_state
);
8620 #endif /* NSUPDATE */