2 * Copyright (C) 2006-2016 by Internet Systems Consortium, Inc. ("ISC")
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
17 /*! \file server/dhcpv6.c */
24 static void forw_dhcpv4_query(struct packet
*packet
);
25 static void send_dhcpv4_response(struct data_string
*raw
);
27 static void recv_dhcpv4_query(struct data_string
*raw
);
28 static void dhcp4o6_dhcpv4_query(struct data_string
*reply_ret
,
29 struct packet
*packet
);
33 * We use print_hex_1() to output DUID values. We could actually output
34 * the DUID with more information... MAC address if using type 1 or 3,
35 * and so on. However, RFC 3315 contains Grave Warnings against actually
36 * attempting to understand a DUID.
40 * TODO: gettext() or other method of localization for the messages
41 * for status codes (and probably for log formats eventually)
42 * TODO: refactoring (simplify, simplify, simplify)
43 * TODO: support multiple shared_networks on each interface (this
44 * will allow the server to issue multiple IPv6 addresses to
49 * DHCPv6 Reply workflow assist. A Reply packet is built by various
50 * different functions; this gives us one location where we keep state
54 /* root level persistent state */
55 struct shared_network
*shared
;
56 struct host_decl
*host
;
57 struct subnet
*subnet
; /* Used to match fixed-addrs to subnet scopes. */
58 struct option_state
*opt_state
;
59 struct packet
*packet
;
60 struct data_string client_id
;
62 /* IA level persistent state */
65 unsigned client_resources
;
66 isc_boolean_t resources_included
;
67 isc_boolean_t static_lease
;
68 unsigned static_prefixes
;
71 struct option_state
*reply_ia
;
72 struct data_string fixed
;
73 struct iaddrcidrnet fixed_pref
; /* static prefix for logging */
75 /* IAADDR/PREFIX level persistent state */
76 struct iasubopt
*lease
;
79 * "t1", "t2", preferred, and valid lifetimes records for calculating
80 * t1 and t2 (min/max).
82 u_int32_t renew
, rebind
, min_prefer
, min_valid
;
84 /* Client-requested valid and preferred lifetimes. */
85 u_int32_t client_valid
, client_prefer
;
87 /* Chosen values to transmit for valid and preferred lifetimes. */
88 u_int32_t send_valid
, send_prefer
;
90 /* Preferred prefix length (-1 is any). */
93 /* Index into the data field that has been consumed. */
96 /* Space for the on commit statements for a fixed host */
97 struct on_star on_star
;
100 unsigned char data
[65536];
101 struct dhcpv6_packet reply
;
106 * Prototypes local to this file.
108 static int get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
109 struct data_string
*enc_opt_data
,
110 struct packet
*packet
,
111 struct option_cache
*oc
,
113 static void build_dhcpv6_reply(struct data_string
*, struct packet
*);
114 static isc_result_t
shared_network_from_packet6(struct shared_network
**shared
,
115 struct packet
*packet
);
116 static void seek_shared_host(struct host_decl
**hp
,
117 struct shared_network
*shared
);
118 static isc_boolean_t
fixed_matches_shared(struct host_decl
*host
,
119 struct shared_network
*shared
);
120 static isc_result_t
reply_process_ia_na(struct reply_state
*reply
,
121 struct option_cache
*ia
);
122 static isc_result_t
reply_process_ia_ta(struct reply_state
*reply
,
123 struct option_cache
*ia
);
124 static isc_result_t
reply_process_addr(struct reply_state
*reply
,
125 struct option_cache
*addr
);
126 static isc_boolean_t
address_is_owned(struct reply_state
*reply
,
128 static isc_boolean_t
temporary_is_available(struct reply_state
*reply
,
130 static isc_result_t
find_client_temporaries(struct reply_state
*reply
);
131 static isc_result_t
reply_process_try_addr(struct reply_state
*reply
,
133 static isc_result_t
find_client_address(struct reply_state
*reply
);
134 static isc_result_t
reply_process_is_addressed(struct reply_state
*reply
,
135 struct binding_scope
**scope
,
136 struct group
*group
);
137 static isc_result_t
reply_process_send_addr(struct reply_state
*reply
,
139 static struct iasubopt
*lease_compare(struct iasubopt
*alpha
,
140 struct iasubopt
*beta
);
141 static isc_result_t
reply_process_ia_pd(struct reply_state
*reply
,
142 struct option_cache
*ia_pd
);
143 static struct group
*find_group_by_prefix(struct reply_state
*reply
);
144 static isc_result_t
reply_process_prefix(struct reply_state
*reply
,
145 struct option_cache
*pref
);
146 static isc_boolean_t
prefix_is_owned(struct reply_state
*reply
,
147 struct iaddrcidrnet
*pref
);
148 static isc_result_t
find_client_prefix(struct reply_state
*reply
);
149 static isc_result_t
reply_process_try_prefix(struct reply_state
*reply
,
150 struct iaddrcidrnet
*pref
);
151 static isc_result_t
reply_process_is_prefixed(struct reply_state
*reply
,
152 struct binding_scope
**scope
,
153 struct group
*group
);
154 static isc_result_t
reply_process_send_prefix(struct reply_state
*reply
,
155 struct iaddrcidrnet
*pref
);
156 static struct iasubopt
*prefix_compare(struct reply_state
*reply
,
157 struct iasubopt
*alpha
,
158 struct iasubopt
*beta
);
159 static void schedule_lease_timeout_reply(struct reply_state
*reply
);
161 static int eval_prefix_mode(int thislen
, int preflen
, int prefix_mode
);
162 static isc_result_t
pick_v6_prefix_helper(struct reply_state
*reply
,
165 static void unicast_reject(struct data_string
*reply_ret
, struct packet
*packet
,
166 const struct data_string
*client_id
,
167 const struct data_string
*server_id
);
169 static isc_boolean_t
is_unicast_option_defined(struct packet
*packet
);
170 static isc_result_t
shared_network_from_requested_addr (struct shared_network
172 struct packet
* packet
);
173 static isc_result_t
get_first_ia_addr_val (struct packet
* packet
, int addr_type
,
174 struct iaddr
* iaddr
);
177 set_reply_tee_times(struct reply_state
* reply
, unsigned ia_cursor
);
181 * \brief Omapi I/O handler
183 * The inter-process communication receive handler.
184 * Get the message, put it into the raw data_string
185 * and call \ref send_dhcpv4_response() (DHCPv6 side) or
186 * \ref recv_dhcpv4_query() (DHCPv4 side)
188 * \param h the OMAPI object
189 * \return a result for I/O success or error (used by the I/O subsystem)
191 isc_result_t
dhcpv4o6_handler(omapi_object_t
*h
) {
193 struct data_string raw
;
196 if (h
->type
!= dhcp4o6_type
)
197 return DHCP_R_INVALIDARG
;
199 cc
= recv(dhcp4o6_fd
, buf
, sizeof(buf
), 0);
201 if (cc
< DHCP_FIXED_NON_UDP
+ 32)
202 return ISC_R_UNEXPECTED
;
203 memset(&raw
, 0, sizeof(raw
));
204 if (!buffer_allocate(&raw
.buffer
, cc
, MDL
)) {
205 log_error("dhcpv4o6_handler: no memory buffer.");
206 return ISC_R_NOMEMORY
;
208 raw
.data
= raw
.buffer
->data
;
210 memcpy(raw
.buffer
->data
, buf
, cc
);
212 if (local_family
== AF_INET6
) {
213 send_dhcpv4_response(&raw
);
215 recv_dhcpv4_query(&raw
);
218 data_string_forget(&raw
, MDL
);
220 return ISC_R_SUCCESS
;
224 * \brief Send the DHCPv4-response back to the DHCPv6 side
225 * (DHCPv6 server function)
227 * Format: interface:16 + address:16 + DHCPv6 DHCPv4-response message
229 * \param raw the IPC message content
231 static void send_dhcpv4_response(struct data_string
*raw
) {
232 struct interface_info
*ip
;
234 struct sockaddr_in6 to_addr
;
235 char pbuf
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
238 memset(name
, 0, sizeof(name
));
239 memcpy(name
, raw
->data
, 16);
240 for (ip
= interfaces
; ip
!= NULL
; ip
= ip
->next
) {
241 if (!strcmp(name
, ip
->name
))
245 log_error("send_dhcpv4_response: can't find interface %s.",
250 memset(&to_addr
, 0, sizeof(to_addr
));
251 to_addr
.sin6_family
= AF_INET6
;
252 memcpy(&to_addr
.sin6_addr
, raw
->data
+ 16, 16);
253 if ((raw
->data
[32] == DHCPV6_RELAY_FORW
) ||
254 (raw
->data
[32] == DHCPV6_RELAY_REPL
)) {
255 to_addr
.sin6_port
= local_port
;
257 to_addr
.sin6_port
= remote_port
;
260 log_info("send_dhcpv4_response(): sending %s on %s to %s port %d",
261 dhcpv6_type_names
[raw
->data
[32]],
263 inet_ntop(AF_INET6
, raw
->data
+ 16, pbuf
, sizeof(pbuf
)),
264 ntohs(to_addr
.sin6_port
));
266 send_ret
= send_packet6(ip
, raw
->data
+ 32, raw
->len
- 32, &to_addr
);
268 log_error("send_dhcpv4_response: send_packet6(): %m");
269 } else if (send_ret
!= raw
->len
- 32) {
270 log_error("send_dhcpv4_response: send_packet6() "
271 "sent %d of %d bytes",
272 send_ret
, raw
->len
- 32);
278 * Schedule lease timeouts for all of the iasubopts in the reply.
279 * This is currently used to schedule timeouts for soft leases.
283 schedule_lease_timeout_reply(struct reply_state
*reply
) {
284 struct iasubopt
*tmp
;
287 /* sanity check the reply */
288 if ((reply
== NULL
) || (reply
->ia
== NULL
) || (reply
->ia
->iasubopt
== NULL
))
291 /* walk through the list, scheduling as we go */
292 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
293 tmp
= reply
->ia
->iasubopt
[i
];
294 schedule_lease_timeout(tmp
->ipv6_pool
);
299 * This function returns the time since DUID time start for the
300 * given time_t value.
303 duid_time(time_t when
) {
305 * This time is modulo 2^32.
307 while ((when
- DUID_TIME_EPOCH
) > 4294967295u) {
308 /* use 2^31 to avoid spurious compiler warnings */
313 return when
- DUID_TIME_EPOCH
;
320 * This must remain the same for the lifetime of this server, because
321 * clients return the server DUID that we sent them in Request packets.
323 * We pick the server DUID like this:
325 * 1. Check dhcpd.conf - any value the administrator has configured
326 * overrides any possible values.
327 * 2. Check the leases.txt - we want to use the previous value if
329 * 3. Check if dhcpd.conf specifies a type of server DUID to use,
330 * and generate that type.
331 * 4. Generate a type 1 (time + hardware address) DUID.
333 static struct data_string server_duid
;
336 * Check if the server_duid has been set.
339 server_duid_isset(void) {
340 return (server_duid
.data
!= NULL
);
344 * Return the server_duid.
347 copy_server_duid(struct data_string
*ds
, const char *file
, int line
) {
348 data_string_copy(ds
, &server_duid
, file
, line
);
352 * Set the server DUID to a specified value. This is used when
353 * the server DUID is stored in persistent memory (basically the
357 set_server_duid(struct data_string
*new_duid
) {
358 /* INSIST(new_duid != NULL); */
359 /* INSIST(new_duid->data != NULL); */
361 if (server_duid_isset()) {
362 data_string_forget(&server_duid
, MDL
);
364 data_string_copy(&server_duid
, new_duid
, MDL
);
369 * Set the server DUID based on the D6O_SERVERID option. This handles
370 * the case where the administrator explicitly put it in the dhcpd.conf
374 set_server_duid_from_option(void) {
375 struct option_state
*opt_state
;
376 struct option_cache
*oc
;
377 struct data_string option_duid
;
378 isc_result_t ret_val
;
381 if (!option_state_allocate(&opt_state
, MDL
)) {
382 log_fatal("No memory for server DUID.");
385 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
,
386 opt_state
, &global_scope
, root_group
,
389 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
391 ret_val
= ISC_R_NOTFOUND
;
393 memset(&option_duid
, 0, sizeof(option_duid
));
394 if (!evaluate_option_cache(&option_duid
, NULL
, NULL
, NULL
,
395 opt_state
, NULL
, &global_scope
,
397 ret_val
= ISC_R_UNEXPECTED
;
399 set_server_duid(&option_duid
);
400 data_string_forget(&option_duid
, MDL
);
401 ret_val
= ISC_R_SUCCESS
;
405 option_state_dereference(&opt_state
, MDL
);
411 * DUID layout, as defined in RFC 3315, section 9.
413 * We support type 1 (hardware address plus time) and type 3 (hardware
416 * We can support type 2 for specific vendors in the future, if they
417 * publish the specification. And of course there may be additional
420 static int server_duid_type
= DUID_LLT
;
426 set_server_duid_type(int type
) {
427 server_duid_type
= type
;
431 * Generate a new server DUID. This is done if there was no DUID in
432 * the leases.txt or in the dhcpd.conf file.
435 generate_new_server_duid(void) {
436 struct interface_info
*p
;
438 struct data_string generated_duid
;
441 * Verify we have a type that we support.
443 if ((server_duid_type
!= DUID_LL
) && (server_duid_type
!= DUID_LLT
)) {
444 log_error("Invalid DUID type %d specified, "
445 "only LL and LLT types supported", server_duid_type
);
446 return DHCP_R_INVALIDARG
;
450 * Find an interface with a hardware address.
453 for (p
= interfaces
; p
!= NULL
; p
= p
->next
) {
454 if (p
->hw_address
.hlen
> 0) {
459 return ISC_R_UNEXPECTED
;
465 memset(&generated_duid
, 0, sizeof(generated_duid
));
466 if (server_duid_type
== DUID_LLT
) {
467 time_val
= duid_time(time(NULL
));
468 generated_duid
.len
= 8 + p
->hw_address
.hlen
- 1;
469 if (!buffer_allocate(&generated_duid
.buffer
,
470 generated_duid
.len
, MDL
)) {
471 log_fatal("No memory for server DUID.");
473 generated_duid
.data
= generated_duid
.buffer
->data
;
474 putUShort(generated_duid
.buffer
->data
, DUID_LLT
);
475 putUShort(generated_duid
.buffer
->data
+ 2,
476 p
->hw_address
.hbuf
[0]);
477 putULong(generated_duid
.buffer
->data
+ 4, time_val
);
478 memcpy(generated_duid
.buffer
->data
+ 8,
479 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
480 } else if (server_duid_type
== DUID_LL
) {
481 generated_duid
.len
= 4 + p
->hw_address
.hlen
- 1;
482 if (!buffer_allocate(&generated_duid
.buffer
,
483 generated_duid
.len
, MDL
)) {
484 log_fatal("No memory for server DUID.");
486 generated_duid
.data
= generated_duid
.buffer
->data
;
487 putUShort(generated_duid
.buffer
->data
, DUID_LL
);
488 putUShort(generated_duid
.buffer
->data
+ 2,
489 p
->hw_address
.hbuf
[0]);
490 memcpy(generated_duid
.buffer
->data
+ 4,
491 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
493 log_fatal("Unsupported server DUID type %d.", server_duid_type
);
496 set_server_duid(&generated_duid
);
497 data_string_forget(&generated_duid
, MDL
);
499 return ISC_R_SUCCESS
;
503 * Get the client identifier from the packet.
506 get_client_id(struct packet
*packet
, struct data_string
*client_id
) {
507 struct option_cache
*oc
;
510 * Verify our client_id structure is empty.
512 if ((client_id
->data
!= NULL
) || (client_id
->len
!= 0)) {
513 return DHCP_R_INVALIDARG
;
516 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_CLIENTID
);
518 return ISC_R_NOTFOUND
;
521 if (!evaluate_option_cache(client_id
, packet
, NULL
, NULL
,
522 packet
->options
, NULL
,
523 &global_scope
, oc
, MDL
)) {
524 return ISC_R_FAILURE
;
527 return ISC_R_SUCCESS
;
531 * Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
533 * Servers MUST discard any Solicit messages that do not include a
534 * Client Identifier option or that do include a Server Identifier
538 valid_client_msg(struct packet
*packet
, struct data_string
*client_id
) {
540 struct option_cache
*oc
;
541 struct data_string data
;
544 memset(client_id
, 0, sizeof(*client_id
));
545 memset(&data
, 0, sizeof(data
));
547 switch (get_client_id(packet
, client_id
)) {
551 log_debug("Discarding %s from %s; "
552 "client identifier missing",
553 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
554 piaddr(packet
->client_addr
));
557 log_error("Error processing %s from %s; "
558 "unable to evaluate Client Identifier",
559 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
560 piaddr(packet
->client_addr
));
565 * Required by RFC 3315, section 15.
567 if (packet
->unicast
) {
568 log_debug("Discarding %s from %s; packet sent unicast "
570 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
571 piaddr(packet
->client_addr
),
572 print_hex_1(client_id
->len
, client_id
->data
, 60));
577 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
579 if (evaluate_option_cache(&data
, packet
, NULL
, NULL
,
580 packet
->options
, NULL
,
581 &global_scope
, oc
, MDL
)) {
582 log_debug("Discarding %s from %s; "
583 "server identifier found "
584 "(CLIENTID %s, SERVERID %s)",
585 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
586 piaddr(packet
->client_addr
),
587 print_hex_1(client_id
->len
,
588 client_id
->data
, 60),
589 print_hex_2(data
.len
,
592 log_debug("Discarding %s from %s; "
593 "server identifier found "
595 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
596 print_hex_1(client_id
->len
,
597 client_id
->data
, 60),
598 piaddr(packet
->client_addr
));
608 data_string_forget(&data
, MDL
);
611 if (client_id
->len
> 0) {
612 data_string_forget(client_id
, MDL
);
619 * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
620 * 15.9 (slightly different wording, but same meaning):
622 * Servers MUST discard any received Request message that meet any of
623 * the following conditions:
625 * - the message does not include a Server Identifier option.
626 * - the contents of the Server Identifier option do not match the
628 * - the message does not include a Client Identifier option.
631 valid_client_resp(struct packet
*packet
,
632 struct data_string
*client_id
,
633 struct data_string
*server_id
)
636 struct option_cache
*oc
;
638 /* INSIST((duid.data != NULL) && (duid.len > 0)); */
641 memset(client_id
, 0, sizeof(*client_id
));
642 memset(server_id
, 0, sizeof(*server_id
));
644 switch (get_client_id(packet
, client_id
)) {
648 log_debug("Discarding %s from %s; "
649 "client identifier missing",
650 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
651 piaddr(packet
->client_addr
));
654 log_error("Error processing %s from %s; "
655 "unable to evaluate Client Identifier",
656 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
657 piaddr(packet
->client_addr
));
661 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
663 log_debug("Discarding %s from %s: "
664 "server identifier missing (CLIENTID %s)",
665 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
666 piaddr(packet
->client_addr
),
667 print_hex_1(client_id
->len
, client_id
->data
, 60));
670 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
671 packet
->options
, NULL
,
672 &global_scope
, oc
, MDL
)) {
673 log_error("Error processing %s from %s; "
674 "unable to evaluate Server Identifier (CLIENTID %s)",
675 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
676 piaddr(packet
->client_addr
),
677 print_hex_1(client_id
->len
, client_id
->data
, 60));
680 if ((server_duid
.len
!= server_id
->len
) ||
681 (memcmp(server_duid
.data
, server_id
->data
, server_duid
.len
) != 0)) {
682 log_debug("Discarding %s from %s; "
683 "not our server identifier "
684 "(CLIENTID %s, SERVERID %s, server DUID %s)",
685 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
686 piaddr(packet
->client_addr
),
687 print_hex_1(client_id
->len
, client_id
->data
, 60),
688 print_hex_2(server_id
->len
, server_id
->data
, 60),
689 print_hex_3(server_duid
.len
, server_duid
.data
, 60));
698 if (server_id
->len
> 0) {
699 data_string_forget(server_id
, MDL
);
701 if (client_id
->len
> 0) {
702 data_string_forget(client_id
, MDL
);
709 * Information request validation, defined in RFC 3315, section 15.12:
711 * Servers MUST discard any received Information-request message that
712 * meets any of the following conditions:
714 * - The message includes a Server Identifier option and the DUID in
715 * the option does not match the server's DUID.
717 * - The message includes an IA option.
720 valid_client_info_req(struct packet
*packet
, struct data_string
*server_id
) {
722 struct option_cache
*oc
;
723 struct data_string client_id
;
724 char client_id_str
[80]; /* print_hex_1() uses maximum 60 characters,
725 plus a few more for extra information */
728 memset(server_id
, 0, sizeof(*server_id
));
729 memset(&client_id
, 0, sizeof(client_id
));
732 * Make a string that we can print out to give more
733 * information about the client if we need to.
735 * By RFC 3315, Section 18.1.5 clients SHOULD have a
736 * client-id on an Information-request packet, but it
737 * is not strictly necessary.
739 if (get_client_id(packet
, &client_id
) == ISC_R_SUCCESS
) {
740 snprintf(client_id_str
, sizeof(client_id_str
), " (CLIENTID %s)",
741 print_hex_1(client_id
.len
, client_id
.data
, 60));
742 data_string_forget(&client_id
, MDL
);
744 client_id_str
[0] = '\0';
748 * Required by RFC 3315, section 15.
750 if (packet
->unicast
) {
751 log_debug("Discarding %s from %s; packet sent unicast%s",
752 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
753 piaddr(packet
->client_addr
), client_id_str
);
757 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
759 log_debug("Discarding %s from %s; "
760 "IA_NA option present%s",
761 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
762 piaddr(packet
->client_addr
), client_id_str
);
765 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
767 log_debug("Discarding %s from %s; "
768 "IA_TA option present%s",
769 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
770 piaddr(packet
->client_addr
), client_id_str
);
773 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
775 log_debug("Discarding %s from %s; "
776 "IA_PD option present%s",
777 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
778 piaddr(packet
->client_addr
), client_id_str
);
782 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
784 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
785 packet
->options
, NULL
,
786 &global_scope
, oc
, MDL
)) {
787 log_error("Error processing %s from %s; "
788 "unable to evaluate Server Identifier%s",
789 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
790 piaddr(packet
->client_addr
), client_id_str
);
793 if ((server_duid
.len
!= server_id
->len
) ||
794 (memcmp(server_duid
.data
, server_id
->data
,
795 server_duid
.len
) != 0)) {
796 log_debug("Discarding %s from %s; "
797 "not our server identifier "
798 "(SERVERID %s, server DUID %s)%s",
799 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
800 piaddr(packet
->client_addr
),
801 print_hex_1(server_id
->len
,
802 server_id
->data
, 60),
803 print_hex_2(server_duid
.len
,
804 server_duid
.data
, 60),
815 if (server_id
->len
> 0) {
816 data_string_forget(server_id
, MDL
);
823 * Options that we want to send, in addition to what was requested
826 static const int required_opts
[] = {
833 static const int required_opts_solicit
[] = {
845 static const int required_opts_agent
[] = {
850 static const int required_opts_IA
[] = {
855 static const int required_opts_IA_PD
[] = {
860 static const int required_opts_STATUS_CODE
[] = {
865 static const int required_opts_4o6
[] = {
871 static const int unicast_reject_opts
[] = {
880 * Extracts from packet contents an IA_* option, storing the IA structure
881 * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
882 * in enc_opt_state for later lookup and evaluation. The 'offset' indicates
883 * where in the IA_* the DHCPv6 options commence.
886 get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
887 struct data_string
*enc_opt_data
,
888 struct packet
*packet
,
889 struct option_cache
*oc
,
893 * Get the raw data for the encapsulated options.
895 memset(enc_opt_data
, 0, sizeof(*enc_opt_data
));
896 if (!evaluate_option_cache(enc_opt_data
, packet
,
897 NULL
, NULL
, packet
->options
, NULL
,
898 &global_scope
, oc
, MDL
)) {
899 log_error("get_encapsulated_IA_state: "
900 "error evaluating raw option.");
903 if (enc_opt_data
->len
< offset
) {
904 log_error("get_encapsulated_IA_state: raw option too small.");
905 data_string_forget(enc_opt_data
, MDL
);
910 * Now create the option state structure, and pass it to the
911 * function that parses options.
913 *enc_opt_state
= NULL
;
914 if (!option_state_allocate(enc_opt_state
, MDL
)) {
915 log_error("get_encapsulated_IA_state: no memory for options.");
916 data_string_forget(enc_opt_data
, MDL
);
919 if (!parse_option_buffer(*enc_opt_state
,
920 enc_opt_data
->data
+ offset
,
921 enc_opt_data
->len
- offset
,
923 log_error("get_encapsulated_IA_state: error parsing options.");
924 option_state_dereference(enc_opt_state
, MDL
);
925 data_string_forget(enc_opt_data
, MDL
);
933 set_status_code(u_int16_t status_code
, const char *status_message
,
934 struct option_state
*opt_state
)
936 struct data_string d
;
939 memset(&d
, 0, sizeof(d
));
940 d
.len
= sizeof(status_code
) + strlen(status_message
);
941 if (!buffer_allocate(&d
.buffer
, d
.len
, MDL
)) {
942 log_fatal("set_status_code: no memory for status code.");
944 d
.data
= d
.buffer
->data
;
945 putUShort(d
.buffer
->data
, status_code
);
946 memcpy(d
.buffer
->data
+ sizeof(status_code
),
947 status_message
, d
.len
- sizeof(status_code
));
948 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
949 d
.buffer
, (unsigned char *)d
.data
, d
.len
,
950 D6O_STATUS_CODE
, 0)) {
951 log_error("set_status_code: error saving status code.");
956 data_string_forget(&d
, MDL
);
960 void check_pool6_threshold(struct reply_state
*reply
,
961 struct iasubopt
*lease
)
963 struct ipv6_pond
*pond
;
964 isc_uint64_t used
, count
, high_threshold
;
965 int poolhigh
= 0, poollow
= 0;
966 char *shared_name
= "no name";
967 char tmp_addr
[INET6_ADDRSTRLEN
];
969 if ((lease
->ipv6_pool
== NULL
) || (lease
->ipv6_pool
->ipv6_pond
== NULL
))
971 pond
= lease
->ipv6_pool
->ipv6_pond
;
973 /* If the address range is too large to track, just skip all this. */
974 if (pond
->jumbo_range
== 1) {
978 count
= pond
->num_total
;
979 used
= pond
->num_active
;
981 /* get network name for logging */
982 if ((pond
->shared_network
!= NULL
) &&
983 (pond
->shared_network
->name
!= NULL
)) {
984 shared_name
= pond
->shared_network
->name
;
987 /* The logged flag indicates if we have already crossed the high
988 * threshold and emitted a log message. If it is set we check to
989 * see if we have re-crossed the low threshold and need to reset
990 * things. When we cross the high threshold we determine what
991 * the low threshold is and save it into the low_threshold value.
992 * When we cross that threshold we reset the logged flag and
993 * the low_threshold to 0 which allows the high threshold message
994 * to be emitted once again.
995 * if we haven't recrossed the boundry we don't need to do anything.
997 if (pond
->logged
!=0) {
998 if (used
<= pond
->low_threshold
) {
999 pond
->low_threshold
= 0;
1001 log_error("Pool threshold reset - shared subnet: %s; "
1002 "address: %s; low threshold %llu/%llu.",
1004 inet_ntop(AF_INET6
, &lease
->addr
,
1005 tmp_addr
, sizeof(tmp_addr
)),
1011 /* find the high threshold */
1012 if (get_option_int(&poolhigh
, &server_universe
, reply
->packet
, NULL
,
1013 NULL
, reply
->packet
->options
, reply
->opt_state
,
1014 reply
->opt_state
, &lease
->scope
,
1015 SV_LOG_THRESHOLD_HIGH
, MDL
) == 0) {
1016 /* no threshold bail out */
1020 /* We do have a threshold for this pool, see if its valid */
1021 if ((poolhigh
<= 0) || (poolhigh
> 100)) {
1026 /* we have a valid value, have we exceeded it */
1027 high_threshold
= FIND_POND6_PERCENT(count
, poolhigh
);
1028 if (used
< high_threshold
) {
1029 /* nope, no more to do */
1033 /* we've exceeded it, output a message */
1034 log_error("Pool threshold exceeded - shared subnet: %s; "
1035 "address: %s; high threshold %d%% %llu/%llu.",
1037 inet_ntop(AF_INET6
, &lease
->addr
, tmp_addr
, sizeof(tmp_addr
)),
1038 poolhigh
, used
, count
);
1040 /* handle the low threshold now, if we don't
1041 * have one we default to 0. */
1042 if ((get_option_int(&poollow
, &server_universe
, reply
->packet
, NULL
,
1043 NULL
, reply
->packet
->options
, reply
->opt_state
,
1044 reply
->opt_state
, &lease
->scope
,
1045 SV_LOG_THRESHOLD_LOW
, MDL
) == 0) ||
1051 * If the low theshold is higher than the high threshold we continue to log
1052 * If it isn't then we set the flag saying we already logged and determine
1053 * what the reset threshold is.
1055 if (poollow
< poolhigh
) {
1057 pond
->low_threshold
= FIND_POND6_PERCENT(count
, poollow
);
1062 * We have a set of operations we do to set up the reply packet, which
1063 * is the same for many message types.
1066 start_reply(struct packet
*packet
,
1067 const struct data_string
*client_id
,
1068 const struct data_string
*server_id
,
1069 struct option_state
**opt_state
,
1070 struct dhcpv6_packet
*reply
)
1072 struct option_cache
*oc
;
1073 const unsigned char *server_id_data
;
1077 * Build our option state for reply.
1080 if (!option_state_allocate(opt_state
, MDL
)) {
1081 log_error("start_reply: no memory for option_state.");
1084 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1085 packet
->options
, *opt_state
,
1086 &global_scope
, root_group
, NULL
, NULL
);
1089 * A small bit of special handling for Solicit messages.
1091 * We could move the logic into a flag, but for now just check
1094 if (packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
1095 reply
->msg_type
= DHCPV6_ADVERTISE
;
1099 * - this message type supports rapid commit (Solicit), and
1100 * - the server is configured to supply a rapid commit, and
1101 * - the client requests a rapid commit,
1102 * Then we add a rapid commit option, and send Reply (instead
1105 oc
= lookup_option(&dhcpv6_universe
,
1106 *opt_state
, D6O_RAPID_COMMIT
);
1108 oc
= lookup_option(&dhcpv6_universe
,
1109 packet
->options
, D6O_RAPID_COMMIT
);
1111 /* Rapid-commit in action. */
1112 reply
->msg_type
= DHCPV6_REPLY
;
1114 /* Don't want a rapid-commit in advertise. */
1115 delete_option(&dhcpv6_universe
,
1116 *opt_state
, D6O_RAPID_COMMIT
);
1120 reply
->msg_type
= DHCPV6_REPLY
;
1121 /* Delete the rapid-commit from the sent options. */
1122 oc
= lookup_option(&dhcpv6_universe
,
1123 *opt_state
, D6O_RAPID_COMMIT
);
1125 delete_option(&dhcpv6_universe
,
1126 *opt_state
, D6O_RAPID_COMMIT
);
1131 * Use the client's transaction identifier for the reply.
1133 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
1134 sizeof(reply
->transaction_id
));
1137 * RFC 3315, section 18.2 says we need server identifier and
1138 * client identifier.
1140 * If the server ID is defined via the configuration file, then
1141 * it will already be present in the option state at this point,
1142 * so we don't need to set it.
1144 * If we have a server ID passed in from the caller,
1145 * use that, otherwise use the global DUID.
1147 oc
= lookup_option(&dhcpv6_universe
, *opt_state
, D6O_SERVERID
);
1149 if (server_id
== NULL
) {
1150 server_id_data
= server_duid
.data
;
1151 server_id_len
= server_duid
.len
;
1153 server_id_data
= server_id
->data
;
1154 server_id_len
= server_id
->len
;
1156 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1157 NULL
, (unsigned char *)server_id_data
,
1158 server_id_len
, D6O_SERVERID
, 0)) {
1159 log_error("start_reply: "
1160 "error saving server identifier.");
1165 if (client_id
->buffer
!= NULL
) {
1166 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1168 (unsigned char *)client_id
->data
,
1171 log_error("start_reply: error saving "
1172 "client identifier.");
1178 * If the client accepts reconfiguration, let it know that we
1181 * Note: we don't actually do this yet, but DOCSIS requires we
1184 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
1187 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
1188 NULL
, (unsigned char *)"", 0,
1189 D6O_RECONF_ACCEPT
, 0)) {
1190 log_error("start_reply: "
1191 "error saving RECONF_ACCEPT option.");
1192 option_state_dereference(opt_state
, MDL
);
1201 * Try to get the IPv6 address the client asked for from the
1204 * addr is the result (should be a pointer to NULL on entry)
1205 * pool is the pool to search in
1206 * requested_addr is the address the client wants
1209 try_client_v6_address(struct iasubopt
**addr
,
1210 struct ipv6_pool
*pool
,
1211 const struct data_string
*requested_addr
)
1213 struct in6_addr tmp_addr
;
1214 isc_result_t result
;
1216 if (requested_addr
->len
< sizeof(tmp_addr
)) {
1217 return DHCP_R_INVALIDARG
;
1219 memcpy(&tmp_addr
, requested_addr
->data
, sizeof(tmp_addr
));
1220 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
)) {
1221 return ISC_R_FAILURE
;
1225 * The address is not covered by this (or possibly any) dynamic
1228 if (!ipv6_in_pool(&tmp_addr
, pool
)) {
1229 return ISC_R_ADDRNOTAVAIL
;
1232 if (lease6_exists(pool
, &tmp_addr
)) {
1233 return ISC_R_ADDRINUSE
;
1236 result
= iasubopt_allocate(addr
, MDL
);
1237 if (result
!= ISC_R_SUCCESS
) {
1240 (*addr
)->addr
= tmp_addr
;
1243 /* Default is soft binding for 2 minutes. */
1244 result
= add_lease6(pool
, *addr
, cur_time
+ 120);
1245 if (result
!= ISC_R_SUCCESS
) {
1246 iasubopt_dereference(addr
, MDL
);
1254 * \brief Get an IPv6 address for the client.
1256 * Attempt to find a usable address for the client. We walk through
1257 * the ponds checking for permit and deny then through the pools
1258 * seeing if they have an available address.
1260 * \param reply = the state structure for the current work on this request
1261 * if we create a lease we return it using reply->lease
1264 * ISC_R_SUCCESS = we were able to find an address and are returning a
1265 * pointer to the lease
1266 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1267 * is probabalistic. We don't exhaustively try the
1268 * address range, instead we hash the duid and if
1269 * the address derived from the hash is in use we
1270 * hash the address. After a number of failures we
1271 * conclude the pool is basically full.
1274 pick_v6_address(struct reply_state
*reply
)
1276 struct ipv6_pool
*p
= NULL
;
1277 struct ipv6_pond
*pond
;
1280 unsigned int attempts
;
1281 char tmp_buf
[INET6_ADDRSTRLEN
];
1282 struct iasubopt
**addr
= &reply
->lease
;
1283 isc_uint64_t total
= 0;
1284 isc_uint64_t active
= 0;
1285 isc_uint64_t abandoned
= 0;
1286 int jumbo_range
= 0;
1287 char *shared_name
= (reply
->shared
->name
?
1288 reply
->shared
->name
: "(no name)");
1291 * Do a quick walk through of the ponds and pools
1292 * to see if we have any NA address pools
1294 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1295 if (pond
->ipv6_pools
== NULL
)
1298 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1299 if (p
->pool_type
== D6O_IA_NA
)
1306 /* If we get here and p is NULL we have no useful pools */
1308 log_debug("Unable to pick client address: "
1309 "no IPv6 pools on this shared network");
1310 return ISC_R_NORESOURCES
;
1314 * We have at least one pool that could provide an address
1315 * Now we walk through the ponds and pools again and check
1316 * to see if the client is permitted and if an address is
1319 * Within a given pond we start looking at the last pool we
1320 * allocated from, unless it had a collision trying to allocate
1321 * an address. This will tend to move us into less-filled pools.
1324 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1325 isc_result_t result
= ISC_R_FAILURE
;
1327 if (((pond
->prohibit_list
!= NULL
) &&
1328 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1329 ((pond
->permit_list
!= NULL
) &&
1330 (!permitted(reply
->packet
, pond
->permit_list
))))
1333 start_pool
= pond
->last_ipv6_pool
;
1336 p
= pond
->ipv6_pools
[i
];
1337 if (p
->pool_type
== D6O_IA_NA
) {
1338 result
= create_lease6(p
, addr
, &attempts
,
1339 &reply
->ia
->iaid_duid
,
1341 if (result
== ISC_R_SUCCESS
) {
1343 * Record the pool used (or next one if
1344 * there was a collision).
1348 if (pond
->ipv6_pools
[i
]
1354 pond
->last_ipv6_pool
= i
;
1356 log_debug("Picking pool address %s",
1359 tmp_buf
, sizeof(tmp_buf
)));
1360 return (ISC_R_SUCCESS
);
1365 if (pond
->ipv6_pools
[i
] == NULL
) {
1368 } while (i
!= start_pool
);
1370 if (result
== ISC_R_NORESOURCES
) {
1371 jumbo_range
+= pond
->jumbo_range
;
1372 total
+= pond
->num_total
;
1373 active
+= pond
->num_active
;
1374 abandoned
+= pond
->num_abandoned
;
1379 * If we failed to pick an IPv6 address from any of the subnets.
1380 * Presumably that means we have no addresses for the client.
1382 if (jumbo_range
!= 0) {
1383 log_debug("Unable to pick client address: "
1384 "no addresses available - shared network %s: "
1385 " 2^64-1 < total, %llu active, %llu abandoned",
1386 shared_name
, active
- abandoned
, abandoned
);
1388 log_debug("Unable to pick client address: "
1389 "no addresses available - shared network %s: "
1390 "%llu total, %llu active, %llu abandoned",
1391 shared_name
, total
, active
- abandoned
, abandoned
);
1394 return ISC_R_NORESOURCES
;
1398 * Try to get the IPv6 prefix the client asked for from the
1401 * pref is the result (should be a pointer to NULL on entry)
1402 * pool is the prefix pool to search in
1403 * requested_pref is the address the client wants
1406 try_client_v6_prefix(struct iasubopt
**pref
,
1407 struct ipv6_pool
*pool
,
1408 const struct data_string
*requested_pref
)
1411 struct in6_addr tmp_pref
;
1413 isc_result_t result
;
1415 if (requested_pref
->len
< sizeof(tmp_plen
) + sizeof(tmp_pref
)) {
1416 return DHCP_R_INVALIDARG
;
1418 tmp_plen
= (int) requested_pref
->data
[0];
1419 if ((tmp_plen
< 3) || (tmp_plen
> 128) ||
1420 ((int)tmp_plen
!= pool
->units
)) {
1421 return ISC_R_FAILURE
;
1423 memcpy(&tmp_pref
, requested_pref
->data
+ 1, sizeof(tmp_pref
));
1424 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref
)) {
1425 return ISC_R_FAILURE
;
1428 memcpy(&ia
.iabuf
, &tmp_pref
, 16);
1429 if (!is_cidr_mask_valid(&ia
, (int) tmp_plen
)) {
1430 return ISC_R_FAILURE
;
1433 if (!ipv6_in_pool(&tmp_pref
, pool
)) {
1434 return ISC_R_ADDRNOTAVAIL
;
1437 if (prefix6_exists(pool
, &tmp_pref
, tmp_plen
)) {
1438 return ISC_R_ADDRINUSE
;
1441 result
= iasubopt_allocate(pref
, MDL
);
1442 if (result
!= ISC_R_SUCCESS
) {
1445 (*pref
)->addr
= tmp_pref
;
1446 (*pref
)->plen
= tmp_plen
;
1448 /* Default is soft binding for 2 minutes. */
1449 result
= add_lease6(pool
, *pref
, cur_time
+ 120);
1450 if (result
!= ISC_R_SUCCESS
) {
1451 iasubopt_dereference(pref
, MDL
);
1458 * \brief Get an IPv6 prefix for the client.
1460 * Attempt to find a usable prefix for the client. Based upon the prefix
1461 * length mode and the plen supplied by the client (if one), we make one
1462 * or more calls to pick_v6_prefix_helper() to find a prefix as follows:
1464 * PLM_IGNORE or client specifies a plen of zero, use the first available
1465 * prefix regardless of it's length.
1467 * PLM_PREFER – look for an exact match to client's plen first, if none
1468 * found, use the first available prefix of any length
1470 * PLM_EXACT – look for an exact match first, if none found then fail. This
1471 * is the default behavior.
1473 * PLM_MAXIMUM - look for an exact match first, then the first available whose
1474 * prefix length is less than client's plen, otherwise fail.
1476 * PLM_MINIMUM - look for an exact match first, then the first available whose
1477 * prefix length is greater than client's plen, otherwise fail.
1479 * Note that the selection mode is configurable at the global scope only via
1482 * \param reply = the state structure for the current work on this request
1483 * if we create a lease we return it using reply->lease
1486 * ISC_R_SUCCESS = we were able to find an prefix and are returning a
1487 * pointer to the lease
1488 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1489 * is probabalistic. We don't exhaustively try the
1490 * address range, instead we hash the duid and if
1491 * the address derived from the hash is in use we
1492 * hash the address. After a number of failures we
1493 * conclude the pool is basically full.
1496 pick_v6_prefix(struct reply_state
*reply
) {
1497 struct ipv6_pool
*p
= NULL
;
1498 struct ipv6_pond
*pond
;
1500 isc_result_t result
;
1503 * Do a quick walk through of the ponds and pools
1504 * to see if we have any prefix pools
1506 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1507 if (pond
->ipv6_pools
== NULL
)
1510 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1511 if (p
->pool_type
== D6O_IA_PD
)
1518 /* If we get here and p is NULL we have no useful pools */
1520 log_debug("Unable to pick client prefix: "
1521 "no IPv6 pools on this shared network");
1522 return ISC_R_NORESOURCES
;
1525 if (reply
->preflen
<= 0) {
1526 /* If we didn't get a plen (-1) or client plen is 0, then just
1527 * select first available (same as PLM_INGORE) */
1528 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1530 switch (prefix_length_mode
) {
1532 /* First we look for an exact match, if not found
1533 * then first available */
1534 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1535 if (result
!= ISC_R_SUCCESS
) {
1536 result
= pick_v6_prefix_helper(reply
,
1542 /* Match exactly or fail */
1543 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1548 /* First we look for an exact match, if not found
1549 * then first available by mode */
1550 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1551 if (result
!= ISC_R_SUCCESS
) {
1552 result
= pick_v6_prefix_helper(reply
,
1553 prefix_length_mode
);
1558 /* First available */
1559 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1564 if (result
== ISC_R_SUCCESS
) {
1565 char tmp_buf
[INET6_ADDRSTRLEN
];
1567 log_debug("Picking pool prefix %s/%u",
1568 inet_ntop(AF_INET6
, &(reply
->lease
->addr
),
1569 tmp_buf
, sizeof(tmp_buf
)),
1570 (unsigned)(reply
->lease
->plen
));
1571 return (ISC_R_SUCCESS
);
1575 * If we failed to pick an IPv6 prefix
1576 * Presumably that means we have no prefixes for the client.
1578 log_debug("Unable to pick client prefix: no prefixes available");
1579 return ISC_R_NORESOURCES
;
1584 * \brief Get an IPv6 prefix for the client based upon selection mode.
1586 * We walk through the ponds checking for permit and deny. If a pond is
1587 * permissable to use, loop through its PD pools checking prefix lengths
1588 * against the client plen based on the prefix length mode, looking for
1589 * available prefixes.
1591 * \param reply = the state structure for the current work on this request
1592 * if we create a lease we return it using reply->lease
1593 * \prefix_mode = selection mode to use
1596 * ISC_R_SUCCESS = we were able to find a prefix and are returning a
1597 * pointer to the lease
1598 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1599 * is probabalistic. We don't exhaustively try the
1600 * address range, instead we hash the duid and if
1601 * the address derived from the hash is in use we
1602 * hash the address. After a number of failures we
1603 * conclude the pool is basically full.
1606 pick_v6_prefix_helper(struct reply_state
*reply
, int prefix_mode
) {
1607 struct ipv6_pool
*p
= NULL
;
1608 struct ipv6_pond
*pond
;
1610 unsigned int attempts
;
1611 struct iasubopt
**pref
= &reply
->lease
;
1613 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1614 if (((pond
->prohibit_list
!= NULL
) &&
1615 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1616 ((pond
->permit_list
!= NULL
) &&
1617 (!permitted(reply
->packet
, pond
->permit_list
))))
1620 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1621 if ((p
->pool_type
== D6O_IA_PD
) &&
1622 (eval_prefix_mode(p
->units
, reply
->preflen
,
1623 prefix_mode
) == 1) &&
1624 (create_prefix6(p
, pref
, &attempts
,
1625 &reply
->ia
->iaid_duid
,
1626 cur_time
+ 120) == ISC_R_SUCCESS
)) {
1627 return (ISC_R_SUCCESS
);
1632 return ISC_R_NORESOURCES
;
1637 * \brief Test a prefix length against another based on prefix length mode
1639 * \param len - prefix length to test
1640 * \param preflen - preferred prefix length against which to test
1641 * \param prefix_mode - prefix selection mode with which to test
1643 * Note that the case of preferred length of 0 is not short-cut here as it
1644 * is assumed to be done at a higher level.
1646 * \return 1 if the given length is usable based upon mode and a preferred
1650 eval_prefix_mode(int len
, int preflen
, int prefix_mode
) {
1652 switch (prefix_mode
) {
1654 use_it
= (len
== preflen
);
1657 /* they asked for a prefix length no "shorter" than preflen */
1658 use_it
= (len
>= preflen
);
1661 /* they asked for a prefix length no "longer" than preflen */
1662 use_it
= (len
<= preflen
);
1665 /* otherwise use it */
1670 log_debug("eval_prefix_mode: "
1671 "len %d, preflen %d, mode %s, use_it %d",
1673 prefix_length_modes
.values
[prefix_mode
].name
, use_it
);
1680 *! \file server/dhcpv6.c
1682 * \brief construct a reply containing information about a client's lease
1684 * lease_to_client() is called from several messages to construct a
1685 * reply that contains all that we know about the client's correct lease
1686 * (or projected lease).
1688 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1689 * send what we "may" give them on a request.
1691 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1692 * the client should really use).
1694 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1695 * Rebind out any "wrong" addresses the client sends. This means we send
1696 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1697 * possibly send the address with zeroed lifetimes.
1699 * Information-Request - No binding.
1701 * The basic structure is to traverse the client-supplied data first, and
1702 * validate and echo back any contents that can be. If the client-supplied
1703 * data does not error out (on renew/rebind as above), but we did not send
1704 * any addresses, attempt to allocate one.
1706 * At the end of the this function we call commit_leases_timed() to
1707 * fsync and rotate the file as necessary. commit_leases_timed() will
1708 * check that we have written at least one lease to the file and that
1709 * some time has passed before doing any fsync or file rewrite so we
1710 * don't bother tracking if we did a write_ia during this function.
1712 /* TODO: look at client hints for lease times */
1715 lease_to_client(struct data_string
*reply_ret
,
1716 struct packet
*packet
,
1717 const struct data_string
*client_id
,
1718 const struct data_string
*server_id
)
1720 static struct reply_state reply
;
1721 struct option_cache
*oc
;
1722 struct data_string packet_oro
;
1725 memset(&packet_oro
, 0, sizeof(packet_oro
));
1727 /* Locate the client. */
1728 if (shared_network_from_packet6(&reply
.shared
,
1729 packet
) != ISC_R_SUCCESS
)
1733 * Initialize the reply.
1735 packet_reference(&reply
.packet
, packet
, MDL
);
1736 data_string_copy(&reply
.client_id
, client_id
, MDL
);
1738 if (!start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
1742 /* Set the write cursor to just past the reply header. */
1743 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1746 * Get the ORO from the packet, if any.
1748 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ORO
);
1750 if (!evaluate_option_cache(&packet_oro
, packet
,
1752 packet
->options
, NULL
,
1753 &global_scope
, oc
, MDL
)) {
1754 log_error("lease_to_client: error evaluating ORO.");
1760 * Find a host record that matches the packet, if any, and is
1761 * valid for the shared network the client is on.
1763 if (find_hosts6(&reply
.host
, packet
, client_id
, MDL
)) {
1765 seek_shared_host(&reply
.host
, reply
.shared
);
1768 /* Process the client supplied IA's onto the reply buffer. */
1770 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
1772 for (; oc
!= NULL
; oc
= oc
->next
) {
1773 isc_result_t status
;
1775 /* Start counting resources (addresses) offered. */
1776 reply
.client_resources
= 0;
1777 reply
.resources_included
= ISC_FALSE
;
1779 status
= reply_process_ia_na(&reply
, oc
);
1782 * We continue to try other IA's whether we can address
1783 * this one or not. Any other result is an immediate fail.
1785 if ((status
!= ISC_R_SUCCESS
) &&
1786 (status
!= ISC_R_NORESOURCES
))
1789 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
1790 for (; oc
!= NULL
; oc
= oc
->next
) {
1791 isc_result_t status
;
1793 /* Start counting resources (addresses) offered. */
1794 reply
.client_resources
= 0;
1795 reply
.resources_included
= ISC_FALSE
;
1797 status
= reply_process_ia_ta(&reply
, oc
);
1800 * We continue to try other IA's whether we can address
1801 * this one or not. Any other result is an immediate fail.
1803 if ((status
!= ISC_R_SUCCESS
) &&
1804 (status
!= ISC_R_NORESOURCES
))
1808 /* Same for IA_PD's. */
1810 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
1811 for (; oc
!= NULL
; oc
= oc
->next
) {
1812 isc_result_t status
;
1814 /* Start counting resources (prefixes) offered. */
1815 reply
.client_resources
= 0;
1816 reply
.resources_included
= ISC_FALSE
;
1818 status
= reply_process_ia_pd(&reply
, oc
);
1821 * We continue to try other IA_PD's whether we can address
1822 * this one or not. Any other result is an immediate fail.
1824 if ((status
!= ISC_R_SUCCESS
) &&
1825 (status
!= ISC_R_NORESOURCES
))
1830 * Make no reply if we gave no resources and is not
1831 * for Information-Request.
1833 if ((reply
.ia_count
== 0) && (reply
.pd_count
== 0)) {
1834 if (reply
.packet
->dhcpv6_msg_type
!=
1835 DHCPV6_INFORMATION_REQUEST
)
1839 * Because we only execute statements on a per-IA basis,
1840 * we need to execute statements in any non-IA reply to
1841 * source configuration.
1843 execute_statements_in_scope(NULL
, reply
.packet
, NULL
, NULL
,
1844 reply
.packet
->options
,
1845 reply
.opt_state
, &global_scope
,
1846 reply
.shared
->group
, root_group
,
1849 /* Execute statements from class scopes. */
1850 for (i
= reply
.packet
->class_count
; i
> 0; i
--) {
1851 execute_statements_in_scope(NULL
, reply
.packet
,
1853 reply
.packet
->options
,
1856 reply
.packet
->classes
[i
- 1]->group
,
1857 reply
.shared
->group
, NULL
);
1860 /* Bring in any configuration from a host record. */
1861 if (reply
.host
!= NULL
)
1862 execute_statements_in_scope(NULL
, reply
.packet
,
1864 reply
.packet
->options
,
1868 reply
.shared
->group
, NULL
);
1872 * RFC3315 section 17.2.2 (Solicit):
1874 * If the server will not assign any addresses to any IAs in a
1875 * subsequent Request from the client, the server MUST send an
1876 * Advertise message to the client that includes only a Status
1877 * Code option with code NoAddrsAvail and a status message for
1878 * the user, a Server Identifier option with the server's DUID,
1879 * and a Client Identifier option with the client's DUID.
1881 * This has been updated by an errata such that the server
1882 * can always send an IA.
1884 * Section 18.2.1 (Request):
1886 * If the server cannot assign any addresses to an IA in the
1887 * message from the client, the server MUST include the IA in
1888 * the Reply message with no addresses in the IA and a Status
1889 * Code option in the IA containing status code NoAddrsAvail.
1891 * Section 18.1.8 (Client Behavior):
1893 * Leave unchanged any information about addresses the client has
1894 * recorded in the IA but that were not included in the IA from
1896 * Sends a Renew/Rebind if the IA is not in the Reply message.
1900 * Having stored the client's IA's, store any options that
1901 * will fit in the remaining space.
1903 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+ reply
.cursor
,
1904 sizeof(reply
.buf
) - reply
.cursor
,
1905 reply
.opt_state
, reply
.packet
,
1906 required_opts_solicit
,
1909 /* Return our reply to the caller. */
1910 reply_ret
->len
= reply
.cursor
;
1911 reply_ret
->buffer
= NULL
;
1912 if (!buffer_allocate(&reply_ret
->buffer
, reply
.cursor
, MDL
)) {
1913 log_fatal("No memory to store Reply.");
1915 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
, reply
.cursor
);
1916 reply_ret
->data
= reply_ret
->buffer
->data
;
1918 /* If appropriate commit and rotate the lease file */
1919 (void) commit_leases_timed();
1923 if (reply
.shared
!= NULL
)
1924 shared_network_dereference(&reply
.shared
, MDL
);
1925 if (reply
.host
!= NULL
)
1926 host_dereference(&reply
.host
, MDL
);
1927 if (reply
.opt_state
!= NULL
)
1928 option_state_dereference(&reply
.opt_state
, MDL
);
1929 if (reply
.packet
!= NULL
)
1930 packet_dereference(&reply
.packet
, MDL
);
1931 if (reply
.client_id
.data
!= NULL
)
1932 data_string_forget(&reply
.client_id
, MDL
);
1933 if (packet_oro
.buffer
!= NULL
)
1934 data_string_forget(&packet_oro
, MDL
);
1935 reply
.renew
= reply
.rebind
= reply
.min_prefer
= reply
.min_valid
= 0;
1939 /* Process a client-supplied IA_NA. This may append options to the tail of
1940 * the reply packet being built in the reply_state structure.
1943 reply_process_ia_na(struct reply_state
*reply
, struct option_cache
*ia
) {
1944 isc_result_t status
= ISC_R_SUCCESS
;
1947 struct option_state
*packet_ia
;
1948 struct option_cache
*oc
;
1949 struct data_string ia_data
, data
;
1951 /* Initialize values that will get cleaned up on return. */
1953 memset(&ia_data
, 0, sizeof(ia_data
));
1954 memset(&data
, 0, sizeof(data
));
1956 * Note that find_client_address() may set reply->lease.
1959 /* Make sure there is at least room for the header. */
1960 if ((reply
->cursor
+ IA_NA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
1961 log_error("reply_process_ia_na: Reply too long for IA.");
1962 return ISC_R_NOSPACE
;
1966 /* Fetch the IA_NA contents. */
1967 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
1968 ia
, IA_NA_OFFSET
)) {
1969 log_error("reply_process_ia_na: error evaluating ia");
1970 status
= ISC_R_FAILURE
;
1974 /* Extract IA_NA header contents. */
1975 iaid
= getULong(ia_data
.data
);
1976 reply
->renew
= getULong(ia_data
.data
+ 4);
1977 reply
->rebind
= getULong(ia_data
.data
+ 8);
1979 /* Create an IA_NA structure. */
1980 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
1981 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
1982 log_error("reply_process_ia_na: no memory for ia.");
1983 status
= ISC_R_NOMEMORY
;
1986 reply
->ia
->ia_type
= D6O_IA_NA
;
1988 /* Cache pre-existing IA, if any. */
1989 ia_hash_lookup(&reply
->old_ia
, ia_na_active
,
1990 (unsigned char *)reply
->ia
->iaid_duid
.data
,
1991 reply
->ia
->iaid_duid
.len
, MDL
);
1994 * Create an option cache to carry the IA_NA option contents, and
1995 * execute any user-supplied values into it.
1997 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
1998 status
= ISC_R_NOMEMORY
;
2002 /* Check & cache the fixed host record. */
2003 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_addr
!= NULL
)) {
2004 struct iaddr tmp_addr
;
2006 if (!evaluate_option_cache(&reply
->fixed
, NULL
, NULL
, NULL
,
2007 NULL
, NULL
, &global_scope
,
2008 reply
->host
->fixed_addr
, MDL
)) {
2009 log_error("reply_process_ia_na: unable to evaluate "
2011 status
= ISC_R_FAILURE
;
2015 if (reply
->fixed
.len
< 16) {
2016 log_error("reply_process_ia_na: invalid fixed address.");
2017 status
= DHCP_R_INVALIDARG
;
2021 /* Find the static lease's subnet. */
2023 memcpy(tmp_addr
.iabuf
, reply
->fixed
.data
, 16);
2025 if (find_grouped_subnet(&reply
->subnet
, reply
->shared
,
2026 tmp_addr
, MDL
) == 0)
2027 log_fatal("Impossible condition at %s:%d.", MDL
);
2029 reply
->static_lease
= ISC_TRUE
;
2031 reply
->static_lease
= ISC_FALSE
;
2034 * Save the cursor position at the start of the IA, so we can
2035 * set length and adjust t1/t2 values later. We write a temporary
2036 * header out now just in case we decide to adjust the packet
2037 * within sub-process functions.
2039 ia_cursor
= reply
->cursor
;
2041 /* Initialize the IA_NA header. First the code. */
2042 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_NA
);
2045 /* Then option length. */
2046 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
2049 /* Then IA_NA header contents; IAID. */
2050 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2053 /* We store the client's t1 for now, and may over-ride it later. */
2054 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
2057 /* We store the client's t2 for now, and may over-ride it later. */
2058 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
2062 * For each address in this IA_NA, decide what to do about it.
2066 * The client leaves unchanged any information about addresses
2067 * it has recorded but are not included ("cancel/break" below).
2068 * A not included IA ("cleanup" below) could give a Renew/Rebind.
2070 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2071 reply
->min_valid
= reply
->min_prefer
= 0xffffffff;
2072 reply
->client_valid
= reply
->client_prefer
= 0;
2073 for (; oc
!= NULL
; oc
= oc
->next
) {
2074 status
= reply_process_addr(reply
, oc
);
2077 * Canceled means we did not allocate addresses to the
2078 * client, but we're "done" with this IA - we set a status
2079 * code. So transmit this reply, e.g., move on to the next
2082 if (status
== ISC_R_CANCELED
)
2085 if ((status
!= ISC_R_SUCCESS
) &&
2086 (status
!= ISC_R_ADDRINUSE
) &&
2087 (status
!= ISC_R_ADDRNOTAVAIL
))
2094 * If we fell through the above and never gave the client
2095 * an address, give it one now.
2097 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
2098 status
= find_client_address(reply
);
2100 if (status
== ISC_R_NORESOURCES
) {
2101 switch (reply
->packet
->dhcpv6_msg_type
) {
2102 case DHCPV6_SOLICIT
:
2104 * No address for any IA is handled
2109 case DHCPV6_REQUEST
:
2110 /* Section 18.2.1 (Request):
2112 * If the server cannot assign any addresses to
2113 * an IA in the message from the client, the
2114 * server MUST include the IA in the Reply
2115 * message with no addresses in the IA and a
2116 * Status Code option in the IA containing
2117 * status code NoAddrsAvail.
2119 option_state_dereference(&reply
->reply_ia
, MDL
);
2120 if (!option_state_allocate(&reply
->reply_ia
,
2123 log_error("reply_process_ia_na: No "
2124 "memory for option state "
2126 status
= ISC_R_NOMEMORY
;
2130 if (!set_status_code(STATUS_NoAddrsAvail
,
2131 "No addresses available "
2132 "for this interface.",
2134 log_error("reply_process_ia_na: Unable "
2135 "to set NoAddrsAvail status "
2137 status
= ISC_R_FAILURE
;
2141 status
= ISC_R_SUCCESS
;
2146 * RFC 3315 does not tell us to emit a status
2147 * code in this condition, or anything else.
2149 * If we included non-allocated addresses
2150 * (zeroed lifetimes) in an IA, then the client
2151 * will deconfigure them.
2153 * So we want to include the IA even if we
2154 * can't give it a new address if it includes
2155 * zeroed lifetime addresses.
2157 * We don't want to include the IA if we
2158 * provide zero addresses including zeroed
2161 if (reply
->resources_included
)
2162 status
= ISC_R_SUCCESS
;
2169 if (status
!= ISC_R_SUCCESS
)
2173 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2174 sizeof(reply
->buf
) - reply
->cursor
,
2175 reply
->reply_ia
, reply
->packet
,
2176 required_opts_IA
, NULL
);
2178 /* Reset the length of this IA to match what was just written. */
2179 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2180 reply
->cursor
- (ia_cursor
+ 4));
2182 /* Calculate T1/T2 and stuff them in the reply */
2183 set_reply_tee_times(reply
, ia_cursor
);
2186 * yes, goto's aren't the best but we also want to avoid extra
2189 if (status
== ISC_R_CANCELED
)
2193 * Handle static leases, we always log stuff and if it's
2194 * a hard binding we run any commit statements that we have
2196 if (reply
->static_lease
) {
2197 char tmp_addr
[INET6_ADDRSTRLEN
];
2198 log_info("%s NA: address %s to client with duid %s iaid = %d "
2200 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2201 inet_ntop(AF_INET6
, reply
->fixed
.data
, tmp_addr
,
2203 print_hex_1(reply
->client_id
.len
,
2204 reply
->client_id
.data
, 60),
2207 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
2208 (reply
->on_star
.on_commit
!= NULL
)) {
2209 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
2210 reply
->packet
->options
,
2211 reply
->opt_state
, NULL
,
2212 reply
->on_star
.on_commit
, NULL
);
2213 executable_statement_dereference
2214 (&reply
->on_star
.on_commit
, MDL
);
2220 * If we have any addresses log what we are doing.
2222 if (reply
->ia
->num_iasubopt
!= 0) {
2223 struct iasubopt
*tmp
;
2225 char tmp_addr
[INET6_ADDRSTRLEN
];
2227 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2228 tmp
= reply
->ia
->iasubopt
[i
];
2230 log_info("%s NA: address %s to client with duid %s "
2231 "iaid = %d valid for %u seconds",
2232 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2233 inet_ntop(AF_INET6
, &tmp
->addr
,
2234 tmp_addr
, sizeof(tmp_addr
)),
2235 print_hex_1(reply
->client_id
.len
,
2236 reply
->client_id
.data
, 60),
2242 * If this is not a 'soft' binding, consume the new changes into
2243 * the database (if any have been attached to the ia_na).
2245 * Loop through the assigned dynamic addresses, referencing the
2246 * leases onto this IA_NA rather than any old ones, and updating
2247 * pool timers for each (if any).
2250 if ((reply
->ia
->num_iasubopt
!= 0) &&
2251 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
2252 struct iasubopt
*tmp
;
2253 struct data_string
*ia_id
;
2256 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2257 tmp
= reply
->ia
->iasubopt
[i
];
2259 if (tmp
->ia
!= NULL
)
2260 ia_dereference(&tmp
->ia
, MDL
);
2261 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2263 /* Commit 'hard' bindings. */
2264 renew_lease6(tmp
->ipv6_pool
, tmp
);
2265 schedule_lease_timeout(tmp
->ipv6_pool
);
2267 /* If we have anything to do on commit do it now */
2268 if (tmp
->on_star
.on_commit
!= NULL
) {
2269 execute_statements(NULL
, reply
->packet
,
2271 reply
->packet
->options
,
2274 tmp
->on_star
.on_commit
,
2276 executable_statement_dereference
2277 (&tmp
->on_star
.on_commit
, MDL
);
2280 #if defined (NSUPDATE)
2282 * Perform ddns updates.
2284 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2287 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2289 reply
->packet
->options
,
2293 ddns_updates(reply
->packet
, NULL
, NULL
,
2294 tmp
, NULL
, reply
->opt_state
);
2297 /* Do our threshold check. */
2298 check_pool6_threshold(reply
, tmp
);
2301 /* Remove any old ia from the hash. */
2302 if (reply
->old_ia
!= NULL
) {
2303 ia_id
= &reply
->old_ia
->iaid_duid
;
2304 ia_hash_delete(ia_na_active
,
2305 (unsigned char *)ia_id
->data
,
2307 ia_dereference(&reply
->old_ia
, MDL
);
2310 /* Put new ia into the hash. */
2311 reply
->ia
->cltt
= cur_time
;
2312 ia_id
= &reply
->ia
->iaid_duid
;
2313 ia_hash_add(ia_na_active
, (unsigned char *)ia_id
->data
,
2314 ia_id
->len
, reply
->ia
, MDL
);
2316 write_ia(reply
->ia
);
2318 schedule_lease_timeout_reply(reply
);
2322 if (packet_ia
!= NULL
)
2323 option_state_dereference(&packet_ia
, MDL
);
2324 if (reply
->reply_ia
!= NULL
)
2325 option_state_dereference(&reply
->reply_ia
, MDL
);
2326 if (ia_data
.data
!= NULL
)
2327 data_string_forget(&ia_data
, MDL
);
2328 if (data
.data
!= NULL
)
2329 data_string_forget(&data
, MDL
);
2330 if (reply
->ia
!= NULL
)
2331 ia_dereference(&reply
->ia
, MDL
);
2332 if (reply
->old_ia
!= NULL
)
2333 ia_dereference(&reply
->old_ia
, MDL
);
2334 if (reply
->lease
!= NULL
)
2335 iasubopt_dereference(&reply
->lease
, MDL
);
2336 if (reply
->fixed
.data
!= NULL
)
2337 data_string_forget(&reply
->fixed
, MDL
);
2338 if (reply
->subnet
!= NULL
)
2339 subnet_dereference(&reply
->subnet
, MDL
);
2340 if (reply
->on_star
.on_expiry
!= NULL
)
2341 executable_statement_dereference
2342 (&reply
->on_star
.on_expiry
, MDL
);
2343 if (reply
->on_star
.on_release
!= NULL
)
2344 executable_statement_dereference
2345 (&reply
->on_star
.on_release
, MDL
);
2348 * ISC_R_CANCELED is a status code used by the addr processing to
2349 * indicate we're replying with a status code. This is still a
2350 * success at higher layers.
2352 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2356 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
2357 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
2358 * in the event we are replying with a status code and do not wish to process
2359 * more IAADDRs within this IA.
2362 reply_process_addr(struct reply_state
*reply
, struct option_cache
*addr
) {
2363 u_int32_t pref_life
, valid_life
;
2364 struct binding_scope
**scope
;
2365 struct group
*group
;
2366 struct subnet
*subnet
;
2367 struct iaddr tmp_addr
;
2368 struct option_cache
*oc
;
2369 struct data_string iaaddr
, data
;
2370 isc_result_t status
= ISC_R_SUCCESS
;
2372 /* Initializes values that will be cleaned up. */
2373 memset(&iaaddr
, 0, sizeof(iaaddr
));
2374 memset(&data
, 0, sizeof(data
));
2375 /* Note that reply->lease may be set by address_is_owned() */
2378 * There is no point trying to process an incoming address if there
2379 * is no room for an outgoing address.
2381 if ((reply
->cursor
+ 28) > sizeof(reply
->buf
)) {
2382 log_error("reply_process_addr: Out of room for address.");
2383 return ISC_R_NOSPACE
;
2386 /* Extract this IAADDR option. */
2387 if (!evaluate_option_cache(&iaaddr
, reply
->packet
, NULL
, NULL
,
2388 reply
->packet
->options
, NULL
, &global_scope
,
2390 (iaaddr
.len
< IAADDR_OFFSET
)) {
2391 log_error("reply_process_addr: error evaluating IAADDR.");
2392 status
= ISC_R_FAILURE
;
2396 /* The first 16 bytes are the IPv6 address. */
2397 pref_life
= getULong(iaaddr
.data
+ 16);
2398 valid_life
= getULong(iaaddr
.data
+ 20);
2400 if ((reply
->client_valid
== 0) ||
2401 (reply
->client_valid
> valid_life
))
2402 reply
->client_valid
= valid_life
;
2404 if ((reply
->client_prefer
== 0) ||
2405 (reply
->client_prefer
> pref_life
))
2406 reply
->client_prefer
= pref_life
;
2409 * Clients may choose to send :: as an address, with the idea to give
2410 * hints about preferred-lifetime or valid-lifetime.
2413 memset(tmp_addr
.iabuf
, 0, 16);
2414 if (!memcmp(iaaddr
.data
, tmp_addr
.iabuf
, 16)) {
2415 /* Status remains success; we just ignore this one. */
2419 /* tmp_addr len remains 16 */
2420 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2423 * Verify that this address is on the client's network.
2425 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
2426 subnet
= subnet
->next_sibling
) {
2427 if (addr_eq(subnet_number(tmp_addr
, subnet
->netmask
),
2432 /* Address not found on shared network. */
2433 if (subnet
== NULL
) {
2434 /* Ignore this address on 'soft' bindings. */
2435 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
2436 /* disable rapid commit */
2437 reply
->buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
2438 delete_option(&dhcpv6_universe
,
2441 /* status remains success */
2446 * RFC3315 section 18.2.1:
2448 * If the server finds that the prefix on one or more IP
2449 * addresses in any IA in the message from the client is not
2450 * appropriate for the link to which the client is connected,
2451 * the server MUST return the IA to the client with a Status
2452 * Code option with the value NotOnLink.
2454 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) {
2455 /* Rewind the IA_NA to empty. */
2456 option_state_dereference(&reply
->reply_ia
, MDL
);
2457 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2458 log_error("reply_process_addr: No memory for "
2459 "option state wipe.");
2460 status
= ISC_R_NOMEMORY
;
2464 /* Append a NotOnLink status code. */
2465 if (!set_status_code(STATUS_NotOnLink
,
2466 "Address not for use on this "
2467 "link.", reply
->reply_ia
)) {
2468 log_error("reply_process_addr: Failure "
2469 "setting status code.");
2470 status
= ISC_R_FAILURE
;
2474 /* Fin (no more IAADDRs). */
2475 status
= ISC_R_CANCELED
;
2480 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2482 * If the server finds that any of the addresses are not
2483 * appropriate for the link to which the client is attached,
2484 * the server returns the address to the client with lifetimes
2487 if ((reply
->packet
->dhcpv6_msg_type
!= DHCPV6_RENEW
) &&
2488 (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
2489 log_error("It is impossible to lease a client that is "
2490 "not sending a solicit, request, renew, or "
2492 status
= ISC_R_FAILURE
;
2496 reply
->send_prefer
= reply
->send_valid
= 0;
2500 /* Verify the address belongs to the client. */
2501 if (!address_is_owned(reply
, &tmp_addr
)) {
2503 * For solicit and request, any addresses included are
2504 * 'requested' addresses. For rebind, we actually have
2505 * no direction on what to do from 3315 section 18.2.4!
2506 * So I think the best bet is to try and give it out, and if
2507 * we can't, zero lifetimes.
2509 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
2510 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
2511 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
2512 status
= reply_process_try_addr(reply
, &tmp_addr
);
2515 * If the address is in use, or isn't in any dynamic
2516 * range, continue as normal. If any other error was
2519 if ((status
!= ISC_R_SUCCESS
) &&
2520 (status
!= ISC_R_ADDRINUSE
) &&
2521 (status
!= ISC_R_ADDRNOTAVAIL
))
2525 * If we didn't honor this lease, for solicit and
2526 * request we simply omit it from our answer. For
2527 * rebind, we send it with zeroed lifetimes.
2529 if (reply
->lease
== NULL
) {
2530 if (reply
->packet
->dhcpv6_msg_type
==
2532 reply
->send_prefer
= 0;
2533 reply
->send_valid
= 0;
2537 /* status remains success - ignore */
2541 * RFC3315 section 18.2.3:
2543 * If the server cannot find a client entry for the IA the
2544 * server returns the IA containing no addresses with a Status
2545 * Code option set to NoBinding in the Reply message.
2547 * On mismatch we (ab)use this pretending we have not the IA
2548 * as soon as we have not an address.
2550 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
2551 /* Rewind the IA_NA to empty. */
2552 option_state_dereference(&reply
->reply_ia
, MDL
);
2553 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2554 log_error("reply_process_addr: No memory for "
2555 "option state wipe.");
2556 status
= ISC_R_NOMEMORY
;
2560 /* Append a NoBinding status code. */
2561 if (!set_status_code(STATUS_NoBinding
,
2562 "Address not bound to this "
2563 "interface.", reply
->reply_ia
)) {
2564 log_error("reply_process_addr: Unable to "
2565 "attach status code.");
2566 status
= ISC_R_FAILURE
;
2570 /* Fin (no more IAADDRs). */
2571 status
= ISC_R_CANCELED
;
2574 log_error("It is impossible to lease a client that is "
2575 "not sending a solicit, request, renew, or "
2577 status
= ISC_R_FAILURE
;
2582 if (reply
->static_lease
) {
2583 if (reply
->host
== NULL
)
2584 log_fatal("Impossible condition at %s:%d.", MDL
);
2586 scope
= &global_scope
;
2587 group
= reply
->subnet
->group
;
2589 if (reply
->lease
== NULL
)
2590 log_fatal("Impossible condition at %s:%d.", MDL
);
2592 scope
= &reply
->lease
->scope
;
2593 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
2597 * If client_resources is nonzero, then the reply_process_is_addressed
2598 * function has executed configuration state into the reply option
2599 * cache. We will use that valid cache to derive configuration for
2600 * whether or not to engage in additional addresses, and similar.
2602 if (reply
->client_resources
!= 0) {
2606 * Does this client have "enough" addresses already? Default
2607 * to one. Everybody gets one, and one should be enough for
2610 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2611 SV_LIMIT_ADDRS_PER_IA
);
2613 if (!evaluate_option_cache(&data
, reply
->packet
,
2615 reply
->packet
->options
,
2619 log_error("reply_process_addr: unable to "
2620 "evaluate addrs-per-ia value.");
2621 status
= ISC_R_FAILURE
;
2625 limit
= getULong(data
.data
);
2626 data_string_forget(&data
, MDL
);
2630 * If we wish to limit the client to a certain number of
2631 * addresses, then omit the address from the reply.
2633 if (reply
->client_resources
>= limit
)
2637 status
= reply_process_is_addressed(reply
, scope
, group
);
2638 if (status
!= ISC_R_SUCCESS
)
2642 status
= reply_process_send_addr(reply
, &tmp_addr
);
2645 if (iaaddr
.data
!= NULL
)
2646 data_string_forget(&iaaddr
, MDL
);
2647 if (data
.data
!= NULL
)
2648 data_string_forget(&data
, MDL
);
2649 if (reply
->lease
!= NULL
)
2650 iasubopt_dereference(&reply
->lease
, MDL
);
2656 * Verify the address belongs to the client. If we've got a host
2657 * record with a fixed address, it has to be the assigned address
2658 * (fault out all else). Otherwise it's a dynamic address, so lookup
2659 * that address and make sure it belongs to this DUID:IAID pair.
2661 static isc_boolean_t
2662 address_is_owned(struct reply_state
*reply
, struct iaddr
*addr
) {
2664 struct ipv6_pond
*pond
;
2667 * This faults out addresses that don't match fixed addresses.
2669 if (reply
->static_lease
) {
2670 if (reply
->fixed
.data
== NULL
)
2671 log_fatal("Impossible condition at %s:%d.", MDL
);
2673 if (memcmp(addr
->iabuf
, reply
->fixed
.data
, 16) == 0)
2679 if ((reply
->old_ia
== NULL
) || (reply
->old_ia
->num_iasubopt
== 0))
2682 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2683 struct iasubopt
*tmp
;
2685 tmp
= reply
->old_ia
->iasubopt
[i
];
2687 if (memcmp(addr
->iabuf
, &tmp
->addr
, 16) == 0) {
2688 if (lease6_usable(tmp
) == ISC_FALSE
) {
2692 pond
= tmp
->ipv6_pool
->ipv6_pond
;
2693 if (((pond
->prohibit_list
!= NULL
) &&
2694 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
2695 ((pond
->permit_list
!= NULL
) &&
2696 (!permitted(reply
->packet
, pond
->permit_list
))))
2699 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
2708 /* Process a client-supplied IA_TA. This may append options to the tail of
2709 * the reply packet being built in the reply_state structure.
2712 reply_process_ia_ta(struct reply_state
*reply
, struct option_cache
*ia
) {
2713 isc_result_t status
= ISC_R_SUCCESS
;
2716 struct option_state
*packet_ia
;
2717 struct option_cache
*oc
;
2718 struct data_string ia_data
, data
;
2719 struct data_string iaaddr
;
2720 u_int32_t pref_life
, valid_life
;
2721 struct iaddr tmp_addr
;
2723 /* Initialize values that will get cleaned up on return. */
2725 memset(&ia_data
, 0, sizeof(ia_data
));
2726 memset(&data
, 0, sizeof(data
));
2727 memset(&iaaddr
, 0, sizeof(iaaddr
));
2729 /* Make sure there is at least room for the header. */
2730 if ((reply
->cursor
+ IA_TA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2731 log_error("reply_process_ia_ta: Reply too long for IA.");
2732 return ISC_R_NOSPACE
;
2736 /* Fetch the IA_TA contents. */
2737 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2738 ia
, IA_TA_OFFSET
)) {
2739 log_error("reply_process_ia_ta: error evaluating ia");
2740 status
= ISC_R_FAILURE
;
2744 /* Extract IA_TA header contents. */
2745 iaid
= getULong(ia_data
.data
);
2747 /* Create an IA_TA structure. */
2748 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2749 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2750 log_error("reply_process_ia_ta: no memory for ia.");
2751 status
= ISC_R_NOMEMORY
;
2754 reply
->ia
->ia_type
= D6O_IA_TA
;
2756 /* Cache pre-existing IA, if any. */
2757 ia_hash_lookup(&reply
->old_ia
, ia_ta_active
,
2758 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2759 reply
->ia
->iaid_duid
.len
, MDL
);
2762 * Create an option cache to carry the IA_TA option contents, and
2763 * execute any user-supplied values into it.
2765 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2766 status
= ISC_R_NOMEMORY
;
2771 * Temporary leases are dynamic by definition.
2773 reply
->static_lease
= ISC_FALSE
;
2776 * Save the cursor position at the start of the IA, so we can
2777 * set length later. We write a temporary
2778 * header out now just in case we decide to adjust the packet
2779 * within sub-process functions.
2781 ia_cursor
= reply
->cursor
;
2783 /* Initialize the IA_TA header. First the code. */
2784 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_TA
);
2787 /* Then option length. */
2788 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x04u
);
2791 /* Then IA_TA header contents; IAID. */
2792 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2796 * Deal with an IAADDR for lifetimes.
2797 * For all or none, process IAADDRs as hints.
2799 reply
->min_valid
= reply
->min_prefer
= 0xffffffff;
2800 reply
->client_valid
= reply
->client_prefer
= 0;
2801 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2802 for (; oc
!= NULL
; oc
= oc
->next
) {
2803 memset(&iaaddr
, 0, sizeof(iaaddr
));
2804 if (!evaluate_option_cache(&iaaddr
, reply
->packet
,
2806 reply
->packet
->options
, NULL
,
2807 &global_scope
, oc
, MDL
) ||
2808 (iaaddr
.len
< IAADDR_OFFSET
)) {
2809 log_error("reply_process_ia_ta: error "
2810 "evaluating IAADDR.");
2811 status
= ISC_R_FAILURE
;
2814 /* The first 16 bytes are the IPv6 address. */
2815 pref_life
= getULong(iaaddr
.data
+ 16);
2816 valid_life
= getULong(iaaddr
.data
+ 20);
2818 if ((reply
->client_valid
== 0) ||
2819 (reply
->client_valid
> valid_life
))
2820 reply
->client_valid
= valid_life
;
2822 if ((reply
->client_prefer
== 0) ||
2823 (reply
->client_prefer
> pref_life
))
2824 reply
->client_prefer
= pref_life
;
2826 /* Nothing more if something has failed. */
2827 if (status
== ISC_R_CANCELED
)
2831 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2832 if (!temporary_is_available(reply
, &tmp_addr
))
2834 status
= reply_process_is_addressed(reply
,
2835 &reply
->lease
->scope
,
2836 reply
->lease
->ipv6_pool
->ipv6_pond
->group
);
2837 if (status
!= ISC_R_SUCCESS
)
2839 status
= reply_process_send_addr(reply
, &tmp_addr
);
2840 if (status
!= ISC_R_SUCCESS
)
2842 if (reply
->lease
!= NULL
)
2843 iasubopt_dereference(&reply
->lease
, MDL
);
2847 /* Rewind the IA_TA to empty. */
2848 option_state_dereference(&reply
->reply_ia
, MDL
);
2849 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2850 status
= ISC_R_NOMEMORY
;
2853 status
= ISC_R_CANCELED
;
2854 reply
->client_resources
= 0;
2855 reply
->resources_included
= ISC_FALSE
;
2856 if (reply
->lease
!= NULL
)
2857 iasubopt_dereference(&reply
->lease
, MDL
);
2862 * Give the client temporary addresses.
2864 if (reply
->client_resources
!= 0)
2866 status
= find_client_temporaries(reply
);
2867 if (status
== ISC_R_NORESOURCES
) {
2868 switch (reply
->packet
->dhcpv6_msg_type
) {
2869 case DHCPV6_SOLICIT
:
2871 * No address for any IA is handled
2876 case DHCPV6_REQUEST
:
2877 /* Section 18.2.1 (Request):
2879 * If the server cannot assign any addresses to
2880 * an IA in the message from the client, the
2881 * server MUST include the IA in the Reply
2882 * message with no addresses in the IA and a
2883 * Status Code option in the IA containing
2884 * status code NoAddrsAvail.
2886 option_state_dereference(&reply
->reply_ia
, MDL
);
2887 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2888 log_error("reply_process_ia_ta: No "
2889 "memory for option state wipe.");
2890 status
= ISC_R_NOMEMORY
;
2894 if (!set_status_code(STATUS_NoAddrsAvail
,
2895 "No addresses available "
2896 "for this interface.",
2898 log_error("reply_process_ia_ta: Unable "
2899 "to set NoAddrsAvail status code.");
2900 status
= ISC_R_FAILURE
;
2904 status
= ISC_R_SUCCESS
;
2909 * We don't want to include the IA if we
2910 * provide zero addresses including zeroed
2913 if (reply
->resources_included
)
2914 status
= ISC_R_SUCCESS
;
2919 } else if (status
!= ISC_R_SUCCESS
)
2923 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2924 sizeof(reply
->buf
) - reply
->cursor
,
2925 reply
->reply_ia
, reply
->packet
,
2926 required_opts_IA
, NULL
);
2928 /* Reset the length of this IA to match what was just written. */
2929 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2930 reply
->cursor
- (ia_cursor
+ 4));
2933 * yes, goto's aren't the best but we also want to avoid extra
2936 if (status
== ISC_R_CANCELED
)
2940 * If we have any addresses log what we are doing.
2942 if (reply
->ia
->num_iasubopt
!= 0) {
2943 struct iasubopt
*tmp
;
2945 char tmp_addr
[INET6_ADDRSTRLEN
];
2947 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2948 tmp
= reply
->ia
->iasubopt
[i
];
2950 log_info("%s TA: address %s to client with duid %s "
2951 "iaid = %d valid for %u seconds",
2952 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2953 inet_ntop(AF_INET6
, &tmp
->addr
,
2954 tmp_addr
, sizeof(tmp_addr
)),
2955 print_hex_1(reply
->client_id
.len
,
2956 reply
->client_id
.data
, 60),
2963 * For hard bindings we consume the new changes into
2964 * the database (if any have been attached to the ia_ta).
2966 * Loop through the assigned dynamic addresses, referencing the
2967 * leases onto this IA_TA rather than any old ones, and updating
2968 * pool timers for each (if any).
2970 if ((reply
->ia
->num_iasubopt
!= 0) &&
2971 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
2972 struct iasubopt
*tmp
;
2973 struct data_string
*ia_id
;
2976 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2977 tmp
= reply
->ia
->iasubopt
[i
];
2979 if (tmp
->ia
!= NULL
)
2980 ia_dereference(&tmp
->ia
, MDL
);
2981 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2983 /* Commit 'hard' bindings. */
2984 renew_lease6(tmp
->ipv6_pool
, tmp
);
2985 schedule_lease_timeout(tmp
->ipv6_pool
);
2987 /* If we have anything to do on commit do it now */
2988 if (tmp
->on_star
.on_commit
!= NULL
) {
2989 execute_statements(NULL
, reply
->packet
,
2991 reply
->packet
->options
,
2994 tmp
->on_star
.on_commit
,
2996 executable_statement_dereference
2997 (&tmp
->on_star
.on_commit
, MDL
);
3000 #if defined (NSUPDATE)
3002 * Perform ddns updates.
3004 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3007 evaluate_boolean_option_cache(NULL
, reply
->packet
,
3009 reply
->packet
->options
,
3013 ddns_updates(reply
->packet
, NULL
, NULL
,
3014 tmp
, NULL
, reply
->opt_state
);
3017 /* Do our threshold check. */
3018 check_pool6_threshold(reply
, tmp
);
3021 /* Remove any old ia from the hash. */
3022 if (reply
->old_ia
!= NULL
) {
3023 ia_id
= &reply
->old_ia
->iaid_duid
;
3024 ia_hash_delete(ia_ta_active
,
3025 (unsigned char *)ia_id
->data
,
3027 ia_dereference(&reply
->old_ia
, MDL
);
3030 /* Put new ia into the hash. */
3031 reply
->ia
->cltt
= cur_time
;
3032 ia_id
= &reply
->ia
->iaid_duid
;
3033 ia_hash_add(ia_ta_active
, (unsigned char *)ia_id
->data
,
3034 ia_id
->len
, reply
->ia
, MDL
);
3036 write_ia(reply
->ia
);
3038 schedule_lease_timeout_reply(reply
);
3042 if (packet_ia
!= NULL
)
3043 option_state_dereference(&packet_ia
, MDL
);
3044 if (iaaddr
.data
!= NULL
)
3045 data_string_forget(&iaaddr
, MDL
);
3046 if (reply
->reply_ia
!= NULL
)
3047 option_state_dereference(&reply
->reply_ia
, MDL
);
3048 if (ia_data
.data
!= NULL
)
3049 data_string_forget(&ia_data
, MDL
);
3050 if (data
.data
!= NULL
)
3051 data_string_forget(&data
, MDL
);
3052 if (reply
->ia
!= NULL
)
3053 ia_dereference(&reply
->ia
, MDL
);
3054 if (reply
->old_ia
!= NULL
)
3055 ia_dereference(&reply
->old_ia
, MDL
);
3056 if (reply
->lease
!= NULL
)
3057 iasubopt_dereference(&reply
->lease
, MDL
);
3060 * ISC_R_CANCELED is a status code used by the addr processing to
3061 * indicate we're replying with other addresses. This is still a
3062 * success at higher layers.
3064 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
3068 * Verify the temporary address is available.
3070 static isc_boolean_t
3071 temporary_is_available(struct reply_state
*reply
, struct iaddr
*addr
) {
3072 struct in6_addr tmp_addr
;
3073 struct subnet
*subnet
;
3074 struct ipv6_pool
*pool
= NULL
;
3075 struct ipv6_pond
*pond
= NULL
;
3078 memcpy(&tmp_addr
, addr
->iabuf
, sizeof(tmp_addr
));
3080 * Clients may choose to send :: as an address, with the idea to give
3081 * hints about preferred-lifetime or valid-lifetime.
3082 * So this is not a request for this address.
3084 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
))
3088 * Verify that this address is on the client's network.
3090 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
3091 subnet
= subnet
->next_sibling
) {
3092 if (addr_eq(subnet_number(*addr
, subnet
->netmask
),
3097 /* Address not found on shared network. */
3102 * Check if this address is owned (must be before next step).
3104 if (address_is_owned(reply
, addr
))
3108 * Verify that this address is in a temporary pool and try to get it.
3110 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3111 if (((pond
->prohibit_list
!= NULL
) &&
3112 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3113 ((pond
->permit_list
!= NULL
) &&
3114 (!permitted(reply
->packet
, pond
->permit_list
))))
3117 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3118 if (pool
->pool_type
!= D6O_IA_TA
)
3121 if (ipv6_in_pool(&tmp_addr
, pool
))
3131 if (lease6_exists(pool
, &tmp_addr
))
3133 if (iasubopt_allocate(&reply
->lease
, MDL
) != ISC_R_SUCCESS
)
3135 reply
->lease
->addr
= tmp_addr
;
3136 reply
->lease
->plen
= 0;
3137 /* Default is soft binding for 2 minutes. */
3138 if (add_lease6(pool
, reply
->lease
, cur_time
+ 120) != ISC_R_SUCCESS
)
3145 * Get a temporary address per prefix.
3148 find_client_temporaries(struct reply_state
*reply
) {
3150 struct ipv6_pool
*p
= NULL
;
3151 struct ipv6_pond
*pond
;
3152 isc_result_t status
= ISC_R_NORESOURCES
;;
3153 unsigned int attempts
;
3154 struct iaddr send_addr
;
3157 * Do a quick walk through of the ponds and pools
3158 * to see if we have any prefix pools
3160 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3161 if (pond
->ipv6_pools
== NULL
)
3164 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3165 if (p
->pool_type
== D6O_IA_TA
)
3172 /* If we get here and p is NULL we have no useful pools */
3174 log_debug("Unable to get client addresses: "
3175 "no IPv6 pools on this shared network");
3176 return ISC_R_NORESOURCES
;
3180 * We have at least one pool that could provide an address
3181 * Now we walk through the ponds and pools again and check
3182 * to see if the client is permitted and if an address is
3186 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3187 if (((pond
->prohibit_list
!= NULL
) &&
3188 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3189 ((pond
->permit_list
!= NULL
) &&
3190 (!permitted(reply
->packet
, pond
->permit_list
))))
3193 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3194 if (p
->pool_type
!= D6O_IA_TA
) {
3199 * Get an address in this temporary pool.
3201 status
= create_lease6(p
, &reply
->lease
, &attempts
,
3202 &reply
->client_id
, cur_time
+ 120);
3203 if (status
!= ISC_R_SUCCESS
) {
3204 log_debug("Unable to get a temporary address.");
3208 status
= reply_process_is_addressed(reply
,
3209 &reply
->lease
->scope
,
3211 if (status
!= ISC_R_SUCCESS
) {
3215 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3216 status
= reply_process_send_addr(reply
, &send_addr
);
3217 if (status
!= ISC_R_SUCCESS
) {
3221 * reply->lease can't be null as we use it above
3222 * add check if that changes
3224 iasubopt_dereference(&reply
->lease
, MDL
);
3229 if (reply
->lease
!= NULL
) {
3230 iasubopt_dereference(&reply
->lease
, MDL
);
3236 * This function only returns failure on 'hard' failures. If it succeeds,
3237 * it will leave a lease structure behind.
3240 reply_process_try_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3241 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
3242 struct ipv6_pool
*pool
= NULL
;
3243 struct ipv6_pond
*pond
= NULL
;
3245 struct data_string data_addr
;
3247 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
3248 (addr
== NULL
) || (reply
->lease
!= NULL
))
3249 return (DHCP_R_INVALIDARG
);
3252 * Do a quick walk through of the ponds and pools
3253 * to see if we have any NA address pools
3255 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3256 if (pond
->ipv6_pools
== NULL
)
3259 for (i
= 0; ; i
++) {
3260 pool
= pond
->ipv6_pools
[i
];
3261 if ((pool
== NULL
) ||
3262 (pool
->pool_type
== D6O_IA_NA
))
3269 /* If we get here and p is NULL we have no useful pools */
3271 return (ISC_R_ADDRNOTAVAIL
);
3274 memset(&data_addr
, 0, sizeof(data_addr
));
3275 data_addr
.len
= addr
->len
;
3276 data_addr
.data
= addr
->iabuf
;
3279 * We have at least one pool that could provide an address
3280 * Now we walk through the ponds and pools again and check
3281 * to see if the client is permitted and if an address is
3284 * Within a given pond we start looking at the last pool we
3285 * allocated from, unless it had a collision trying to allocate
3286 * an address. This will tend to move us into less-filled pools.
3289 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3290 if (((pond
->prohibit_list
!= NULL
) &&
3291 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3292 ((pond
->permit_list
!= NULL
) &&
3293 (!permitted(reply
->packet
, pond
->permit_list
))))
3296 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3297 if (pool
->pool_type
!= D6O_IA_NA
)
3300 status
= try_client_v6_address(&reply
->lease
, pool
,
3302 if (status
== ISC_R_SUCCESS
)
3306 if (status
== ISC_R_SUCCESS
)
3310 /* Note that this is just pedantry. There is no allocation to free. */
3311 data_string_forget(&data_addr
, MDL
);
3312 /* Return just the most recent status... */
3316 /* Look around for an address to give the client. First, look through the
3317 * old IA for addresses we can extend. Second, try to allocate a new address.
3318 * Finally, actually add that address into the current reply IA.
3321 find_client_address(struct reply_state
*reply
) {
3322 struct iaddr send_addr
;
3323 isc_result_t status
= ISC_R_NORESOURCES
;
3324 struct iasubopt
*lease
, *best_lease
= NULL
;
3325 struct binding_scope
**scope
;
3326 struct group
*group
;
3329 if (reply
->static_lease
) {
3330 if (reply
->host
== NULL
)
3331 return DHCP_R_INVALIDARG
;
3334 memcpy(send_addr
.iabuf
, reply
->fixed
.data
, 16);
3336 scope
= &global_scope
;
3337 group
= reply
->subnet
->group
;
3341 if (reply
->old_ia
!= NULL
) {
3342 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3343 struct shared_network
*candidate_shared
;
3344 struct ipv6_pond
*pond
;
3346 lease
= reply
->old_ia
->iasubopt
[i
];
3347 candidate_shared
= lease
->ipv6_pool
->shared_network
;
3348 pond
= lease
->ipv6_pool
->ipv6_pond
;
3351 * Look for the best lease on the client's shared
3352 * network, that is still permitted
3355 if ((candidate_shared
!= reply
->shared
) ||
3356 (lease6_usable(lease
) != ISC_TRUE
))
3359 if (((pond
->prohibit_list
!= NULL
) &&
3360 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3361 ((pond
->permit_list
!= NULL
) &&
3362 (!permitted(reply
->packet
, pond
->permit_list
))))
3365 best_lease
= lease_compare(lease
, best_lease
);
3369 /* Try to pick a new address if we didn't find one, or if we found an
3372 if ((best_lease
== NULL
) || (best_lease
->state
== FTS_ABANDONED
)) {
3373 status
= pick_v6_address(reply
);
3374 } else if (best_lease
!= NULL
) {
3375 iasubopt_reference(&reply
->lease
, best_lease
, MDL
);
3376 status
= ISC_R_SUCCESS
;
3379 /* Pick the abandoned lease as a last resort. */
3380 if ((status
== ISC_R_NORESOURCES
) && (best_lease
!= NULL
)) {
3381 /* I don't see how this is supposed to be done right now. */
3382 log_error("Best match for DUID %s is an abandoned address,"
3383 " This may be a result of multiple clients attempting"
3384 " to use this DUID",
3385 print_hex_1(reply
->client_id
.len
,
3386 reply
->client_id
.data
, 60));
3387 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
3390 /* Give up now if we didn't find a lease. */
3391 if (status
!= ISC_R_SUCCESS
)
3394 if (reply
->lease
== NULL
)
3395 log_fatal("Impossible condition at %s:%d.", MDL
);
3397 /* Draw binding scopes from the lease's binding scope, and config
3398 * from the lease's containing subnet and higher. Note that it may
3399 * be desirable to place the group attachment directly in the pool.
3401 scope
= &reply
->lease
->scope
;
3402 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
3405 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3408 status
= reply_process_is_addressed(reply
, scope
, group
);
3409 if (status
!= ISC_R_SUCCESS
)
3412 status
= reply_process_send_addr(reply
, &send_addr
);
3416 /* Once an address is found for a client, perform several common functions;
3417 * Calculate and store valid and preferred lease times, draw client options
3418 * into the option state.
3421 reply_process_is_addressed(struct reply_state
*reply
,
3422 struct binding_scope
**scope
, struct group
*group
)
3424 isc_result_t status
= ISC_R_SUCCESS
;
3425 struct data_string data
;
3426 struct option_cache
*oc
;
3427 struct option_state
*tmp_options
= NULL
;
3428 struct on_star
*on_star
;
3431 /* Initialize values we will cleanup. */
3432 memset(&data
, 0, sizeof(data
));
3435 * Find the proper on_star block to use. We use the
3436 * one in the lease if we have a lease or the one in
3437 * the reply if we don't have a lease because this is
3441 on_star
= &reply
->lease
->on_star
;
3443 on_star
= &reply
->on_star
;
3447 * Bring in the root configuration. We only do this to bring
3448 * in the on * statements, as we didn't have the lease available
3449 * we did it the first time.
3451 option_state_allocate(&tmp_options
, MDL
);
3452 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3453 reply
->packet
->options
, tmp_options
,
3454 &global_scope
, root_group
, NULL
,
3456 if (tmp_options
!= NULL
) {
3457 option_state_dereference(&tmp_options
, MDL
);
3461 * Bring configured options into the root packet level cache - start
3462 * with the lease's closest enclosing group (passed in by the caller
3465 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3466 reply
->packet
->options
, reply
->opt_state
,
3467 scope
, group
, root_group
, on_star
);
3469 /* Execute statements from class scopes. */
3470 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3471 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3472 reply
->packet
->options
,
3473 reply
->opt_state
, scope
,
3474 reply
->packet
->classes
[i
- 1]->group
,
3479 * If there is a host record, over-ride with values configured there,
3480 * without re-evaluating configuration from the previously executed
3481 * group or its common enclosers.
3483 if (reply
->host
!= NULL
)
3484 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3485 reply
->packet
->options
,
3486 reply
->opt_state
, scope
,
3487 reply
->host
->group
, group
,
3490 /* Determine valid lifetime. */
3491 if (reply
->client_valid
== 0)
3492 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
3494 reply
->send_valid
= reply
->client_valid
;
3496 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3497 SV_DEFAULT_LEASE_TIME
);
3499 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3500 reply
->packet
->options
,
3504 log_error("reply_process_is_addressed: unable to "
3505 "evaluate default lease time");
3506 status
= ISC_R_FAILURE
;
3510 reply
->send_valid
= getULong(data
.data
);
3511 data_string_forget(&data
, MDL
);
3514 /* Check to see if the lease time would cause us to wrap
3515 * in which case we make it infinite.
3516 * The following doesn't work on at least some systems:
3517 * (cur_time + reply->send_valid < cur_time)
3519 if (reply
->send_valid
!= 0xFFFFFFFF) {
3520 time_t test_time
= cur_time
+ reply
->send_valid
;
3521 if (test_time
< cur_time
)
3522 reply
->send_valid
= 0xFFFFFFFF;
3525 if (reply
->client_prefer
== 0)
3526 reply
->send_prefer
= reply
->send_valid
;
3528 reply
->send_prefer
= reply
->client_prefer
;
3530 if ((reply
->send_prefer
>= reply
->send_valid
) &&
3531 (reply
->send_valid
!= 0xFFFFFFFF))
3532 reply
->send_prefer
= (reply
->send_valid
/ 2) +
3533 (reply
->send_valid
/ 8);
3535 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3536 SV_PREFER_LIFETIME
);
3538 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3539 reply
->packet
->options
,
3543 log_error("reply_process_is_addressed: unable to "
3544 "evaluate preferred lease time");
3545 status
= ISC_R_FAILURE
;
3549 reply
->send_prefer
= getULong(data
.data
);
3550 data_string_forget(&data
, MDL
);
3553 /* Note lowest values for later calculation of renew/rebind times. */
3554 if (reply
->min_prefer
> reply
->send_prefer
)
3555 reply
->min_prefer
= reply
->send_prefer
;
3557 if (reply
->min_valid
> reply
->send_valid
)
3558 reply
->min_valid
= reply
->send_valid
;
3562 * XXX: Old 4.0.0 alpha code would change the host {} record
3563 * XXX: uid upon lease assignment. This was intended to cover the
3564 * XXX: case where a client first identifies itself using vendor
3565 * XXX: options in a solicit, or request, but later neglects to include
3566 * XXX: these options in a Renew or Rebind. It is not clear that this
3567 * XXX: is required, and has some startling ramifications (such as
3568 * XXX: how to recover this dynamic host {} state across restarts).
3570 if (reply
->host
!= NULL
)
3571 change_host_uid(host
, reply
->client_id
->data
,
3572 reply
->client_id
->len
);
3575 /* Perform dynamic lease related update work. */
3576 if (reply
->lease
!= NULL
) {
3577 /* Cached lifetimes */
3578 reply
->lease
->prefer
= reply
->send_prefer
;
3579 reply
->lease
->valid
= reply
->send_valid
;
3581 /* Advance (or rewind) the valid lifetime.
3582 * In the protocol 0xFFFFFFFF is infinite
3583 * when connecting to the lease file MAX_TIME is
3585 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
3586 if (reply
->send_valid
== 0xFFFFFFFF) {
3587 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
3589 reply
->lease
->soft_lifetime_end_time
=
3590 cur_time
+ reply
->send_valid
;
3592 /* Wait before renew! */
3595 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
3596 if (status
!= ISC_R_SUCCESS
) {
3597 log_fatal("reply_process_is_addressed: Unable to "
3598 "attach lease to new IA: %s",
3599 isc_result_totext(status
));
3603 * If this is a new lease, make sure it is attached somewhere.
3605 if (reply
->lease
->ia
== NULL
) {
3606 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
3610 /* Bring a copy of the relevant options into the IA scope. */
3611 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3612 reply
->packet
->options
, reply
->reply_ia
,
3613 scope
, group
, root_group
, NULL
);
3615 /* Execute statements from class scopes. */
3616 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3617 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3618 reply
->packet
->options
,
3619 reply
->reply_ia
, scope
,
3620 reply
->packet
->classes
[i
- 1]->group
,
3625 * And bring in host record configuration, if any, but not to overlap
3626 * the previous group or its common enclosers.
3628 if (reply
->host
!= NULL
)
3629 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3630 reply
->packet
->options
,
3631 reply
->reply_ia
, scope
,
3632 reply
->host
->group
, group
, NULL
);
3635 if (data
.data
!= NULL
)
3636 data_string_forget(&data
, MDL
);
3638 if (status
== ISC_R_SUCCESS
)
3639 reply
->client_resources
++;
3644 /* Simply send an IAADDR within the IA scope as described. */
3646 reply_process_send_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3647 isc_result_t status
= ISC_R_SUCCESS
;
3648 struct data_string data
;
3650 memset(&data
, 0, sizeof(data
));
3652 /* Now append the lease. */
3653 data
.len
= IAADDR_OFFSET
;
3654 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
3655 log_error("reply_process_send_addr: out of memory"
3656 "allocating new IAADDR buffer.");
3657 status
= ISC_R_NOMEMORY
;
3660 data
.data
= data
.buffer
->data
;
3662 memcpy(data
.buffer
->data
, addr
->iabuf
, 16);
3663 putULong(data
.buffer
->data
+ 16, reply
->send_prefer
);
3664 putULong(data
.buffer
->data
+ 20, reply
->send_valid
);
3666 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
3667 data
.buffer
, data
.buffer
->data
,
3668 data
.len
, D6O_IAADDR
, 0)) {
3669 log_error("reply_process_send_addr: unable "
3670 "to save IAADDR option");
3671 status
= ISC_R_FAILURE
;
3675 reply
->resources_included
= ISC_TRUE
;
3678 if (data
.data
!= NULL
)
3679 data_string_forget(&data
, MDL
);
3684 /* Choose the better of two leases. */
3685 static struct iasubopt
*
3686 lease_compare(struct iasubopt
*alpha
, struct iasubopt
*beta
) {
3692 switch(alpha
->state
) {
3694 switch(beta
->state
) {
3696 /* Choose the lease with the longest lifetime (most
3697 * likely the most recently allocated).
3699 if (alpha
->hard_lifetime_end_time
<
3700 beta
->hard_lifetime_end_time
)
3710 log_fatal("Impossible condition at %s:%d.", MDL
);
3715 switch (beta
->state
) {
3720 /* Choose the most recently expired lease. */
3721 if (alpha
->hard_lifetime_end_time
<
3722 beta
->hard_lifetime_end_time
)
3724 else if ((alpha
->hard_lifetime_end_time
==
3725 beta
->hard_lifetime_end_time
) &&
3726 (alpha
->soft_lifetime_end_time
<
3727 beta
->soft_lifetime_end_time
))
3736 log_fatal("Impossible condition at %s:%d.", MDL
);
3741 switch (beta
->state
) {
3747 /* Choose the lease that was abandoned longest ago. */
3748 if (alpha
->hard_lifetime_end_time
<
3749 beta
->hard_lifetime_end_time
)
3755 log_fatal("Impossible condition at %s:%d.", MDL
);
3760 log_fatal("Impossible condition at %s:%d.", MDL
);
3763 log_fatal("Triple impossible condition at %s:%d.", MDL
);
3767 /* Process a client-supplied IA_PD. This may append options to the tail of
3768 * the reply packet being built in the reply_state structure.
3771 reply_process_ia_pd(struct reply_state
*reply
, struct option_cache
*ia
) {
3772 isc_result_t status
= ISC_R_SUCCESS
;
3775 struct option_state
*packet_ia
;
3776 struct option_cache
*oc
;
3777 struct data_string ia_data
, data
;
3779 /* Initialize values that will get cleaned up on return. */
3781 memset(&ia_data
, 0, sizeof(ia_data
));
3782 memset(&data
, 0, sizeof(data
));
3784 * Note that find_client_prefix() may set reply->lease.
3787 /* Make sure there is at least room for the header. */
3788 if ((reply
->cursor
+ IA_PD_OFFSET
+ 4) > sizeof(reply
->buf
)) {
3789 log_error("reply_process_ia_pd: Reply too long for IA.");
3790 return ISC_R_NOSPACE
;
3794 /* Fetch the IA_PD contents. */
3795 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
3796 ia
, IA_PD_OFFSET
)) {
3797 log_error("reply_process_ia_pd: error evaluating ia");
3798 status
= ISC_R_FAILURE
;
3802 /* Extract IA_PD header contents. */
3803 iaid
= getULong(ia_data
.data
);
3804 reply
->renew
= getULong(ia_data
.data
+ 4);
3805 reply
->rebind
= getULong(ia_data
.data
+ 8);
3807 /* Create an IA_PD structure. */
3808 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
3809 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
3810 log_error("reply_process_ia_pd: no memory for ia.");
3811 status
= ISC_R_NOMEMORY
;
3814 reply
->ia
->ia_type
= D6O_IA_PD
;
3816 /* Cache pre-existing IA_PD, if any. */
3817 ia_hash_lookup(&reply
->old_ia
, ia_pd_active
,
3818 (unsigned char *)reply
->ia
->iaid_duid
.data
,
3819 reply
->ia
->iaid_duid
.len
, MDL
);
3822 * Create an option cache to carry the IA_PD option contents, and
3823 * execute any user-supplied values into it.
3825 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
3826 status
= ISC_R_NOMEMORY
;
3830 /* Check & count the fixed prefix host records. */
3831 reply
->static_prefixes
= 0;
3832 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_prefix
!= NULL
)) {
3833 struct iaddrcidrnetlist
*fp
;
3835 for (fp
= reply
->host
->fixed_prefix
; fp
!= NULL
;
3837 reply
->static_prefixes
+= 1;
3842 * Save the cursor position at the start of the IA_PD, so we can
3843 * set length and adjust t1/t2 values later. We write a temporary
3844 * header out now just in case we decide to adjust the packet
3845 * within sub-process functions.
3847 ia_cursor
= reply
->cursor
;
3849 /* Initialize the IA_PD header. First the code. */
3850 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_PD
);
3853 /* Then option length. */
3854 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
3857 /* Then IA_PD header contents; IAID. */
3858 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
3861 /* We store the client's t1 for now, and may over-ride it later. */
3862 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
3865 /* We store the client's t2 for now, and may over-ride it later. */
3866 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
3870 * For each prefix in this IA_PD, decide what to do about it.
3872 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAPREFIX
);
3873 reply
->min_valid
= reply
->min_prefer
= 0xffffffff;
3874 reply
->client_valid
= reply
->client_prefer
= 0;
3875 reply
->preflen
= -1;
3876 for (; oc
!= NULL
; oc
= oc
->next
) {
3877 status
= reply_process_prefix(reply
, oc
);
3880 * Canceled means we did not allocate prefixes to the
3881 * client, but we're "done" with this IA - we set a status
3882 * code. So transmit this reply, e.g., move on to the next
3885 if (status
== ISC_R_CANCELED
)
3888 if ((status
!= ISC_R_SUCCESS
) &&
3889 (status
!= ISC_R_ADDRINUSE
) &&
3890 (status
!= ISC_R_ADDRNOTAVAIL
))
3897 * If we fell through the above and never gave the client
3898 * a prefix, give it one now.
3900 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
3901 status
= find_client_prefix(reply
);
3903 if (status
== ISC_R_NORESOURCES
) {
3904 switch (reply
->packet
->dhcpv6_msg_type
) {
3905 case DHCPV6_SOLICIT
:
3907 * No prefix for any IA is handled
3912 case DHCPV6_REQUEST
:
3913 /* Same than for addresses. */
3914 option_state_dereference(&reply
->reply_ia
, MDL
);
3915 if (!option_state_allocate(&reply
->reply_ia
,
3918 log_error("reply_process_ia_pd: No "
3919 "memory for option state "
3921 status
= ISC_R_NOMEMORY
;
3925 if (!set_status_code(STATUS_NoPrefixAvail
,
3926 "No prefixes available "
3927 "for this interface.",
3929 log_error("reply_process_ia_pd: "
3931 "NoPrefixAvail status "
3933 status
= ISC_R_FAILURE
;
3937 status
= ISC_R_SUCCESS
;
3941 if (reply
->resources_included
)
3942 status
= ISC_R_SUCCESS
;
3949 if (status
!= ISC_R_SUCCESS
)
3953 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
3954 sizeof(reply
->buf
) - reply
->cursor
,
3955 reply
->reply_ia
, reply
->packet
,
3956 required_opts_IA_PD
, NULL
);
3958 /* Reset the length of this IA_PD to match what was just written. */
3959 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
3960 reply
->cursor
- (ia_cursor
+ 4));
3962 /* Calculate T1/T2 and stuff them in the reply */
3963 set_reply_tee_times(reply
, ia_cursor
);
3966 * yes, goto's aren't the best but we also want to avoid extra
3969 if (status
== ISC_R_CANCELED
)
3973 * Handle static prefixes, we always log stuff and if it's
3974 * a hard binding we run any commit statements that we have
3976 if (reply
->static_prefixes
!= 0) {
3977 char tmp_addr
[INET6_ADDRSTRLEN
];
3978 log_info("%s PD: address %s/%d to client with duid %s "
3980 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
3981 inet_ntop(AF_INET6
, reply
->fixed_pref
.lo_addr
.iabuf
,
3982 tmp_addr
, sizeof(tmp_addr
)),
3983 reply
->fixed_pref
.bits
,
3984 print_hex_1(reply
->client_id
.len
,
3985 reply
->client_id
.data
, 60),
3987 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
3988 (reply
->on_star
.on_commit
!= NULL
)) {
3989 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
3990 reply
->packet
->options
,
3992 NULL
, reply
->on_star
.on_commit
,
3994 executable_statement_dereference
3995 (&reply
->on_star
.on_commit
, MDL
);
4001 * If we have any addresses log what we are doing.
4003 if (reply
->ia
->num_iasubopt
!= 0) {
4004 struct iasubopt
*tmp
;
4006 char tmp_addr
[INET6_ADDRSTRLEN
];
4008 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
4009 tmp
= reply
->ia
->iasubopt
[i
];
4011 log_info("%s PD: address %s/%d to client with duid %s"
4012 " iaid = %d valid for %u seconds",
4013 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
4014 inet_ntop(AF_INET6
, &tmp
->addr
,
4015 tmp_addr
, sizeof(tmp_addr
)),
4017 print_hex_1(reply
->client_id
.len
,
4018 reply
->client_id
.data
, 60),
4024 * If this is not a 'soft' binding, consume the new changes into
4025 * the database (if any have been attached to the ia_pd).
4027 * Loop through the assigned dynamic prefixes, referencing the
4028 * prefixes onto this IA_PD rather than any old ones, and updating
4029 * prefix pool timers for each (if any).
4031 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
4032 (reply
->ia
->num_iasubopt
!= 0)) {
4033 struct iasubopt
*tmp
;
4034 struct data_string
*ia_id
;
4037 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
4038 tmp
= reply
->ia
->iasubopt
[i
];
4040 if (tmp
->ia
!= NULL
)
4041 ia_dereference(&tmp
->ia
, MDL
);
4042 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
4044 /* Commit 'hard' bindings. */
4045 renew_lease6(tmp
->ipv6_pool
, tmp
);
4046 schedule_lease_timeout(tmp
->ipv6_pool
);
4048 /* If we have anything to do on commit do it now */
4049 if (tmp
->on_star
.on_commit
!= NULL
) {
4050 execute_statements(NULL
, reply
->packet
,
4052 reply
->packet
->options
,
4055 tmp
->on_star
.on_commit
,
4057 executable_statement_dereference
4058 (&tmp
->on_star
.on_commit
, MDL
);
4061 /* Do our threshold check. */
4062 check_pool6_threshold(reply
, tmp
);
4065 /* Remove any old ia from the hash. */
4066 if (reply
->old_ia
!= NULL
) {
4067 ia_id
= &reply
->old_ia
->iaid_duid
;
4068 ia_hash_delete(ia_pd_active
,
4069 (unsigned char *)ia_id
->data
,
4071 ia_dereference(&reply
->old_ia
, MDL
);
4074 /* Put new ia into the hash. */
4075 reply
->ia
->cltt
= cur_time
;
4076 ia_id
= &reply
->ia
->iaid_duid
;
4077 ia_hash_add(ia_pd_active
, (unsigned char *)ia_id
->data
,
4078 ia_id
->len
, reply
->ia
, MDL
);
4080 write_ia(reply
->ia
);
4082 schedule_lease_timeout_reply(reply
);
4086 if (packet_ia
!= NULL
)
4087 option_state_dereference(&packet_ia
, MDL
);
4088 if (reply
->reply_ia
!= NULL
)
4089 option_state_dereference(&reply
->reply_ia
, MDL
);
4090 if (ia_data
.data
!= NULL
)
4091 data_string_forget(&ia_data
, MDL
);
4092 if (data
.data
!= NULL
)
4093 data_string_forget(&data
, MDL
);
4094 if (reply
->ia
!= NULL
)
4095 ia_dereference(&reply
->ia
, MDL
);
4096 if (reply
->old_ia
!= NULL
)
4097 ia_dereference(&reply
->old_ia
, MDL
);
4098 if (reply
->lease
!= NULL
)
4099 iasubopt_dereference(&reply
->lease
, MDL
);
4100 if (reply
->on_star
.on_expiry
!= NULL
)
4101 executable_statement_dereference
4102 (&reply
->on_star
.on_expiry
, MDL
);
4103 if (reply
->on_star
.on_release
!= NULL
)
4104 executable_statement_dereference
4105 (&reply
->on_star
.on_release
, MDL
);
4108 * ISC_R_CANCELED is a status code used by the prefix processing to
4109 * indicate we're replying with a status code. This is still a
4110 * success at higher layers.
4112 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
4117 * \brief Find the proper scoping group for use with a v6 static prefix.
4119 * We start by trying to find a subnet based on the given prefix and
4120 * the shared network. If we don't find one then the prefix has been
4121 * declared outside of any subnets. If there is a static address
4122 * associated with the host we use it to try and find a subnet (this
4123 * should succeed). If there isn't a static address we fall back
4124 * to the shared subnet itself.
4125 * Once we have a subnet we extract the group from it and return it.
4127 * \param reply - the reply structure we use to collect information
4128 * we will use the fields shared, fixed_pref and host
4129 * from the structure
4131 * \return a pointer to the group structure to use for scoping
4134 static struct group
*
4135 find_group_by_prefix(struct reply_state
*reply
) {
4136 /* default group if we don't find anything better */
4137 struct group
*group
= reply
->shared
->group
;
4138 struct subnet
*subnet
= NULL
;
4139 struct iaddr tmp_addr
;
4140 struct data_string fixed_addr
;
4142 /* Try with the prefix first */
4143 if (find_grouped_subnet(&subnet
, reply
->shared
,
4144 reply
->fixed_pref
.lo_addr
, MDL
) != 0) {
4145 group
= subnet
->group
;
4146 subnet_dereference(&subnet
, MDL
);
4150 /* Didn't find a subnet via prefix, what about fixed address */
4151 /* The caller has already tested reply->host != NULL */
4153 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
4155 if ((reply
->host
->fixed_addr
!= NULL
) &&
4156 (evaluate_option_cache(&fixed_addr
, NULL
, NULL
, NULL
,
4157 NULL
, NULL
, &global_scope
,
4158 reply
->host
->fixed_addr
, MDL
))) {
4159 if (fixed_addr
.len
>= 16) {
4161 memcpy(tmp_addr
.iabuf
, fixed_addr
.data
, 16);
4162 if (find_grouped_subnet(&subnet
, reply
->shared
,
4163 tmp_addr
, MDL
) != 0) {
4164 group
= subnet
->group
;
4165 subnet_dereference(&subnet
, MDL
);
4168 data_string_forget(&fixed_addr
, MDL
);
4171 /* return whatever we got */
4176 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
4177 * contents into the reply's current ia_pd-scoped option cache. Returns
4178 * ISC_R_CANCELED in the event we are replying with a status code and do
4179 * not wish to process more IAPREFIXes within this IA_PD.
4182 reply_process_prefix(struct reply_state
*reply
, struct option_cache
*pref
) {
4183 u_int32_t pref_life
, valid_life
;
4184 struct binding_scope
**scope
;
4185 struct iaddrcidrnet tmp_pref
;
4186 struct option_cache
*oc
;
4187 struct data_string iapref
, data
;
4188 isc_result_t status
= ISC_R_SUCCESS
;
4189 struct group
*group
;
4191 /* Initializes values that will be cleaned up. */
4192 memset(&iapref
, 0, sizeof(iapref
));
4193 memset(&data
, 0, sizeof(data
));
4194 /* Note that reply->lease may be set by prefix_is_owned() */
4197 * There is no point trying to process an incoming prefix if there
4198 * is no room for an outgoing prefix.
4200 if ((reply
->cursor
+ 29) > sizeof(reply
->buf
)) {
4201 log_error("reply_process_prefix: Out of room for prefix.");
4202 return ISC_R_NOSPACE
;
4205 /* Extract this IAPREFIX option. */
4206 if (!evaluate_option_cache(&iapref
, reply
->packet
, NULL
, NULL
,
4207 reply
->packet
->options
, NULL
, &global_scope
,
4209 (iapref
.len
< IAPREFIX_OFFSET
)) {
4210 log_error("reply_process_prefix: error evaluating IAPREFIX.");
4211 status
= ISC_R_FAILURE
;
4216 * Layout: preferred and valid lifetimes followed by the prefix
4217 * length and the IPv6 address.
4219 pref_life
= getULong(iapref
.data
);
4220 valid_life
= getULong(iapref
.data
+ 4);
4222 if ((reply
->client_valid
== 0) ||
4223 (reply
->client_valid
> valid_life
))
4224 reply
->client_valid
= valid_life
;
4226 if ((reply
->client_prefer
== 0) ||
4227 (reply
->client_prefer
> pref_life
))
4228 reply
->client_prefer
= pref_life
;
4231 * Clients may choose to send ::/0 as a prefix, with the idea to give
4232 * hints about preferred-lifetime or valid-lifetime.
4234 tmp_pref
.lo_addr
.len
= 16;
4235 memset(tmp_pref
.lo_addr
.iabuf
, 0, 16);
4236 if ((iapref
.data
[8] == 0) &&
4237 (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0)) {
4238 /* Status remains success; we just ignore this one. */
4243 * Clients may choose to send ::/X as a prefix to specify a
4244 * preferred/requested prefix length. Note X is never zero here.
4246 tmp_pref
.bits
= (int) iapref
.data
[8];
4247 if (reply
->preflen
< 0) {
4248 /* Cache the first preferred prefix length. */
4249 reply
->preflen
= tmp_pref
.bits
;
4251 if (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0) {
4255 memcpy(tmp_pref
.lo_addr
.iabuf
, iapref
.data
+ 9, 16);
4257 /* Verify the prefix belongs to the client. */
4258 if (!prefix_is_owned(reply
, &tmp_pref
)) {
4259 /* Same than for addresses. */
4260 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
4261 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
4262 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
4263 status
= reply_process_try_prefix(reply
, &tmp_pref
);
4265 /* Either error out or skip this prefix. */
4266 if ((status
!= ISC_R_SUCCESS
) &&
4267 (status
!= ISC_R_ADDRINUSE
) &&
4268 (status
!= ISC_R_ADDRNOTAVAIL
))
4271 if (reply
->lease
== NULL
) {
4272 if (reply
->packet
->dhcpv6_msg_type
==
4274 reply
->send_prefer
= 0;
4275 reply
->send_valid
= 0;
4279 /* status remains success - ignore */
4283 * RFC3633 section 18.2.3:
4285 * If the delegating router cannot find a binding
4286 * for the requesting router's IA_PD the delegating
4287 * router returns the IA_PD containing no prefixes
4288 * with a Status Code option set to NoBinding in the
4291 * On mismatch we (ab)use this pretending we have not the IA
4292 * as soon as we have not a prefix.
4294 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
4295 /* Rewind the IA_PD to empty. */
4296 option_state_dereference(&reply
->reply_ia
, MDL
);
4297 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
4298 log_error("reply_process_prefix: No memory "
4299 "for option state wipe.");
4300 status
= ISC_R_NOMEMORY
;
4304 /* Append a NoBinding status code. */
4305 if (!set_status_code(STATUS_NoBinding
,
4306 "Prefix not bound to this "
4307 "interface.", reply
->reply_ia
)) {
4308 log_error("reply_process_prefix: Unable to "
4309 "attach status code.");
4310 status
= ISC_R_FAILURE
;
4314 /* Fin (no more IAPREFIXes). */
4315 status
= ISC_R_CANCELED
;
4318 log_error("It is impossible to lease a client that is "
4319 "not sending a solicit, request, renew, or "
4321 status
= ISC_R_FAILURE
;
4326 if (reply
->static_prefixes
> 0) {
4327 if (reply
->host
== NULL
)
4328 log_fatal("Impossible condition at %s:%d.", MDL
);
4330 scope
= &global_scope
;
4332 /* Copy the static prefix for logging and finding the group */
4333 memcpy(&reply
->fixed_pref
, &tmp_pref
, sizeof(tmp_pref
));
4335 /* Try to find a group for the static prefix */
4336 group
= find_group_by_prefix(reply
);
4338 if (reply
->lease
== NULL
)
4339 log_fatal("Impossible condition at %s:%d.", MDL
);
4341 scope
= &reply
->lease
->scope
;
4342 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4346 * If client_resources is nonzero, then the reply_process_is_prefixed
4347 * function has executed configuration state into the reply option
4348 * cache. We will use that valid cache to derive configuration for
4349 * whether or not to engage in additional prefixes, and similar.
4351 if (reply
->client_resources
!= 0) {
4355 * Does this client have "enough" prefixes already? Default
4356 * to one. Everybody gets one, and one should be enough for
4359 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4360 SV_LIMIT_PREFS_PER_IA
);
4362 if (!evaluate_option_cache(&data
, reply
->packet
,
4364 reply
->packet
->options
,
4368 log_error("reply_process_prefix: unable to "
4369 "evaluate prefs-per-ia value.");
4370 status
= ISC_R_FAILURE
;
4374 limit
= getULong(data
.data
);
4375 data_string_forget(&data
, MDL
);
4379 * If we wish to limit the client to a certain number of
4380 * prefixes, then omit the prefix from the reply.
4382 if (reply
->client_resources
>= limit
)
4386 status
= reply_process_is_prefixed(reply
, scope
, group
);
4387 if (status
!= ISC_R_SUCCESS
)
4391 status
= reply_process_send_prefix(reply
, &tmp_pref
);
4394 if (iapref
.data
!= NULL
)
4395 data_string_forget(&iapref
, MDL
);
4396 if (data
.data
!= NULL
)
4397 data_string_forget(&data
, MDL
);
4398 if (reply
->lease
!= NULL
)
4399 iasubopt_dereference(&reply
->lease
, MDL
);
4405 * Verify the prefix belongs to the client. If we've got a host
4406 * record with fixed prefixes, it has to be an assigned prefix
4407 * (fault out all else). Otherwise it's a dynamic prefix, so lookup
4408 * that prefix and make sure it belongs to this DUID:IAID pair.
4410 static isc_boolean_t
4411 prefix_is_owned(struct reply_state
*reply
, struct iaddrcidrnet
*pref
) {
4412 struct iaddrcidrnetlist
*l
;
4414 struct ipv6_pond
*pond
;
4417 * This faults out prefixes that don't match fixed prefixes.
4419 if (reply
->static_prefixes
> 0) {
4420 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4421 if ((pref
->bits
== l
->cidrnet
.bits
) &&
4422 (memcmp(pref
->lo_addr
.iabuf
,
4423 l
->cidrnet
.lo_addr
.iabuf
, 16) == 0))
4429 if ((reply
->old_ia
== NULL
) ||
4430 (reply
->old_ia
->num_iasubopt
== 0))
4433 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4434 struct iasubopt
*tmp
;
4436 tmp
= reply
->old_ia
->iasubopt
[i
];
4438 if ((pref
->bits
== (int) tmp
->plen
) &&
4439 (memcmp(pref
->lo_addr
.iabuf
, &tmp
->addr
, 16) == 0)) {
4440 if (lease6_usable(tmp
) == ISC_FALSE
) {
4444 pond
= tmp
->ipv6_pool
->ipv6_pond
;
4445 if (((pond
->prohibit_list
!= NULL
) &&
4446 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4447 ((pond
->permit_list
!= NULL
) &&
4448 (!permitted(reply
->packet
, pond
->permit_list
))))
4451 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
4460 * This function only returns failure on 'hard' failures. If it succeeds,
4461 * it will leave a prefix structure behind.
4464 reply_process_try_prefix(struct reply_state
*reply
,
4465 struct iaddrcidrnet
*pref
) {
4466 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
4467 struct ipv6_pool
*pool
= NULL
;
4468 struct ipv6_pond
*pond
= NULL
;
4470 struct data_string data_pref
;
4472 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
4473 (pref
== NULL
) || (reply
->lease
!= NULL
))
4474 return (DHCP_R_INVALIDARG
);
4477 * Do a quick walk through of the ponds and pools
4478 * to see if we have any prefix pools
4480 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4481 if (pond
->ipv6_pools
== NULL
)
4484 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4485 if (pool
->pool_type
== D6O_IA_PD
)
4492 /* If we get here and p is NULL we have no useful pools */
4494 return (ISC_R_ADDRNOTAVAIL
);
4497 memset(&data_pref
, 0, sizeof(data_pref
));
4499 if (!buffer_allocate(&data_pref
.buffer
, data_pref
.len
, MDL
)) {
4500 log_error("reply_process_try_prefix: out of memory.");
4501 return (ISC_R_NOMEMORY
);
4503 data_pref
.data
= data_pref
.buffer
->data
;
4504 data_pref
.buffer
->data
[0] = (u_int8_t
) pref
->bits
;
4505 memcpy(data_pref
.buffer
->data
+ 1, pref
->lo_addr
.iabuf
, 16);
4508 * We have at least one pool that could provide a prefix
4509 * Now we walk through the ponds and pools again and check
4510 * to see if the client is permitted and if an prefix is
4515 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4516 if (((pond
->prohibit_list
!= NULL
) &&
4517 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4518 ((pond
->permit_list
!= NULL
) &&
4519 (!permitted(reply
->packet
, pond
->permit_list
))))
4522 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4523 if (pool
->pool_type
!= D6O_IA_PD
) {
4527 status
= try_client_v6_prefix(&reply
->lease
, pool
,
4529 /* If we found it in this pool (either in use or available),
4530 there is no need to look further. */
4531 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4534 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4538 data_string_forget(&data_pref
, MDL
);
4539 /* Return just the most recent status... */
4543 /* Look around for a prefix to give the client. First, look through the old
4544 * IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
4545 * Finally, actually add that prefix into the current reply IA_PD.
4548 find_client_prefix(struct reply_state
*reply
) {
4549 struct iaddrcidrnet send_pref
;
4550 isc_result_t status
= ISC_R_NORESOURCES
;
4551 struct iasubopt
*prefix
, *best_prefix
= NULL
;
4552 struct binding_scope
**scope
;
4554 struct group
*group
;
4556 if (reply
->static_prefixes
> 0) {
4557 struct iaddrcidrnetlist
*l
;
4559 if (reply
->host
== NULL
)
4560 return DHCP_R_INVALIDARG
;
4562 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4563 if (l
->cidrnet
.bits
== reply
->preflen
)
4568 * If no fixed prefix has the preferred length,
4569 * get the first one.
4571 l
= reply
->host
->fixed_prefix
;
4573 memcpy(&send_pref
, &l
->cidrnet
, sizeof(send_pref
));
4575 scope
= &global_scope
;
4577 /* Copy the prefix for logging purposes */
4578 memcpy(&reply
->fixed_pref
, &l
->cidrnet
, sizeof(send_pref
));
4580 /* Try to find a group for the static prefix */
4581 group
= find_group_by_prefix(reply
);
4586 if (reply
->old_ia
!= NULL
) {
4587 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4588 struct shared_network
*candidate_shared
;
4589 struct ipv6_pond
*pond
;
4591 prefix
= reply
->old_ia
->iasubopt
[i
];
4592 candidate_shared
= prefix
->ipv6_pool
->shared_network
;
4593 pond
= prefix
->ipv6_pool
->ipv6_pond
;
4596 * Consider this prefix if it is in a global pool or
4597 * if it is scoped in a pool under the client's shared
4600 if (((candidate_shared
!= NULL
) &&
4601 (candidate_shared
!= reply
->shared
)) ||
4602 (lease6_usable(prefix
) != ISC_TRUE
))
4606 * And check if the prefix is still permitted
4609 if (((pond
->prohibit_list
!= NULL
) &&
4610 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4611 ((pond
->permit_list
!= NULL
) &&
4612 (!permitted(reply
->packet
, pond
->permit_list
))))
4615 best_prefix
= prefix_compare(reply
, prefix
,
4620 /* Try to pick a new prefix if we didn't find one, or if we found an
4623 if ((best_prefix
== NULL
) || (best_prefix
->state
== FTS_ABANDONED
)) {
4624 status
= pick_v6_prefix(reply
);
4625 } else if (best_prefix
!= NULL
) {
4626 iasubopt_reference(&reply
->lease
, best_prefix
, MDL
);
4627 status
= ISC_R_SUCCESS
;
4630 /* Pick the abandoned prefix as a last resort. */
4631 if ((status
== ISC_R_NORESOURCES
) && (best_prefix
!= NULL
)) {
4632 /* I don't see how this is supposed to be done right now. */
4633 log_error("Reclaiming abandoned prefixes is not yet "
4634 "supported. Treating this as an out of space "
4636 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
4639 /* Give up now if we didn't find a prefix. */
4640 if (status
!= ISC_R_SUCCESS
)
4643 if (reply
->lease
== NULL
)
4644 log_fatal("Impossible condition at %s:%d.", MDL
);
4646 scope
= &reply
->lease
->scope
;
4647 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4649 send_pref
.lo_addr
.len
= 16;
4650 memcpy(send_pref
.lo_addr
.iabuf
, &reply
->lease
->addr
, 16);
4651 send_pref
.bits
= (int) reply
->lease
->plen
;
4654 status
= reply_process_is_prefixed(reply
, scope
, group
);
4655 if (status
!= ISC_R_SUCCESS
)
4658 status
= reply_process_send_prefix(reply
, &send_pref
);
4662 /* Once a prefix is found for a client, perform several common functions;
4663 * Calculate and store valid and preferred prefix times, draw client options
4664 * into the option state.
4667 reply_process_is_prefixed(struct reply_state
*reply
,
4668 struct binding_scope
**scope
, struct group
*group
)
4670 isc_result_t status
= ISC_R_SUCCESS
;
4671 struct data_string data
;
4672 struct option_cache
*oc
;
4673 struct option_state
*tmp_options
= NULL
;
4674 struct on_star
*on_star
;
4677 /* Initialize values we will cleanup. */
4678 memset(&data
, 0, sizeof(data
));
4681 * Find the proper on_star block to use. We use the
4682 * one in the lease if we have a lease or the one in
4683 * the reply if we don't have a lease because this is
4687 on_star
= &reply
->lease
->on_star
;
4689 on_star
= &reply
->on_star
;
4693 * Bring in the root configuration. We only do this to bring
4694 * in the on * statements, as we didn't have the lease available
4695 * we we did it the first time.
4697 option_state_allocate(&tmp_options
, MDL
);
4698 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4699 reply
->packet
->options
, tmp_options
,
4700 &global_scope
, root_group
, NULL
,
4702 if (tmp_options
!= NULL
) {
4703 option_state_dereference(&tmp_options
, MDL
);
4707 * Bring configured options into the root packet level cache - start
4708 * with the lease's closest enclosing group (passed in by the caller
4711 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4712 reply
->packet
->options
, reply
->opt_state
,
4713 scope
, group
, root_group
, on_star
);
4715 /* Execute statements from class scopes. */
4716 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
4717 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4718 reply
->packet
->options
,
4719 reply
->opt_state
, scope
,
4720 reply
->packet
->classes
[i
- 1]->group
,
4725 * If there is a host record, over-ride with values configured there,
4726 * without re-evaluating configuration from the previously executed
4727 * group or its common enclosers.
4729 if (reply
->host
!= NULL
)
4730 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4731 reply
->packet
->options
,
4732 reply
->opt_state
, scope
,
4733 reply
->host
->group
, group
,
4736 /* Determine valid lifetime. */
4737 if (reply
->client_valid
== 0)
4738 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
4740 reply
->send_valid
= reply
->client_valid
;
4742 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4743 SV_DEFAULT_LEASE_TIME
);
4745 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4746 reply
->packet
->options
,
4750 log_error("reply_process_is_prefixed: unable to "
4751 "evaluate default prefix time");
4752 status
= ISC_R_FAILURE
;
4756 reply
->send_valid
= getULong(data
.data
);
4757 data_string_forget(&data
, MDL
);
4760 /* Check to see if the lease time would cause us to wrap
4761 * in which case we make it infinite.
4762 * The following doesn't work on at least some systems:
4763 * (cur_time + reply->send_valid < cur_time)
4765 if (reply
->send_valid
!= 0xFFFFFFFF) {
4766 time_t test_time
= cur_time
+ reply
->send_valid
;
4767 if (test_time
< cur_time
)
4768 reply
->send_valid
= 0xFFFFFFFF;
4771 if (reply
->client_prefer
== 0)
4772 reply
->send_prefer
= reply
->send_valid
;
4774 reply
->send_prefer
= reply
->client_prefer
;
4776 if ((reply
->send_prefer
>= reply
->send_valid
) &&
4777 (reply
->send_valid
!= 0xFFFFFFFF))
4778 reply
->send_prefer
= (reply
->send_valid
/ 2) +
4779 (reply
->send_valid
/ 8);
4781 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4782 SV_PREFER_LIFETIME
);
4784 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4785 reply
->packet
->options
,
4789 log_error("reply_process_is_prefixed: unable to "
4790 "evaluate preferred prefix time");
4791 status
= ISC_R_FAILURE
;
4795 reply
->send_prefer
= getULong(data
.data
);
4796 data_string_forget(&data
, MDL
);
4799 /* Note lowest values for later calculation of renew/rebind times. */
4800 if (reply
->min_prefer
> reply
->send_prefer
)
4801 reply
->min_prefer
= reply
->send_prefer
;
4803 if (reply
->min_valid
> reply
->send_valid
)
4804 reply
->min_valid
= reply
->send_valid
;
4806 /* Perform dynamic prefix related update work. */
4807 if (reply
->lease
!= NULL
) {
4808 /* Cached lifetimes */
4809 reply
->lease
->prefer
= reply
->send_prefer
;
4810 reply
->lease
->valid
= reply
->send_valid
;
4812 /* Advance (or rewind) the valid lifetime.
4813 * In the protocol 0xFFFFFFFF is infinite
4814 * when connecting to the lease file MAX_TIME is
4816 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
4817 if (reply
->send_valid
== 0xFFFFFFFF) {
4818 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
4820 reply
->lease
->soft_lifetime_end_time
=
4821 cur_time
+ reply
->send_valid
;
4823 /* Wait before renew! */
4826 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
4827 if (status
!= ISC_R_SUCCESS
) {
4828 log_fatal("reply_process_is_prefixed: Unable to "
4829 "attach prefix to new IA_PD: %s",
4830 isc_result_totext(status
));
4834 * If this is a new prefix, make sure it is attached somewhere.
4836 if (reply
->lease
->ia
== NULL
) {
4837 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
4841 /* Bring a copy of the relevant options into the IA_PD scope. */
4842 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4843 reply
->packet
->options
, reply
->reply_ia
,
4844 scope
, group
, root_group
, NULL
);
4846 /* Execute statements from class scopes. */
4847 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
4848 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4849 reply
->packet
->options
,
4850 reply
->reply_ia
, scope
,
4851 reply
->packet
->classes
[i
- 1]->group
,
4856 * And bring in host record configuration, if any, but not to overlap
4857 * the previous group or its common enclosers.
4859 if (reply
->host
!= NULL
)
4860 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4861 reply
->packet
->options
,
4862 reply
->reply_ia
, scope
,
4863 reply
->host
->group
, group
, NULL
);
4866 if (data
.data
!= NULL
)
4867 data_string_forget(&data
, MDL
);
4869 if (status
== ISC_R_SUCCESS
)
4870 reply
->client_resources
++;
4875 /* Simply send an IAPREFIX within the IA_PD scope as described. */
4877 reply_process_send_prefix(struct reply_state
*reply
,
4878 struct iaddrcidrnet
*pref
) {
4879 isc_result_t status
= ISC_R_SUCCESS
;
4880 struct data_string data
;
4882 memset(&data
, 0, sizeof(data
));
4884 /* Now append the prefix. */
4885 data
.len
= IAPREFIX_OFFSET
;
4886 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
4887 log_error("reply_process_send_prefix: out of memory"
4888 "allocating new IAPREFIX buffer.");
4889 status
= ISC_R_NOMEMORY
;
4892 data
.data
= data
.buffer
->data
;
4894 putULong(data
.buffer
->data
, reply
->send_prefer
);
4895 putULong(data
.buffer
->data
+ 4, reply
->send_valid
);
4896 data
.buffer
->data
[8] = pref
->bits
;
4897 memcpy(data
.buffer
->data
+ 9, pref
->lo_addr
.iabuf
, 16);
4899 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
4900 data
.buffer
, data
.buffer
->data
,
4901 data
.len
, D6O_IAPREFIX
, 0)) {
4902 log_error("reply_process_send_prefix: unable "
4903 "to save IAPREFIX option");
4904 status
= ISC_R_FAILURE
;
4908 reply
->resources_included
= ISC_TRUE
;
4911 if (data
.data
!= NULL
)
4912 data_string_forget(&data
, MDL
);
4917 /* Choose the better of two prefixes. */
4918 static struct iasubopt
*
4919 prefix_compare(struct reply_state
*reply
,
4920 struct iasubopt
*alpha
, struct iasubopt
*beta
) {
4926 if (reply
->preflen
>= 0) {
4927 if ((alpha
->plen
== reply
->preflen
) &&
4928 (beta
->plen
!= reply
->preflen
))
4930 if ((beta
->plen
== reply
->preflen
) &&
4931 (alpha
->plen
!= reply
->preflen
))
4935 switch(alpha
->state
) {
4937 switch(beta
->state
) {
4939 /* Choose the prefix with the longest lifetime (most
4940 * likely the most recently allocated).
4942 if (alpha
->hard_lifetime_end_time
<
4943 beta
->hard_lifetime_end_time
)
4953 log_fatal("Impossible condition at %s:%d.", MDL
);
4958 switch (beta
->state
) {
4963 /* Choose the most recently expired prefix. */
4964 if (alpha
->hard_lifetime_end_time
<
4965 beta
->hard_lifetime_end_time
)
4967 else if ((alpha
->hard_lifetime_end_time
==
4968 beta
->hard_lifetime_end_time
) &&
4969 (alpha
->soft_lifetime_end_time
<
4970 beta
->soft_lifetime_end_time
))
4979 log_fatal("Impossible condition at %s:%d.", MDL
);
4984 switch (beta
->state
) {
4990 /* Choose the prefix that was abandoned longest ago. */
4991 if (alpha
->hard_lifetime_end_time
<
4992 beta
->hard_lifetime_end_time
)
4998 log_fatal("Impossible condition at %s:%d.", MDL
);
5003 log_fatal("Impossible condition at %s:%d.", MDL
);
5006 log_fatal("Triple impossible condition at %s:%d.", MDL
);
5011 * Solicit is how a client starts requesting addresses.
5013 * If the client asks for rapid commit, and we support it, we will
5014 * allocate the addresses and reply.
5016 * Otherwise we will send an advertise message.
5020 dhcpv6_solicit(struct data_string
*reply_ret
, struct packet
*packet
) {
5021 struct data_string client_id
;
5024 * Validate our input.
5026 if (!valid_client_msg(packet
, &client_id
)) {
5030 lease_to_client(reply_ret
, packet
, &client_id
, NULL
);
5035 data_string_forget(&client_id
, MDL
);
5039 * Request is how a client actually requests addresses.
5041 * Very similar to Solicit handling, except the server DUID is required.
5045 dhcpv6_request(struct data_string
*reply_ret
, struct packet
*packet
) {
5046 struct data_string client_id
;
5047 struct data_string server_id
;
5050 * Validate our input.
5052 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5056 /* If the REQUEST arrived via unicast and unicast option isn't set,
5057 * reject it per RFC 3315, Sec 18.2.1 */
5058 if (packet
->unicast
== ISC_TRUE
&&
5059 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5060 unicast_reject(reply_ret
, packet
, &client_id
, &server_id
);
5065 lease_to_client(reply_ret
, packet
, &client_id
, &server_id
);
5071 data_string_forget(&client_id
, MDL
);
5072 data_string_forget(&server_id
, MDL
);
5075 /* Find a DHCPv6 packet's shared network from hints in the packet.
5078 shared_network_from_packet6(struct shared_network
**shared
,
5079 struct packet
*packet
)
5081 const struct packet
*chk_packet
;
5082 const struct in6_addr
*link_addr
, *first_link_addr
;
5083 struct iaddr tmp_addr
;
5084 struct subnet
*subnet
;
5085 isc_result_t status
;
5087 if ((shared
== NULL
) || (*shared
!= NULL
) || (packet
== NULL
))
5088 return DHCP_R_INVALIDARG
;
5091 * First, find the link address where the packet from the client
5092 * first appeared (if this packet was relayed).
5094 first_link_addr
= NULL
;
5095 chk_packet
= packet
->dhcpv6_container_packet
;
5096 while (chk_packet
!= NULL
) {
5097 link_addr
= &chk_packet
->dhcpv6_link_address
;
5098 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
5099 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
5100 first_link_addr
= link_addr
;
5103 chk_packet
= chk_packet
->dhcpv6_container_packet
;
5107 * If there is a relayed link address, find the subnet associated
5108 * with that, and use that to get the appropriate
5111 if (first_link_addr
!= NULL
) {
5112 tmp_addr
.len
= sizeof(*first_link_addr
);
5113 memcpy(tmp_addr
.iabuf
,
5114 first_link_addr
, sizeof(*first_link_addr
));
5116 if (!find_subnet(&subnet
, tmp_addr
, MDL
)) {
5117 log_debug("No subnet found for link-address %s.",
5119 return ISC_R_NOTFOUND
;
5121 status
= shared_network_reference(shared
,
5122 subnet
->shared_network
, MDL
);
5123 subnet_dereference(&subnet
, MDL
);
5126 * If there is no link address, we will use the interface
5127 * that this packet came in on to pick the shared_network.
5129 } else if (packet
->interface
!= NULL
) {
5130 status
= shared_network_reference(shared
,
5131 packet
->interface
->shared_network
,
5133 if (packet
->dhcpv6_container_packet
!= NULL
) {
5134 log_info("[L2 Relay] No link address in relay packet "
5135 "assuming L2 relay and using receiving "
5141 * We shouldn't be able to get here but if there is no link
5142 * address and no interface we don't know where to get the
5143 * pool from log an error and return an error.
5145 log_error("No interface and no link address "
5146 "can't determine pool");
5147 status
= DHCP_R_INVALIDARG
;
5154 * When a client thinks it might be on a new link, it sends a
5157 * From RFC3315 section 18.2.2:
5159 * When the server receives a Confirm message, the server determines
5160 * whether the addresses in the Confirm message are appropriate for the
5161 * link to which the client is attached. If all of the addresses in the
5162 * Confirm message pass this test, the server returns a status of
5163 * Success. If any of the addresses do not pass this test, the server
5164 * returns a status of NotOnLink. If the server is unable to perform
5165 * this test (for example, the server does not have information about
5166 * prefixes on the link to which the client is connected), or there were
5167 * no addresses in any of the IAs sent by the client, the server MUST
5168 * NOT send a reply to the client.
5172 dhcpv6_confirm(struct data_string
*reply_ret
, struct packet
*packet
) {
5173 struct shared_network
*shared
;
5174 struct subnet
*subnet
;
5175 struct option_cache
*ia
, *ta
, *oc
;
5176 struct data_string cli_enc_opt_data
, iaaddr
, client_id
, packet_oro
;
5177 struct option_state
*cli_enc_opt_state
, *opt_state
;
5178 struct iaddr cli_addr
;
5180 isc_boolean_t inappropriate
, has_addrs
;
5181 char reply_data
[65536];
5182 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5183 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5186 * Basic client message validation.
5188 memset(&client_id
, 0, sizeof(client_id
));
5189 if (!valid_client_msg(packet
, &client_id
)) {
5194 * Do not process Confirms that do not have IA's we do not recognize.
5196 ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5197 ta
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
5198 if ((ia
== NULL
) && (ta
== NULL
))
5202 * IA_PD's are simply ignored.
5204 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5207 * Bit of variable initialization.
5209 opt_state
= cli_enc_opt_state
= NULL
;
5210 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5211 memset(&iaaddr
, 0, sizeof(iaaddr
));
5212 memset(&packet_oro
, 0, sizeof(packet_oro
));
5214 /* Determine what shared network the client is connected to. We
5215 * must not respond if we don't have any information about the
5216 * network the client is on.
5219 if ((shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
) ||
5223 /* If there are no recorded subnets, then we have no
5224 * information about this subnet - ignore Confirms.
5226 subnet
= shared
->subnets
;
5230 /* Are the addresses in all the IA's appropriate for that link? */
5231 has_addrs
= inappropriate
= ISC_FALSE
;
5233 while(!inappropriate
) {
5234 /* If we've reached the end of the IA_NA pass, move to the
5237 if ((pass
== D6O_IA_NA
) && (ia
== NULL
)) {
5242 /* If we've reached the end of all passes, we're done. */
5246 if (((pass
== D6O_IA_NA
) &&
5247 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5249 packet
, ia
, IA_NA_OFFSET
)) ||
5250 ((pass
== D6O_IA_TA
) &&
5251 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5253 packet
, ia
, IA_TA_OFFSET
))) {
5257 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5260 for ( ; oc
!= NULL
; oc
= oc
->next
) {
5261 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5262 packet
->options
, NULL
,
5263 &global_scope
, oc
, MDL
) ||
5264 (iaaddr
.len
< IAADDR_OFFSET
)) {
5265 log_error("dhcpv6_confirm: "
5266 "error evaluating IAADDR.");
5270 /* Copy out the IPv6 address for processing. */
5272 memcpy(cli_addr
.iabuf
, iaaddr
.data
, 16);
5274 data_string_forget(&iaaddr
, MDL
);
5276 /* Record that we've processed at least one address. */
5277 has_addrs
= ISC_TRUE
;
5279 /* Find out if any subnets cover this address. */
5280 for (subnet
= shared
->subnets
; subnet
!= NULL
;
5281 subnet
= subnet
->next_sibling
) {
5282 if (addr_eq(subnet_number(cli_addr
,
5288 /* If we reach the end of the subnet list, and no
5289 * subnet matches the client address, then it must
5290 * be inappropriate to the link (so far as our
5291 * configuration says). Once we've found one
5292 * inappropriate address, there is no reason to
5293 * continue searching.
5295 if (subnet
== NULL
) {
5296 inappropriate
= ISC_TRUE
;
5301 option_state_dereference(&cli_enc_opt_state
, MDL
);
5302 data_string_forget(&cli_enc_opt_data
, MDL
);
5304 /* Advance to the next IA_*. */
5308 /* If the client supplied no addresses, do not reply. */
5315 if (!start_reply(packet
, &client_id
, NULL
, &opt_state
, reply
)) {
5322 if (inappropriate
) {
5323 if (!set_status_code(STATUS_NotOnLink
,
5324 "Some of the addresses are not on link.",
5329 if (!set_status_code(STATUS_Success
,
5330 "All addresses still on link.",
5337 * Only one option: add it.
5339 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5340 sizeof(reply_data
)-reply_ofs
,
5342 required_opts
, &packet_oro
);
5345 * Return our reply to the caller.
5347 reply_ret
->len
= reply_ofs
;
5348 reply_ret
->buffer
= NULL
;
5349 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5350 log_fatal("No memory to store reply.");
5352 reply_ret
->data
= reply_ret
->buffer
->data
;
5353 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5356 /* Cleanup any stale data strings. */
5357 if (cli_enc_opt_data
.buffer
!= NULL
)
5358 data_string_forget(&cli_enc_opt_data
, MDL
);
5359 if (iaaddr
.buffer
!= NULL
)
5360 data_string_forget(&iaaddr
, MDL
);
5361 if (client_id
.buffer
!= NULL
)
5362 data_string_forget(&client_id
, MDL
);
5363 if (packet_oro
.buffer
!= NULL
)
5364 data_string_forget(&packet_oro
, MDL
);
5366 /* Release any stale option states. */
5367 if (cli_enc_opt_state
!= NULL
)
5368 option_state_dereference(&cli_enc_opt_state
, MDL
);
5369 if (opt_state
!= NULL
)
5370 option_state_dereference(&opt_state
, MDL
);
5374 * Renew is when a client wants to extend its lease/prefix, at time T1.
5376 * We handle this the same as if the client wants a new lease/prefix,
5377 * except for the error code of when addresses don't match.
5381 dhcpv6_renew(struct data_string
*reply
, struct packet
*packet
) {
5382 struct data_string client_id
;
5383 struct data_string server_id
;
5386 * Validate the request.
5388 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5392 /* If the RENEW arrived via unicast and unicast option isn't set,
5393 * reject it per RFC 3315, Sec 18.2.3 */
5394 if (packet
->unicast
== ISC_TRUE
&&
5395 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5396 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5401 lease_to_client(reply
, packet
, &client_id
, &server_id
);
5407 data_string_forget(&server_id
, MDL
);
5408 data_string_forget(&client_id
, MDL
);
5412 * Rebind is when a client wants to extend its lease, at time T2.
5414 * We handle this the same as if the client wants a new lease, except
5415 * for the error code of when addresses don't match.
5419 dhcpv6_rebind(struct data_string
*reply
, struct packet
*packet
) {
5420 struct data_string client_id
;
5422 if (!valid_client_msg(packet
, &client_id
)) {
5426 lease_to_client(reply
, packet
, &client_id
, NULL
);
5428 data_string_forget(&client_id
, MDL
);
5432 ia_na_match_decline(const struct data_string
*client_id
,
5433 const struct data_string
*iaaddr
,
5434 struct iasubopt
*lease
)
5436 char tmp_addr
[INET6_ADDRSTRLEN
];
5438 log_error("Client %s reports address %s is "
5439 "already in use by another host!",
5440 print_hex_1(client_id
->len
, client_id
->data
, 60),
5441 inet_ntop(AF_INET6
, iaaddr
->data
,
5442 tmp_addr
, sizeof(tmp_addr
)));
5443 if (lease
!= NULL
) {
5444 decline_lease6(lease
->ipv6_pool
, lease
);
5445 lease
->ia
->cltt
= cur_time
;
5446 write_ia(lease
->ia
);
5451 ia_na_nomatch_decline(const struct data_string
*client_id
,
5452 const struct data_string
*iaaddr
,
5453 u_int32_t
*ia_na_id
,
5454 struct packet
*packet
,
5459 char tmp_addr
[INET6_ADDRSTRLEN
];
5460 struct option_state
*host_opt_state
;
5463 log_info("Client %s declines address %s, which is not offered to it.",
5464 print_hex_1(client_id
->len
, client_id
->data
, 60),
5465 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5468 * Create state for this IA_NA.
5470 host_opt_state
= NULL
;
5471 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5472 log_error("ia_na_nomatch_decline: out of memory "
5473 "allocating option_state.");
5477 if (!set_status_code(STATUS_NoBinding
, "Decline for unknown address.",
5483 * Insure we have enough space
5485 if (reply_len
< (*reply_ofs
+ 16)) {
5486 log_error("ia_na_nomatch_decline: "
5487 "out of space for reply packet.");
5492 * Put our status code into the reply packet.
5494 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5495 reply_len
-(*reply_ofs
)-16,
5496 host_opt_state
, packet
,
5497 required_opts_STATUS_CODE
, NULL
);
5500 * Store the non-encapsulated option data for this
5501 * IA_NA into our reply packet. Defined in RFC 3315,
5505 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5507 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5508 /* IA_NA, copied from the client */
5509 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5510 /* t1 and t2, odd that we need them, but here it is */
5511 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5512 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5515 * Get ready for next IA_NA.
5517 *reply_ofs
+= (len
+ 16);
5520 option_state_dereference(&host_opt_state
, MDL
);
5524 iterate_over_ia_na(struct data_string
*reply_ret
,
5525 struct packet
*packet
,
5526 const struct data_string
*client_id
,
5527 const struct data_string
*server_id
,
5528 const char *packet_type
,
5529 void (*ia_na_match
)(),
5530 void (*ia_na_nomatch
)())
5532 struct option_state
*opt_state
;
5533 struct host_decl
*packet_host
;
5534 struct option_cache
*ia
;
5535 struct option_cache
*oc
;
5536 /* cli_enc_... variables come from the IA_NA/IA_TA options */
5537 struct data_string cli_enc_opt_data
;
5538 struct option_state
*cli_enc_opt_state
;
5539 struct host_decl
*host
;
5540 struct data_string iaaddr
;
5541 struct data_string fixed_addr
;
5542 char reply_data
[65536];
5543 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5544 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5545 char status_msg
[32];
5546 struct iasubopt
*lease
;
5547 struct ia_xx
*existing_ia_na
;
5549 struct data_string key
;
5553 * Initialize to empty values, in case we have to exit early.
5556 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5557 cli_enc_opt_state
= NULL
;
5558 memset(&iaaddr
, 0, sizeof(iaaddr
));
5559 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
5563 * Find the host record that matches from the packet, if any.
5566 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
5569 * Set our reply information.
5571 reply
->msg_type
= DHCPV6_REPLY
;
5572 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
5573 sizeof(reply
->transaction_id
));
5576 * Build our option state for reply.
5579 if (!option_state_allocate(&opt_state
, MDL
)) {
5580 log_error("iterate_over_ia_na: no memory for option_state.");
5583 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5584 packet
->options
, opt_state
,
5585 &global_scope
, root_group
, NULL
, NULL
);
5588 * RFC 3315, section 18.2.7 tells us which options to include.
5590 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
5592 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5593 (unsigned char *)server_duid
.data
,
5594 server_duid
.len
, D6O_SERVERID
, 0)) {
5595 log_error("iterate_over_ia_na: "
5596 "error saving server identifier.");
5601 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
5603 (unsigned char *)client_id
->data
,
5606 log_error("iterate_over_ia_na: "
5607 "error saving client identifier.");
5611 snprintf(status_msg
, sizeof(status_msg
), "%s received.", packet_type
);
5612 if (!set_status_code(STATUS_Success
, status_msg
, opt_state
)) {
5617 * Add our options that are not associated with any IA_NA or IA_TA.
5619 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5620 sizeof(reply_data
)-reply_ofs
,
5622 required_opts
, NULL
);
5625 * Loop through the IA_NA reported by the client, and deal with
5626 * addresses reported as already in use.
5628 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5629 ia
!= NULL
; ia
= ia
->next
) {
5631 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
5633 packet
, ia
, IA_NA_OFFSET
)) {
5637 iaid
= getULong(cli_enc_opt_data
.data
);
5640 * XXX: It is possible that we can get multiple addresses
5641 * sent by the client. We don't send multiple
5642 * addresses, so this indicates a client error.
5643 * We should check for multiple IAADDR options, log
5644 * if found, and set as an error.
5646 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5649 /* no address given for this IA, ignore */
5650 option_state_dereference(&cli_enc_opt_state
, MDL
);
5651 data_string_forget(&cli_enc_opt_data
, MDL
);
5655 memset(&iaaddr
, 0, sizeof(iaaddr
));
5656 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5657 packet
->options
, NULL
,
5658 &global_scope
, oc
, MDL
)) {
5659 log_error("iterate_over_ia_na: "
5660 "error evaluating IAADDR.");
5665 * Now we need to figure out which host record matches
5666 * this IA_NA and IAADDR (encapsulated option contents
5667 * matching a host record by option).
5669 * XXX: We don't currently track IA_NA separately, but
5670 * we will need to do this!
5673 if (!find_hosts_by_option(&host
, packet
,
5674 cli_enc_opt_state
, MDL
)) {
5675 if (packet_host
!= NULL
) {
5681 while (host
!= NULL
) {
5682 if (host
->fixed_addr
!= NULL
) {
5683 if (!evaluate_option_cache(&fixed_addr
, NULL
,
5685 NULL
, &global_scope
,
5688 log_error("iterate_over_ia_na: error "
5689 "evaluating host address.");
5692 if ((iaaddr
.len
>= 16) &&
5693 !memcmp(fixed_addr
.data
, iaaddr
.data
, 16)) {
5694 data_string_forget(&fixed_addr
, MDL
);
5697 data_string_forget(&fixed_addr
, MDL
);
5699 host
= host
->n_ipaddr
;
5702 if ((host
== NULL
) && (iaaddr
.len
>= IAADDR_OFFSET
)) {
5704 * Find existing IA_NA.
5706 if (ia_make_key(&key
, iaid
,
5707 (char *)client_id
->data
,
5709 MDL
) != ISC_R_SUCCESS
) {
5710 log_fatal("iterate_over_ia_na: no memory for "
5714 existing_ia_na
= NULL
;
5715 if (ia_hash_lookup(&existing_ia_na
, ia_na_active
,
5716 (unsigned char *)key
.data
,
5719 * Make sure this address is in the IA_NA.
5721 for (i
=0; i
<existing_ia_na
->num_iasubopt
; i
++) {
5722 struct iasubopt
*tmp
;
5723 struct in6_addr
*in6_addr
;
5725 tmp
= existing_ia_na
->iasubopt
[i
];
5726 in6_addr
= &tmp
->addr
;
5727 if (memcmp(in6_addr
,
5728 iaaddr
.data
, 16) == 0) {
5729 iasubopt_reference(&lease
,
5736 data_string_forget(&key
, MDL
);
5739 if ((host
!= NULL
) || (lease
!= NULL
)) {
5740 ia_na_match(client_id
, &iaaddr
, lease
);
5742 ia_na_nomatch(client_id
, &iaaddr
,
5743 (u_int32_t
*)cli_enc_opt_data
.data
,
5744 packet
, reply_data
, &reply_ofs
,
5745 sizeof(reply_data
));
5748 if (lease
!= NULL
) {
5749 iasubopt_dereference(&lease
, MDL
);
5752 data_string_forget(&iaaddr
, MDL
);
5753 option_state_dereference(&cli_enc_opt_state
, MDL
);
5754 data_string_forget(&cli_enc_opt_data
, MDL
);
5758 * Return our reply to the caller.
5760 reply_ret
->len
= reply_ofs
;
5761 reply_ret
->buffer
= NULL
;
5762 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5763 log_fatal("No memory to store reply.");
5765 reply_ret
->data
= reply_ret
->buffer
->data
;
5766 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5769 if (lease
!= NULL
) {
5770 iasubopt_dereference(&lease
, MDL
);
5772 if (fixed_addr
.buffer
!= NULL
) {
5773 data_string_forget(&fixed_addr
, MDL
);
5775 if (iaaddr
.buffer
!= NULL
) {
5776 data_string_forget(&iaaddr
, MDL
);
5778 if (cli_enc_opt_state
!= NULL
) {
5779 option_state_dereference(&cli_enc_opt_state
, MDL
);
5781 if (cli_enc_opt_data
.buffer
!= NULL
) {
5782 data_string_forget(&cli_enc_opt_data
, MDL
);
5784 if (opt_state
!= NULL
) {
5785 option_state_dereference(&opt_state
, MDL
);
5790 * Decline means a client has detected that something else is using an
5791 * address we gave it.
5793 * Since we're only dealing with fixed leases for now, there's not
5794 * much we can do, other that log the occurrence.
5796 * When we start issuing addresses from pools, then we will have to
5797 * record our declined addresses and issue another. In general with
5798 * IPv6 there is no worry about DoS by clients exhausting space, but
5799 * we still need to be aware of this possibility.
5804 dhcpv6_decline(struct data_string
*reply
, struct packet
*packet
) {
5805 struct data_string client_id
;
5806 struct data_string server_id
;
5809 * Validate our input.
5811 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5815 /* If the DECLINE arrived via unicast and unicast option isn't set,
5816 * reject it per RFC 3315, Sec 18.2.7 */
5817 if (packet
->unicast
== ISC_TRUE
&&
5818 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5819 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5822 * Undefined for IA_PD.
5824 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5827 * And operate on each IA_NA in this packet.
5829 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
5830 "Decline", ia_na_match_decline
,
5831 ia_na_nomatch_decline
);
5835 data_string_forget(&server_id
, MDL
);
5836 data_string_forget(&client_id
, MDL
);
5840 ia_na_match_release(const struct data_string
*client_id
,
5841 const struct data_string
*iaaddr
,
5842 struct iasubopt
*lease
)
5844 char tmp_addr
[INET6_ADDRSTRLEN
];
5846 log_info("Client %s releases address %s",
5847 print_hex_1(client_id
->len
, client_id
->data
, 60),
5848 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5849 if (lease
!= NULL
) {
5850 release_lease6(lease
->ipv6_pool
, lease
);
5851 lease
->ia
->cltt
= cur_time
;
5852 write_ia(lease
->ia
);
5857 ia_na_nomatch_release(const struct data_string
*client_id
,
5858 const struct data_string
*iaaddr
,
5859 u_int32_t
*ia_na_id
,
5860 struct packet
*packet
,
5865 char tmp_addr
[INET6_ADDRSTRLEN
];
5866 struct option_state
*host_opt_state
;
5869 log_info("Client %s releases address %s, which is not leased to it.",
5870 print_hex_1(client_id
->len
, client_id
->data
, 60),
5871 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5874 * Create state for this IA_NA.
5876 host_opt_state
= NULL
;
5877 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5878 log_error("ia_na_nomatch_release: out of memory "
5879 "allocating option_state.");
5883 if (!set_status_code(STATUS_NoBinding
,
5884 "Release for non-leased address.",
5890 * Insure we have enough space
5892 if (reply_len
< (*reply_ofs
+ 16)) {
5893 log_error("ia_na_nomatch_release: "
5894 "out of space for reply packet.");
5899 * Put our status code into the reply packet.
5901 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5902 reply_len
-(*reply_ofs
)-16,
5903 host_opt_state
, packet
,
5904 required_opts_STATUS_CODE
, NULL
);
5907 * Store the non-encapsulated option data for this
5908 * IA_NA into our reply packet. Defined in RFC 3315,
5912 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5914 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5915 /* IA_NA, copied from the client */
5916 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5917 /* t1 and t2, odd that we need them, but here it is */
5918 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5919 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5922 * Get ready for next IA_NA.
5924 *reply_ofs
+= (len
+ 16);
5927 option_state_dereference(&host_opt_state
, MDL
);
5931 ia_pd_match_release(const struct data_string
*client_id
,
5932 const struct data_string
*iapref
,
5933 struct iasubopt
*prefix
)
5935 char tmp_addr
[INET6_ADDRSTRLEN
];
5937 log_info("Client %s releases prefix %s/%u",
5938 print_hex_1(client_id
->len
, client_id
->data
, 60),
5939 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5940 tmp_addr
, sizeof(tmp_addr
)),
5941 (unsigned) getUChar(iapref
->data
+ 8));
5942 if (prefix
!= NULL
) {
5943 release_lease6(prefix
->ipv6_pool
, prefix
);
5944 prefix
->ia
->cltt
= cur_time
;
5945 write_ia(prefix
->ia
);
5950 ia_pd_nomatch_release(const struct data_string
*client_id
,
5951 const struct data_string
*iapref
,
5952 u_int32_t
*ia_pd_id
,
5953 struct packet
*packet
,
5958 char tmp_addr
[INET6_ADDRSTRLEN
];
5959 struct option_state
*host_opt_state
;
5962 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
5963 print_hex_1(client_id
->len
, client_id
->data
, 60),
5964 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5965 tmp_addr
, sizeof(tmp_addr
)),
5966 (unsigned) getUChar(iapref
->data
+ 8));
5969 * Create state for this IA_PD.
5971 host_opt_state
= NULL
;
5972 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5973 log_error("ia_pd_nomatch_release: out of memory "
5974 "allocating option_state.");
5978 if (!set_status_code(STATUS_NoBinding
,
5979 "Release for non-leased prefix.",
5985 * Insure we have enough space
5987 if (reply_len
< (*reply_ofs
+ 16)) {
5988 log_error("ia_pd_nomatch_release: "
5989 "out of space for reply packet.");
5994 * Put our status code into the reply packet.
5996 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5997 reply_len
-(*reply_ofs
)-16,
5998 host_opt_state
, packet
,
5999 required_opts_STATUS_CODE
, NULL
);
6002 * Store the non-encapsulated option data for this
6003 * IA_PD into our reply packet. Defined in RFC 3315,
6007 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_PD
);
6009 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
6010 /* IA_PD, copied from the client */
6011 memcpy(reply_data
+(*reply_ofs
)+4, ia_pd_id
, 4);
6012 /* t1 and t2, odd that we need them, but here it is */
6013 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
6014 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
6017 * Get ready for next IA_PD.
6019 *reply_ofs
+= (len
+ 16);
6022 option_state_dereference(&host_opt_state
, MDL
);
6026 iterate_over_ia_pd(struct data_string
*reply_ret
,
6027 struct packet
*packet
,
6028 const struct data_string
*client_id
,
6029 const struct data_string
*server_id
,
6030 const char *packet_type
,
6031 void (*ia_pd_match
)(),
6032 void (*ia_pd_nomatch
)())
6034 struct data_string reply_new
;
6036 struct option_state
*opt_state
;
6037 struct host_decl
*packet_host
;
6038 struct option_cache
*ia
;
6039 struct option_cache
*oc
;
6040 /* cli_enc_... variables come from the IA_PD options */
6041 struct data_string cli_enc_opt_data
;
6042 struct option_state
*cli_enc_opt_state
;
6043 struct host_decl
*host
;
6044 struct data_string iaprefix
;
6045 char reply_data
[65536];
6047 struct iasubopt
*prefix
;
6048 struct ia_xx
*existing_ia_pd
;
6050 struct data_string key
;
6054 * Initialize to empty values, in case we have to exit early.
6056 memset(&reply_new
, 0, sizeof(reply_new
));
6058 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
6059 cli_enc_opt_state
= NULL
;
6060 memset(&iaprefix
, 0, sizeof(iaprefix
));
6064 * Compute the available length for the reply.
6066 reply_len
= sizeof(reply_data
) - reply_ret
->len
;
6070 * Find the host record that matches from the packet, if any.
6073 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
6076 * Build our option state for reply.
6079 if (!option_state_allocate(&opt_state
, MDL
)) {
6080 log_error("iterate_over_ia_pd: no memory for option_state.");
6083 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
6084 packet
->options
, opt_state
,
6085 &global_scope
, root_group
, NULL
, NULL
);
6088 * Loop through the IA_PD reported by the client, and deal with
6089 * prefixes reported as already in use.
6091 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
6092 ia
!= NULL
; ia
= ia
->next
) {
6094 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
6096 packet
, ia
, IA_PD_OFFSET
)) {
6100 iaid
= getULong(cli_enc_opt_data
.data
);
6102 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
6105 /* no prefix given for this IA_PD, ignore */
6106 option_state_dereference(&cli_enc_opt_state
, MDL
);
6107 data_string_forget(&cli_enc_opt_data
, MDL
);
6111 for (; oc
!= NULL
; oc
= oc
->next
) {
6112 memset(&iaprefix
, 0, sizeof(iaprefix
));
6113 if (!evaluate_option_cache(&iaprefix
, packet
, NULL
, NULL
,
6114 packet
->options
, NULL
,
6115 &global_scope
, oc
, MDL
)) {
6116 log_error("iterate_over_ia_pd: "
6117 "error evaluating IAPREFIX.");
6122 * Now we need to figure out which host record matches
6123 * this IA_PD and IAPREFIX (encapsulated option contents
6124 * matching a host record by option).
6126 * XXX: We don't currently track IA_PD separately, but
6127 * we will need to do this!
6130 if (!find_hosts_by_option(&host
, packet
,
6131 cli_enc_opt_state
, MDL
)) {
6132 if (packet_host
!= NULL
) {
6138 while (host
!= NULL
) {
6139 if (host
->fixed_prefix
!= NULL
) {
6140 struct iaddrcidrnetlist
*l
;
6141 int plen
= (int) getUChar(iaprefix
.data
+ 8);
6143 for (l
= host
->fixed_prefix
; l
!= NULL
;
6145 if (plen
!= l
->cidrnet
.bits
)
6147 if (memcmp(iaprefix
.data
+ 9,
6148 l
->cidrnet
.lo_addr
.iabuf
,
6152 if ((l
!= NULL
) && (iaprefix
.len
>= 17))
6155 host
= host
->n_ipaddr
;
6158 if ((host
== NULL
) && (iaprefix
.len
>= IAPREFIX_OFFSET
)) {
6160 * Find existing IA_PD.
6162 if (ia_make_key(&key
, iaid
,
6163 (char *)client_id
->data
,
6165 MDL
) != ISC_R_SUCCESS
) {
6166 log_fatal("iterate_over_ia_pd: no memory for "
6170 existing_ia_pd
= NULL
;
6171 if (ia_hash_lookup(&existing_ia_pd
, ia_pd_active
,
6172 (unsigned char *)key
.data
,
6175 * Make sure this prefix is in the IA_PD.
6178 i
< existing_ia_pd
->num_iasubopt
;
6180 struct iasubopt
*tmp
;
6183 plen
= getUChar(iaprefix
.data
+ 8);
6184 tmp
= existing_ia_pd
->iasubopt
[i
];
6185 if ((tmp
->plen
== plen
) &&
6189 iasubopt_reference(&prefix
,
6196 data_string_forget(&key
, MDL
);
6199 if ((host
!= NULL
) || (prefix
!= NULL
)) {
6200 ia_pd_match(client_id
, &iaprefix
, prefix
);
6202 ia_pd_nomatch(client_id
, &iaprefix
,
6203 (u_int32_t
*)cli_enc_opt_data
.data
,
6204 packet
, reply_data
, &reply_ofs
,
6205 reply_len
- reply_ofs
);
6208 if (prefix
!= NULL
) {
6209 iasubopt_dereference(&prefix
, MDL
);
6212 data_string_forget(&iaprefix
, MDL
);
6215 option_state_dereference(&cli_enc_opt_state
, MDL
);
6216 data_string_forget(&cli_enc_opt_data
, MDL
);
6220 * Return our reply to the caller.
6221 * The IA_NA routine has already filled at least the header.
6223 reply_new
.len
= reply_ret
->len
+ reply_ofs
;
6224 if (!buffer_allocate(&reply_new
.buffer
, reply_new
.len
, MDL
)) {
6225 log_fatal("No memory to store reply.");
6227 reply_new
.data
= reply_new
.buffer
->data
;
6228 memcpy(reply_new
.buffer
->data
,
6229 reply_ret
->buffer
->data
, reply_ret
->len
);
6230 memcpy(reply_new
.buffer
->data
+ reply_ret
->len
,
6231 reply_data
, reply_ofs
);
6232 data_string_forget(reply_ret
, MDL
);
6233 data_string_copy(reply_ret
, &reply_new
, MDL
);
6234 data_string_forget(&reply_new
, MDL
);
6237 if (prefix
!= NULL
) {
6238 iasubopt_dereference(&prefix
, MDL
);
6240 if (iaprefix
.buffer
!= NULL
) {
6241 data_string_forget(&iaprefix
, MDL
);
6243 if (cli_enc_opt_state
!= NULL
) {
6244 option_state_dereference(&cli_enc_opt_state
, MDL
);
6246 if (cli_enc_opt_data
.buffer
!= NULL
) {
6247 data_string_forget(&cli_enc_opt_data
, MDL
);
6249 if (opt_state
!= NULL
) {
6250 option_state_dereference(&opt_state
, MDL
);
6255 * Release means a client is done with the leases.
6259 dhcpv6_release(struct data_string
*reply
, struct packet
*packet
) {
6260 struct data_string client_id
;
6261 struct data_string server_id
;
6264 * Validate our input.
6266 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
6270 /* If the RELEASE arrived via unicast and unicast option isn't set,
6271 * reject it per RFC 3315, Sec 18.2.6 */
6272 if (packet
->unicast
== ISC_TRUE
&&
6273 is_unicast_option_defined(packet
) == ISC_FALSE
) {
6274 unicast_reject(reply
, packet
, &client_id
, &server_id
);
6277 * And operate on each IA_NA in this packet.
6279 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
6280 "Release", ia_na_match_release
,
6281 ia_na_nomatch_release
);
6284 * And operate on each IA_PD in this packet.
6286 iterate_over_ia_pd(reply
, packet
, &client_id
, &server_id
,
6287 "Release", ia_pd_match_release
,
6288 ia_pd_nomatch_release
);
6291 data_string_forget(&server_id
, MDL
);
6292 data_string_forget(&client_id
, MDL
);
6296 * Information-Request is used by clients who have obtained an address
6297 * from other means, but want configuration information from the server.
6301 dhcpv6_information_request(struct data_string
*reply
, struct packet
*packet
) {
6302 struct data_string client_id
;
6303 struct data_string server_id
;
6306 * Validate our input.
6308 if (!valid_client_info_req(packet
, &server_id
)) {
6313 * Get our client ID, if there is one.
6315 memset(&client_id
, 0, sizeof(client_id
));
6316 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
) {
6317 data_string_forget(&client_id
, MDL
);
6321 * Use the lease_to_client() function. This will work fine,
6322 * because the valid_client_info_req() insures that we
6323 * don't have any IA that would cause us to allocate
6324 * resources to the client.
6326 lease_to_client(reply
, packet
, &client_id
,
6327 server_id
.data
!= NULL
? &server_id
: NULL
);
6332 if (client_id
.data
!= NULL
) {
6333 data_string_forget(&client_id
, MDL
);
6335 data_string_forget(&server_id
, MDL
);
6339 * The Relay-forw message is sent by relays. It typically contains a
6340 * single option, which encapsulates an entire packet.
6342 * We need to build an encapsulated reply.
6345 /* XXX: this is very, very similar to do_packet6(), and should probably
6346 be combined in a clever way */
6347 /* DHCPv6 server side */
6349 dhcpv6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
6350 struct option_cache
*oc
;
6351 struct data_string enc_opt_data
;
6352 struct packet
*enc_packet
;
6353 unsigned char msg_type
;
6354 const struct dhcpv6_packet
*msg
;
6355 const struct dhcpv6_relay_packet
*relay
;
6356 struct data_string enc_reply
;
6357 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6358 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6359 struct data_string a_opt
, packet_ero
;
6360 struct option_state
*opt_state
;
6361 static char reply_data
[65536];
6362 struct dhcpv6_relay_packet
*reply
;
6366 * Initialize variables for early exit.
6369 memset(&a_opt
, 0, sizeof(a_opt
));
6370 memset(&packet_ero
, 0, sizeof(packet_ero
));
6371 memset(&enc_reply
, 0, sizeof(enc_reply
));
6372 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6376 * Get our encapsulated relay message.
6378 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
6380 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
6381 link_addr
, sizeof(link_addr
));
6382 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
6383 peer_addr
, sizeof(peer_addr
));
6384 log_info("Relay-forward from %s with link address=%s and "
6385 "peer address=%s missing Relay Message option.",
6386 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
6390 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
6391 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
6392 /* should be dhcpv6_relay_forw */
6393 log_error("dhcpv6_forw_relay: error evaluating "
6394 "relayed message.");
6398 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
6399 /* should be dhcpv6_relay_forw */
6400 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
6405 * Build a packet structure from this encapsulated packet.
6408 if (!packet_allocate(&enc_packet
, MDL
)) {
6409 /* should be dhcpv6_relay_forw */
6410 log_error("dhcpv6_forw_relay: "
6411 "no memory for encapsulated packet.");
6415 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
6416 /* should be dhcpv6_relay_forw */
6417 log_error("dhcpv6_forw_relay: "
6418 "no memory for encapsulated packet's options.");
6422 enc_packet
->client_port
= packet
->client_port
;
6423 enc_packet
->client_addr
= packet
->client_addr
;
6424 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
6425 enc_packet
->dhcpv6_container_packet
= packet
;
6427 msg_type
= enc_opt_data
.data
[0];
6428 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
6429 (msg_type
== DHCPV6_RELAY_REPL
)) {
6430 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6431 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
6432 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
6434 /* relay-specific data */
6435 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
6436 memcpy(&enc_packet
->dhcpv6_link_address
,
6437 relay
->link_address
, sizeof(relay
->link_address
));
6438 memcpy(&enc_packet
->dhcpv6_peer_address
,
6439 relay
->peer_address
, sizeof(relay
->peer_address
));
6441 if (!parse_option_buffer(enc_packet
->options
,
6443 enc_opt_data
.len
- relaylen
,
6444 &dhcpv6_universe
)) {
6445 /* no logging here, as parse_option_buffer() logs all
6446 cases where it fails */
6449 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
6450 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6452 if (!dhcpv4_over_dhcpv6
||
6453 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6454 log_error("dhcpv6_relay_forw: "
6455 "unsupported %s message type.",
6456 dhcpv6_type_names
[msg_type
]);
6459 forw_dhcpv4_query(packet
);
6462 log_error("dhcpv6_relay_forw: unsupported %s message type.",
6463 dhcpv6_type_names
[msg_type
]);
6465 #endif /* DHCP4o6 */
6467 int msglen
= (int)(offsetof(struct dhcpv6_packet
, options
));
6468 msg
= (struct dhcpv6_packet
*)enc_opt_data
.data
;
6469 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
6471 /* message-specific data */
6472 memcpy(enc_packet
->dhcpv6_transaction_id
,
6473 msg
->transaction_id
,
6474 sizeof(enc_packet
->dhcpv6_transaction_id
));
6476 if (!parse_option_buffer(enc_packet
->options
,
6478 enc_opt_data
.len
- msglen
,
6479 &dhcpv6_universe
)) {
6480 /* no logging here, as parse_option_buffer() logs all
6481 cases where it fails */
6487 * This is recursive. It is possible to exceed maximum packet size.
6488 * XXX: This will cause the packet send to fail.
6490 build_dhcpv6_reply(&enc_reply
, enc_packet
);
6493 * If we got no encapsulated data, then it is discarded, and
6494 * our reply-forw is also discarded.
6496 if (enc_reply
.data
== NULL
) {
6501 * Now we can use the reply_data buffer.
6502 * Packet header stuff all comes from the forward message.
6504 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
6505 reply
->msg_type
= DHCPV6_RELAY_REPL
;
6506 reply
->hop_count
= packet
->dhcpv6_hop_count
;
6507 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
6508 sizeof(reply
->link_address
));
6509 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
6510 sizeof(reply
->peer_address
));
6511 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6514 * Get the reply option state.
6517 if (!option_state_allocate(&opt_state
, MDL
)) {
6518 log_error("dhcpv6_relay_forw: no memory for option state.");
6523 * Append the interface-id if present.
6525 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6528 if (!evaluate_option_cache(&a_opt
, packet
,
6530 packet
->options
, NULL
,
6531 &global_scope
, oc
, MDL
)) {
6532 log_error("dhcpv6_relay_forw: error evaluating "
6536 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6537 (unsigned char *)a_opt
.data
,
6539 D6O_INTERFACE_ID
, 0)) {
6540 log_error("dhcpv6_relay_forw: error saving "
6544 data_string_forget(&a_opt
, MDL
);
6548 * Append our encapsulated stuff for caller.
6550 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6551 (unsigned char *)enc_reply
.data
,
6553 D6O_RELAY_MSG
, 0)) {
6554 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
6559 * Get the ERO if any.
6561 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
6566 if (!evaluate_option_cache(&packet_ero
, packet
,
6568 packet
->options
, NULL
,
6569 &global_scope
, oc
, MDL
) ||
6570 (packet_ero
.len
& 1)) {
6571 log_error("dhcpv6_relay_forw: error evaluating ERO.");
6575 /* Decode and apply the ERO. */
6576 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
6577 req
= getUShort(packet_ero
.data
+ i
);
6578 /* Already in the reply? */
6579 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
6582 /* Get it from the packet if present. */
6583 oc
= lookup_option(&dhcpv6_universe
,
6588 if (!evaluate_option_cache(&a_opt
, packet
,
6590 packet
->options
, NULL
,
6591 &global_scope
, oc
, MDL
)) {
6592 log_error("dhcpv6_relay_forw: error "
6593 "evaluating option %u.", req
);
6596 if (!save_option_buffer(&dhcpv6_universe
,
6599 (unsigned char *)a_opt
.data
,
6603 log_error("dhcpv6_relay_forw: error saving "
6607 data_string_forget(&a_opt
, MDL
);
6611 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
6612 sizeof(reply_data
) - reply_ofs
,
6614 required_opts_agent
, &packet_ero
);
6617 * Return our reply to the caller.
6619 reply_ret
->len
= reply_ofs
;
6620 reply_ret
->buffer
= NULL
;
6621 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
6622 log_fatal("No memory to store reply.");
6624 reply_ret
->data
= reply_ret
->buffer
->data
;
6625 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
6628 if (opt_state
!= NULL
)
6629 option_state_dereference(&opt_state
, MDL
);
6630 if (a_opt
.data
!= NULL
) {
6631 data_string_forget(&a_opt
, MDL
);
6633 if (packet_ero
.data
!= NULL
) {
6634 data_string_forget(&packet_ero
, MDL
);
6636 if (enc_reply
.data
!= NULL
) {
6637 data_string_forget(&enc_reply
, MDL
);
6639 if (enc_opt_data
.data
!= NULL
) {
6640 data_string_forget(&enc_opt_data
, MDL
);
6642 if (enc_packet
!= NULL
) {
6643 packet_dereference(&enc_packet
, MDL
);
6648 /* \brief Internal processing of a relayed DHCPv4-query
6649 * (DHCPv4 server side)
6651 * Code copied from \ref dhcpv6_relay_forw() which itself is
6652 * from \ref do_packet6().
6654 * \param reply_ret pointer to the response
6655 * \param packet the query
6658 dhcp4o6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
6659 struct option_cache
*oc
;
6660 struct data_string enc_opt_data
;
6661 struct packet
*enc_packet
;
6662 unsigned char msg_type
;
6663 const struct dhcpv6_relay_packet
*relay
;
6664 const struct dhcpv4_over_dhcpv6_packet
*msg
;
6665 struct data_string enc_reply
;
6666 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6667 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6668 struct data_string a_opt
, packet_ero
;
6669 struct option_state
*opt_state
;
6670 static char reply_data
[65536];
6671 struct dhcpv6_relay_packet
*reply
;
6675 * Initialize variables for early exit.
6678 memset(&a_opt
, 0, sizeof(a_opt
));
6679 memset(&packet_ero
, 0, sizeof(packet_ero
));
6680 memset(&enc_reply
, 0, sizeof(enc_reply
));
6681 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6685 * Get our encapsulated relay message.
6687 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
6689 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
6690 link_addr
, sizeof(link_addr
));
6691 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
6692 peer_addr
, sizeof(peer_addr
));
6693 log_info("Relay-forward from %s with link address=%s and "
6694 "peer address=%s missing Relay Message option.",
6695 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
6699 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
6700 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
6701 log_error("dhcp4o6_relay_forw: error evaluating "
6702 "relayed message.");
6706 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
6707 log_error("dhcp4o6_relay_forw: "
6708 "encapsulated packet too short.");
6713 * Build a packet structure from this encapsulated packet.
6715 if (!packet_allocate(&enc_packet
, MDL
)) {
6716 log_error("dhcp4o6_relay_forw: "
6717 "no memory for encapsulated packet.");
6721 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
6722 log_error("dhcp4o6_relay_forw: "
6723 "no memory for encapsulated packet's options.");
6727 enc_packet
->client_port
= packet
->client_port
;
6728 enc_packet
->client_addr
= packet
->client_addr
;
6729 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
6730 enc_packet
->dhcpv6_container_packet
= packet
;
6732 msg_type
= enc_opt_data
.data
[0];
6733 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
6734 (msg_type
== DHCPV6_RELAY_REPL
)) {
6735 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6736 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
6737 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
6739 /* relay-specific data */
6740 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
6741 memcpy(&enc_packet
->dhcpv6_link_address
,
6742 relay
->link_address
, sizeof(relay
->link_address
));
6743 memcpy(&enc_packet
->dhcpv6_peer_address
,
6744 relay
->peer_address
, sizeof(relay
->peer_address
));
6746 if (!parse_option_buffer(enc_packet
->options
,
6748 enc_opt_data
.len
- relaylen
,
6749 &dhcpv6_universe
)) {
6750 /* no logging here, as parse_option_buffer() logs all
6751 cases where it fails */
6754 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
6755 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6757 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
6758 msg
= (struct dhcpv4_over_dhcpv6_packet
*)enc_opt_data
.data
;
6759 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
6761 /* message-specific data */
6762 memcpy(enc_packet
->dhcp4o6_flags
,
6764 sizeof(enc_packet
->dhcp4o6_flags
));
6766 if (!parse_option_buffer(enc_packet
->options
,
6768 enc_opt_data
.len
- msglen
,
6769 &dhcpv6_universe
)) {
6770 /* no logging here, as parse_option_buffer() logs all
6771 cases where it fails */
6775 log_error("dhcp4o6_relay_forw: unexpected message of type %d.",
6781 * This is recursive. It is possible to exceed maximum packet size.
6782 * XXX: This will cause the packet send to fail.
6784 build_dhcpv6_reply(&enc_reply
, enc_packet
);
6787 * If we got no encapsulated data, then it is discarded, and
6788 * our reply-forw is also discarded.
6790 if (enc_reply
.data
== NULL
) {
6795 * Now we can use the reply_data buffer.
6796 * Packet header stuff all comes from the forward message.
6798 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
6799 reply
->msg_type
= DHCPV6_RELAY_REPL
;
6800 reply
->hop_count
= packet
->dhcpv6_hop_count
;
6801 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
6802 sizeof(reply
->link_address
));
6803 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
6804 sizeof(reply
->peer_address
));
6805 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6808 * Get the reply option state.
6810 if (!option_state_allocate(&opt_state
, MDL
)) {
6811 log_error("dhcp4o6_relay_forw: no memory for option state.");
6816 * Append the interface-id if present.
6818 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6821 if (!evaluate_option_cache(&a_opt
, packet
,
6823 packet
->options
, NULL
,
6824 &global_scope
, oc
, MDL
)) {
6825 log_error("dhcp4o6_relay_forw: error evaluating "
6829 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6830 (unsigned char *)a_opt
.data
,
6832 D6O_INTERFACE_ID
, 0)) {
6833 log_error("dhcp4o6_relay_forw: error saving "
6837 data_string_forget(&a_opt
, MDL
);
6841 * Append our encapsulated stuff for caller.
6843 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6844 (unsigned char *)enc_reply
.data
,
6846 D6O_RELAY_MSG
, 0)) {
6847 log_error("dhcp4o6_relay_forw: error saving Relay MSG.");
6852 * Get the ERO if any.
6854 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
6859 if (!evaluate_option_cache(&packet_ero
, packet
,
6861 packet
->options
, NULL
,
6862 &global_scope
, oc
, MDL
) ||
6863 (packet_ero
.len
& 1)) {
6864 log_error("dhcp4o6_relay_forw: error evaluating ERO.");
6868 /* Decode and apply the ERO. */
6869 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
6870 req
= getUShort(packet_ero
.data
+ i
);
6871 /* Already in the reply? */
6872 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
6875 /* Get it from the packet if present. */
6876 oc
= lookup_option(&dhcpv6_universe
,
6881 if (!evaluate_option_cache(&a_opt
, packet
,
6883 packet
->options
, NULL
,
6884 &global_scope
, oc
, MDL
)) {
6885 log_error("dhcp4o6_relay_forw: error "
6886 "evaluating option %u.", req
);
6889 if (!save_option_buffer(&dhcpv6_universe
,
6892 (unsigned char *)a_opt
.data
,
6896 log_error("dhcp4o6_relay_forw: error saving "
6900 data_string_forget(&a_opt
, MDL
);
6904 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
6905 sizeof(reply_data
) - reply_ofs
,
6907 required_opts_agent
, &packet_ero
);
6910 * Return our reply to the caller.
6912 reply_ret
->len
= reply_ofs
;
6913 reply_ret
->buffer
= NULL
;
6914 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
6915 log_fatal("No memory to store reply.");
6917 reply_ret
->data
= reply_ret
->buffer
->data
;
6918 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
6921 if (opt_state
!= NULL
)
6922 option_state_dereference(&opt_state
, MDL
);
6923 if (a_opt
.data
!= NULL
) {
6924 data_string_forget(&a_opt
, MDL
);
6926 if (packet_ero
.data
!= NULL
) {
6927 data_string_forget(&packet_ero
, MDL
);
6929 if (enc_reply
.data
!= NULL
) {
6930 data_string_forget(&enc_reply
, MDL
);
6932 if (enc_opt_data
.data
!= NULL
) {
6933 data_string_forget(&enc_opt_data
, MDL
);
6935 if (enc_packet
!= NULL
) {
6936 packet_dereference(&enc_packet
, MDL
);
6941 * \brief Internal processing of a DHCPv4-query
6942 * (DHCPv4 server function)
6944 * Code copied from \ref do_packet().
6946 * \param reply_ret pointer to the response
6947 * \param packet the query
6950 dhcp4o6_dhcpv4_query(struct data_string
*reply_ret
, struct packet
*packet
) {
6951 struct option_cache
*oc
;
6952 struct data_string enc_opt_data
;
6953 struct packet
*enc_packet
;
6954 struct data_string enc_response
;
6955 struct option_state
*opt_state
;
6956 static char response_data
[65536];
6957 struct dhcpv4_over_dhcpv6_packet
*response
;
6961 * Initialize variables for early exit.
6964 memset(&enc_response
, 0, sizeof(enc_response
));
6965 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6969 * Get our encapsulated relay message.
6971 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_DHCPV4_MSG
);
6973 log_info("DHCPv4-query from %s missing DHCPv4 Message option.",
6974 piaddr(packet
->client_addr
));
6978 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
6979 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
6980 log_error("dhcp4o6_dhcpv4_query: error evaluating "
6985 if (enc_opt_data
.len
< DHCP_FIXED_NON_UDP
) {
6986 log_error("dhcp4o6_dhcpv4_query: DHCPv4 packet too short.");
6991 * Build a packet structure from this encapsulated packet.
6993 if (!packet_allocate(&enc_packet
, MDL
)) {
6994 log_error("dhcp4o6_dhcpv4_query: "
6995 "no memory for encapsulated packet.");
6999 enc_packet
->raw
= (struct dhcp_packet
*)enc_opt_data
.data
;
7000 enc_packet
->packet_length
= enc_opt_data
.len
;
7001 enc_packet
->dhcp4o6_response
= &enc_response
;
7002 enc_packet
->client_port
= packet
->client_port
;
7003 enc_packet
->client_addr
= packet
->client_addr
;
7004 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
7005 enc_packet
->dhcpv6_container_packet
= packet
;
7006 if (packet
->dhcp4o6_flags
[0] & DHCP4O6_QUERY_UNICAST
)
7007 enc_packet
->unicast
= 1;
7009 if (enc_packet
->raw
->hlen
> sizeof(enc_packet
->raw
->chaddr
)) {
7010 log_info("dhcp4o6_dhcpv4_query: "
7011 "discarding packet with bogus hlen.");
7015 /* Allocate packet->options now so it is non-null for all packets */
7016 if (!option_state_allocate (&enc_packet
->options
, MDL
)) {
7017 log_error("dhcp4o6_dhcpv4_query: no memory for options.");
7021 /* If there's an option buffer, try to parse it. */
7022 if (enc_packet
->packet_length
>= DHCP_FIXED_NON_UDP
+ 4) {
7023 struct option_cache
*op
;
7024 if (!parse_options(enc_packet
)) {
7025 if (enc_packet
->options
)
7026 option_state_dereference
7027 (&enc_packet
->options
, MDL
);
7028 packet_dereference (&enc_packet
, MDL
);
7032 if (enc_packet
->options_valid
&&
7033 (op
= lookup_option(&dhcp_universe
,
7034 enc_packet
->options
,
7035 DHO_DHCP_MESSAGE_TYPE
))) {
7036 struct data_string dp
;
7037 memset(&dp
, 0, sizeof dp
);
7038 evaluate_option_cache(&dp
, enc_packet
, NULL
, NULL
,
7039 enc_packet
->options
, NULL
,
7042 enc_packet
->packet_type
= dp
.data
[0];
7044 enc_packet
->packet_type
= 0;
7045 data_string_forget(&dp
, MDL
);
7049 if (validate_packet(enc_packet
) != 0) {
7050 if (enc_packet
->packet_type
)
7056 /* If the caller kept the packet, they'll have upped the refcnt. */
7057 packet_dereference(&enc_packet
, MDL
);
7060 * If we got no response data, then it is discarded, and
7061 * our DHCPv4-response is also discarded.
7063 if (enc_response
.data
== NULL
) {
7068 * Now we can use the response_data buffer.
7070 response
= (struct dhcpv4_over_dhcpv6_packet
*)response_data
;
7071 response
->msg_type
= DHCPV6_DHCPV4_RESPONSE
;
7072 response
->flags
[0] = response
->flags
[1] = response
->flags
[2] = 0;
7074 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7077 * Get the response option state.
7079 if (!option_state_allocate(&opt_state
, MDL
)) {
7080 log_error("dhcp4o6_dhcpv4_query: no memory for option state.");
7085 * Append our encapsulated stuff for caller.
7087 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7088 (unsigned char *)enc_response
.data
,
7090 D6O_DHCPV4_MSG
, 0)) {
7091 log_error("dhcp4o6_dhcpv4_query: error saving DHCPv4 MSG.");
7095 response_ofs
+= store_options6(response_data
+ response_ofs
,
7096 sizeof(response_data
) - response_ofs
,
7098 required_opts_4o6
, NULL
);
7101 * Return our response to the caller.
7103 reply_ret
->len
= response_ofs
;
7104 reply_ret
->buffer
= NULL
;
7105 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
7106 log_fatal("dhcp4o6_dhcpv4_query: no memory to store reply.");
7108 reply_ret
->data
= reply_ret
->buffer
->data
;
7109 memcpy(reply_ret
->buffer
->data
, response_data
, response_ofs
);
7112 if (opt_state
!= NULL
)
7113 option_state_dereference(&opt_state
, MDL
);
7114 if (enc_response
.data
!= NULL
) {
7115 data_string_forget(&enc_response
, MDL
);
7117 if (enc_opt_data
.data
!= NULL
) {
7118 data_string_forget(&enc_opt_data
, MDL
);
7120 if (enc_packet
!= NULL
) {
7121 packet_dereference(&enc_packet
, MDL
);
7126 * \brief Forward a DHCPv4-query message to the DHCPv4 side
7127 * (DHCPv6 server function)
7129 * Format: interface:16 + address:16 + DHCPv6 DHCPv4-query message
7131 * \brief packet the DHCPv6 DHCPv4-query message
7133 static void forw_dhcpv4_query(struct packet
*packet
) {
7134 struct data_string ds
;
7138 /* Get the initial message. */
7139 while (packet
->dhcpv6_container_packet
!= NULL
)
7140 packet
= packet
->dhcpv6_container_packet
;
7142 /* Check the initial message. */
7143 if ((packet
->raw
== NULL
) ||
7144 (packet
->client_addr
.len
!= 16) ||
7145 (packet
->interface
== NULL
)) {
7146 log_error("forw_dhcpv4_query: can't find initial message.");
7151 len
= packet
->packet_length
+ 32;
7152 memset(&ds
, 0, sizeof(ds
));
7153 if (!buffer_allocate(&ds
.buffer
, len
, MDL
)) {
7154 log_error("forw_dhcpv4_query: "
7155 "no memory for encapsulating packet.");
7158 ds
.data
= ds
.buffer
->data
;
7161 /* Fill the buffer. */
7162 strncpy((char *)ds
.buffer
->data
, packet
->interface
->name
, 16);
7163 memcpy(ds
.buffer
->data
+ 16,
7164 packet
->client_addr
.iabuf
, 16);
7165 memcpy(ds
.buffer
->data
+ 32,
7166 (unsigned char *)packet
->raw
,
7167 packet
->packet_length
);
7169 /* Forward to the DHCPv4 server. */
7170 cc
= send(dhcp4o6_fd
, ds
.data
, ds
.len
, 0);
7172 log_error("forw_dhcpv4_query: send(): %m");
7173 data_string_forget(&ds
, MDL
);
7178 dhcpv6_discard(struct packet
*packet
) {
7179 /* INSIST(packet->msg_type > 0); */
7180 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
7182 log_debug("Discarding %s from %s; message type not handled by server",
7183 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7184 piaddr(packet
->client_addr
));
7188 build_dhcpv6_reply(struct data_string
*reply
, struct packet
*packet
) {
7189 memset(reply
, 0, sizeof(*reply
));
7191 /* I would like to classify the client once here, but
7192 * as I don't want to classify all of the incoming packets
7193 * I need to do it before handling specific types.
7194 * We don't need to classify if we are tossing the packet
7195 * or if it is a relay - the classification step will get
7196 * done when we process the inner client packet.
7199 switch (packet
->dhcpv6_msg_type
) {
7200 case DHCPV6_SOLICIT
:
7201 classify_client(packet
);
7202 dhcpv6_solicit(reply
, packet
);
7204 case DHCPV6_ADVERTISE
:
7205 dhcpv6_discard(packet
);
7207 case DHCPV6_REQUEST
:
7208 classify_client(packet
);
7209 dhcpv6_request(reply
, packet
);
7211 case DHCPV6_CONFIRM
:
7212 classify_client(packet
);
7213 dhcpv6_confirm(reply
, packet
);
7216 classify_client(packet
);
7217 dhcpv6_renew(reply
, packet
);
7220 classify_client(packet
);
7221 dhcpv6_rebind(reply
, packet
);
7224 dhcpv6_discard(packet
);
7226 case DHCPV6_RELEASE
:
7227 classify_client(packet
);
7228 dhcpv6_release(reply
, packet
);
7230 case DHCPV6_DECLINE
:
7231 classify_client(packet
);
7232 dhcpv6_decline(reply
, packet
);
7234 case DHCPV6_RECONFIGURE
:
7235 dhcpv6_discard(packet
);
7237 case DHCPV6_INFORMATION_REQUEST
:
7238 classify_client(packet
);
7239 dhcpv6_information_request(reply
, packet
);
7241 case DHCPV6_RELAY_FORW
:
7243 if (dhcpv4_over_dhcpv6
&& (local_family
== AF_INET
))
7244 dhcp4o6_relay_forw(reply
, packet
);
7246 #endif /* DHCP4o6 */
7247 dhcpv6_relay_forw(reply
, packet
);
7249 case DHCPV6_RELAY_REPL
:
7250 dhcpv6_discard(packet
);
7252 case DHCPV6_LEASEQUERY
:
7253 classify_client(packet
);
7254 dhcpv6_leasequery(reply
, packet
);
7256 case DHCPV6_LEASEQUERY_REPLY
:
7257 dhcpv6_discard(packet
);
7259 case DHCPV6_DHCPV4_QUERY
:
7261 if (dhcpv4_over_dhcpv6
) {
7262 if (local_family
== AF_INET6
) {
7263 forw_dhcpv4_query(packet
);
7265 dhcp4o6_dhcpv4_query(reply
, packet
);
7268 #endif /* DHCP4o6 */
7269 dhcpv6_discard(packet
);
7271 case DHCPV6_DHCPV4_RESPONSE
:
7272 dhcpv6_discard(packet
);
7275 /* XXX: would be nice if we had "notice" level,
7276 as syslog, for this */
7277 log_info("Discarding unknown DHCPv6 message type %d "
7278 "from %s", packet
->dhcpv6_msg_type
,
7279 piaddr(packet
->client_addr
));
7284 log_packet_in(const struct packet
*packet
) {
7285 struct data_string s
;
7287 char tmp_addr
[INET6_ADDRSTRLEN
];
7290 memset(&s
, 0, sizeof(s
));
7292 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
7293 data_string_sprintfa(&s
, "%s message from %s port %d",
7294 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7295 piaddr(packet
->client_addr
),
7296 ntohs(packet
->client_port
));
7298 data_string_sprintfa(&s
,
7299 "Unknown message type %d from %s port %d",
7300 packet
->dhcpv6_msg_type
,
7301 piaddr(packet
->client_addr
),
7302 ntohs(packet
->client_port
));
7304 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7305 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7306 addr
= &packet
->dhcpv6_link_address
;
7307 data_string_sprintfa(&s
, ", link address %s",
7308 inet_ntop(AF_INET6
, addr
,
7309 tmp_addr
, sizeof(tmp_addr
)));
7310 addr
= &packet
->dhcpv6_peer_address
;
7311 data_string_sprintfa(&s
, ", peer address %s",
7312 inet_ntop(AF_INET6
, addr
,
7313 tmp_addr
, sizeof(tmp_addr
)));
7314 } else if ((packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_QUERY
) &&
7315 (packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_RESPONSE
)) {
7317 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
7318 data_string_sprintfa(&s
, ", transaction ID 0x%06X", tid
);
7321 oc = lookup_option(&dhcpv6_universe, packet->options,
7324 memset(&tmp_ds, 0, sizeof(tmp_ds_));
7325 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
7326 packet->options, NULL,
7327 &global_scope, oc, MDL)) {
7328 log_error("Error evaluating Client Identifier");
7330 data_strint_sprintf(&s, ", client ID %s",
7332 data_string_forget(&tmp_ds, MDL);
7338 log_info("%s", s
.data
);
7340 data_string_forget(&s
, MDL
);
7344 dhcpv6(struct packet
*packet
) {
7345 struct data_string reply
;
7346 struct sockaddr_in6 to_addr
;
7350 * Log a message that we received this packet.
7352 log_packet_in(packet
);
7355 * Build our reply packet.
7357 build_dhcpv6_reply(&reply
, packet
);
7359 if (reply
.data
!= NULL
) {
7361 * Send our reply, if we have one.
7363 memset(&to_addr
, 0, sizeof(to_addr
));
7364 to_addr
.sin6_family
= AF_INET6
;
7365 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7366 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7367 to_addr
.sin6_port
= local_port
;
7369 to_addr
.sin6_port
= remote_port
;
7372 #if defined (REPLY_TO_SOURCE_PORT)
7374 * This appears to have been included for testing so we would
7375 * not need a root client, but was accidently left in the
7376 * final code. We continue to include it in case
7377 * some users have come to rely upon it, but leave
7378 * it off by default as it's a bad idea.
7380 to_addr
.sin6_port
= packet
->client_port
;
7383 memcpy(&to_addr
.sin6_addr
, packet
->client_addr
.iabuf
,
7384 sizeof(to_addr
.sin6_addr
));
7386 log_info("Sending %s to %s port %d",
7387 dhcpv6_type_names
[reply
.data
[0]],
7388 piaddr(packet
->client_addr
),
7389 ntohs(to_addr
.sin6_port
));
7391 send_ret
= send_packet6(packet
->interface
,
7392 reply
.data
, reply
.len
, &to_addr
);
7393 if (send_ret
!= reply
.len
) {
7394 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
7395 send_ret
, reply
.len
);
7397 data_string_forget(&reply
, MDL
);
7403 * \brief Receive a DHCPv4-query message from the DHCPv6 side
7404 * (DHCPv4 server function)
7406 * Receive a message with a DHCPv4-query inside from the DHCPv6 server.
7407 * (code copied from \ref do_packet6() \ref and dhcpv6())
7409 * Format: interface:16 + address:16 + DHCPv6 DHCPv4-query message
7411 * \param raw the DHCPv6 DHCPv4-query message raw content
7413 static void recv_dhcpv4_query(struct data_string
*raw
) {
7414 struct interface_info
*ip
;
7417 struct packet
*packet
;
7418 unsigned char msg_type
;
7419 const struct dhcpv6_relay_packet
*relay
;
7420 const struct dhcpv4_over_dhcpv6_packet
*msg
;
7421 struct data_string reply
;
7422 struct data_string ds
;
7426 memset(name
, 0, sizeof(name
));
7427 memcpy(name
, raw
->data
, 16);
7428 for (ip
= interfaces
; ip
!= NULL
; ip
= ip
->next
) {
7429 if (!strcmp(name
, ip
->name
))
7433 log_error("recv_dhcpv4_query: can't find interface %s.",
7439 memcpy(iaddr
.iabuf
, raw
->data
+ 16, 16);
7442 * From do_packet6().
7445 if (!packet6_len_okay((char *)raw
->data
+ 32, raw
->len
- 32)) {
7446 log_error("recv_dhcpv4_query: "
7447 "short packet from %s, len %d, dropped",
7448 piaddr(iaddr
), raw
->len
- 32);
7453 * Build a packet structure.
7456 if (!packet_allocate(&packet
, MDL
)) {
7457 log_error("recv_dhcpv4_query: no memory for packet.");
7461 if (!option_state_allocate(&packet
->options
, MDL
)) {
7462 log_error("recv_dhcpv4_query: no memory for options.");
7463 packet_dereference(&packet
, MDL
);
7467 packet
->raw
= (struct dhcp_packet
*)(raw
->data
+ 32);
7468 packet
->packet_length
= raw
->len
- 32;
7469 packet
->client_port
= remote_port
;
7470 packet
->client_addr
= iaddr
;
7471 interface_reference(&packet
->interface
, ip
, MDL
);
7473 msg_type
= raw
->data
[32];
7474 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
7475 (msg_type
== DHCPV6_RELAY_REPL
)) {
7477 (int)(offsetof(struct dhcpv6_relay_packet
, options
));
7478 relay
= (const struct dhcpv6_relay_packet
*)(raw
->data
+ 32);
7479 packet
->dhcpv6_msg_type
= relay
->msg_type
;
7481 /* relay-specific data */
7482 packet
->dhcpv6_hop_count
= relay
->hop_count
;
7483 memcpy(&packet
->dhcpv6_link_address
,
7484 relay
->link_address
, sizeof(relay
->link_address
));
7485 memcpy(&packet
->dhcpv6_peer_address
,
7486 relay
->peer_address
, sizeof(relay
->peer_address
));
7488 if (!parse_option_buffer(packet
->options
,
7490 raw
->len
- 32 - relaylen
,
7491 &dhcpv6_universe
)) {
7492 /* no logging here, as parse_option_buffer() logs all
7493 cases where it fails */
7494 packet_dereference(&packet
, MDL
);
7497 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
7498 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
7500 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7501 msg
= (struct dhcpv4_over_dhcpv6_packet
*)(raw
->data
+ 32);
7502 packet
->dhcpv6_msg_type
= msg
->msg_type
;
7504 /* message-specific data */
7505 memcpy(packet
->dhcp4o6_flags
, msg
->flags
,
7506 sizeof(packet
->dhcp4o6_flags
));
7508 if (!parse_option_buffer(packet
->options
,
7510 raw
->len
- 32 - msglen
,
7511 &dhcpv6_universe
)) {
7512 /* no logging here, as parse_option_buffer() logs all
7513 cases where it fails */
7514 packet_dereference(&packet
, MDL
);
7518 log_error("recv_dhcpv4_query: unexpected message of type %d.",
7520 packet_dereference(&packet
, MDL
);
7529 * Log a message that we received this packet.
7531 /* log_packet_in(packet); */
7532 memset(&ds
, 0, sizeof(ds
));
7533 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
7534 data_string_sprintfa(&ds
, "%s message from %s",
7535 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7536 piaddr(packet
->client_addr
));
7538 data_string_sprintfa(&ds
,
7539 "Unknown message type %d from %s",
7540 packet
->dhcpv6_msg_type
,
7541 piaddr(packet
->client_addr
));
7543 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7544 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7545 char tmp_addr
[INET6_ADDRSTRLEN
];
7548 addr
= &packet
->dhcpv6_link_address
;
7549 data_string_sprintfa(&ds
, ", link address %s",
7550 inet_ntop(AF_INET6
, addr
,
7551 tmp_addr
, sizeof(tmp_addr
)));
7552 addr
= &packet
->dhcpv6_peer_address
;
7553 data_string_sprintfa(&ds
, ", peer address %s",
7554 inet_ntop(AF_INET6
, addr
,
7555 tmp_addr
, sizeof(tmp_addr
)));
7556 } else if ((packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_QUERY
) &&
7557 (packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_RESPONSE
)) {
7560 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
7561 data_string_sprintfa(&ds
, ", transaction ID 0x%06X", tid
);
7563 log_info("%s", ds
.data
);
7564 data_string_forget(&ds
, MDL
);
7567 * Build our reply packet.
7569 build_dhcpv6_reply(&reply
, packet
);
7571 packet_dereference(&packet
, MDL
);
7573 if (reply
.data
== NULL
)
7577 * Forward the response.
7579 len
= reply
.len
+ 32;
7580 memset(&ds
, 0, sizeof(ds
));
7581 if (!buffer_allocate(&ds
.buffer
, len
, MDL
)) {
7582 log_error("recv_dhcpv4_query: no memory.");
7585 ds
.data
= ds
.buffer
->data
;
7588 memcpy(ds
.buffer
->data
, name
, 16);
7589 memcpy(ds
.buffer
->data
+ 16, iaddr
.iabuf
, 16);
7590 memcpy(ds
.buffer
->data
+ 32, reply
.data
, reply
.len
);
7591 cc
= send(dhcp4o6_fd
, ds
.data
, ds
.len
, 0);
7593 log_error("recv_dhcpv4_query: send(): %m");
7594 data_string_forget(&ds
, MDL
);
7596 #endif /* DHCP4o6 */
7599 seek_shared_host(struct host_decl
**hp
, struct shared_network
*shared
) {
7600 struct host_decl
*nofixed
= NULL
;
7601 struct host_decl
*seek
, *hold
= NULL
;
7604 * Seek forward through fixed addresses for the right link.
7606 * Note: how to do this for fixed prefixes???
7608 host_reference(&hold
, *hp
, MDL
);
7609 host_dereference(hp
, MDL
);
7611 while (seek
!= NULL
) {
7612 if (seek
->fixed_addr
== NULL
)
7614 else if (fixed_matches_shared(seek
, shared
))
7617 seek
= seek
->n_ipaddr
;
7620 if ((seek
== NULL
) && (nofixed
!= NULL
))
7624 host_reference(hp
, seek
, MDL
);
7627 static isc_boolean_t
7628 fixed_matches_shared(struct host_decl
*host
, struct shared_network
*shared
) {
7629 struct subnet
*subnet
;
7630 struct data_string addr
;
7631 isc_boolean_t matched
;
7634 if (host
->fixed_addr
== NULL
)
7637 memset(&addr
, 0, sizeof(addr
));
7638 if (!evaluate_option_cache(&addr
, NULL
, NULL
, NULL
, NULL
, NULL
,
7639 &global_scope
, host
->fixed_addr
, MDL
))
7642 if (addr
.len
< 16) {
7643 data_string_forget(&addr
, MDL
);
7648 memcpy(fixed
.iabuf
, addr
.data
, 16);
7650 matched
= ISC_FALSE
;
7651 for (subnet
= shared
->subnets
; subnet
!= NULL
;
7652 subnet
= subnet
->next_sibling
) {
7653 if (addr_eq(subnet_number(fixed
, subnet
->netmask
),
7660 data_string_forget(&addr
, MDL
);
7666 * \brief Constructs a REPLY with status of UseMulticast to a given packet
7668 * Per RFC 3315 Secs 18.2.1,3,6 & 7, when a server rejects a client's
7669 * unicast-sent packet, the response must only contain the client id,
7670 * server id, and a status code option of 5 (UseMulticast). This function
7671 * constructs such a packet and returns it as a data_string.
7673 * \param reply_ret = data_string which will receive the newly constructed
7675 * \param packet = client request which is being rejected
7676 * \param client_id = data_string which contains the client id
7677 * \param server_id = data_string which which contains the server id
7681 unicast_reject(struct data_string
*reply_ret
,
7682 struct packet
*packet
,
7683 const struct data_string
*client_id
,
7684 const struct data_string
*server_id
)
7686 struct reply_state reply
;
7687 memset(&reply
, 0x0, sizeof(struct reply_state
));
7689 /* Locate the client. */
7690 if (shared_network_from_packet6(&reply
.shared
, packet
)
7692 log_error("unicast_reject: could not locate client.");
7696 /* Initialize the reply. */
7697 packet_reference(&reply
.packet
, packet
, MDL
);
7698 data_string_copy(&reply
.client_id
, client_id
, MDL
);
7700 if (start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
7701 &reply
.buf
.reply
)) {
7702 /* Set the UseMulticast status code. */
7703 if (!set_status_code(STATUS_UseMulticast
,
7704 "Unicast not allowed by server.",
7706 log_error("unicast_reject: Unable to set status code.");
7708 /* Set write cursor to just past the reply header. */
7709 reply
.cursor
= REPLY_OPTIONS_INDEX
;
7710 reply
.cursor
+= store_options6(((char *)reply
.buf
.data
7716 unicast_reject_opts
,
7719 /* Return our reply to the caller. */
7720 reply_ret
->len
= reply
.cursor
;
7721 reply_ret
->buffer
= NULL
;
7722 if (!buffer_allocate(&reply_ret
->buffer
,
7723 reply
.cursor
, MDL
)) {
7724 log_fatal("unicast_reject:"
7725 "No memory to store Reply.");
7728 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
,
7730 reply_ret
->data
= reply_ret
->buffer
->data
;
7736 if (reply
.shared
!= NULL
)
7737 shared_network_dereference(&reply
.shared
, MDL
);
7738 if (reply
.opt_state
!= NULL
)
7739 option_state_dereference(&reply
.opt_state
, MDL
);
7740 if (reply
.packet
!= NULL
)
7741 packet_dereference(&reply
.packet
, MDL
);
7742 if (reply
.client_id
.data
!= NULL
)
7743 data_string_forget(&reply
.client_id
, MDL
);
7748 * \brief Checks if the dhcp6.unicast option has been defined
7750 * Scans the option space for the presence of the dhcp6.unicast option. The
7751 * function attempts to map the inbound packet to a shared network first
7752 * by an ip address specified via an D6O_IA_XX option and if that fails then
7753 * by the packet's source information (e.g. relay link, link, or interace).
7754 * Once the packet is mapped to a shared network, the function executes all
7755 * statements from the network's group outward into a local option cache.
7756 * The option cache is then scanned for the presence of unicast option. If
7757 * the packet cannot be mapped to a shared network, the function returns
7759 * \param packet inbound packet from the client
7761 * \return ISC_TRUE if the dhcp6.unicast option is defined, false otherwise.
7765 is_unicast_option_defined(struct packet
*packet
) {
7766 isc_boolean_t is_defined
= ISC_FALSE
;
7767 struct option_state
*opt_state
= NULL
;
7768 struct option_cache
*oc
= NULL
;
7769 struct shared_network
*shared
= NULL
;
7771 if (!option_state_allocate(&opt_state
, MDL
)) {
7772 log_fatal("is_unicast_option_defined:"
7773 "No memory for option state.");
7776 /* We try to map the packet to a network first by an IA_XX value.
7777 * If that fails, we try by packet source. */
7778 if (((shared_network_from_requested_addr(&shared
, packet
)
7779 != ISC_R_SUCCESS
) &&
7780 (shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
))
7781 || (shared
== NULL
)) {
7782 /* @todo what would this really mean? I think wrong network
7783 * logic will catch it */
7784 log_error("is_unicast_option_defined:"
7785 "cannot attribute packet to a network.");
7789 /* Now that we've mapped it to a network, execute statments to that
7790 * scope, looking for the unicast option. We don't care about the
7791 * value of the option, only whether or not it is defined. */
7792 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
, opt_state
,
7793 &global_scope
, shared
->group
, NULL
, NULL
);
7795 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_UNICAST
);
7796 is_defined
= (oc
!= NULL
? ISC_TRUE
: ISC_FALSE
);
7797 log_debug("is_unicast_option_defined: option found : %d", is_defined
);
7799 if (shared
!= NULL
) {
7800 shared_network_dereference(&shared
, MDL
);
7803 if (opt_state
!= NULL
) {
7804 option_state_dereference(&opt_state
, MDL
);
7807 return (is_defined
);
7812 * \brief Maps a packet to a shared network based on the requested IP address
7814 * The function attempts to find a subnet that matches the first requested IP
7815 * address contained within the given packet. Note that it looks first for
7816 * D6O_IA_NAs, then D6O_IA_PDs and lastly D6O_IA_TAs. If a matching network is
7817 * found, a reference to it is returned in the parameter, shared.
7819 * \param shared shared_network pointer which will receive the matching network
7820 * \param packet inbound packet from the client
7822 * \return ISC_R_SUCCESS if the packet can be mapped to a shared_network.
7826 shared_network_from_requested_addr (struct shared_network
**shared
,
7827 struct packet
* packet
) {
7829 struct subnet
* subnet
= NULL
;
7830 isc_result_t status
= ISC_R_FAILURE
;
7832 /* Try to match first IA_ address or prefix we find to a subnet. In
7833 * theory all IA_ values in a given request are supposed to be in the
7834 * same subnet so we only need to try one right? */
7835 if ((get_first_ia_addr_val(packet
, D6O_IA_NA
, &iaddr
) != ISC_R_SUCCESS
)
7836 && (get_first_ia_addr_val(packet
, D6O_IA_PD
, &iaddr
)
7838 && (get_first_ia_addr_val(packet
, D6O_IA_TA
, &iaddr
)
7839 != ISC_R_SUCCESS
)) {
7840 /* we found nothing to match against */
7841 log_debug("share_network_from_request_addr: nothing to match");
7842 return (ISC_R_FAILURE
);
7845 if (!find_subnet(&subnet
, iaddr
, MDL
)) {
7846 log_debug("shared_network_from_requested_addr:"
7847 "No subnet found for addr %s.", piaddr(iaddr
));
7849 status
= shared_network_reference(shared
,
7850 subnet
->shared_network
, MDL
);
7851 subnet_dereference(&subnet
, MDL
);
7852 log_debug("shared_network_from_requested_addr:"
7853 " found shared network %s for address %s.",
7854 ((*shared
)->name
? (*shared
)->name
: "unnamed"),
7859 return (ISC_R_FAILURE
);
7864 * \brief Retrieves the first IP address from a given packet of a given type
7866 * Search a packet for options of a given type (D6O_IA_AN, D6O_IA_PD, or
7867 * D6O_IA_TA) for the first non-blank IA_XX value and return its IP address
7870 * \param packet packet received from the client
7871 * \param addr_type the address option type (D6O_IA_NA , D6O_IA_PD, or
7872 * D6O_IP_TA) to look for within the packet.
7873 * \param iaddr pointer to the iaddr structure which will receive the extracted
7876 * \return ISC_R_SUCCESS if an address was succesfully extracted, ISC_R_FALURE
7881 get_first_ia_addr_val (struct packet
* packet
, int addr_type
,
7882 struct iaddr
* iaddr
) {
7883 struct option_cache
*ia
;
7884 struct option_cache
*oc
= NULL
;
7885 struct data_string cli_enc_opt_data
;
7886 struct option_state
*cli_enc_opt_state
;
7887 int addr_opt_offset
;
7889 int addr_opt_data_len
;
7892 isc_result_t status
= ISC_R_FAILURE
;
7893 memset(iaddr
, 0, sizeof(struct iaddr
));
7895 /* Set up address type specifics */
7896 switch (addr_type
) {
7898 addr_opt_offset
= IA_NA_OFFSET
;
7899 addr_opt
= D6O_IAADDR
;
7900 addr_opt_data_len
= 24;
7904 addr_opt_offset
= IA_TA_OFFSET
;
7905 addr_opt
= D6O_IAADDR
;
7906 addr_opt_data_len
= 24;
7910 addr_opt_offset
= IA_PD_OFFSET
;
7911 addr_opt
= D6O_IAPREFIX
;
7912 addr_opt_data_len
= 25;
7916 /* shouldn't be here */
7917 log_error ("get_first_ia_addr_val: invalid opt type %d",
7919 return (ISC_R_FAILURE
);
7922 /* Find the first, non-blank IA_XX value within an D6O_IA_XX option. */
7923 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, addr_type
);
7924 ia
!= NULL
&& oc
== NULL
; ia
= ia
->next
) {
7925 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
7927 packet
, ia
, addr_opt_offset
)) {
7928 log_debug ("get_first_ia_addr_val:"
7929 " couldn't unroll enclosing option");
7930 return (ISC_R_FAILURE
);
7933 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
7936 /* no address given for this IA, ignore */
7937 option_state_dereference(&cli_enc_opt_state
, MDL
);
7938 data_string_forget(&cli_enc_opt_data
, MDL
);
7942 /* If we found a non-blank IA_XX then extract its ip address. */
7944 struct data_string iaddr_str
;
7946 memset(&iaddr_str
, 0, sizeof(iaddr_str
));
7947 if (!evaluate_option_cache(&iaddr_str
, packet
, NULL
, NULL
,
7948 packet
->options
, NULL
, &global_scope
,
7950 log_error("get_first_ia_addr_val: "
7951 "error evaluating IA_XX option.");
7953 if (iaddr_str
.len
!= addr_opt_data_len
) {
7954 log_error("shared_network_from_requested_addr:"
7955 " invalid length %d, expected %d",
7956 iaddr_str
.len
, addr_opt_data_len
);
7959 memcpy (iaddr
->iabuf
,
7960 iaddr_str
.data
+ ip_addr_offset
, 16);
7961 status
= ISC_R_SUCCESS
;
7963 data_string_forget(&iaddr_str
, MDL
);
7966 option_state_dereference(&cli_enc_opt_state
, MDL
);
7967 data_string_forget(&cli_enc_opt_data
, MDL
);
7974 * \brief Calculates the reply T1/T2 times and stuffs them in outbound buffer
7976 * T1/T2 time selection is kind of weird. We actually use DHCP * (v4) scoped
7977 * options, dhcp-renewal-time and dhcp-rebinding-time, as handy existing places
7978 * where these can be configured by an administrator. A value of zero tells the
7979 * client it may choose its own value.
7981 * When those options are not defined, the values will be set to zero unless
7982 * the global option, dhcpv6-set-tee-times is enabled. When this option is
7983 * enabled the values are calculated as recommended by RFC 3315, Section 22.4:
7985 * T1 will be set to 0.5 times the shortest preferred lifetime
7986 * in the IA_XX option. If the "shortest" preferred lifetime is
7987 * 0xFFFFFFFF, T1 will set to 0xFFFFFFFF.
7989 * T2 will be set to 0.8 times the shortest preferred lifetime
7990 * in the IA_XX option. If the "shortest" preferred lifetime is
7991 * 0xFFFFFFFF, T2 will set to 0xFFFFFFFF.
7993 * Note that dhcpv6-set-tee-times is intended to be transitional and will
7994 * likely be removed in 4.4.0, leaving the behavior as getting the values
7995 * either from the configured parameters (if you want zeros, define them as
7996 * zeros) or by calculating them per the RFC.
7998 * \param reply - pointer to the reply_state structure
7999 * \param ia_cursor - offset of the beginning of the IA_XX option within the
8000 * reply's outbound data buffer
8003 set_reply_tee_times(struct reply_state
* reply
, unsigned ia_cursor
)
8005 struct option_cache
*oc
;
8008 /* Found out if calculated values are enabled. */
8009 oc
= lookup_option(&server_universe
, reply
->opt_state
,
8010 SV_DHCPV6_SET_TEE_TIMES
);
8011 set_tee_times
= (oc
&&
8012 evaluate_boolean_option_cache(NULL
, reply
->packet
,
8014 reply
->packet
->options
,
8016 &global_scope
, oc
, MDL
));
8018 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
8019 DHO_DHCP_RENEWAL_TIME
);
8021 /* dhcp-renewal-time is defined, use it */
8022 struct data_string data
;
8023 memset(&data
, 0x00, sizeof(data
));
8025 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
8026 reply
->packet
->options
,
8027 reply
->opt_state
, &global_scope
,
8030 log_error("Invalid renewal time.");
8033 reply
->renew
= getULong(data
.data
);
8036 if (data
.data
!= NULL
)
8037 data_string_forget(&data
, MDL
);
8038 } else if (set_tee_times
) {
8039 /* Setting them is enabled so T1 is either infinite or
8040 * 0.5 * the shortest preferred lifetime in the IA_XX */
8041 reply
->renew
= (reply
->min_prefer
== 0xFFFFFFFF ? 0xFFFFFFFF
8042 : reply
->min_prefer
/ 2);
8044 /* Default is to let the client choose */
8048 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
8051 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
8052 DHO_DHCP_REBINDING_TIME
);
8054 /* dhcp-rebinding-time is defined, use it */
8055 struct data_string data
;
8056 memset(&data
, 0x00, sizeof(data
));
8058 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
8059 reply
->packet
->options
,
8060 reply
->opt_state
, &global_scope
,
8063 log_error("Invalid rebinding time.");
8066 reply
->rebind
= getULong(data
.data
);
8069 if (data
.data
!= NULL
)
8070 data_string_forget(&data
, MDL
);
8071 } else if (set_tee_times
) {
8072 /* Setting them is enabled so T2 is either infinite or
8073 * 0.8 * the shortest preferred lifetime in the reply */
8074 reply
->rebind
= (reply
->min_prefer
== 0xFFFFFFFF ? 0xFFFFFFFF
8075 : (reply
->min_prefer
/ 5) * 4);
8077 /* Default is to let the client choose */
8081 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);