2 * Copyright (C) 2006-2017 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
);
1253 * \brief Get an IPv6 address for the client.
1255 * Attempt to find a usable address for the client. We walk through
1256 * the ponds checking for permit and deny then through the pools
1257 * seeing if they have an available address.
1259 * \param reply = the state structure for the current work on this request
1260 * if we create a lease we return it using reply->lease
1263 * ISC_R_SUCCESS = we were able to find an address and are returning a
1264 * pointer to the lease
1265 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1266 * is probabalistic. We don't exhaustively try the
1267 * address range, instead we hash the duid and if
1268 * the address derived from the hash is in use we
1269 * hash the address. After a number of failures we
1270 * conclude the pool is basically full.
1273 pick_v6_address(struct reply_state
*reply
)
1275 struct ipv6_pool
*p
= NULL
;
1276 struct ipv6_pond
*pond
;
1279 unsigned int attempts
;
1280 char tmp_buf
[INET6_ADDRSTRLEN
];
1281 struct iasubopt
**addr
= &reply
->lease
;
1282 isc_uint64_t total
= 0;
1283 isc_uint64_t active
= 0;
1284 isc_uint64_t abandoned
= 0;
1285 int jumbo_range
= 0;
1286 char *shared_name
= (reply
->shared
->name
?
1287 reply
->shared
->name
: "(no name)");
1290 * Do a quick walk through of the ponds and pools
1291 * to see if we have any NA address pools
1293 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1294 if (pond
->ipv6_pools
== NULL
)
1297 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1298 if (p
->pool_type
== D6O_IA_NA
)
1305 /* If we get here and p is NULL we have no useful pools */
1307 log_debug("Unable to pick client address: "
1308 "no IPv6 pools on this shared network");
1309 return ISC_R_NORESOURCES
;
1313 * We have at least one pool that could provide an address
1314 * Now we walk through the ponds and pools again and check
1315 * to see if the client is permitted and if an address is
1318 * Within a given pond we start looking at the last pool we
1319 * allocated from, unless it had a collision trying to allocate
1320 * an address. This will tend to move us into less-filled pools.
1323 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1324 isc_result_t result
= ISC_R_FAILURE
;
1326 if (((pond
->prohibit_list
!= NULL
) &&
1327 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1328 ((pond
->permit_list
!= NULL
) &&
1329 (!permitted(reply
->packet
, pond
->permit_list
))))
1333 /* If pond is EUI-64 but client duid isn't a valid EUI-64
1334 * id, then skip this pond */
1335 if (pond
->use_eui_64
&&
1336 !valid_eui_64_duid(&reply
->ia
->iaid_duid
, IAID_LEN
)) {
1341 start_pool
= pond
->last_ipv6_pool
;
1344 p
= pond
->ipv6_pools
[i
];
1345 if (p
->pool_type
== D6O_IA_NA
) {
1347 if (pond
->use_eui_64
) {
1349 create_lease6_eui_64(p
, addr
,
1350 &reply
->ia
->iaid_duid
,
1357 create_lease6(p
, addr
, &attempts
,
1358 &reply
->ia
->iaid_duid
,
1363 if (result
== ISC_R_SUCCESS
) {
1365 * Record the pool used (or next one if
1366 * there was a collision).
1370 if (pond
->ipv6_pools
[i
]
1376 pond
->last_ipv6_pool
= i
;
1378 log_debug("Picking pool address %s",
1381 tmp_buf
, sizeof(tmp_buf
)));
1382 return (ISC_R_SUCCESS
);
1387 if (pond
->ipv6_pools
[i
] == NULL
) {
1390 } while (i
!= start_pool
);
1392 if (result
== ISC_R_NORESOURCES
) {
1393 jumbo_range
+= pond
->jumbo_range
;
1394 total
+= pond
->num_total
;
1395 active
+= pond
->num_active
;
1396 abandoned
+= pond
->num_abandoned
;
1401 * If we failed to pick an IPv6 address from any of the subnets.
1402 * Presumably that means we have no addresses for the client.
1404 if (jumbo_range
!= 0) {
1405 log_debug("Unable to pick client address: "
1406 "no addresses available - shared network %s: "
1407 " 2^64-1 < total, %llu active, %llu abandoned",
1408 shared_name
, active
- abandoned
, abandoned
);
1410 log_debug("Unable to pick client address: "
1411 "no addresses available - shared network %s: "
1412 "%llu total, %llu active, %llu abandoned",
1413 shared_name
, total
, active
- abandoned
, abandoned
);
1416 return ISC_R_NORESOURCES
;
1420 * Try to get the IPv6 prefix the client asked for from the
1423 * pref is the result (should be a pointer to NULL on entry)
1424 * pool is the prefix pool to search in
1425 * requested_pref is the address the client wants
1428 try_client_v6_prefix(struct iasubopt
**pref
,
1429 struct ipv6_pool
*pool
,
1430 const struct data_string
*requested_pref
)
1433 struct in6_addr tmp_pref
;
1435 isc_result_t result
;
1437 if (requested_pref
->len
< sizeof(tmp_plen
) + sizeof(tmp_pref
)) {
1438 return DHCP_R_INVALIDARG
;
1441 tmp_plen
= (int) requested_pref
->data
[0];
1442 if ((tmp_plen
< 3) || (tmp_plen
> 128)) {
1443 return ISC_R_FAILURE
;
1446 memcpy(&tmp_pref
, requested_pref
->data
+ 1, sizeof(tmp_pref
));
1447 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref
)) {
1448 return ISC_R_FAILURE
;
1452 memcpy(&ia
.iabuf
, &tmp_pref
, 16);
1453 if (!is_cidr_mask_valid(&ia
, (int) tmp_plen
)) {
1454 return ISC_R_FAILURE
;
1457 if (!ipv6_in_pool(&tmp_pref
, pool
) ||
1458 ((int)tmp_plen
!= pool
->units
)) {
1459 return ISC_R_ADDRNOTAVAIL
;
1462 if (prefix6_exists(pool
, &tmp_pref
, tmp_plen
)) {
1463 return ISC_R_ADDRINUSE
;
1466 result
= iasubopt_allocate(pref
, MDL
);
1467 if (result
!= ISC_R_SUCCESS
) {
1471 (*pref
)->addr
= tmp_pref
;
1472 (*pref
)->plen
= tmp_plen
;
1474 /* Default is soft binding for 2 minutes. */
1475 result
= add_lease6(pool
, *pref
, cur_time
+ 120);
1476 if (result
!= ISC_R_SUCCESS
) {
1477 iasubopt_dereference(pref
, MDL
);
1485 * \brief Get an IPv6 prefix for the client.
1487 * Attempt to find a usable prefix for the client. Based upon the prefix
1488 * length mode and the plen supplied by the client (if one), we make one
1489 * or more calls to pick_v6_prefix_helper() to find a prefix as follows:
1491 * PLM_IGNORE or client specifies a plen of zero, use the first available
1492 * prefix regardless of it's length.
1494 * PLM_PREFER – look for an exact match to client's plen first, if none
1495 * found, use the first available prefix of any length
1497 * PLM_EXACT – look for an exact match first, if none found then fail. This
1498 * is the default behavior.
1500 * PLM_MAXIMUM - look for an exact match first, then the first available whose
1501 * prefix length is less than client's plen, otherwise fail.
1503 * PLM_MINIMUM - look for an exact match first, then the first available whose
1504 * prefix length is greater than client's plen, otherwise fail.
1506 * Note that the selection mode is configurable at the global scope only via
1509 * \param reply = the state structure for the current work on this request
1510 * if we create a lease we return it using reply->lease
1513 * ISC_R_SUCCESS = we were able to find an prefix and are returning a
1514 * pointer to the lease
1515 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1516 * is probabalistic. We don't exhaustively try the
1517 * address range, instead we hash the duid and if
1518 * the address derived from the hash is in use we
1519 * hash the address. After a number of failures we
1520 * conclude the pool is basically full.
1523 pick_v6_prefix(struct reply_state
*reply
) {
1524 struct ipv6_pool
*p
= NULL
;
1525 struct ipv6_pond
*pond
;
1527 isc_result_t result
;
1530 * Do a quick walk through of the ponds and pools
1531 * to see if we have any prefix pools
1533 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1534 if (pond
->ipv6_pools
== NULL
)
1537 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1538 if (p
->pool_type
== D6O_IA_PD
)
1545 /* If we get here and p is NULL we have no useful pools */
1547 log_debug("Unable to pick client prefix: "
1548 "no IPv6 pools on this shared network");
1549 return ISC_R_NORESOURCES
;
1552 if (reply
->preflen
<= 0) {
1553 /* If we didn't get a plen (-1) or client plen is 0, then just
1554 * select first available (same as PLM_INGORE) */
1555 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1557 switch (prefix_length_mode
) {
1559 /* First we look for an exact match, if not found
1560 * then first available */
1561 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1562 if (result
!= ISC_R_SUCCESS
) {
1563 result
= pick_v6_prefix_helper(reply
,
1569 /* Match exactly or fail */
1570 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1575 /* First we look for an exact match, if not found
1576 * then first available by mode */
1577 result
= pick_v6_prefix_helper(reply
, PLM_EXACT
);
1578 if (result
!= ISC_R_SUCCESS
) {
1579 result
= pick_v6_prefix_helper(reply
,
1580 prefix_length_mode
);
1585 /* First available */
1586 result
= pick_v6_prefix_helper(reply
, PLM_IGNORE
);
1591 if (result
== ISC_R_SUCCESS
) {
1592 char tmp_buf
[INET6_ADDRSTRLEN
];
1594 log_debug("Picking pool prefix %s/%u",
1595 inet_ntop(AF_INET6
, &(reply
->lease
->addr
),
1596 tmp_buf
, sizeof(tmp_buf
)),
1597 (unsigned)(reply
->lease
->plen
));
1598 return (ISC_R_SUCCESS
);
1602 * If we failed to pick an IPv6 prefix
1603 * Presumably that means we have no prefixes for the client.
1605 log_debug("Unable to pick client prefix: no prefixes available");
1606 return ISC_R_NORESOURCES
;
1611 * \brief Get an IPv6 prefix for the client based upon selection mode.
1613 * We walk through the ponds checking for permit and deny. If a pond is
1614 * permissable to use, loop through its PD pools checking prefix lengths
1615 * against the client plen based on the prefix length mode, looking for
1616 * available prefixes.
1618 * \param reply = the state structure for the current work on this request
1619 * if we create a lease we return it using reply->lease
1620 * \prefix_mode = selection mode to use
1623 * ISC_R_SUCCESS = we were able to find a prefix and are returning a
1624 * pointer to the lease
1625 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1626 * is probabalistic. We don't exhaustively try the
1627 * address range, instead we hash the duid and if
1628 * the address derived from the hash is in use we
1629 * hash the address. After a number of failures we
1630 * conclude the pool is basically full.
1633 pick_v6_prefix_helper(struct reply_state
*reply
, int prefix_mode
) {
1634 struct ipv6_pool
*p
= NULL
;
1635 struct ipv6_pond
*pond
;
1637 unsigned int attempts
;
1638 struct iasubopt
**pref
= &reply
->lease
;
1640 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
1641 if (((pond
->prohibit_list
!= NULL
) &&
1642 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
1643 ((pond
->permit_list
!= NULL
) &&
1644 (!permitted(reply
->packet
, pond
->permit_list
))))
1647 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
1648 if ((p
->pool_type
== D6O_IA_PD
) &&
1649 (eval_prefix_mode(p
->units
, reply
->preflen
,
1650 prefix_mode
) == 1) &&
1651 (create_prefix6(p
, pref
, &attempts
,
1652 &reply
->ia
->iaid_duid
,
1653 cur_time
+ 120) == ISC_R_SUCCESS
)) {
1654 return (ISC_R_SUCCESS
);
1659 return ISC_R_NORESOURCES
;
1664 * \brief Test a prefix length against another based on prefix length mode
1666 * \param len - prefix length to test
1667 * \param preflen - preferred prefix length against which to test
1668 * \param prefix_mode - prefix selection mode with which to test
1670 * Note that the case of preferred length of 0 is not short-cut here as it
1671 * is assumed to be done at a higher level.
1673 * \return 1 if the given length is usable based upon mode and a preferred
1677 eval_prefix_mode(int len
, int preflen
, int prefix_mode
) {
1679 switch (prefix_mode
) {
1681 use_it
= (len
== preflen
);
1684 /* they asked for a prefix length no "shorter" than preflen */
1685 use_it
= (len
>= preflen
);
1688 /* they asked for a prefix length no "longer" than preflen */
1689 use_it
= (len
<= preflen
);
1692 /* otherwise use it */
1700 *! \file server/dhcpv6.c
1702 * \brief construct a reply containing information about a client's lease
1704 * lease_to_client() is called from several messages to construct a
1705 * reply that contains all that we know about the client's correct lease
1706 * (or projected lease).
1708 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1709 * send what we "may" give them on a request.
1711 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1712 * the client should really use).
1714 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1715 * Rebind out any "wrong" addresses the client sends. This means we send
1716 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1717 * possibly send the address with zeroed lifetimes.
1719 * Information-Request - No binding.
1721 * The basic structure is to traverse the client-supplied data first, and
1722 * validate and echo back any contents that can be. If the client-supplied
1723 * data does not error out (on renew/rebind as above), but we did not send
1724 * any addresses, attempt to allocate one.
1726 * At the end of the this function we call commit_leases_timed() to
1727 * fsync and rotate the file as necessary. commit_leases_timed() will
1728 * check that we have written at least one lease to the file and that
1729 * some time has passed before doing any fsync or file rewrite so we
1730 * don't bother tracking if we did a write_ia during this function.
1732 /* TODO: look at client hints for lease times */
1735 lease_to_client(struct data_string
*reply_ret
,
1736 struct packet
*packet
,
1737 const struct data_string
*client_id
,
1738 const struct data_string
*server_id
)
1740 static struct reply_state reply
;
1741 struct option_cache
*oc
;
1742 struct data_string packet_oro
;
1745 memset(&packet_oro
, 0, sizeof(packet_oro
));
1747 /* Locate the client. */
1748 if (shared_network_from_packet6(&reply
.shared
,
1749 packet
) != ISC_R_SUCCESS
)
1753 * Initialize the reply.
1755 packet_reference(&reply
.packet
, packet
, MDL
);
1756 data_string_copy(&reply
.client_id
, client_id
, MDL
);
1758 if (!start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
1762 /* Set the write cursor to just past the reply header. */
1763 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1766 * Get the ORO from the packet, if any.
1768 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ORO
);
1770 if (!evaluate_option_cache(&packet_oro
, packet
,
1772 packet
->options
, NULL
,
1773 &global_scope
, oc
, MDL
)) {
1774 log_error("lease_to_client: error evaluating ORO.");
1780 * Find a host record that matches the packet, if any, and is
1781 * valid for the shared network the client is on.
1783 if (find_hosts6(&reply
.host
, packet
, client_id
, MDL
)) {
1785 seek_shared_host(&reply
.host
, reply
.shared
);
1788 /* Process the client supplied IA's onto the reply buffer. */
1790 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
1792 for (; oc
!= NULL
; oc
= oc
->next
) {
1793 isc_result_t status
;
1795 /* Start counting resources (addresses) offered. */
1796 reply
.client_resources
= 0;
1797 reply
.resources_included
= ISC_FALSE
;
1799 status
= reply_process_ia_na(&reply
, oc
);
1802 * We continue to try other IA's whether we can address
1803 * this one or not. Any other result is an immediate fail.
1805 if ((status
!= ISC_R_SUCCESS
) &&
1806 (status
!= ISC_R_NORESOURCES
))
1809 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
1810 for (; oc
!= NULL
; oc
= oc
->next
) {
1811 isc_result_t status
;
1813 /* Start counting resources (addresses) offered. */
1814 reply
.client_resources
= 0;
1815 reply
.resources_included
= ISC_FALSE
;
1817 status
= reply_process_ia_ta(&reply
, oc
);
1820 * We continue to try other IA's whether we can address
1821 * this one or not. Any other result is an immediate fail.
1823 if ((status
!= ISC_R_SUCCESS
) &&
1824 (status
!= ISC_R_NORESOURCES
))
1828 /* Same for IA_PD's. */
1830 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
1831 for (; oc
!= NULL
; oc
= oc
->next
) {
1832 isc_result_t status
;
1834 /* Start counting resources (prefixes) offered. */
1835 reply
.client_resources
= 0;
1836 reply
.resources_included
= ISC_FALSE
;
1838 status
= reply_process_ia_pd(&reply
, oc
);
1841 * We continue to try other IA_PD's whether we can address
1842 * this one or not. Any other result is an immediate fail.
1844 if ((status
!= ISC_R_SUCCESS
) &&
1845 (status
!= ISC_R_NORESOURCES
))
1850 * Make no reply if we gave no resources and is not
1851 * for Information-Request.
1853 if ((reply
.ia_count
== 0) && (reply
.pd_count
== 0)) {
1854 if (reply
.packet
->dhcpv6_msg_type
!=
1855 DHCPV6_INFORMATION_REQUEST
)
1859 * Because we only execute statements on a per-IA basis,
1860 * we need to execute statements in any non-IA reply to
1861 * source configuration.
1863 execute_statements_in_scope(NULL
, reply
.packet
, NULL
, NULL
,
1864 reply
.packet
->options
,
1865 reply
.opt_state
, &global_scope
,
1866 reply
.shared
->group
, root_group
,
1869 /* Execute statements from class scopes. */
1870 for (i
= reply
.packet
->class_count
; i
> 0; i
--) {
1871 execute_statements_in_scope(NULL
, reply
.packet
,
1873 reply
.packet
->options
,
1876 reply
.packet
->classes
[i
- 1]->group
,
1877 reply
.shared
->group
, NULL
);
1880 /* Bring in any configuration from a host record. */
1881 if (reply
.host
!= NULL
)
1882 execute_statements_in_scope(NULL
, reply
.packet
,
1884 reply
.packet
->options
,
1888 reply
.shared
->group
, NULL
);
1892 * RFC3315 section 17.2.2 (Solicit):
1894 * If the server will not assign any addresses to any IAs in a
1895 * subsequent Request from the client, the server MUST send an
1896 * Advertise message to the client that includes only a Status
1897 * Code option with code NoAddrsAvail and a status message for
1898 * the user, a Server Identifier option with the server's DUID,
1899 * and a Client Identifier option with the client's DUID.
1901 * This has been updated by an errata such that the server
1902 * can always send an IA.
1904 * Section 18.2.1 (Request):
1906 * If the server cannot assign any addresses to an IA in the
1907 * message from the client, the server MUST include the IA in
1908 * the Reply message with no addresses in the IA and a Status
1909 * Code option in the IA containing status code NoAddrsAvail.
1911 * Section 18.1.8 (Client Behavior):
1913 * Leave unchanged any information about addresses the client has
1914 * recorded in the IA but that were not included in the IA from
1916 * Sends a Renew/Rebind if the IA is not in the Reply message.
1920 * Having stored the client's IA's, store any options that
1921 * will fit in the remaining space.
1923 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+ reply
.cursor
,
1924 sizeof(reply
.buf
) - reply
.cursor
,
1925 reply
.opt_state
, reply
.packet
,
1926 required_opts_solicit
,
1929 /* Return our reply to the caller. */
1930 reply_ret
->len
= reply
.cursor
;
1931 reply_ret
->buffer
= NULL
;
1932 if (!buffer_allocate(&reply_ret
->buffer
, reply
.cursor
, MDL
)) {
1933 log_fatal("No memory to store Reply.");
1935 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
, reply
.cursor
);
1936 reply_ret
->data
= reply_ret
->buffer
->data
;
1938 /* If appropriate commit and rotate the lease file */
1939 (void) commit_leases_timed();
1943 if (reply
.shared
!= NULL
)
1944 shared_network_dereference(&reply
.shared
, MDL
);
1945 if (reply
.host
!= NULL
)
1946 host_dereference(&reply
.host
, MDL
);
1947 if (reply
.opt_state
!= NULL
)
1948 option_state_dereference(&reply
.opt_state
, MDL
);
1949 if (reply
.packet
!= NULL
)
1950 packet_dereference(&reply
.packet
, MDL
);
1951 if (reply
.client_id
.data
!= NULL
)
1952 data_string_forget(&reply
.client_id
, MDL
);
1953 if (packet_oro
.buffer
!= NULL
)
1954 data_string_forget(&packet_oro
, MDL
);
1955 reply
.renew
= reply
.rebind
= reply
.min_prefer
= reply
.min_valid
= 0;
1959 /* Process a client-supplied IA_NA. This may append options to the tail of
1960 * the reply packet being built in the reply_state structure.
1963 reply_process_ia_na(struct reply_state
*reply
, struct option_cache
*ia
) {
1964 isc_result_t status
= ISC_R_SUCCESS
;
1967 struct option_state
*packet_ia
;
1968 struct option_cache
*oc
;
1969 struct data_string ia_data
, data
;
1971 /* Initialize values that will get cleaned up on return. */
1973 memset(&ia_data
, 0, sizeof(ia_data
));
1974 memset(&data
, 0, sizeof(data
));
1976 * Note that find_client_address() may set reply->lease.
1979 /* Make sure there is at least room for the header. */
1980 if ((reply
->cursor
+ IA_NA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
1981 log_error("reply_process_ia_na: Reply too long for IA.");
1982 return ISC_R_NOSPACE
;
1986 /* Fetch the IA_NA contents. */
1987 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
1988 ia
, IA_NA_OFFSET
)) {
1989 log_error("reply_process_ia_na: error evaluating ia");
1990 status
= ISC_R_FAILURE
;
1994 /* Extract IA_NA header contents. */
1995 iaid
= getULong(ia_data
.data
);
1996 reply
->renew
= getULong(ia_data
.data
+ 4);
1997 reply
->rebind
= getULong(ia_data
.data
+ 8);
1999 /* Create an IA_NA structure. */
2000 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2001 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2002 log_error("reply_process_ia_na: no memory for ia.");
2003 status
= ISC_R_NOMEMORY
;
2006 reply
->ia
->ia_type
= D6O_IA_NA
;
2008 /* Cache pre-existing IA, if any. */
2009 ia_hash_lookup(&reply
->old_ia
, ia_na_active
,
2010 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2011 reply
->ia
->iaid_duid
.len
, MDL
);
2014 * Create an option cache to carry the IA_NA option contents, and
2015 * execute any user-supplied values into it.
2017 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2018 status
= ISC_R_NOMEMORY
;
2022 /* Check & cache the fixed host record. */
2023 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_addr
!= NULL
)) {
2024 struct iaddr tmp_addr
;
2026 if (!evaluate_option_cache(&reply
->fixed
, NULL
, NULL
, NULL
,
2027 NULL
, NULL
, &global_scope
,
2028 reply
->host
->fixed_addr
, MDL
)) {
2029 log_error("reply_process_ia_na: unable to evaluate "
2031 status
= ISC_R_FAILURE
;
2035 if (reply
->fixed
.len
< 16) {
2036 log_error("reply_process_ia_na: invalid fixed address.");
2037 status
= DHCP_R_INVALIDARG
;
2041 /* Find the static lease's subnet. */
2043 memcpy(tmp_addr
.iabuf
, reply
->fixed
.data
, 16);
2045 if (find_grouped_subnet(&reply
->subnet
, reply
->shared
,
2046 tmp_addr
, MDL
) == 0)
2047 log_fatal("Impossible condition at %s:%d.", MDL
);
2049 reply
->static_lease
= ISC_TRUE
;
2051 reply
->static_lease
= ISC_FALSE
;
2054 * Save the cursor position at the start of the IA, so we can
2055 * set length and adjust t1/t2 values later. We write a temporary
2056 * header out now just in case we decide to adjust the packet
2057 * within sub-process functions.
2059 ia_cursor
= reply
->cursor
;
2061 /* Initialize the IA_NA header. First the code. */
2062 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_NA
);
2065 /* Then option length. */
2066 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
2069 /* Then IA_NA header contents; IAID. */
2070 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2073 /* We store the client's t1 for now, and may over-ride it later. */
2074 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
2077 /* We store the client's t2 for now, and may over-ride it later. */
2078 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
2082 * For each address in this IA_NA, decide what to do about it.
2086 * The client leaves unchanged any information about addresses
2087 * it has recorded but are not included ("cancel/break" below).
2088 * A not included IA ("cleanup" below) could give a Renew/Rebind.
2090 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2091 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
2092 reply
->client_valid
= reply
->client_prefer
= 0;
2093 for (; oc
!= NULL
; oc
= oc
->next
) {
2094 status
= reply_process_addr(reply
, oc
);
2097 * Canceled means we did not allocate addresses to the
2098 * client, but we're "done" with this IA - we set a status
2099 * code. So transmit this reply, e.g., move on to the next
2102 if (status
== ISC_R_CANCELED
)
2105 if ((status
!= ISC_R_SUCCESS
) &&
2106 (status
!= ISC_R_ADDRINUSE
) &&
2107 (status
!= ISC_R_ADDRNOTAVAIL
))
2114 * If we fell through the above and never gave the client
2115 * an address, give it one now.
2117 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
2118 status
= find_client_address(reply
);
2120 if (status
== ISC_R_NORESOURCES
) {
2121 switch (reply
->packet
->dhcpv6_msg_type
) {
2122 case DHCPV6_SOLICIT
:
2124 * No address for any IA is handled
2129 case DHCPV6_REQUEST
:
2130 /* Section 18.2.1 (Request):
2132 * If the server cannot assign any addresses to
2133 * an IA in the message from the client, the
2134 * server MUST include the IA in the Reply
2135 * message with no addresses in the IA and a
2136 * Status Code option in the IA containing
2137 * status code NoAddrsAvail.
2139 option_state_dereference(&reply
->reply_ia
, MDL
);
2140 if (!option_state_allocate(&reply
->reply_ia
,
2143 log_error("reply_process_ia_na: No "
2144 "memory for option state "
2146 status
= ISC_R_NOMEMORY
;
2150 if (!set_status_code(STATUS_NoAddrsAvail
,
2151 "No addresses available "
2152 "for this interface.",
2154 log_error("reply_process_ia_na: Unable "
2155 "to set NoAddrsAvail status "
2157 status
= ISC_R_FAILURE
;
2161 status
= ISC_R_SUCCESS
;
2166 * RFC 3315 does not tell us to emit a status
2167 * code in this condition, or anything else.
2169 * If we included non-allocated addresses
2170 * (zeroed lifetimes) in an IA, then the client
2171 * will deconfigure them.
2173 * So we want to include the IA even if we
2174 * can't give it a new address if it includes
2175 * zeroed lifetime addresses.
2177 * We don't want to include the IA if we
2178 * provide zero addresses including zeroed
2181 if (reply
->resources_included
)
2182 status
= ISC_R_SUCCESS
;
2189 if (status
!= ISC_R_SUCCESS
)
2193 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2194 sizeof(reply
->buf
) - reply
->cursor
,
2195 reply
->reply_ia
, reply
->packet
,
2196 required_opts_IA
, NULL
);
2198 /* Reset the length of this IA to match what was just written. */
2199 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2200 reply
->cursor
- (ia_cursor
+ 4));
2202 /* Calculate T1/T2 and stuff them in the reply */
2203 set_reply_tee_times(reply
, ia_cursor
);
2206 * yes, goto's aren't the best but we also want to avoid extra
2209 if (status
== ISC_R_CANCELED
)
2213 * Handle static leases, we always log stuff and if it's
2214 * a hard binding we run any commit statements that we have
2216 if (reply
->static_lease
) {
2217 char tmp_addr
[INET6_ADDRSTRLEN
];
2218 log_info("%s NA: address %s to client with duid %s iaid = %d "
2220 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2221 inet_ntop(AF_INET6
, reply
->fixed
.data
, tmp_addr
,
2223 print_hex_1(reply
->client_id
.len
,
2224 reply
->client_id
.data
, 60),
2227 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
2228 (reply
->on_star
.on_commit
!= NULL
)) {
2229 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
2230 reply
->packet
->options
,
2231 reply
->opt_state
, NULL
,
2232 reply
->on_star
.on_commit
, NULL
);
2233 executable_statement_dereference
2234 (&reply
->on_star
.on_commit
, MDL
);
2240 * If we have any addresses log what we are doing.
2242 if (reply
->ia
->num_iasubopt
!= 0) {
2243 struct iasubopt
*tmp
;
2245 char tmp_addr
[INET6_ADDRSTRLEN
];
2247 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2248 tmp
= reply
->ia
->iasubopt
[i
];
2250 log_info("%s NA: address %s to client with duid %s "
2251 "iaid = %d valid for %u seconds",
2252 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
2253 inet_ntop(AF_INET6
, &tmp
->addr
,
2254 tmp_addr
, sizeof(tmp_addr
)),
2255 print_hex_1(reply
->client_id
.len
,
2256 reply
->client_id
.data
, 60),
2262 * If this is not a 'soft' binding, consume the new changes into
2263 * the database (if any have been attached to the ia_na).
2265 * Loop through the assigned dynamic addresses, referencing the
2266 * leases onto this IA_NA rather than any old ones, and updating
2267 * pool timers for each (if any).
2270 if ((reply
->ia
->num_iasubopt
!= 0) &&
2271 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
2272 struct iasubopt
*tmp
;
2273 struct data_string
*ia_id
;
2276 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2277 tmp
= reply
->ia
->iasubopt
[i
];
2279 if (tmp
->ia
!= NULL
)
2280 ia_dereference(&tmp
->ia
, MDL
);
2281 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
2283 /* Commit 'hard' bindings. */
2284 renew_lease6(tmp
->ipv6_pool
, tmp
);
2285 schedule_lease_timeout(tmp
->ipv6_pool
);
2287 /* If we have anything to do on commit do it now */
2288 if (tmp
->on_star
.on_commit
!= NULL
) {
2289 execute_statements(NULL
, reply
->packet
,
2291 reply
->packet
->options
,
2294 tmp
->on_star
.on_commit
,
2296 executable_statement_dereference
2297 (&tmp
->on_star
.on_commit
, MDL
);
2300 #if defined (NSUPDATE)
2302 * Perform ddns updates.
2304 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2307 evaluate_boolean_option_cache(NULL
, reply
->packet
,
2309 reply
->packet
->options
,
2313 ddns_updates(reply
->packet
, NULL
, NULL
,
2314 tmp
, NULL
, reply
->opt_state
);
2317 /* Do our threshold check. */
2318 check_pool6_threshold(reply
, tmp
);
2321 /* Remove any old ia from the hash. */
2322 if (reply
->old_ia
!= NULL
) {
2323 ia_id
= &reply
->old_ia
->iaid_duid
;
2324 ia_hash_delete(ia_na_active
,
2325 (unsigned char *)ia_id
->data
,
2327 ia_dereference(&reply
->old_ia
, MDL
);
2330 /* Put new ia into the hash. */
2331 reply
->ia
->cltt
= cur_time
;
2332 ia_id
= &reply
->ia
->iaid_duid
;
2333 ia_hash_add(ia_na_active
, (unsigned char *)ia_id
->data
,
2334 ia_id
->len
, reply
->ia
, MDL
);
2336 write_ia(reply
->ia
);
2338 schedule_lease_timeout_reply(reply
);
2342 if (packet_ia
!= NULL
)
2343 option_state_dereference(&packet_ia
, MDL
);
2344 if (reply
->reply_ia
!= NULL
)
2345 option_state_dereference(&reply
->reply_ia
, MDL
);
2346 if (ia_data
.data
!= NULL
)
2347 data_string_forget(&ia_data
, MDL
);
2348 if (data
.data
!= NULL
)
2349 data_string_forget(&data
, MDL
);
2350 if (reply
->ia
!= NULL
)
2351 ia_dereference(&reply
->ia
, MDL
);
2352 if (reply
->old_ia
!= NULL
)
2353 ia_dereference(&reply
->old_ia
, MDL
);
2354 if (reply
->lease
!= NULL
)
2355 iasubopt_dereference(&reply
->lease
, MDL
);
2356 if (reply
->fixed
.data
!= NULL
)
2357 data_string_forget(&reply
->fixed
, MDL
);
2358 if (reply
->subnet
!= NULL
)
2359 subnet_dereference(&reply
->subnet
, MDL
);
2360 if (reply
->on_star
.on_expiry
!= NULL
)
2361 executable_statement_dereference
2362 (&reply
->on_star
.on_expiry
, MDL
);
2363 if (reply
->on_star
.on_release
!= NULL
)
2364 executable_statement_dereference
2365 (&reply
->on_star
.on_release
, MDL
);
2368 * ISC_R_CANCELED is a status code used by the addr processing to
2369 * indicate we're replying with a status code. This is still a
2370 * success at higher layers.
2372 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
2376 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
2377 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
2378 * in the event we are replying with a status code and do not wish to process
2379 * more IAADDRs within this IA.
2382 reply_process_addr(struct reply_state
*reply
, struct option_cache
*addr
) {
2383 u_int32_t pref_life
, valid_life
;
2384 struct binding_scope
**scope
;
2385 struct group
*group
;
2386 struct subnet
*subnet
;
2387 struct iaddr tmp_addr
;
2388 struct option_cache
*oc
;
2389 struct data_string iaaddr
, data
;
2390 isc_result_t status
= ISC_R_SUCCESS
;
2392 int invalid_for_eui_64
= 0;
2395 /* Initializes values that will be cleaned up. */
2396 memset(&iaaddr
, 0, sizeof(iaaddr
));
2397 memset(&data
, 0, sizeof(data
));
2398 /* Note that reply->lease may be set by address_is_owned() */
2401 * There is no point trying to process an incoming address if there
2402 * is no room for an outgoing address.
2404 if ((reply
->cursor
+ 28) > sizeof(reply
->buf
)) {
2405 log_error("reply_process_addr: Out of room for address.");
2406 return ISC_R_NOSPACE
;
2409 /* Extract this IAADDR option. */
2410 if (!evaluate_option_cache(&iaaddr
, reply
->packet
, NULL
, NULL
,
2411 reply
->packet
->options
, NULL
, &global_scope
,
2413 (iaaddr
.len
< IAADDR_OFFSET
)) {
2414 log_error("reply_process_addr: error evaluating IAADDR.");
2415 status
= ISC_R_FAILURE
;
2419 /* The first 16 bytes are the IPv6 address. */
2420 pref_life
= getULong(iaaddr
.data
+ 16);
2421 valid_life
= getULong(iaaddr
.data
+ 20);
2423 if ((reply
->client_valid
== 0) ||
2424 (reply
->client_valid
> valid_life
))
2425 reply
->client_valid
= valid_life
;
2427 if ((reply
->client_prefer
== 0) ||
2428 (reply
->client_prefer
> pref_life
))
2429 reply
->client_prefer
= pref_life
;
2432 * Clients may choose to send :: as an address, with the idea to give
2433 * hints about preferred-lifetime or valid-lifetime.
2436 memset(tmp_addr
.iabuf
, 0, 16);
2437 if (!memcmp(iaaddr
.data
, tmp_addr
.iabuf
, 16)) {
2438 /* Status remains success; we just ignore this one. */
2442 /* tmp_addr len remains 16 */
2443 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2446 * Verify that this address is on the client's network.
2448 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
2449 subnet
= subnet
->next_sibling
) {
2450 if (addr_eq(subnet_number(tmp_addr
, subnet
->netmask
),
2457 /* If the requested address falls into an EUI-64 pool, then
2458 * we need to verify if it has EUI-64 duid AND the requested
2459 * address is correct for that duid. If not we treat it just
2460 * like an not-on-link request. */
2461 struct ipv6_pool
* pool
= NULL
;
2462 struct in6_addr
* addr
= (struct in6_addr
*)(iaaddr
.data
);
2463 if ((find_ipv6_pool(&pool
, D6O_IA_NA
, addr
) == ISC_R_SUCCESS
)
2464 && (pool
->ipv6_pond
->use_eui_64
) &&
2465 (!valid_for_eui_64_pool(pool
, &reply
->client_id
, 0, addr
))) {
2466 log_debug ("Requested address: %s,"
2467 " not valid for EUI-64 pool",
2469 invalid_for_eui_64
= 1;
2474 /* Address not found on shared network. */
2476 if ((subnet
== NULL
) || invalid_for_eui_64
) {
2478 if (subnet
== NULL
) {
2480 /* Ignore this address on 'soft' bindings. */
2481 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
2482 /* disable rapid commit */
2483 reply
->buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
2484 delete_option(&dhcpv6_universe
,
2487 /* status remains success */
2492 * RFC3315 section 18.2.1:
2494 * If the server finds that the prefix on one or more IP
2495 * addresses in any IA in the message from the client is not
2496 * appropriate for the link to which the client is connected,
2497 * the server MUST return the IA to the client with a Status
2498 * Code option with the value NotOnLink.
2500 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) {
2501 /* Rewind the IA_NA to empty. */
2502 option_state_dereference(&reply
->reply_ia
, MDL
);
2503 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2504 log_error("reply_process_addr: No memory for "
2505 "option state wipe.");
2506 status
= ISC_R_NOMEMORY
;
2510 /* Append a NotOnLink status code. */
2511 if (!set_status_code(STATUS_NotOnLink
,
2512 "Address not for use on this "
2513 "link.", reply
->reply_ia
)) {
2514 log_error("reply_process_addr: Failure "
2515 "setting status code.");
2516 status
= ISC_R_FAILURE
;
2520 /* Fin (no more IAADDRs). */
2521 status
= ISC_R_CANCELED
;
2526 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2528 * If the server finds that any of the addresses are not
2529 * appropriate for the link to which the client is attached,
2530 * the server returns the address to the client with lifetimes
2533 if ((reply
->packet
->dhcpv6_msg_type
!= DHCPV6_RENEW
) &&
2534 (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
2535 log_error("It is impossible to lease a client that is "
2536 "not sending a solicit, request, renew, or "
2538 status
= ISC_R_FAILURE
;
2542 reply
->send_prefer
= reply
->send_valid
= 0;
2547 /* Verify the address belongs to the client. */
2548 if (!address_is_owned(reply
, &tmp_addr
)) {
2550 * For solicit and request, any addresses included are
2551 * 'requested' addresses. For rebind, we actually have
2552 * no direction on what to do from 3315 section 18.2.4!
2553 * So I think the best bet is to try and give it out, and if
2554 * we can't, zero lifetimes.
2556 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
2557 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
2558 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
2559 status
= reply_process_try_addr(reply
, &tmp_addr
);
2562 * If the address is in use, or isn't in any dynamic
2563 * range, continue as normal. If any other error was
2566 if ((status
!= ISC_R_SUCCESS
) &&
2567 (status
!= ISC_R_ADDRINUSE
) &&
2568 (status
!= ISC_R_ADDRNOTAVAIL
))
2572 * If we didn't honor this lease, for solicit and
2573 * request we simply omit it from our answer. For
2574 * rebind, we send it with zeroed lifetimes.
2576 if (reply
->lease
== NULL
) {
2577 if (reply
->packet
->dhcpv6_msg_type
==
2579 reply
->send_prefer
= 0;
2580 reply
->send_valid
= 0;
2584 /* status remains success - ignore */
2588 * RFC3315 section 18.2.3:
2590 * If the server cannot find a client entry for the IA the
2591 * server returns the IA containing no addresses with a Status
2592 * Code option set to NoBinding in the Reply message.
2594 * On mismatch we (ab)use this pretending we have not the IA
2595 * as soon as we have not an address.
2597 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
2598 /* Rewind the IA_NA to empty. */
2599 option_state_dereference(&reply
->reply_ia
, MDL
);
2600 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2601 log_error("reply_process_addr: No memory for "
2602 "option state wipe.");
2603 status
= ISC_R_NOMEMORY
;
2607 /* Append a NoBinding status code. */
2608 if (!set_status_code(STATUS_NoBinding
,
2609 "Address not bound to this "
2610 "interface.", reply
->reply_ia
)) {
2611 log_error("reply_process_addr: Unable to "
2612 "attach status code.");
2613 status
= ISC_R_FAILURE
;
2617 /* Fin (no more IAADDRs). */
2618 status
= ISC_R_CANCELED
;
2621 log_error("It is impossible to lease a client that is "
2622 "not sending a solicit, request, renew, or "
2624 status
= ISC_R_FAILURE
;
2629 if (reply
->static_lease
) {
2630 if (reply
->host
== NULL
)
2631 log_fatal("Impossible condition at %s:%d.", MDL
);
2633 scope
= &global_scope
;
2634 group
= reply
->subnet
->group
;
2636 if (reply
->lease
== NULL
)
2637 log_fatal("Impossible condition at %s:%d.", MDL
);
2639 scope
= &reply
->lease
->scope
;
2640 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
2644 * If client_resources is nonzero, then the reply_process_is_addressed
2645 * function has executed configuration state into the reply option
2646 * cache. We will use that valid cache to derive configuration for
2647 * whether or not to engage in additional addresses, and similar.
2649 if (reply
->client_resources
!= 0) {
2653 * Does this client have "enough" addresses already? Default
2654 * to one. Everybody gets one, and one should be enough for
2657 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2658 SV_LIMIT_ADDRS_PER_IA
);
2660 if (!evaluate_option_cache(&data
, reply
->packet
,
2662 reply
->packet
->options
,
2666 log_error("reply_process_addr: unable to "
2667 "evaluate addrs-per-ia value.");
2668 status
= ISC_R_FAILURE
;
2672 limit
= getULong(data
.data
);
2673 data_string_forget(&data
, MDL
);
2677 * If we wish to limit the client to a certain number of
2678 * addresses, then omit the address from the reply.
2680 if (reply
->client_resources
>= limit
)
2684 status
= reply_process_is_addressed(reply
, scope
, group
);
2685 if (status
!= ISC_R_SUCCESS
)
2689 status
= reply_process_send_addr(reply
, &tmp_addr
);
2692 if (iaaddr
.data
!= NULL
)
2693 data_string_forget(&iaaddr
, MDL
);
2694 if (data
.data
!= NULL
)
2695 data_string_forget(&data
, MDL
);
2696 if (reply
->lease
!= NULL
)
2697 iasubopt_dereference(&reply
->lease
, MDL
);
2703 * Verify the address belongs to the client. If we've got a host
2704 * record with a fixed address, it has to be the assigned address
2705 * (fault out all else). Otherwise it's a dynamic address, so lookup
2706 * that address and make sure it belongs to this DUID:IAID pair.
2708 static isc_boolean_t
2709 address_is_owned(struct reply_state
*reply
, struct iaddr
*addr
) {
2711 struct ipv6_pond
*pond
;
2714 * This faults out addresses that don't match fixed addresses.
2716 if (reply
->static_lease
) {
2717 if (reply
->fixed
.data
== NULL
)
2718 log_fatal("Impossible condition at %s:%d.", MDL
);
2720 if (memcmp(addr
->iabuf
, reply
->fixed
.data
, 16) == 0)
2726 if ((reply
->old_ia
== NULL
) || (reply
->old_ia
->num_iasubopt
== 0))
2729 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
2730 struct iasubopt
*tmp
;
2732 tmp
= reply
->old_ia
->iasubopt
[i
];
2734 if (memcmp(addr
->iabuf
, &tmp
->addr
, 16) == 0) {
2735 if (lease6_usable(tmp
) == ISC_FALSE
) {
2739 pond
= tmp
->ipv6_pool
->ipv6_pond
;
2740 if (((pond
->prohibit_list
!= NULL
) &&
2741 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
2742 ((pond
->permit_list
!= NULL
) &&
2743 (!permitted(reply
->packet
, pond
->permit_list
))))
2746 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
2755 /* Process a client-supplied IA_TA. This may append options to the tail of
2756 * the reply packet being built in the reply_state structure.
2759 reply_process_ia_ta(struct reply_state
*reply
, struct option_cache
*ia
) {
2760 isc_result_t status
= ISC_R_SUCCESS
;
2763 struct option_state
*packet_ia
;
2764 struct option_cache
*oc
;
2765 struct data_string ia_data
, data
;
2766 struct data_string iaaddr
;
2767 u_int32_t pref_life
, valid_life
;
2768 struct iaddr tmp_addr
;
2770 /* Initialize values that will get cleaned up on return. */
2772 memset(&ia_data
, 0, sizeof(ia_data
));
2773 memset(&data
, 0, sizeof(data
));
2774 memset(&iaaddr
, 0, sizeof(iaaddr
));
2776 /* Make sure there is at least room for the header. */
2777 if ((reply
->cursor
+ IA_TA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
2778 log_error("reply_process_ia_ta: Reply too long for IA.");
2779 return ISC_R_NOSPACE
;
2783 /* Fetch the IA_TA contents. */
2784 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
2785 ia
, IA_TA_OFFSET
)) {
2786 log_error("reply_process_ia_ta: error evaluating ia");
2787 status
= ISC_R_FAILURE
;
2791 /* Extract IA_TA header contents. */
2792 iaid
= getULong(ia_data
.data
);
2794 /* Create an IA_TA structure. */
2795 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
2796 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
2797 log_error("reply_process_ia_ta: no memory for ia.");
2798 status
= ISC_R_NOMEMORY
;
2801 reply
->ia
->ia_type
= D6O_IA_TA
;
2803 /* Cache pre-existing IA, if any. */
2804 ia_hash_lookup(&reply
->old_ia
, ia_ta_active
,
2805 (unsigned char *)reply
->ia
->iaid_duid
.data
,
2806 reply
->ia
->iaid_duid
.len
, MDL
);
2809 * Create an option cache to carry the IA_TA option contents, and
2810 * execute any user-supplied values into it.
2812 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2813 status
= ISC_R_NOMEMORY
;
2818 * Temporary leases are dynamic by definition.
2820 reply
->static_lease
= ISC_FALSE
;
2823 * Save the cursor position at the start of the IA, so we can
2824 * set length later. We write a temporary
2825 * header out now just in case we decide to adjust the packet
2826 * within sub-process functions.
2828 ia_cursor
= reply
->cursor
;
2830 /* Initialize the IA_TA header. First the code. */
2831 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_TA
);
2834 /* Then option length. */
2835 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x04u
);
2838 /* Then IA_TA header contents; IAID. */
2839 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
2843 * Deal with an IAADDR for lifetimes.
2844 * For all or none, process IAADDRs as hints.
2846 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
2847 reply
->client_valid
= reply
->client_prefer
= 0;
2848 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
2849 for (; oc
!= NULL
; oc
= oc
->next
) {
2850 memset(&iaaddr
, 0, sizeof(iaaddr
));
2851 if (!evaluate_option_cache(&iaaddr
, reply
->packet
,
2853 reply
->packet
->options
, NULL
,
2854 &global_scope
, oc
, MDL
) ||
2855 (iaaddr
.len
< IAADDR_OFFSET
)) {
2856 log_error("reply_process_ia_ta: error "
2857 "evaluating IAADDR.");
2858 status
= ISC_R_FAILURE
;
2861 /* The first 16 bytes are the IPv6 address. */
2862 pref_life
= getULong(iaaddr
.data
+ 16);
2863 valid_life
= getULong(iaaddr
.data
+ 20);
2865 if ((reply
->client_valid
== 0) ||
2866 (reply
->client_valid
> valid_life
))
2867 reply
->client_valid
= valid_life
;
2869 if ((reply
->client_prefer
== 0) ||
2870 (reply
->client_prefer
> pref_life
))
2871 reply
->client_prefer
= pref_life
;
2873 /* Nothing more if something has failed. */
2874 if (status
== ISC_R_CANCELED
)
2878 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
2879 if (!temporary_is_available(reply
, &tmp_addr
))
2881 status
= reply_process_is_addressed(reply
,
2882 &reply
->lease
->scope
,
2883 reply
->lease
->ipv6_pool
->ipv6_pond
->group
);
2884 if (status
!= ISC_R_SUCCESS
)
2886 status
= reply_process_send_addr(reply
, &tmp_addr
);
2887 if (status
!= ISC_R_SUCCESS
)
2889 if (reply
->lease
!= NULL
)
2890 iasubopt_dereference(&reply
->lease
, MDL
);
2894 /* Rewind the IA_TA to empty. */
2895 option_state_dereference(&reply
->reply_ia
, MDL
);
2896 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2897 status
= ISC_R_NOMEMORY
;
2900 status
= ISC_R_CANCELED
;
2901 reply
->client_resources
= 0;
2902 reply
->resources_included
= ISC_FALSE
;
2903 if (reply
->lease
!= NULL
)
2904 iasubopt_dereference(&reply
->lease
, MDL
);
2909 * Give the client temporary addresses.
2911 if (reply
->client_resources
!= 0)
2913 status
= find_client_temporaries(reply
);
2914 if (status
== ISC_R_NORESOURCES
) {
2915 switch (reply
->packet
->dhcpv6_msg_type
) {
2916 case DHCPV6_SOLICIT
:
2918 * No address for any IA is handled
2923 case DHCPV6_REQUEST
:
2924 /* Section 18.2.1 (Request):
2926 * If the server cannot assign any addresses to
2927 * an IA in the message from the client, the
2928 * server MUST include the IA in the Reply
2929 * message with no addresses in the IA and a
2930 * Status Code option in the IA containing
2931 * status code NoAddrsAvail.
2933 option_state_dereference(&reply
->reply_ia
, MDL
);
2934 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
2935 log_error("reply_process_ia_ta: No "
2936 "memory for option state wipe.");
2937 status
= ISC_R_NOMEMORY
;
2941 if (!set_status_code(STATUS_NoAddrsAvail
,
2942 "No addresses available "
2943 "for this interface.",
2945 log_error("reply_process_ia_ta: Unable "
2946 "to set NoAddrsAvail status code.");
2947 status
= ISC_R_FAILURE
;
2951 status
= ISC_R_SUCCESS
;
2956 * We don't want to include the IA if we
2957 * provide zero addresses including zeroed
2960 if (reply
->resources_included
)
2961 status
= ISC_R_SUCCESS
;
2966 } else if (status
!= ISC_R_SUCCESS
)
2970 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
2971 sizeof(reply
->buf
) - reply
->cursor
,
2972 reply
->reply_ia
, reply
->packet
,
2973 required_opts_IA
, NULL
);
2975 /* Reset the length of this IA to match what was just written. */
2976 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
2977 reply
->cursor
- (ia_cursor
+ 4));
2980 * yes, goto's aren't the best but we also want to avoid extra
2983 if (status
== ISC_R_CANCELED
)
2987 * If we have any addresses log what we are doing.
2989 if (reply
->ia
->num_iasubopt
!= 0) {
2990 struct iasubopt
*tmp
;
2992 char tmp_addr
[INET6_ADDRSTRLEN
];
2994 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
2995 tmp
= reply
->ia
->iasubopt
[i
];
2997 log_info("%s TA: address %s to client with duid %s "
2998 "iaid = %d valid for %u seconds",
2999 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
3000 inet_ntop(AF_INET6
, &tmp
->addr
,
3001 tmp_addr
, sizeof(tmp_addr
)),
3002 print_hex_1(reply
->client_id
.len
,
3003 reply
->client_id
.data
, 60),
3010 * For hard bindings we consume the new changes into
3011 * the database (if any have been attached to the ia_ta).
3013 * Loop through the assigned dynamic addresses, referencing the
3014 * leases onto this IA_TA rather than any old ones, and updating
3015 * pool timers for each (if any).
3017 if ((reply
->ia
->num_iasubopt
!= 0) &&
3018 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
)) {
3019 struct iasubopt
*tmp
;
3020 struct data_string
*ia_id
;
3023 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
3024 tmp
= reply
->ia
->iasubopt
[i
];
3026 if (tmp
->ia
!= NULL
)
3027 ia_dereference(&tmp
->ia
, MDL
);
3028 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
3030 /* Commit 'hard' bindings. */
3031 renew_lease6(tmp
->ipv6_pool
, tmp
);
3032 schedule_lease_timeout(tmp
->ipv6_pool
);
3034 /* If we have anything to do on commit do it now */
3035 if (tmp
->on_star
.on_commit
!= NULL
) {
3036 execute_statements(NULL
, reply
->packet
,
3038 reply
->packet
->options
,
3041 tmp
->on_star
.on_commit
,
3043 executable_statement_dereference
3044 (&tmp
->on_star
.on_commit
, MDL
);
3047 #if defined (NSUPDATE)
3049 * Perform ddns updates.
3051 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3054 evaluate_boolean_option_cache(NULL
, reply
->packet
,
3056 reply
->packet
->options
,
3060 ddns_updates(reply
->packet
, NULL
, NULL
,
3061 tmp
, NULL
, reply
->opt_state
);
3064 /* Do our threshold check. */
3065 check_pool6_threshold(reply
, tmp
);
3068 /* Remove any old ia from the hash. */
3069 if (reply
->old_ia
!= NULL
) {
3070 ia_id
= &reply
->old_ia
->iaid_duid
;
3071 ia_hash_delete(ia_ta_active
,
3072 (unsigned char *)ia_id
->data
,
3074 ia_dereference(&reply
->old_ia
, MDL
);
3077 /* Put new ia into the hash. */
3078 reply
->ia
->cltt
= cur_time
;
3079 ia_id
= &reply
->ia
->iaid_duid
;
3080 ia_hash_add(ia_ta_active
, (unsigned char *)ia_id
->data
,
3081 ia_id
->len
, reply
->ia
, MDL
);
3083 write_ia(reply
->ia
);
3085 schedule_lease_timeout_reply(reply
);
3089 if (packet_ia
!= NULL
)
3090 option_state_dereference(&packet_ia
, MDL
);
3091 if (iaaddr
.data
!= NULL
)
3092 data_string_forget(&iaaddr
, MDL
);
3093 if (reply
->reply_ia
!= NULL
)
3094 option_state_dereference(&reply
->reply_ia
, MDL
);
3095 if (ia_data
.data
!= NULL
)
3096 data_string_forget(&ia_data
, MDL
);
3097 if (data
.data
!= NULL
)
3098 data_string_forget(&data
, MDL
);
3099 if (reply
->ia
!= NULL
)
3100 ia_dereference(&reply
->ia
, MDL
);
3101 if (reply
->old_ia
!= NULL
)
3102 ia_dereference(&reply
->old_ia
, MDL
);
3103 if (reply
->lease
!= NULL
)
3104 iasubopt_dereference(&reply
->lease
, MDL
);
3107 * ISC_R_CANCELED is a status code used by the addr processing to
3108 * indicate we're replying with other addresses. This is still a
3109 * success at higher layers.
3111 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
3115 * Verify the temporary address is available.
3117 static isc_boolean_t
3118 temporary_is_available(struct reply_state
*reply
, struct iaddr
*addr
) {
3119 struct in6_addr tmp_addr
;
3120 struct subnet
*subnet
;
3121 struct ipv6_pool
*pool
= NULL
;
3122 struct ipv6_pond
*pond
= NULL
;
3125 memcpy(&tmp_addr
, addr
->iabuf
, sizeof(tmp_addr
));
3127 * Clients may choose to send :: as an address, with the idea to give
3128 * hints about preferred-lifetime or valid-lifetime.
3129 * So this is not a request for this address.
3131 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
))
3135 * Verify that this address is on the client's network.
3137 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
3138 subnet
= subnet
->next_sibling
) {
3139 if (addr_eq(subnet_number(*addr
, subnet
->netmask
),
3144 /* Address not found on shared network. */
3149 * Check if this address is owned (must be before next step).
3151 if (address_is_owned(reply
, addr
))
3155 * Verify that this address is in a temporary pool and try to get it.
3157 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3158 if (((pond
->prohibit_list
!= NULL
) &&
3159 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3160 ((pond
->permit_list
!= NULL
) &&
3161 (!permitted(reply
->packet
, pond
->permit_list
))))
3164 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3165 if (pool
->pool_type
!= D6O_IA_TA
)
3168 if (ipv6_in_pool(&tmp_addr
, pool
))
3178 if (lease6_exists(pool
, &tmp_addr
))
3180 if (iasubopt_allocate(&reply
->lease
, MDL
) != ISC_R_SUCCESS
)
3182 reply
->lease
->addr
= tmp_addr
;
3183 reply
->lease
->plen
= 0;
3184 /* Default is soft binding for 2 minutes. */
3185 if (add_lease6(pool
, reply
->lease
, cur_time
+ 120) != ISC_R_SUCCESS
)
3192 * Get a temporary address per prefix.
3195 find_client_temporaries(struct reply_state
*reply
) {
3197 struct ipv6_pool
*p
= NULL
;
3198 struct ipv6_pond
*pond
;
3199 isc_result_t status
= ISC_R_NORESOURCES
;;
3200 unsigned int attempts
;
3201 struct iaddr send_addr
;
3204 * Do a quick walk through of the ponds and pools
3205 * to see if we have any prefix pools
3207 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3208 if (pond
->ipv6_pools
== NULL
)
3211 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3212 if (p
->pool_type
== D6O_IA_TA
)
3219 /* If we get here and p is NULL we have no useful pools */
3221 log_debug("Unable to get client addresses: "
3222 "no IPv6 pools on this shared network");
3223 return ISC_R_NORESOURCES
;
3227 * We have at least one pool that could provide an address
3228 * Now we walk through the ponds and pools again and check
3229 * to see if the client is permitted and if an address is
3233 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3234 if (((pond
->prohibit_list
!= NULL
) &&
3235 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3236 ((pond
->permit_list
!= NULL
) &&
3237 (!permitted(reply
->packet
, pond
->permit_list
))))
3240 for (i
= 0; (p
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3241 if (p
->pool_type
!= D6O_IA_TA
) {
3246 * Get an address in this temporary pool.
3248 status
= create_lease6(p
, &reply
->lease
, &attempts
,
3252 if (status
!= ISC_R_SUCCESS
) {
3253 log_debug("Unable to get a temporary address.");
3257 status
= reply_process_is_addressed(reply
,
3258 &reply
->lease
->scope
,
3260 if (status
!= ISC_R_SUCCESS
) {
3264 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3265 status
= reply_process_send_addr(reply
, &send_addr
);
3266 if (status
!= ISC_R_SUCCESS
) {
3270 * reply->lease can't be null as we use it above
3271 * add check if that changes
3273 iasubopt_dereference(&reply
->lease
, MDL
);
3278 if (reply
->lease
!= NULL
) {
3279 iasubopt_dereference(&reply
->lease
, MDL
);
3285 * This function only returns failure on 'hard' failures. If it succeeds,
3286 * it will leave a lease structure behind.
3289 reply_process_try_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3290 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
3291 struct ipv6_pool
*pool
= NULL
;
3292 struct ipv6_pond
*pond
= NULL
;
3294 struct data_string data_addr
;
3296 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
3297 (addr
== NULL
) || (reply
->lease
!= NULL
))
3298 return (DHCP_R_INVALIDARG
);
3301 * Do a quick walk through of the ponds and pools
3302 * to see if we have any NA address pools
3304 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3305 if (pond
->ipv6_pools
== NULL
)
3308 for (i
= 0; ; i
++) {
3309 pool
= pond
->ipv6_pools
[i
];
3310 if ((pool
== NULL
) ||
3311 (pool
->pool_type
== D6O_IA_NA
))
3318 /* If we get here and p is NULL we have no useful pools */
3320 return (ISC_R_ADDRNOTAVAIL
);
3323 memset(&data_addr
, 0, sizeof(data_addr
));
3324 data_addr
.len
= addr
->len
;
3325 data_addr
.data
= addr
->iabuf
;
3328 * We have at least one pool that could provide an address
3329 * Now we walk through the ponds and pools again and check
3330 * to see if the client is permitted and if an address is
3333 * Within a given pond we start looking at the last pool we
3334 * allocated from, unless it had a collision trying to allocate
3335 * an address. This will tend to move us into less-filled pools.
3338 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
3339 if (((pond
->prohibit_list
!= NULL
) &&
3340 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3341 ((pond
->permit_list
!= NULL
) &&
3342 (!permitted(reply
->packet
, pond
->permit_list
))))
3345 for (i
= 0 ; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
3346 if (pool
->pool_type
!= D6O_IA_NA
)
3349 status
= try_client_v6_address(&reply
->lease
, pool
,
3351 if (status
== ISC_R_SUCCESS
)
3355 if (status
== ISC_R_SUCCESS
)
3359 /* Note that this is just pedantry. There is no allocation to free. */
3360 data_string_forget(&data_addr
, MDL
);
3361 /* Return just the most recent status... */
3365 /* Look around for an address to give the client. First, look through the
3366 * old IA for addresses we can extend. Second, try to allocate a new address.
3367 * Finally, actually add that address into the current reply IA.
3370 find_client_address(struct reply_state
*reply
) {
3371 struct iaddr send_addr
;
3372 isc_result_t status
= ISC_R_NORESOURCES
;
3373 struct iasubopt
*lease
, *best_lease
= NULL
;
3374 struct binding_scope
**scope
;
3375 struct group
*group
;
3378 if (reply
->static_lease
) {
3379 if (reply
->host
== NULL
)
3380 return DHCP_R_INVALIDARG
;
3383 memcpy(send_addr
.iabuf
, reply
->fixed
.data
, 16);
3385 scope
= &global_scope
;
3386 group
= reply
->subnet
->group
;
3390 if (reply
->old_ia
!= NULL
) {
3391 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
3392 struct shared_network
*candidate_shared
;
3393 struct ipv6_pond
*pond
;
3395 lease
= reply
->old_ia
->iasubopt
[i
];
3396 candidate_shared
= lease
->ipv6_pool
->shared_network
;
3397 pond
= lease
->ipv6_pool
->ipv6_pond
;
3400 * Look for the best lease on the client's shared
3401 * network, that is still permitted
3404 if ((candidate_shared
!= reply
->shared
) ||
3405 (lease6_usable(lease
) != ISC_TRUE
))
3408 if (((pond
->prohibit_list
!= NULL
) &&
3409 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
3410 ((pond
->permit_list
!= NULL
) &&
3411 (!permitted(reply
->packet
, pond
->permit_list
))))
3414 best_lease
= lease_compare(lease
, best_lease
);
3418 /* Try to pick a new address if we didn't find one, or if we found an
3421 if ((best_lease
== NULL
) || (best_lease
->state
== FTS_ABANDONED
)) {
3422 status
= pick_v6_address(reply
);
3423 } else if (best_lease
!= NULL
) {
3424 iasubopt_reference(&reply
->lease
, best_lease
, MDL
);
3425 status
= ISC_R_SUCCESS
;
3428 /* Pick the abandoned lease as a last resort. */
3429 if ((status
== ISC_R_NORESOURCES
) && (best_lease
!= NULL
)) {
3430 /* I don't see how this is supposed to be done right now. */
3431 log_error("Best match for DUID %s is an abandoned address,"
3432 " This may be a result of multiple clients attempting"
3433 " to use this DUID",
3434 print_hex_1(reply
->client_id
.len
,
3435 reply
->client_id
.data
, 60));
3436 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
3439 /* Give up now if we didn't find a lease. */
3440 if (status
!= ISC_R_SUCCESS
)
3443 if (reply
->lease
== NULL
)
3444 log_fatal("Impossible condition at %s:%d.", MDL
);
3446 /* Draw binding scopes from the lease's binding scope, and config
3447 * from the lease's containing subnet and higher. Note that it may
3448 * be desirable to place the group attachment directly in the pool.
3450 scope
= &reply
->lease
->scope
;
3451 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
3454 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
3457 status
= reply_process_is_addressed(reply
, scope
, group
);
3458 if (status
!= ISC_R_SUCCESS
)
3461 status
= reply_process_send_addr(reply
, &send_addr
);
3465 /* Once an address is found for a client, perform several common functions;
3466 * Calculate and store valid and preferred lease times, draw client options
3467 * into the option state.
3470 reply_process_is_addressed(struct reply_state
*reply
,
3471 struct binding_scope
**scope
, struct group
*group
)
3473 isc_result_t status
= ISC_R_SUCCESS
;
3474 struct data_string data
;
3475 struct option_cache
*oc
;
3476 struct option_state
*tmp_options
= NULL
;
3477 struct on_star
*on_star
;
3480 /* Initialize values we will cleanup. */
3481 memset(&data
, 0, sizeof(data
));
3484 * Find the proper on_star block to use. We use the
3485 * one in the lease if we have a lease or the one in
3486 * the reply if we don't have a lease because this is
3490 on_star
= &reply
->lease
->on_star
;
3492 on_star
= &reply
->on_star
;
3496 * Bring in the root configuration. We only do this to bring
3497 * in the on * statements, as we didn't have the lease available
3498 * we did it the first time.
3500 option_state_allocate(&tmp_options
, MDL
);
3501 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3502 reply
->packet
->options
, tmp_options
,
3503 &global_scope
, root_group
, NULL
,
3505 if (tmp_options
!= NULL
) {
3506 option_state_dereference(&tmp_options
, MDL
);
3510 * Bring configured options into the root packet level cache - start
3511 * with the lease's closest enclosing group (passed in by the caller
3514 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3515 reply
->packet
->options
, reply
->opt_state
,
3516 scope
, group
, root_group
, on_star
);
3518 /* Execute statements from class scopes. */
3519 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3520 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3521 reply
->packet
->options
,
3522 reply
->opt_state
, scope
,
3523 reply
->packet
->classes
[i
- 1]->group
,
3528 * If there is a host record, over-ride with values configured there,
3529 * without re-evaluating configuration from the previously executed
3530 * group or its common enclosers.
3532 if (reply
->host
!= NULL
)
3533 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3534 reply
->packet
->options
,
3535 reply
->opt_state
, scope
,
3536 reply
->host
->group
, group
,
3539 /* Determine valid lifetime. */
3540 if (reply
->client_valid
== 0)
3541 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
3543 reply
->send_valid
= reply
->client_valid
;
3545 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3546 SV_DEFAULT_LEASE_TIME
);
3548 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3549 reply
->packet
->options
,
3553 log_error("reply_process_is_addressed: unable to "
3554 "evaluate default lease time");
3555 status
= ISC_R_FAILURE
;
3559 reply
->send_valid
= getULong(data
.data
);
3560 data_string_forget(&data
, MDL
);
3563 /* Check to see if the lease time would cause us to wrap
3564 * in which case we make it infinite.
3565 * The following doesn't work on at least some systems:
3566 * (cur_time + reply->send_valid < cur_time)
3568 if (reply
->send_valid
!= INFINITE_TIME
) {
3569 time_t test_time
= cur_time
+ reply
->send_valid
;
3570 if (test_time
< cur_time
)
3571 reply
->send_valid
= INFINITE_TIME
;
3574 if (reply
->client_prefer
== 0)
3575 reply
->send_prefer
= reply
->send_valid
;
3577 reply
->send_prefer
= reply
->client_prefer
;
3579 if ((reply
->send_prefer
>= reply
->send_valid
) &&
3580 (reply
->send_valid
!= INFINITE_TIME
))
3581 reply
->send_prefer
= (reply
->send_valid
/ 2) +
3582 (reply
->send_valid
/ 8);
3584 oc
= lookup_option(&server_universe
, reply
->opt_state
,
3585 SV_PREFER_LIFETIME
);
3587 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
3588 reply
->packet
->options
,
3592 log_error("reply_process_is_addressed: unable to "
3593 "evaluate preferred lease time");
3594 status
= ISC_R_FAILURE
;
3598 reply
->send_prefer
= getULong(data
.data
);
3599 data_string_forget(&data
, MDL
);
3602 /* Note lowest values for later calculation of renew/rebind times. */
3603 if (reply
->min_prefer
> reply
->send_prefer
)
3604 reply
->min_prefer
= reply
->send_prefer
;
3606 if (reply
->min_valid
> reply
->send_valid
)
3607 reply
->min_valid
= reply
->send_valid
;
3611 * XXX: Old 4.0.0 alpha code would change the host {} record
3612 * XXX: uid upon lease assignment. This was intended to cover the
3613 * XXX: case where a client first identifies itself using vendor
3614 * XXX: options in a solicit, or request, but later neglects to include
3615 * XXX: these options in a Renew or Rebind. It is not clear that this
3616 * XXX: is required, and has some startling ramifications (such as
3617 * XXX: how to recover this dynamic host {} state across restarts).
3619 if (reply
->host
!= NULL
)
3620 change_host_uid(host
, reply
->client_id
->data
,
3621 reply
->client_id
->len
);
3624 /* Perform dynamic lease related update work. */
3625 if (reply
->lease
!= NULL
) {
3626 /* Cached lifetimes */
3627 reply
->lease
->prefer
= reply
->send_prefer
;
3628 reply
->lease
->valid
= reply
->send_valid
;
3630 /* Advance (or rewind) the valid lifetime.
3631 * In the protocol 0xFFFFFFFF is infinite
3632 * when connecting to the lease file MAX_TIME is
3634 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
3635 if (reply
->send_valid
== INFINITE_TIME
) {
3636 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
3638 reply
->lease
->soft_lifetime_end_time
=
3639 cur_time
+ reply
->send_valid
;
3641 /* Wait before renew! */
3644 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
3645 if (status
!= ISC_R_SUCCESS
) {
3646 log_fatal("reply_process_is_addressed: Unable to "
3647 "attach lease to new IA: %s",
3648 isc_result_totext(status
));
3652 * If this is a new lease, make sure it is attached somewhere.
3654 if (reply
->lease
->ia
== NULL
) {
3655 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
3659 /* Bring a copy of the relevant options into the IA scope. */
3660 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3661 reply
->packet
->options
, reply
->reply_ia
,
3662 scope
, group
, root_group
, NULL
);
3664 /* Execute statements from class scopes. */
3665 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
3666 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3667 reply
->packet
->options
,
3668 reply
->reply_ia
, scope
,
3669 reply
->packet
->classes
[i
- 1]->group
,
3674 * And bring in host record configuration, if any, but not to overlap
3675 * the previous group or its common enclosers.
3677 if (reply
->host
!= NULL
)
3678 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
3679 reply
->packet
->options
,
3680 reply
->reply_ia
, scope
,
3681 reply
->host
->group
, group
, NULL
);
3684 if (data
.data
!= NULL
)
3685 data_string_forget(&data
, MDL
);
3687 if (status
== ISC_R_SUCCESS
)
3688 reply
->client_resources
++;
3693 /* Simply send an IAADDR within the IA scope as described. */
3695 reply_process_send_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
3696 isc_result_t status
= ISC_R_SUCCESS
;
3697 struct data_string data
;
3699 memset(&data
, 0, sizeof(data
));
3701 /* Now append the lease. */
3702 data
.len
= IAADDR_OFFSET
;
3703 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
3704 log_error("reply_process_send_addr: out of memory"
3705 "allocating new IAADDR buffer.");
3706 status
= ISC_R_NOMEMORY
;
3709 data
.data
= data
.buffer
->data
;
3711 memcpy(data
.buffer
->data
, addr
->iabuf
, 16);
3712 putULong(data
.buffer
->data
+ 16, reply
->send_prefer
);
3713 putULong(data
.buffer
->data
+ 20, reply
->send_valid
);
3715 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
3716 data
.buffer
, data
.buffer
->data
,
3717 data
.len
, D6O_IAADDR
, 0)) {
3718 log_error("reply_process_send_addr: unable "
3719 "to save IAADDR option");
3720 status
= ISC_R_FAILURE
;
3724 reply
->resources_included
= ISC_TRUE
;
3727 if (data
.data
!= NULL
)
3728 data_string_forget(&data
, MDL
);
3733 /* Choose the better of two leases. */
3734 static struct iasubopt
*
3735 lease_compare(struct iasubopt
*alpha
, struct iasubopt
*beta
) {
3741 switch(alpha
->state
) {
3743 switch(beta
->state
) {
3745 /* Choose the lease with the longest lifetime (most
3746 * likely the most recently allocated).
3748 if (alpha
->hard_lifetime_end_time
<
3749 beta
->hard_lifetime_end_time
)
3759 log_fatal("Impossible condition at %s:%d.", MDL
);
3764 switch (beta
->state
) {
3769 /* Choose the most recently expired lease. */
3770 if (alpha
->hard_lifetime_end_time
<
3771 beta
->hard_lifetime_end_time
)
3773 else if ((alpha
->hard_lifetime_end_time
==
3774 beta
->hard_lifetime_end_time
) &&
3775 (alpha
->soft_lifetime_end_time
<
3776 beta
->soft_lifetime_end_time
))
3785 log_fatal("Impossible condition at %s:%d.", MDL
);
3790 switch (beta
->state
) {
3796 /* Choose the lease that was abandoned longest ago. */
3797 if (alpha
->hard_lifetime_end_time
<
3798 beta
->hard_lifetime_end_time
)
3804 log_fatal("Impossible condition at %s:%d.", MDL
);
3809 log_fatal("Impossible condition at %s:%d.", MDL
);
3812 log_fatal("Triple impossible condition at %s:%d.", MDL
);
3816 /* Process a client-supplied IA_PD. This may append options to the tail of
3817 * the reply packet being built in the reply_state structure.
3820 reply_process_ia_pd(struct reply_state
*reply
, struct option_cache
*ia
) {
3821 isc_result_t status
= ISC_R_SUCCESS
;
3824 struct option_state
*packet_ia
;
3825 struct option_cache
*oc
;
3826 struct data_string ia_data
, data
;
3828 /* Initialize values that will get cleaned up on return. */
3830 memset(&ia_data
, 0, sizeof(ia_data
));
3831 memset(&data
, 0, sizeof(data
));
3833 * Note that find_client_prefix() may set reply->lease.
3836 /* Make sure there is at least room for the header. */
3837 if ((reply
->cursor
+ IA_PD_OFFSET
+ 4) > sizeof(reply
->buf
)) {
3838 log_error("reply_process_ia_pd: Reply too long for IA.");
3839 return ISC_R_NOSPACE
;
3843 /* Fetch the IA_PD contents. */
3844 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
3845 ia
, IA_PD_OFFSET
)) {
3846 log_error("reply_process_ia_pd: error evaluating ia");
3847 status
= ISC_R_FAILURE
;
3851 /* Extract IA_PD header contents. */
3852 iaid
= getULong(ia_data
.data
);
3853 reply
->renew
= getULong(ia_data
.data
+ 4);
3854 reply
->rebind
= getULong(ia_data
.data
+ 8);
3856 /* Create an IA_PD structure. */
3857 if (ia_allocate(&reply
->ia
, iaid
, (char *)reply
->client_id
.data
,
3858 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
3859 log_error("reply_process_ia_pd: no memory for ia.");
3860 status
= ISC_R_NOMEMORY
;
3863 reply
->ia
->ia_type
= D6O_IA_PD
;
3865 /* Cache pre-existing IA_PD, if any. */
3866 ia_hash_lookup(&reply
->old_ia
, ia_pd_active
,
3867 (unsigned char *)reply
->ia
->iaid_duid
.data
,
3868 reply
->ia
->iaid_duid
.len
, MDL
);
3871 * Create an option cache to carry the IA_PD option contents, and
3872 * execute any user-supplied values into it.
3874 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
3875 status
= ISC_R_NOMEMORY
;
3879 /* Check & count the fixed prefix host records. */
3880 reply
->static_prefixes
= 0;
3881 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_prefix
!= NULL
)) {
3882 struct iaddrcidrnetlist
*fp
;
3884 for (fp
= reply
->host
->fixed_prefix
; fp
!= NULL
;
3886 reply
->static_prefixes
+= 1;
3891 * Save the cursor position at the start of the IA_PD, so we can
3892 * set length and adjust t1/t2 values later. We write a temporary
3893 * header out now just in case we decide to adjust the packet
3894 * within sub-process functions.
3896 ia_cursor
= reply
->cursor
;
3898 /* Initialize the IA_PD header. First the code. */
3899 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_PD
);
3902 /* Then option length. */
3903 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
3906 /* Then IA_PD header contents; IAID. */
3907 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
3910 /* We store the client's t1 for now, and may over-ride it later. */
3911 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
3914 /* We store the client's t2 for now, and may over-ride it later. */
3915 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
3919 * For each prefix in this IA_PD, decide what to do about it.
3921 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAPREFIX
);
3922 reply
->min_valid
= reply
->min_prefer
= INFINITE_TIME
;
3923 reply
->client_valid
= reply
->client_prefer
= 0;
3924 reply
->preflen
= -1;
3925 for (; oc
!= NULL
; oc
= oc
->next
) {
3926 status
= reply_process_prefix(reply
, oc
);
3929 * Canceled means we did not allocate prefixes to the
3930 * client, but we're "done" with this IA - we set a status
3931 * code. So transmit this reply, e.g., move on to the next
3934 if (status
== ISC_R_CANCELED
)
3937 if ((status
!= ISC_R_SUCCESS
) &&
3938 (status
!= ISC_R_ADDRINUSE
) &&
3939 (status
!= ISC_R_ADDRNOTAVAIL
))
3946 * If we fell through the above and never gave the client
3947 * a prefix, give it one now.
3949 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
3950 status
= find_client_prefix(reply
);
3952 if (status
== ISC_R_NORESOURCES
) {
3953 switch (reply
->packet
->dhcpv6_msg_type
) {
3954 case DHCPV6_SOLICIT
:
3956 * No prefix for any IA is handled
3961 case DHCPV6_REQUEST
:
3962 /* Same than for addresses. */
3963 option_state_dereference(&reply
->reply_ia
, MDL
);
3964 if (!option_state_allocate(&reply
->reply_ia
,
3967 log_error("reply_process_ia_pd: No "
3968 "memory for option state "
3970 status
= ISC_R_NOMEMORY
;
3974 if (!set_status_code(STATUS_NoPrefixAvail
,
3975 "No prefixes available "
3976 "for this interface.",
3978 log_error("reply_process_ia_pd: "
3980 "NoPrefixAvail status "
3982 status
= ISC_R_FAILURE
;
3986 status
= ISC_R_SUCCESS
;
3990 if (reply
->resources_included
)
3991 status
= ISC_R_SUCCESS
;
3998 if (status
!= ISC_R_SUCCESS
)
4002 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
4003 sizeof(reply
->buf
) - reply
->cursor
,
4004 reply
->reply_ia
, reply
->packet
,
4005 required_opts_IA_PD
, NULL
);
4007 /* Reset the length of this IA_PD to match what was just written. */
4008 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
4009 reply
->cursor
- (ia_cursor
+ 4));
4011 /* Calculate T1/T2 and stuff them in the reply */
4012 set_reply_tee_times(reply
, ia_cursor
);
4015 * yes, goto's aren't the best but we also want to avoid extra
4018 if (status
== ISC_R_CANCELED
)
4022 * Handle static prefixes, we always log stuff and if it's
4023 * a hard binding we run any commit statements that we have
4025 if (reply
->static_prefixes
!= 0) {
4026 char tmp_addr
[INET6_ADDRSTRLEN
];
4027 log_info("%s PD: address %s/%d to client with duid %s "
4029 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
4030 inet_ntop(AF_INET6
, reply
->fixed_pref
.lo_addr
.iabuf
,
4031 tmp_addr
, sizeof(tmp_addr
)),
4032 reply
->fixed_pref
.bits
,
4033 print_hex_1(reply
->client_id
.len
,
4034 reply
->client_id
.data
, 60),
4036 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
4037 (reply
->on_star
.on_commit
!= NULL
)) {
4038 execute_statements(NULL
, reply
->packet
, NULL
, NULL
,
4039 reply
->packet
->options
,
4041 NULL
, reply
->on_star
.on_commit
,
4043 executable_statement_dereference
4044 (&reply
->on_star
.on_commit
, MDL
);
4050 * If we have any addresses log what we are doing.
4052 if (reply
->ia
->num_iasubopt
!= 0) {
4053 struct iasubopt
*tmp
;
4055 char tmp_addr
[INET6_ADDRSTRLEN
];
4057 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
4058 tmp
= reply
->ia
->iasubopt
[i
];
4060 log_info("%s PD: address %s/%d to client with duid %s"
4061 " iaid = %d valid for %u seconds",
4062 dhcpv6_type_names
[reply
->buf
.reply
.msg_type
],
4063 inet_ntop(AF_INET6
, &tmp
->addr
,
4064 tmp_addr
, sizeof(tmp_addr
)),
4066 print_hex_1(reply
->client_id
.len
,
4067 reply
->client_id
.data
, 60),
4073 * If this is not a 'soft' binding, consume the new changes into
4074 * the database (if any have been attached to the ia_pd).
4076 * Loop through the assigned dynamic prefixes, referencing the
4077 * prefixes onto this IA_PD rather than any old ones, and updating
4078 * prefix pool timers for each (if any).
4080 if ((reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
4081 (reply
->ia
->num_iasubopt
!= 0)) {
4082 struct iasubopt
*tmp
;
4083 struct data_string
*ia_id
;
4086 for (i
= 0 ; i
< reply
->ia
->num_iasubopt
; i
++) {
4087 tmp
= reply
->ia
->iasubopt
[i
];
4089 if (tmp
->ia
!= NULL
)
4090 ia_dereference(&tmp
->ia
, MDL
);
4091 ia_reference(&tmp
->ia
, reply
->ia
, MDL
);
4093 /* Commit 'hard' bindings. */
4094 renew_lease6(tmp
->ipv6_pool
, tmp
);
4095 schedule_lease_timeout(tmp
->ipv6_pool
);
4097 /* If we have anything to do on commit do it now */
4098 if (tmp
->on_star
.on_commit
!= NULL
) {
4099 execute_statements(NULL
, reply
->packet
,
4101 reply
->packet
->options
,
4104 tmp
->on_star
.on_commit
,
4106 executable_statement_dereference
4107 (&tmp
->on_star
.on_commit
, MDL
);
4110 /* Do our threshold check. */
4111 check_pool6_threshold(reply
, tmp
);
4114 /* Remove any old ia from the hash. */
4115 if (reply
->old_ia
!= NULL
) {
4116 ia_id
= &reply
->old_ia
->iaid_duid
;
4117 ia_hash_delete(ia_pd_active
,
4118 (unsigned char *)ia_id
->data
,
4120 ia_dereference(&reply
->old_ia
, MDL
);
4123 /* Put new ia into the hash. */
4124 reply
->ia
->cltt
= cur_time
;
4125 ia_id
= &reply
->ia
->iaid_duid
;
4126 ia_hash_add(ia_pd_active
, (unsigned char *)ia_id
->data
,
4127 ia_id
->len
, reply
->ia
, MDL
);
4129 write_ia(reply
->ia
);
4131 schedule_lease_timeout_reply(reply
);
4135 if (packet_ia
!= NULL
)
4136 option_state_dereference(&packet_ia
, MDL
);
4137 if (reply
->reply_ia
!= NULL
)
4138 option_state_dereference(&reply
->reply_ia
, MDL
);
4139 if (ia_data
.data
!= NULL
)
4140 data_string_forget(&ia_data
, MDL
);
4141 if (data
.data
!= NULL
)
4142 data_string_forget(&data
, MDL
);
4143 if (reply
->ia
!= NULL
)
4144 ia_dereference(&reply
->ia
, MDL
);
4145 if (reply
->old_ia
!= NULL
)
4146 ia_dereference(&reply
->old_ia
, MDL
);
4147 if (reply
->lease
!= NULL
)
4148 iasubopt_dereference(&reply
->lease
, MDL
);
4149 if (reply
->on_star
.on_expiry
!= NULL
)
4150 executable_statement_dereference
4151 (&reply
->on_star
.on_expiry
, MDL
);
4152 if (reply
->on_star
.on_release
!= NULL
)
4153 executable_statement_dereference
4154 (&reply
->on_star
.on_release
, MDL
);
4157 * ISC_R_CANCELED is a status code used by the prefix processing to
4158 * indicate we're replying with a status code. This is still a
4159 * success at higher layers.
4161 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
4166 * \brief Find the proper scoping group for use with a v6 static prefix.
4168 * We start by trying to find a subnet based on the given prefix and
4169 * the shared network. If we don't find one then the prefix has been
4170 * declared outside of any subnets. If there is a static address
4171 * associated with the host we use it to try and find a subnet (this
4172 * should succeed). If there isn't a static address we fall back
4173 * to the shared subnet itself.
4174 * Once we have a subnet we extract the group from it and return it.
4176 * \param reply - the reply structure we use to collect information
4177 * we will use the fields shared, fixed_pref and host
4178 * from the structure
4180 * \return a pointer to the group structure to use for scoping
4183 static struct group
*
4184 find_group_by_prefix(struct reply_state
*reply
) {
4185 /* default group if we don't find anything better */
4186 struct group
*group
= reply
->shared
->group
;
4187 struct subnet
*subnet
= NULL
;
4188 struct iaddr tmp_addr
;
4189 struct data_string fixed_addr
;
4191 /* Try with the prefix first */
4192 if (find_grouped_subnet(&subnet
, reply
->shared
,
4193 reply
->fixed_pref
.lo_addr
, MDL
) != 0) {
4194 group
= subnet
->group
;
4195 subnet_dereference(&subnet
, MDL
);
4199 /* Didn't find a subnet via prefix, what about fixed address */
4200 /* The caller has already tested reply->host != NULL */
4202 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
4204 if ((reply
->host
->fixed_addr
!= NULL
) &&
4205 (evaluate_option_cache(&fixed_addr
, NULL
, NULL
, NULL
,
4206 NULL
, NULL
, &global_scope
,
4207 reply
->host
->fixed_addr
, MDL
))) {
4208 if (fixed_addr
.len
>= 16) {
4210 memcpy(tmp_addr
.iabuf
, fixed_addr
.data
, 16);
4211 if (find_grouped_subnet(&subnet
, reply
->shared
,
4212 tmp_addr
, MDL
) != 0) {
4213 group
= subnet
->group
;
4214 subnet_dereference(&subnet
, MDL
);
4217 data_string_forget(&fixed_addr
, MDL
);
4220 /* return whatever we got */
4225 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
4226 * contents into the reply's current ia_pd-scoped option cache. Returns
4227 * ISC_R_CANCELED in the event we are replying with a status code and do
4228 * not wish to process more IAPREFIXes within this IA_PD.
4231 reply_process_prefix(struct reply_state
*reply
, struct option_cache
*pref
) {
4232 u_int32_t pref_life
, valid_life
;
4233 struct binding_scope
**scope
;
4234 struct iaddrcidrnet tmp_pref
;
4235 struct option_cache
*oc
;
4236 struct data_string iapref
, data
;
4237 isc_result_t status
= ISC_R_SUCCESS
;
4238 struct group
*group
;
4240 /* Initializes values that will be cleaned up. */
4241 memset(&iapref
, 0, sizeof(iapref
));
4242 memset(&data
, 0, sizeof(data
));
4243 /* Note that reply->lease may be set by prefix_is_owned() */
4246 * There is no point trying to process an incoming prefix if there
4247 * is no room for an outgoing prefix.
4249 if ((reply
->cursor
+ 29) > sizeof(reply
->buf
)) {
4250 log_error("reply_process_prefix: Out of room for prefix.");
4251 return ISC_R_NOSPACE
;
4254 /* Extract this IAPREFIX option. */
4255 if (!evaluate_option_cache(&iapref
, reply
->packet
, NULL
, NULL
,
4256 reply
->packet
->options
, NULL
, &global_scope
,
4258 (iapref
.len
< IAPREFIX_OFFSET
)) {
4259 log_error("reply_process_prefix: error evaluating IAPREFIX.");
4260 status
= ISC_R_FAILURE
;
4265 * Layout: preferred and valid lifetimes followed by the prefix
4266 * length and the IPv6 address.
4268 pref_life
= getULong(iapref
.data
);
4269 valid_life
= getULong(iapref
.data
+ 4);
4271 if ((reply
->client_valid
== 0) ||
4272 (reply
->client_valid
> valid_life
))
4273 reply
->client_valid
= valid_life
;
4275 if ((reply
->client_prefer
== 0) ||
4276 (reply
->client_prefer
> pref_life
))
4277 reply
->client_prefer
= pref_life
;
4280 * Clients may choose to send ::/0 as a prefix, with the idea to give
4281 * hints about preferred-lifetime or valid-lifetime.
4283 tmp_pref
.lo_addr
.len
= 16;
4284 memset(tmp_pref
.lo_addr
.iabuf
, 0, 16);
4285 if ((iapref
.data
[8] == 0) &&
4286 (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0)) {
4287 /* Status remains success; we just ignore this one. */
4292 * Clients may choose to send ::/X as a prefix to specify a
4293 * preferred/requested prefix length. Note X is never zero here.
4295 tmp_pref
.bits
= (int) iapref
.data
[8];
4296 if (reply
->preflen
< 0) {
4297 /* Cache the first preferred prefix length. */
4298 reply
->preflen
= tmp_pref
.bits
;
4300 if (memcmp(iapref
.data
+ 9, tmp_pref
.lo_addr
.iabuf
, 16) == 0) {
4304 memcpy(tmp_pref
.lo_addr
.iabuf
, iapref
.data
+ 9, 16);
4306 /* Verify the prefix belongs to the client. */
4307 if (!prefix_is_owned(reply
, &tmp_pref
)) {
4308 /* Same than for addresses. */
4309 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
4310 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
4311 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
4312 status
= reply_process_try_prefix(reply
, &tmp_pref
);
4314 /* Either error out or skip this prefix. */
4315 if ((status
!= ISC_R_SUCCESS
) &&
4316 (status
!= ISC_R_ADDRINUSE
) &&
4317 (status
!= ISC_R_ADDRNOTAVAIL
))
4320 if (reply
->lease
== NULL
) {
4321 if (reply
->packet
->dhcpv6_msg_type
==
4323 reply
->send_prefer
= 0;
4324 reply
->send_valid
= 0;
4328 /* status remains success - ignore */
4332 * RFC3633 section 18.2.3:
4334 * If the delegating router cannot find a binding
4335 * for the requesting router's IA_PD the delegating
4336 * router returns the IA_PD containing no prefixes
4337 * with a Status Code option set to NoBinding in the
4340 * On mismatch we (ab)use this pretending we have not the IA
4341 * as soon as we have not a prefix.
4343 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
4344 /* Rewind the IA_PD to empty. */
4345 option_state_dereference(&reply
->reply_ia
, MDL
);
4346 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
4347 log_error("reply_process_prefix: No memory "
4348 "for option state wipe.");
4349 status
= ISC_R_NOMEMORY
;
4353 /* Append a NoBinding status code. */
4354 if (!set_status_code(STATUS_NoBinding
,
4355 "Prefix not bound to this "
4356 "interface.", reply
->reply_ia
)) {
4357 log_error("reply_process_prefix: Unable to "
4358 "attach status code.");
4359 status
= ISC_R_FAILURE
;
4363 /* Fin (no more IAPREFIXes). */
4364 status
= ISC_R_CANCELED
;
4367 log_error("It is impossible to lease a client that is "
4368 "not sending a solicit, request, renew, or "
4370 status
= ISC_R_FAILURE
;
4375 if (reply
->static_prefixes
> 0) {
4376 if (reply
->host
== NULL
)
4377 log_fatal("Impossible condition at %s:%d.", MDL
);
4379 scope
= &global_scope
;
4381 /* Copy the static prefix for logging and finding the group */
4382 memcpy(&reply
->fixed_pref
, &tmp_pref
, sizeof(tmp_pref
));
4384 /* Try to find a group for the static prefix */
4385 group
= find_group_by_prefix(reply
);
4387 if (reply
->lease
== NULL
)
4388 log_fatal("Impossible condition at %s:%d.", MDL
);
4390 scope
= &reply
->lease
->scope
;
4391 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4395 * If client_resources is nonzero, then the reply_process_is_prefixed
4396 * function has executed configuration state into the reply option
4397 * cache. We will use that valid cache to derive configuration for
4398 * whether or not to engage in additional prefixes, and similar.
4400 if (reply
->client_resources
!= 0) {
4404 * Does this client have "enough" prefixes already? Default
4405 * to one. Everybody gets one, and one should be enough for
4408 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4409 SV_LIMIT_PREFS_PER_IA
);
4411 if (!evaluate_option_cache(&data
, reply
->packet
,
4413 reply
->packet
->options
,
4417 log_error("reply_process_prefix: unable to "
4418 "evaluate prefs-per-ia value.");
4419 status
= ISC_R_FAILURE
;
4423 limit
= getULong(data
.data
);
4424 data_string_forget(&data
, MDL
);
4428 * If we wish to limit the client to a certain number of
4429 * prefixes, then omit the prefix from the reply.
4431 if (reply
->client_resources
>= limit
)
4435 status
= reply_process_is_prefixed(reply
, scope
, group
);
4436 if (status
!= ISC_R_SUCCESS
)
4440 status
= reply_process_send_prefix(reply
, &tmp_pref
);
4443 if (iapref
.data
!= NULL
)
4444 data_string_forget(&iapref
, MDL
);
4445 if (data
.data
!= NULL
)
4446 data_string_forget(&data
, MDL
);
4447 if (reply
->lease
!= NULL
)
4448 iasubopt_dereference(&reply
->lease
, MDL
);
4454 * Verify the prefix belongs to the client. If we've got a host
4455 * record with fixed prefixes, it has to be an assigned prefix
4456 * (fault out all else). Otherwise it's a dynamic prefix, so lookup
4457 * that prefix and make sure it belongs to this DUID:IAID pair.
4459 static isc_boolean_t
4460 prefix_is_owned(struct reply_state
*reply
, struct iaddrcidrnet
*pref
) {
4461 struct iaddrcidrnetlist
*l
;
4463 struct ipv6_pond
*pond
;
4466 * This faults out prefixes that don't match fixed prefixes.
4468 if (reply
->static_prefixes
> 0) {
4469 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4470 if ((pref
->bits
== l
->cidrnet
.bits
) &&
4471 (memcmp(pref
->lo_addr
.iabuf
,
4472 l
->cidrnet
.lo_addr
.iabuf
, 16) == 0))
4478 if ((reply
->old_ia
== NULL
) ||
4479 (reply
->old_ia
->num_iasubopt
== 0))
4482 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4483 struct iasubopt
*tmp
;
4485 tmp
= reply
->old_ia
->iasubopt
[i
];
4487 if ((pref
->bits
== (int) tmp
->plen
) &&
4488 (memcmp(pref
->lo_addr
.iabuf
, &tmp
->addr
, 16) == 0)) {
4489 if (lease6_usable(tmp
) == ISC_FALSE
) {
4493 pond
= tmp
->ipv6_pool
->ipv6_pond
;
4494 if (((pond
->prohibit_list
!= NULL
) &&
4495 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4496 ((pond
->permit_list
!= NULL
) &&
4497 (!permitted(reply
->packet
, pond
->permit_list
))))
4500 iasubopt_reference(&reply
->lease
, tmp
, MDL
);
4509 * This function only returns failure on 'hard' failures. If it succeeds,
4510 * it will leave a prefix structure behind.
4513 reply_process_try_prefix(struct reply_state
*reply
,
4514 struct iaddrcidrnet
*pref
) {
4515 isc_result_t status
= ISC_R_ADDRNOTAVAIL
;
4516 struct ipv6_pool
*pool
= NULL
;
4517 struct ipv6_pond
*pond
= NULL
;
4519 struct data_string data_pref
;
4521 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
4522 (pref
== NULL
) || (reply
->lease
!= NULL
))
4523 return (DHCP_R_INVALIDARG
);
4526 * Do a quick walk through of the ponds and pools
4527 * to see if we have any prefix pools
4529 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4530 if (pond
->ipv6_pools
== NULL
)
4533 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4534 if (pool
->pool_type
== D6O_IA_PD
)
4541 /* If we get here and p is NULL we have no useful pools */
4543 return (ISC_R_ADDRNOTAVAIL
);
4546 memset(&data_pref
, 0, sizeof(data_pref
));
4548 if (!buffer_allocate(&data_pref
.buffer
, data_pref
.len
, MDL
)) {
4549 log_error("reply_process_try_prefix: out of memory.");
4550 return (ISC_R_NOMEMORY
);
4552 data_pref
.data
= data_pref
.buffer
->data
;
4553 data_pref
.buffer
->data
[0] = (u_int8_t
) pref
->bits
;
4554 memcpy(data_pref
.buffer
->data
+ 1, pref
->lo_addr
.iabuf
, 16);
4557 * We have at least one pool that could provide a prefix
4558 * Now we walk through the ponds and pools again and check
4559 * to see if the client is permitted and if an prefix is
4564 for (pond
= reply
->shared
->ipv6_pond
; pond
!= NULL
; pond
= pond
->next
) {
4565 if (((pond
->prohibit_list
!= NULL
) &&
4566 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4567 ((pond
->permit_list
!= NULL
) &&
4568 (!permitted(reply
->packet
, pond
->permit_list
))))
4571 for (i
= 0; (pool
= pond
->ipv6_pools
[i
]) != NULL
; i
++) {
4572 if (pool
->pool_type
!= D6O_IA_PD
) {
4576 status
= try_client_v6_prefix(&reply
->lease
, pool
,
4578 /* If we found it in this pool (either in use or available),
4579 there is no need to look further. */
4580 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4583 if ( (status
== ISC_R_SUCCESS
) || (status
== ISC_R_ADDRINUSE
) )
4587 data_string_forget(&data_pref
, MDL
);
4588 /* Return just the most recent status... */
4592 /* Look around for a prefix to give the client. First, look through the old
4593 * IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
4594 * Finally, actually add that prefix into the current reply IA_PD.
4597 find_client_prefix(struct reply_state
*reply
) {
4598 struct iaddrcidrnet send_pref
;
4599 isc_result_t status
= ISC_R_NORESOURCES
;
4600 struct iasubopt
*prefix
, *best_prefix
= NULL
;
4601 struct binding_scope
**scope
;
4603 struct group
*group
;
4605 if (reply
->static_prefixes
> 0) {
4606 struct iaddrcidrnetlist
*l
;
4608 if (reply
->host
== NULL
)
4609 return DHCP_R_INVALIDARG
;
4611 for (l
= reply
->host
->fixed_prefix
; l
!= NULL
; l
= l
->next
) {
4612 if (l
->cidrnet
.bits
== reply
->preflen
)
4617 * If no fixed prefix has the preferred length,
4618 * get the first one.
4620 l
= reply
->host
->fixed_prefix
;
4622 memcpy(&send_pref
, &l
->cidrnet
, sizeof(send_pref
));
4624 scope
= &global_scope
;
4626 /* Copy the prefix for logging purposes */
4627 memcpy(&reply
->fixed_pref
, &l
->cidrnet
, sizeof(send_pref
));
4629 /* Try to find a group for the static prefix */
4630 group
= find_group_by_prefix(reply
);
4635 if (reply
->old_ia
!= NULL
) {
4636 for (i
= 0 ; i
< reply
->old_ia
->num_iasubopt
; i
++) {
4637 struct shared_network
*candidate_shared
;
4638 struct ipv6_pond
*pond
;
4640 prefix
= reply
->old_ia
->iasubopt
[i
];
4641 candidate_shared
= prefix
->ipv6_pool
->shared_network
;
4642 pond
= prefix
->ipv6_pool
->ipv6_pond
;
4645 * Consider this prefix if it is in a global pool or
4646 * if it is scoped in a pool under the client's shared
4649 if (((candidate_shared
!= NULL
) &&
4650 (candidate_shared
!= reply
->shared
)) ||
4651 (lease6_usable(prefix
) != ISC_TRUE
))
4655 * And check if the prefix is still permitted
4658 if (((pond
->prohibit_list
!= NULL
) &&
4659 (permitted(reply
->packet
, pond
->prohibit_list
))) ||
4660 ((pond
->permit_list
!= NULL
) &&
4661 (!permitted(reply
->packet
, pond
->permit_list
))))
4664 best_prefix
= prefix_compare(reply
, prefix
,
4669 /* Try to pick a new prefix if we didn't find one, or if we found an
4672 if ((best_prefix
== NULL
) || (best_prefix
->state
== FTS_ABANDONED
)) {
4673 status
= pick_v6_prefix(reply
);
4674 } else if (best_prefix
!= NULL
) {
4675 iasubopt_reference(&reply
->lease
, best_prefix
, MDL
);
4676 status
= ISC_R_SUCCESS
;
4679 /* Pick the abandoned prefix as a last resort. */
4680 if ((status
== ISC_R_NORESOURCES
) && (best_prefix
!= NULL
)) {
4681 /* I don't see how this is supposed to be done right now. */
4682 log_error("Reclaiming abandoned prefixes is not yet "
4683 "supported. Treating this as an out of space "
4685 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
4688 /* Give up now if we didn't find a prefix. */
4689 if (status
!= ISC_R_SUCCESS
)
4692 if (reply
->lease
== NULL
)
4693 log_fatal("Impossible condition at %s:%d.", MDL
);
4695 scope
= &reply
->lease
->scope
;
4696 group
= reply
->lease
->ipv6_pool
->ipv6_pond
->group
;
4698 send_pref
.lo_addr
.len
= 16;
4699 memcpy(send_pref
.lo_addr
.iabuf
, &reply
->lease
->addr
, 16);
4700 send_pref
.bits
= (int) reply
->lease
->plen
;
4703 status
= reply_process_is_prefixed(reply
, scope
, group
);
4704 if (status
!= ISC_R_SUCCESS
)
4707 status
= reply_process_send_prefix(reply
, &send_pref
);
4711 /* Once a prefix is found for a client, perform several common functions;
4712 * Calculate and store valid and preferred prefix times, draw client options
4713 * into the option state.
4716 reply_process_is_prefixed(struct reply_state
*reply
,
4717 struct binding_scope
**scope
, struct group
*group
)
4719 isc_result_t status
= ISC_R_SUCCESS
;
4720 struct data_string data
;
4721 struct option_cache
*oc
;
4722 struct option_state
*tmp_options
= NULL
;
4723 struct on_star
*on_star
;
4726 /* Initialize values we will cleanup. */
4727 memset(&data
, 0, sizeof(data
));
4730 * Find the proper on_star block to use. We use the
4731 * one in the lease if we have a lease or the one in
4732 * the reply if we don't have a lease because this is
4736 on_star
= &reply
->lease
->on_star
;
4738 on_star
= &reply
->on_star
;
4742 * Bring in the root configuration. We only do this to bring
4743 * in the on * statements, as we didn't have the lease available
4744 * we we did it the first time.
4746 option_state_allocate(&tmp_options
, MDL
);
4747 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4748 reply
->packet
->options
, tmp_options
,
4749 &global_scope
, root_group
, NULL
,
4751 if (tmp_options
!= NULL
) {
4752 option_state_dereference(&tmp_options
, MDL
);
4756 * Bring configured options into the root packet level cache - start
4757 * with the lease's closest enclosing group (passed in by the caller
4760 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4761 reply
->packet
->options
, reply
->opt_state
,
4762 scope
, group
, root_group
, on_star
);
4764 /* Execute statements from class scopes. */
4765 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
4766 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4767 reply
->packet
->options
,
4768 reply
->opt_state
, scope
,
4769 reply
->packet
->classes
[i
- 1]->group
,
4774 * If there is a host record, over-ride with values configured there,
4775 * without re-evaluating configuration from the previously executed
4776 * group or its common enclosers.
4778 if (reply
->host
!= NULL
)
4779 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4780 reply
->packet
->options
,
4781 reply
->opt_state
, scope
,
4782 reply
->host
->group
, group
,
4785 /* Determine valid lifetime. */
4786 if (reply
->client_valid
== 0)
4787 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
4789 reply
->send_valid
= reply
->client_valid
;
4791 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4792 SV_DEFAULT_LEASE_TIME
);
4794 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4795 reply
->packet
->options
,
4799 log_error("reply_process_is_prefixed: unable to "
4800 "evaluate default prefix time");
4801 status
= ISC_R_FAILURE
;
4805 reply
->send_valid
= getULong(data
.data
);
4806 data_string_forget(&data
, MDL
);
4809 /* Check to see if the lease time would cause us to wrap
4810 * in which case we make it infinite.
4811 * The following doesn't work on at least some systems:
4812 * (cur_time + reply->send_valid < cur_time)
4814 if (reply
->send_valid
!= INFINITE_TIME
) {
4815 time_t test_time
= cur_time
+ reply
->send_valid
;
4816 if (test_time
< cur_time
)
4817 reply
->send_valid
= INFINITE_TIME
;
4820 if (reply
->client_prefer
== 0)
4821 reply
->send_prefer
= reply
->send_valid
;
4823 reply
->send_prefer
= reply
->client_prefer
;
4825 if ((reply
->send_prefer
>= reply
->send_valid
) &&
4826 (reply
->send_valid
!= INFINITE_TIME
))
4827 reply
->send_prefer
= (reply
->send_valid
/ 2) +
4828 (reply
->send_valid
/ 8);
4830 oc
= lookup_option(&server_universe
, reply
->opt_state
,
4831 SV_PREFER_LIFETIME
);
4833 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
4834 reply
->packet
->options
,
4838 log_error("reply_process_is_prefixed: unable to "
4839 "evaluate preferred prefix time");
4840 status
= ISC_R_FAILURE
;
4844 reply
->send_prefer
= getULong(data
.data
);
4845 data_string_forget(&data
, MDL
);
4848 /* Note lowest values for later calculation of renew/rebind times. */
4849 if (reply
->min_prefer
> reply
->send_prefer
)
4850 reply
->min_prefer
= reply
->send_prefer
;
4852 if (reply
->min_valid
> reply
->send_valid
)
4853 reply
->min_valid
= reply
->send_valid
;
4855 /* Perform dynamic prefix related update work. */
4856 if (reply
->lease
!= NULL
) {
4857 /* Cached lifetimes */
4858 reply
->lease
->prefer
= reply
->send_prefer
;
4859 reply
->lease
->valid
= reply
->send_valid
;
4861 /* Advance (or rewind) the valid lifetime.
4862 * In the protocol 0xFFFFFFFF is infinite
4863 * when connecting to the lease file MAX_TIME is
4865 if (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) {
4866 if (reply
->send_valid
== INFINITE_TIME
) {
4867 reply
->lease
->soft_lifetime_end_time
= MAX_TIME
;
4869 reply
->lease
->soft_lifetime_end_time
=
4870 cur_time
+ reply
->send_valid
;
4872 /* Wait before renew! */
4875 status
= ia_add_iasubopt(reply
->ia
, reply
->lease
, MDL
);
4876 if (status
!= ISC_R_SUCCESS
) {
4877 log_fatal("reply_process_is_prefixed: Unable to "
4878 "attach prefix to new IA_PD: %s",
4879 isc_result_totext(status
));
4883 * If this is a new prefix, make sure it is attached somewhere.
4885 if (reply
->lease
->ia
== NULL
) {
4886 ia_reference(&reply
->lease
->ia
, reply
->ia
, MDL
);
4890 /* Bring a copy of the relevant options into the IA_PD scope. */
4891 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4892 reply
->packet
->options
, reply
->reply_ia
,
4893 scope
, group
, root_group
, NULL
);
4895 /* Execute statements from class scopes. */
4896 for (i
= reply
->packet
->class_count
; i
> 0; i
--) {
4897 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4898 reply
->packet
->options
,
4899 reply
->reply_ia
, scope
,
4900 reply
->packet
->classes
[i
- 1]->group
,
4905 * And bring in host record configuration, if any, but not to overlap
4906 * the previous group or its common enclosers.
4908 if (reply
->host
!= NULL
)
4909 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
4910 reply
->packet
->options
,
4911 reply
->reply_ia
, scope
,
4912 reply
->host
->group
, group
, NULL
);
4915 if (data
.data
!= NULL
)
4916 data_string_forget(&data
, MDL
);
4918 if (status
== ISC_R_SUCCESS
)
4919 reply
->client_resources
++;
4924 /* Simply send an IAPREFIX within the IA_PD scope as described. */
4926 reply_process_send_prefix(struct reply_state
*reply
,
4927 struct iaddrcidrnet
*pref
) {
4928 isc_result_t status
= ISC_R_SUCCESS
;
4929 struct data_string data
;
4931 memset(&data
, 0, sizeof(data
));
4933 /* Now append the prefix. */
4934 data
.len
= IAPREFIX_OFFSET
;
4935 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
4936 log_error("reply_process_send_prefix: out of memory"
4937 "allocating new IAPREFIX buffer.");
4938 status
= ISC_R_NOMEMORY
;
4941 data
.data
= data
.buffer
->data
;
4943 putULong(data
.buffer
->data
, reply
->send_prefer
);
4944 putULong(data
.buffer
->data
+ 4, reply
->send_valid
);
4945 data
.buffer
->data
[8] = pref
->bits
;
4946 memcpy(data
.buffer
->data
+ 9, pref
->lo_addr
.iabuf
, 16);
4948 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
4949 data
.buffer
, data
.buffer
->data
,
4950 data
.len
, D6O_IAPREFIX
, 0)) {
4951 log_error("reply_process_send_prefix: unable "
4952 "to save IAPREFIX option");
4953 status
= ISC_R_FAILURE
;
4957 reply
->resources_included
= ISC_TRUE
;
4960 if (data
.data
!= NULL
)
4961 data_string_forget(&data
, MDL
);
4966 /* Choose the better of two prefixes. */
4967 static struct iasubopt
*
4968 prefix_compare(struct reply_state
*reply
,
4969 struct iasubopt
*alpha
, struct iasubopt
*beta
) {
4975 if (reply
->preflen
>= 0) {
4976 if ((alpha
->plen
== reply
->preflen
) &&
4977 (beta
->plen
!= reply
->preflen
))
4979 if ((beta
->plen
== reply
->preflen
) &&
4980 (alpha
->plen
!= reply
->preflen
))
4984 switch(alpha
->state
) {
4986 switch(beta
->state
) {
4988 /* Choose the prefix with the longest lifetime (most
4989 * likely the most recently allocated).
4991 if (alpha
->hard_lifetime_end_time
<
4992 beta
->hard_lifetime_end_time
)
5002 log_fatal("Impossible condition at %s:%d.", MDL
);
5007 switch (beta
->state
) {
5012 /* Choose the most recently expired prefix. */
5013 if (alpha
->hard_lifetime_end_time
<
5014 beta
->hard_lifetime_end_time
)
5016 else if ((alpha
->hard_lifetime_end_time
==
5017 beta
->hard_lifetime_end_time
) &&
5018 (alpha
->soft_lifetime_end_time
<
5019 beta
->soft_lifetime_end_time
))
5028 log_fatal("Impossible condition at %s:%d.", MDL
);
5033 switch (beta
->state
) {
5039 /* Choose the prefix that was abandoned longest ago. */
5040 if (alpha
->hard_lifetime_end_time
<
5041 beta
->hard_lifetime_end_time
)
5047 log_fatal("Impossible condition at %s:%d.", MDL
);
5052 log_fatal("Impossible condition at %s:%d.", MDL
);
5055 log_fatal("Triple impossible condition at %s:%d.", MDL
);
5060 * Solicit is how a client starts requesting addresses.
5062 * If the client asks for rapid commit, and we support it, we will
5063 * allocate the addresses and reply.
5065 * Otherwise we will send an advertise message.
5069 dhcpv6_solicit(struct data_string
*reply_ret
, struct packet
*packet
) {
5070 struct data_string client_id
;
5073 * Validate our input.
5075 if (!valid_client_msg(packet
, &client_id
)) {
5079 lease_to_client(reply_ret
, packet
, &client_id
, NULL
);
5084 data_string_forget(&client_id
, MDL
);
5088 * Request is how a client actually requests addresses.
5090 * Very similar to Solicit handling, except the server DUID is required.
5094 dhcpv6_request(struct data_string
*reply_ret
, struct packet
*packet
) {
5095 struct data_string client_id
;
5096 struct data_string server_id
;
5099 * Validate our input.
5101 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5105 /* If the REQUEST arrived via unicast and unicast option isn't set,
5106 * reject it per RFC 3315, Sec 18.2.1 */
5107 if (packet
->unicast
== ISC_TRUE
&&
5108 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5109 unicast_reject(reply_ret
, packet
, &client_id
, &server_id
);
5114 lease_to_client(reply_ret
, packet
, &client_id
, &server_id
);
5120 data_string_forget(&client_id
, MDL
);
5121 data_string_forget(&server_id
, MDL
);
5124 /* Find a DHCPv6 packet's shared network from hints in the packet.
5127 shared_network_from_packet6(struct shared_network
**shared
,
5128 struct packet
*packet
)
5130 const struct packet
*chk_packet
;
5131 const struct in6_addr
*link_addr
, *first_link_addr
;
5132 struct iaddr tmp_addr
;
5133 struct subnet
*subnet
;
5134 isc_result_t status
;
5136 if ((shared
== NULL
) || (*shared
!= NULL
) || (packet
== NULL
))
5137 return DHCP_R_INVALIDARG
;
5140 * First, find the link address where the packet from the client
5141 * first appeared (if this packet was relayed).
5143 first_link_addr
= NULL
;
5144 chk_packet
= packet
->dhcpv6_container_packet
;
5145 while (chk_packet
!= NULL
) {
5146 link_addr
= &chk_packet
->dhcpv6_link_address
;
5147 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
5148 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
5149 first_link_addr
= link_addr
;
5152 chk_packet
= chk_packet
->dhcpv6_container_packet
;
5156 * If there is a relayed link address, find the subnet associated
5157 * with that, and use that to get the appropriate
5160 if (first_link_addr
!= NULL
) {
5161 tmp_addr
.len
= sizeof(*first_link_addr
);
5162 memcpy(tmp_addr
.iabuf
,
5163 first_link_addr
, sizeof(*first_link_addr
));
5165 if (!find_subnet(&subnet
, tmp_addr
, MDL
)) {
5166 log_debug("No subnet found for link-address %s.",
5168 return ISC_R_NOTFOUND
;
5170 status
= shared_network_reference(shared
,
5171 subnet
->shared_network
, MDL
);
5172 subnet_dereference(&subnet
, MDL
);
5175 * If there is no link address, we will use the interface
5176 * that this packet came in on to pick the shared_network.
5178 } else if (packet
->interface
!= NULL
) {
5179 status
= shared_network_reference(shared
,
5180 packet
->interface
->shared_network
,
5182 if (packet
->dhcpv6_container_packet
!= NULL
) {
5183 log_info("[L2 Relay] No link address in relay packet "
5184 "assuming L2 relay and using receiving "
5190 * We shouldn't be able to get here but if there is no link
5191 * address and no interface we don't know where to get the
5192 * pool from log an error and return an error.
5194 log_error("No interface and no link address "
5195 "can't determine pool");
5196 status
= DHCP_R_INVALIDARG
;
5203 * When a client thinks it might be on a new link, it sends a
5206 * From RFC3315 section 18.2.2:
5208 * When the server receives a Confirm message, the server determines
5209 * whether the addresses in the Confirm message are appropriate for the
5210 * link to which the client is attached. If all of the addresses in the
5211 * Confirm message pass this test, the server returns a status of
5212 * Success. If any of the addresses do not pass this test, the server
5213 * returns a status of NotOnLink. If the server is unable to perform
5214 * this test (for example, the server does not have information about
5215 * prefixes on the link to which the client is connected), or there were
5216 * no addresses in any of the IAs sent by the client, the server MUST
5217 * NOT send a reply to the client.
5221 dhcpv6_confirm(struct data_string
*reply_ret
, struct packet
*packet
) {
5222 struct shared_network
*shared
;
5223 struct subnet
*subnet
;
5224 struct option_cache
*ia
, *ta
, *oc
;
5225 struct data_string cli_enc_opt_data
, iaaddr
, client_id
, packet_oro
;
5226 struct option_state
*cli_enc_opt_state
, *opt_state
;
5227 struct iaddr cli_addr
;
5229 isc_boolean_t inappropriate
, has_addrs
;
5230 char reply_data
[65536];
5231 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5232 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5235 * Basic client message validation.
5237 memset(&client_id
, 0, sizeof(client_id
));
5238 if (!valid_client_msg(packet
, &client_id
)) {
5243 * Do not process Confirms that do not have IA's we do not recognize.
5245 ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5246 ta
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
5247 if ((ia
== NULL
) && (ta
== NULL
))
5251 * IA_PD's are simply ignored.
5253 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5256 * Bit of variable initialization.
5258 opt_state
= cli_enc_opt_state
= NULL
;
5259 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5260 memset(&iaaddr
, 0, sizeof(iaaddr
));
5261 memset(&packet_oro
, 0, sizeof(packet_oro
));
5263 /* Determine what shared network the client is connected to. We
5264 * must not respond if we don't have any information about the
5265 * network the client is on.
5268 if ((shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
) ||
5272 /* If there are no recorded subnets, then we have no
5273 * information about this subnet - ignore Confirms.
5275 subnet
= shared
->subnets
;
5279 /* Are the addresses in all the IA's appropriate for that link? */
5280 has_addrs
= inappropriate
= ISC_FALSE
;
5282 while(!inappropriate
) {
5283 /* If we've reached the end of the IA_NA pass, move to the
5286 if ((pass
== D6O_IA_NA
) && (ia
== NULL
)) {
5291 /* If we've reached the end of all passes, we're done. */
5295 if (((pass
== D6O_IA_NA
) &&
5296 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5298 packet
, ia
, IA_NA_OFFSET
)) ||
5299 ((pass
== D6O_IA_TA
) &&
5300 !get_encapsulated_IA_state(&cli_enc_opt_state
,
5302 packet
, ia
, IA_TA_OFFSET
))) {
5306 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5309 for ( ; oc
!= NULL
; oc
= oc
->next
) {
5310 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5311 packet
->options
, NULL
,
5312 &global_scope
, oc
, MDL
) ||
5313 (iaaddr
.len
< IAADDR_OFFSET
)) {
5314 log_error("dhcpv6_confirm: "
5315 "error evaluating IAADDR.");
5319 /* Copy out the IPv6 address for processing. */
5321 memcpy(cli_addr
.iabuf
, iaaddr
.data
, 16);
5323 data_string_forget(&iaaddr
, MDL
);
5325 /* Record that we've processed at least one address. */
5326 has_addrs
= ISC_TRUE
;
5328 /* Find out if any subnets cover this address. */
5329 for (subnet
= shared
->subnets
; subnet
!= NULL
;
5330 subnet
= subnet
->next_sibling
) {
5331 if (addr_eq(subnet_number(cli_addr
,
5337 /* If we reach the end of the subnet list, and no
5338 * subnet matches the client address, then it must
5339 * be inappropriate to the link (so far as our
5340 * configuration says). Once we've found one
5341 * inappropriate address, there is no reason to
5342 * continue searching.
5344 if (subnet
== NULL
) {
5345 inappropriate
= ISC_TRUE
;
5350 option_state_dereference(&cli_enc_opt_state
, MDL
);
5351 data_string_forget(&cli_enc_opt_data
, MDL
);
5353 /* Advance to the next IA_*. */
5357 /* If the client supplied no addresses, do not reply. */
5364 if (!start_reply(packet
, &client_id
, NULL
, &opt_state
, reply
)) {
5371 if (inappropriate
) {
5372 if (!set_status_code(STATUS_NotOnLink
,
5373 "Some of the addresses are not on link.",
5378 if (!set_status_code(STATUS_Success
,
5379 "All addresses still on link.",
5386 * Only one option: add it.
5388 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5389 sizeof(reply_data
)-reply_ofs
,
5391 required_opts
, &packet_oro
);
5394 * Return our reply to the caller.
5396 reply_ret
->len
= reply_ofs
;
5397 reply_ret
->buffer
= NULL
;
5398 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5399 log_fatal("No memory to store reply.");
5401 reply_ret
->data
= reply_ret
->buffer
->data
;
5402 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5405 /* Cleanup any stale data strings. */
5406 if (cli_enc_opt_data
.buffer
!= NULL
)
5407 data_string_forget(&cli_enc_opt_data
, MDL
);
5408 if (iaaddr
.buffer
!= NULL
)
5409 data_string_forget(&iaaddr
, MDL
);
5410 if (client_id
.buffer
!= NULL
)
5411 data_string_forget(&client_id
, MDL
);
5412 if (packet_oro
.buffer
!= NULL
)
5413 data_string_forget(&packet_oro
, MDL
);
5415 /* Release any stale option states. */
5416 if (cli_enc_opt_state
!= NULL
)
5417 option_state_dereference(&cli_enc_opt_state
, MDL
);
5418 if (opt_state
!= NULL
)
5419 option_state_dereference(&opt_state
, MDL
);
5423 * Renew is when a client wants to extend its lease/prefix, at time T1.
5425 * We handle this the same as if the client wants a new lease/prefix,
5426 * except for the error code of when addresses don't match.
5430 dhcpv6_renew(struct data_string
*reply
, struct packet
*packet
) {
5431 struct data_string client_id
;
5432 struct data_string server_id
;
5435 * Validate the request.
5437 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5441 /* If the RENEW arrived via unicast and unicast option isn't set,
5442 * reject it per RFC 3315, Sec 18.2.3 */
5443 if (packet
->unicast
== ISC_TRUE
&&
5444 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5445 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5450 lease_to_client(reply
, packet
, &client_id
, &server_id
);
5456 data_string_forget(&server_id
, MDL
);
5457 data_string_forget(&client_id
, MDL
);
5461 * Rebind is when a client wants to extend its lease, at time T2.
5463 * We handle this the same as if the client wants a new lease, except
5464 * for the error code of when addresses don't match.
5468 dhcpv6_rebind(struct data_string
*reply
, struct packet
*packet
) {
5469 struct data_string client_id
;
5471 if (!valid_client_msg(packet
, &client_id
)) {
5475 lease_to_client(reply
, packet
, &client_id
, NULL
);
5477 data_string_forget(&client_id
, MDL
);
5481 ia_na_match_decline(const struct data_string
*client_id
,
5482 const struct data_string
*iaaddr
,
5483 struct iasubopt
*lease
)
5485 char tmp_addr
[INET6_ADDRSTRLEN
];
5487 log_error("Client %s reports address %s is "
5488 "already in use by another host!",
5489 print_hex_1(client_id
->len
, client_id
->data
, 60),
5490 inet_ntop(AF_INET6
, iaaddr
->data
,
5491 tmp_addr
, sizeof(tmp_addr
)));
5492 if (lease
!= NULL
) {
5493 decline_lease6(lease
->ipv6_pool
, lease
);
5494 lease
->ia
->cltt
= cur_time
;
5495 write_ia(lease
->ia
);
5500 ia_na_nomatch_decline(const struct data_string
*client_id
,
5501 const struct data_string
*iaaddr
,
5502 u_int32_t
*ia_na_id
,
5503 struct packet
*packet
,
5508 char tmp_addr
[INET6_ADDRSTRLEN
];
5509 struct option_state
*host_opt_state
;
5512 log_info("Client %s declines address %s, which is not offered to it.",
5513 print_hex_1(client_id
->len
, client_id
->data
, 60),
5514 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5517 * Create state for this IA_NA.
5519 host_opt_state
= NULL
;
5520 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5521 log_error("ia_na_nomatch_decline: out of memory "
5522 "allocating option_state.");
5526 if (!set_status_code(STATUS_NoBinding
, "Decline for unknown address.",
5532 * Insure we have enough space
5534 if (reply_len
< (*reply_ofs
+ 16)) {
5535 log_error("ia_na_nomatch_decline: "
5536 "out of space for reply packet.");
5541 * Put our status code into the reply packet.
5543 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5544 reply_len
-(*reply_ofs
)-16,
5545 host_opt_state
, packet
,
5546 required_opts_STATUS_CODE
, NULL
);
5549 * Store the non-encapsulated option data for this
5550 * IA_NA into our reply packet. Defined in RFC 3315,
5554 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5556 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5557 /* IA_NA, copied from the client */
5558 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5559 /* t1 and t2, odd that we need them, but here it is */
5560 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5561 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5564 * Get ready for next IA_NA.
5566 *reply_ofs
+= (len
+ 16);
5569 option_state_dereference(&host_opt_state
, MDL
);
5573 iterate_over_ia_na(struct data_string
*reply_ret
,
5574 struct packet
*packet
,
5575 const struct data_string
*client_id
,
5576 const struct data_string
*server_id
,
5577 const char *packet_type
,
5578 void (*ia_na_match
)(),
5579 void (*ia_na_nomatch
)())
5581 struct option_state
*opt_state
;
5582 struct host_decl
*packet_host
;
5583 struct option_cache
*ia
;
5584 struct option_cache
*oc
;
5585 /* cli_enc_... variables come from the IA_NA/IA_TA options */
5586 struct data_string cli_enc_opt_data
;
5587 struct option_state
*cli_enc_opt_state
;
5588 struct host_decl
*host
;
5589 struct data_string iaaddr
;
5590 struct data_string fixed_addr
;
5591 char reply_data
[65536];
5592 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
5593 int reply_ofs
= (int)(offsetof(struct dhcpv6_packet
, options
));
5594 char status_msg
[32];
5595 struct iasubopt
*lease
;
5596 struct ia_xx
*existing_ia_na
;
5598 struct data_string key
;
5602 * Initialize to empty values, in case we have to exit early.
5605 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
5606 cli_enc_opt_state
= NULL
;
5607 memset(&iaaddr
, 0, sizeof(iaaddr
));
5608 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
5612 * Find the host record that matches from the packet, if any.
5615 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
5618 * Set our reply information.
5620 reply
->msg_type
= DHCPV6_REPLY
;
5621 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
5622 sizeof(reply
->transaction_id
));
5625 * Build our option state for reply.
5628 if (!option_state_allocate(&opt_state
, MDL
)) {
5629 log_error("iterate_over_ia_na: no memory for option_state.");
5632 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5633 packet
->options
, opt_state
,
5634 &global_scope
, root_group
, NULL
, NULL
);
5637 * RFC 3315, section 18.2.7 tells us which options to include.
5639 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
5641 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
5642 (unsigned char *)server_duid
.data
,
5643 server_duid
.len
, D6O_SERVERID
, 0)) {
5644 log_error("iterate_over_ia_na: "
5645 "error saving server identifier.");
5650 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
5652 (unsigned char *)client_id
->data
,
5655 log_error("iterate_over_ia_na: "
5656 "error saving client identifier.");
5660 snprintf(status_msg
, sizeof(status_msg
), "%s received.", packet_type
);
5661 if (!set_status_code(STATUS_Success
, status_msg
, opt_state
)) {
5666 * Add our options that are not associated with any IA_NA or IA_TA.
5668 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
5669 sizeof(reply_data
)-reply_ofs
,
5671 required_opts
, NULL
);
5674 * Loop through the IA_NA reported by the client, and deal with
5675 * addresses reported as already in use.
5677 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
5678 ia
!= NULL
; ia
= ia
->next
) {
5680 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
5682 packet
, ia
, IA_NA_OFFSET
)) {
5686 iaid
= getULong(cli_enc_opt_data
.data
);
5689 * XXX: It is possible that we can get multiple addresses
5690 * sent by the client. We don't send multiple
5691 * addresses, so this indicates a client error.
5692 * We should check for multiple IAADDR options, log
5693 * if found, and set as an error.
5695 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
5698 /* no address given for this IA, ignore */
5699 option_state_dereference(&cli_enc_opt_state
, MDL
);
5700 data_string_forget(&cli_enc_opt_data
, MDL
);
5704 memset(&iaaddr
, 0, sizeof(iaaddr
));
5705 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
5706 packet
->options
, NULL
,
5707 &global_scope
, oc
, MDL
)) {
5708 log_error("iterate_over_ia_na: "
5709 "error evaluating IAADDR.");
5714 * Now we need to figure out which host record matches
5715 * this IA_NA and IAADDR (encapsulated option contents
5716 * matching a host record by option).
5718 * XXX: We don't currently track IA_NA separately, but
5719 * we will need to do this!
5722 if (!find_hosts_by_option(&host
, packet
,
5723 cli_enc_opt_state
, MDL
)) {
5724 if (packet_host
!= NULL
) {
5730 while (host
!= NULL
) {
5731 if (host
->fixed_addr
!= NULL
) {
5732 if (!evaluate_option_cache(&fixed_addr
, NULL
,
5734 NULL
, &global_scope
,
5737 log_error("iterate_over_ia_na: error "
5738 "evaluating host address.");
5741 if ((iaaddr
.len
>= 16) &&
5742 !memcmp(fixed_addr
.data
, iaaddr
.data
, 16)) {
5743 data_string_forget(&fixed_addr
, MDL
);
5746 data_string_forget(&fixed_addr
, MDL
);
5748 host
= host
->n_ipaddr
;
5751 if ((host
== NULL
) && (iaaddr
.len
>= IAADDR_OFFSET
)) {
5753 * Find existing IA_NA.
5755 if (ia_make_key(&key
, iaid
,
5756 (char *)client_id
->data
,
5758 MDL
) != ISC_R_SUCCESS
) {
5759 log_fatal("iterate_over_ia_na: no memory for "
5763 existing_ia_na
= NULL
;
5764 if (ia_hash_lookup(&existing_ia_na
, ia_na_active
,
5765 (unsigned char *)key
.data
,
5768 * Make sure this address is in the IA_NA.
5770 for (i
=0; i
<existing_ia_na
->num_iasubopt
; i
++) {
5771 struct iasubopt
*tmp
;
5772 struct in6_addr
*in6_addr
;
5774 tmp
= existing_ia_na
->iasubopt
[i
];
5775 in6_addr
= &tmp
->addr
;
5776 if (memcmp(in6_addr
,
5777 iaaddr
.data
, 16) == 0) {
5778 iasubopt_reference(&lease
,
5785 data_string_forget(&key
, MDL
);
5788 if ((host
!= NULL
) || (lease
!= NULL
)) {
5789 ia_na_match(client_id
, &iaaddr
, lease
);
5791 ia_na_nomatch(client_id
, &iaaddr
,
5792 (u_int32_t
*)cli_enc_opt_data
.data
,
5793 packet
, reply_data
, &reply_ofs
,
5794 sizeof(reply_data
));
5797 if (lease
!= NULL
) {
5798 iasubopt_dereference(&lease
, MDL
);
5801 data_string_forget(&iaaddr
, MDL
);
5802 option_state_dereference(&cli_enc_opt_state
, MDL
);
5803 data_string_forget(&cli_enc_opt_data
, MDL
);
5807 * Return our reply to the caller.
5809 reply_ret
->len
= reply_ofs
;
5810 reply_ret
->buffer
= NULL
;
5811 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
5812 log_fatal("No memory to store reply.");
5814 reply_ret
->data
= reply_ret
->buffer
->data
;
5815 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
5818 if (lease
!= NULL
) {
5819 iasubopt_dereference(&lease
, MDL
);
5821 if (fixed_addr
.buffer
!= NULL
) {
5822 data_string_forget(&fixed_addr
, MDL
);
5824 if (iaaddr
.buffer
!= NULL
) {
5825 data_string_forget(&iaaddr
, MDL
);
5827 if (cli_enc_opt_state
!= NULL
) {
5828 option_state_dereference(&cli_enc_opt_state
, MDL
);
5830 if (cli_enc_opt_data
.buffer
!= NULL
) {
5831 data_string_forget(&cli_enc_opt_data
, MDL
);
5833 if (opt_state
!= NULL
) {
5834 option_state_dereference(&opt_state
, MDL
);
5839 * Decline means a client has detected that something else is using an
5840 * address we gave it.
5842 * Since we're only dealing with fixed leases for now, there's not
5843 * much we can do, other that log the occurrence.
5845 * When we start issuing addresses from pools, then we will have to
5846 * record our declined addresses and issue another. In general with
5847 * IPv6 there is no worry about DoS by clients exhausting space, but
5848 * we still need to be aware of this possibility.
5853 dhcpv6_decline(struct data_string
*reply
, struct packet
*packet
) {
5854 struct data_string client_id
;
5855 struct data_string server_id
;
5858 * Validate our input.
5860 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
5864 /* If the DECLINE arrived via unicast and unicast option isn't set,
5865 * reject it per RFC 3315, Sec 18.2.7 */
5866 if (packet
->unicast
== ISC_TRUE
&&
5867 is_unicast_option_defined(packet
) == ISC_FALSE
) {
5868 unicast_reject(reply
, packet
, &client_id
, &server_id
);
5871 * Undefined for IA_PD.
5873 delete_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
5876 * And operate on each IA_NA in this packet.
5878 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
5879 "Decline", ia_na_match_decline
,
5880 ia_na_nomatch_decline
);
5884 data_string_forget(&server_id
, MDL
);
5885 data_string_forget(&client_id
, MDL
);
5889 ia_na_match_release(const struct data_string
*client_id
,
5890 const struct data_string
*iaaddr
,
5891 struct iasubopt
*lease
)
5893 char tmp_addr
[INET6_ADDRSTRLEN
];
5895 log_info("Client %s releases address %s",
5896 print_hex_1(client_id
->len
, client_id
->data
, 60),
5897 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5898 if (lease
!= NULL
) {
5899 release_lease6(lease
->ipv6_pool
, lease
);
5900 lease
->ia
->cltt
= cur_time
;
5901 write_ia(lease
->ia
);
5906 ia_na_nomatch_release(const struct data_string
*client_id
,
5907 const struct data_string
*iaaddr
,
5908 u_int32_t
*ia_na_id
,
5909 struct packet
*packet
,
5914 char tmp_addr
[INET6_ADDRSTRLEN
];
5915 struct option_state
*host_opt_state
;
5918 log_info("Client %s releases address %s, which is not leased to it.",
5919 print_hex_1(client_id
->len
, client_id
->data
, 60),
5920 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
5923 * Create state for this IA_NA.
5925 host_opt_state
= NULL
;
5926 if (!option_state_allocate(&host_opt_state
, MDL
)) {
5927 log_error("ia_na_nomatch_release: out of memory "
5928 "allocating option_state.");
5932 if (!set_status_code(STATUS_NoBinding
,
5933 "Release for non-leased address.",
5939 * Insure we have enough space
5941 if (reply_len
< (*reply_ofs
+ 16)) {
5942 log_error("ia_na_nomatch_release: "
5943 "out of space for reply packet.");
5948 * Put our status code into the reply packet.
5950 len
= store_options6(reply_data
+(*reply_ofs
)+16,
5951 reply_len
-(*reply_ofs
)-16,
5952 host_opt_state
, packet
,
5953 required_opts_STATUS_CODE
, NULL
);
5956 * Store the non-encapsulated option data for this
5957 * IA_NA into our reply packet. Defined in RFC 3315,
5961 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
5963 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
5964 /* IA_NA, copied from the client */
5965 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
5966 /* t1 and t2, odd that we need them, but here it is */
5967 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
5968 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
5971 * Get ready for next IA_NA.
5973 *reply_ofs
+= (len
+ 16);
5976 option_state_dereference(&host_opt_state
, MDL
);
5980 ia_pd_match_release(const struct data_string
*client_id
,
5981 const struct data_string
*iapref
,
5982 struct iasubopt
*prefix
)
5984 char tmp_addr
[INET6_ADDRSTRLEN
];
5986 log_info("Client %s releases prefix %s/%u",
5987 print_hex_1(client_id
->len
, client_id
->data
, 60),
5988 inet_ntop(AF_INET6
, iapref
->data
+ 9,
5989 tmp_addr
, sizeof(tmp_addr
)),
5990 (unsigned) getUChar(iapref
->data
+ 8));
5991 if (prefix
!= NULL
) {
5992 release_lease6(prefix
->ipv6_pool
, prefix
);
5993 prefix
->ia
->cltt
= cur_time
;
5994 write_ia(prefix
->ia
);
5999 ia_pd_nomatch_release(const struct data_string
*client_id
,
6000 const struct data_string
*iapref
,
6001 u_int32_t
*ia_pd_id
,
6002 struct packet
*packet
,
6007 char tmp_addr
[INET6_ADDRSTRLEN
];
6008 struct option_state
*host_opt_state
;
6011 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
6012 print_hex_1(client_id
->len
, client_id
->data
, 60),
6013 inet_ntop(AF_INET6
, iapref
->data
+ 9,
6014 tmp_addr
, sizeof(tmp_addr
)),
6015 (unsigned) getUChar(iapref
->data
+ 8));
6018 * Create state for this IA_PD.
6020 host_opt_state
= NULL
;
6021 if (!option_state_allocate(&host_opt_state
, MDL
)) {
6022 log_error("ia_pd_nomatch_release: out of memory "
6023 "allocating option_state.");
6027 if (!set_status_code(STATUS_NoBinding
,
6028 "Release for non-leased prefix.",
6034 * Insure we have enough space
6036 if (reply_len
< (*reply_ofs
+ 16)) {
6037 log_error("ia_pd_nomatch_release: "
6038 "out of space for reply packet.");
6043 * Put our status code into the reply packet.
6045 len
= store_options6(reply_data
+(*reply_ofs
)+16,
6046 reply_len
-(*reply_ofs
)-16,
6047 host_opt_state
, packet
,
6048 required_opts_STATUS_CODE
, NULL
);
6051 * Store the non-encapsulated option data for this
6052 * IA_PD into our reply packet. Defined in RFC 3315,
6056 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_PD
);
6058 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
6059 /* IA_PD, copied from the client */
6060 memcpy(reply_data
+(*reply_ofs
)+4, ia_pd_id
, 4);
6061 /* t1 and t2, odd that we need them, but here it is */
6062 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
6063 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
6066 * Get ready for next IA_PD.
6068 *reply_ofs
+= (len
+ 16);
6071 option_state_dereference(&host_opt_state
, MDL
);
6075 iterate_over_ia_pd(struct data_string
*reply_ret
,
6076 struct packet
*packet
,
6077 const struct data_string
*client_id
,
6078 const struct data_string
*server_id
,
6079 const char *packet_type
,
6080 void (*ia_pd_match
)(),
6081 void (*ia_pd_nomatch
)())
6083 struct data_string reply_new
;
6085 struct option_state
*opt_state
;
6086 struct host_decl
*packet_host
;
6087 struct option_cache
*ia
;
6088 struct option_cache
*oc
;
6089 /* cli_enc_... variables come from the IA_PD options */
6090 struct data_string cli_enc_opt_data
;
6091 struct option_state
*cli_enc_opt_state
;
6092 struct host_decl
*host
;
6093 struct data_string iaprefix
;
6094 char reply_data
[65536];
6096 struct iasubopt
*prefix
;
6097 struct ia_xx
*existing_ia_pd
;
6099 struct data_string key
;
6103 * Initialize to empty values, in case we have to exit early.
6105 memset(&reply_new
, 0, sizeof(reply_new
));
6107 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
6108 cli_enc_opt_state
= NULL
;
6109 memset(&iaprefix
, 0, sizeof(iaprefix
));
6113 * Compute the available length for the reply.
6115 reply_len
= sizeof(reply_data
) - reply_ret
->len
;
6119 * Find the host record that matches from the packet, if any.
6122 find_hosts6(&packet_host
, packet
, client_id
, MDL
);
6125 * Build our option state for reply.
6128 if (!option_state_allocate(&opt_state
, MDL
)) {
6129 log_error("iterate_over_ia_pd: no memory for option_state.");
6132 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
6133 packet
->options
, opt_state
,
6134 &global_scope
, root_group
, NULL
, NULL
);
6137 * Loop through the IA_PD reported by the client, and deal with
6138 * prefixes reported as already in use.
6140 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
6141 ia
!= NULL
; ia
= ia
->next
) {
6143 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
6145 packet
, ia
, IA_PD_OFFSET
)) {
6149 iaid
= getULong(cli_enc_opt_data
.data
);
6151 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
6154 /* no prefix given for this IA_PD, ignore */
6155 option_state_dereference(&cli_enc_opt_state
, MDL
);
6156 data_string_forget(&cli_enc_opt_data
, MDL
);
6160 for (; oc
!= NULL
; oc
= oc
->next
) {
6161 memset(&iaprefix
, 0, sizeof(iaprefix
));
6162 if (!evaluate_option_cache(&iaprefix
, packet
, NULL
, NULL
,
6163 packet
->options
, NULL
,
6164 &global_scope
, oc
, MDL
)) {
6165 log_error("iterate_over_ia_pd: "
6166 "error evaluating IAPREFIX.");
6171 * Now we need to figure out which host record matches
6172 * this IA_PD and IAPREFIX (encapsulated option contents
6173 * matching a host record by option).
6175 * XXX: We don't currently track IA_PD separately, but
6176 * we will need to do this!
6179 if (!find_hosts_by_option(&host
, packet
,
6180 cli_enc_opt_state
, MDL
)) {
6181 if (packet_host
!= NULL
) {
6187 while (host
!= NULL
) {
6188 if (host
->fixed_prefix
!= NULL
) {
6189 struct iaddrcidrnetlist
*l
;
6190 int plen
= (int) getUChar(iaprefix
.data
+ 8);
6192 for (l
= host
->fixed_prefix
; l
!= NULL
;
6194 if (plen
!= l
->cidrnet
.bits
)
6196 if (memcmp(iaprefix
.data
+ 9,
6197 l
->cidrnet
.lo_addr
.iabuf
,
6201 if ((l
!= NULL
) && (iaprefix
.len
>= 17))
6204 host
= host
->n_ipaddr
;
6207 if ((host
== NULL
) && (iaprefix
.len
>= IAPREFIX_OFFSET
)) {
6209 * Find existing IA_PD.
6211 if (ia_make_key(&key
, iaid
,
6212 (char *)client_id
->data
,
6214 MDL
) != ISC_R_SUCCESS
) {
6215 log_fatal("iterate_over_ia_pd: no memory for "
6219 existing_ia_pd
= NULL
;
6220 if (ia_hash_lookup(&existing_ia_pd
, ia_pd_active
,
6221 (unsigned char *)key
.data
,
6224 * Make sure this prefix is in the IA_PD.
6227 i
< existing_ia_pd
->num_iasubopt
;
6229 struct iasubopt
*tmp
;
6232 plen
= getUChar(iaprefix
.data
+ 8);
6233 tmp
= existing_ia_pd
->iasubopt
[i
];
6234 if ((tmp
->plen
== plen
) &&
6238 iasubopt_reference(&prefix
,
6245 data_string_forget(&key
, MDL
);
6248 if ((host
!= NULL
) || (prefix
!= NULL
)) {
6249 ia_pd_match(client_id
, &iaprefix
, prefix
);
6251 ia_pd_nomatch(client_id
, &iaprefix
,
6252 (u_int32_t
*)cli_enc_opt_data
.data
,
6253 packet
, reply_data
, &reply_ofs
,
6254 reply_len
- reply_ofs
);
6257 if (prefix
!= NULL
) {
6258 iasubopt_dereference(&prefix
, MDL
);
6261 data_string_forget(&iaprefix
, MDL
);
6264 option_state_dereference(&cli_enc_opt_state
, MDL
);
6265 data_string_forget(&cli_enc_opt_data
, MDL
);
6269 * Return our reply to the caller.
6270 * The IA_NA routine has already filled at least the header.
6272 reply_new
.len
= reply_ret
->len
+ reply_ofs
;
6273 if (!buffer_allocate(&reply_new
.buffer
, reply_new
.len
, MDL
)) {
6274 log_fatal("No memory to store reply.");
6276 reply_new
.data
= reply_new
.buffer
->data
;
6277 memcpy(reply_new
.buffer
->data
,
6278 reply_ret
->buffer
->data
, reply_ret
->len
);
6279 memcpy(reply_new
.buffer
->data
+ reply_ret
->len
,
6280 reply_data
, reply_ofs
);
6281 data_string_forget(reply_ret
, MDL
);
6282 data_string_copy(reply_ret
, &reply_new
, MDL
);
6283 data_string_forget(&reply_new
, MDL
);
6286 if (prefix
!= NULL
) {
6287 iasubopt_dereference(&prefix
, MDL
);
6289 if (iaprefix
.buffer
!= NULL
) {
6290 data_string_forget(&iaprefix
, MDL
);
6292 if (cli_enc_opt_state
!= NULL
) {
6293 option_state_dereference(&cli_enc_opt_state
, MDL
);
6295 if (cli_enc_opt_data
.buffer
!= NULL
) {
6296 data_string_forget(&cli_enc_opt_data
, MDL
);
6298 if (opt_state
!= NULL
) {
6299 option_state_dereference(&opt_state
, MDL
);
6304 * Release means a client is done with the leases.
6308 dhcpv6_release(struct data_string
*reply
, struct packet
*packet
) {
6309 struct data_string client_id
;
6310 struct data_string server_id
;
6313 * Validate our input.
6315 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
6319 /* If the RELEASE arrived via unicast and unicast option isn't set,
6320 * reject it per RFC 3315, Sec 18.2.6 */
6321 if (packet
->unicast
== ISC_TRUE
&&
6322 is_unicast_option_defined(packet
) == ISC_FALSE
) {
6323 unicast_reject(reply
, packet
, &client_id
, &server_id
);
6326 * And operate on each IA_NA in this packet.
6328 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
,
6329 "Release", ia_na_match_release
,
6330 ia_na_nomatch_release
);
6333 * And operate on each IA_PD in this packet.
6335 iterate_over_ia_pd(reply
, packet
, &client_id
, &server_id
,
6336 "Release", ia_pd_match_release
,
6337 ia_pd_nomatch_release
);
6340 data_string_forget(&server_id
, MDL
);
6341 data_string_forget(&client_id
, MDL
);
6345 * Information-Request is used by clients who have obtained an address
6346 * from other means, but want configuration information from the server.
6350 dhcpv6_information_request(struct data_string
*reply
, struct packet
*packet
) {
6351 struct data_string client_id
;
6352 struct data_string server_id
;
6355 * Validate our input.
6357 if (!valid_client_info_req(packet
, &server_id
)) {
6362 * Get our client ID, if there is one.
6364 memset(&client_id
, 0, sizeof(client_id
));
6365 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
) {
6366 data_string_forget(&client_id
, MDL
);
6370 * Use the lease_to_client() function. This will work fine,
6371 * because the valid_client_info_req() insures that we
6372 * don't have any IA that would cause us to allocate
6373 * resources to the client.
6375 lease_to_client(reply
, packet
, &client_id
,
6376 server_id
.data
!= NULL
? &server_id
: NULL
);
6381 if (client_id
.data
!= NULL
) {
6382 data_string_forget(&client_id
, MDL
);
6384 data_string_forget(&server_id
, MDL
);
6388 * The Relay-forw message is sent by relays. It typically contains a
6389 * single option, which encapsulates an entire packet.
6391 * We need to build an encapsulated reply.
6394 /* XXX: this is very, very similar to do_packet6(), and should probably
6395 be combined in a clever way */
6396 /* DHCPv6 server side */
6398 dhcpv6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
6399 struct option_cache
*oc
;
6400 struct data_string enc_opt_data
;
6401 struct packet
*enc_packet
;
6402 unsigned char msg_type
;
6403 const struct dhcpv6_packet
*msg
;
6404 const struct dhcpv6_relay_packet
*relay
;
6405 struct data_string enc_reply
;
6406 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6407 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6408 struct data_string a_opt
, packet_ero
;
6409 struct option_state
*opt_state
;
6410 static char reply_data
[65536];
6411 struct dhcpv6_relay_packet
*reply
;
6415 * Initialize variables for early exit.
6418 memset(&a_opt
, 0, sizeof(a_opt
));
6419 memset(&packet_ero
, 0, sizeof(packet_ero
));
6420 memset(&enc_reply
, 0, sizeof(enc_reply
));
6421 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6425 * Get our encapsulated relay message.
6427 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
6429 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
6430 link_addr
, sizeof(link_addr
));
6431 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
6432 peer_addr
, sizeof(peer_addr
));
6433 log_info("Relay-forward from %s with link address=%s and "
6434 "peer address=%s missing Relay Message option.",
6435 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
6439 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
6440 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
6441 /* should be dhcpv6_relay_forw */
6442 log_error("dhcpv6_forw_relay: error evaluating "
6443 "relayed message.");
6447 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
6448 /* should be dhcpv6_relay_forw */
6449 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
6454 * Build a packet structure from this encapsulated packet.
6457 if (!packet_allocate(&enc_packet
, MDL
)) {
6458 /* should be dhcpv6_relay_forw */
6459 log_error("dhcpv6_forw_relay: "
6460 "no memory for encapsulated packet.");
6464 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
6465 /* should be dhcpv6_relay_forw */
6466 log_error("dhcpv6_forw_relay: "
6467 "no memory for encapsulated packet's options.");
6471 enc_packet
->client_port
= packet
->client_port
;
6472 enc_packet
->client_addr
= packet
->client_addr
;
6473 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
6474 enc_packet
->dhcpv6_container_packet
= packet
;
6476 msg_type
= enc_opt_data
.data
[0];
6477 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
6478 (msg_type
== DHCPV6_RELAY_REPL
)) {
6479 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6480 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
6481 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
6483 /* relay-specific data */
6484 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
6485 memcpy(&enc_packet
->dhcpv6_link_address
,
6486 relay
->link_address
, sizeof(relay
->link_address
));
6487 memcpy(&enc_packet
->dhcpv6_peer_address
,
6488 relay
->peer_address
, sizeof(relay
->peer_address
));
6490 if (!parse_option_buffer(enc_packet
->options
,
6492 enc_opt_data
.len
- relaylen
,
6493 &dhcpv6_universe
)) {
6494 /* no logging here, as parse_option_buffer() logs all
6495 cases where it fails */
6498 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
6499 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6501 if (!dhcpv4_over_dhcpv6
||
6502 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6503 log_error("dhcpv6_relay_forw: "
6504 "unsupported %s message type.",
6505 dhcpv6_type_names
[msg_type
]);
6508 forw_dhcpv4_query(packet
);
6511 log_error("dhcpv6_relay_forw: unsupported %s message type.",
6512 dhcpv6_type_names
[msg_type
]);
6514 #endif /* DHCP4o6 */
6516 int msglen
= (int)(offsetof(struct dhcpv6_packet
, options
));
6517 msg
= (struct dhcpv6_packet
*)enc_opt_data
.data
;
6518 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
6520 /* message-specific data */
6521 memcpy(enc_packet
->dhcpv6_transaction_id
,
6522 msg
->transaction_id
,
6523 sizeof(enc_packet
->dhcpv6_transaction_id
));
6525 if (!parse_option_buffer(enc_packet
->options
,
6527 enc_opt_data
.len
- msglen
,
6528 &dhcpv6_universe
)) {
6529 /* no logging here, as parse_option_buffer() logs all
6530 cases where it fails */
6536 * This is recursive. It is possible to exceed maximum packet size.
6537 * XXX: This will cause the packet send to fail.
6539 build_dhcpv6_reply(&enc_reply
, enc_packet
);
6542 * If we got no encapsulated data, then it is discarded, and
6543 * our reply-forw is also discarded.
6545 if (enc_reply
.data
== NULL
) {
6550 * Now we can use the reply_data buffer.
6551 * Packet header stuff all comes from the forward message.
6553 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
6554 reply
->msg_type
= DHCPV6_RELAY_REPL
;
6555 reply
->hop_count
= packet
->dhcpv6_hop_count
;
6556 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
6557 sizeof(reply
->link_address
));
6558 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
6559 sizeof(reply
->peer_address
));
6560 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6563 * Get the reply option state.
6566 if (!option_state_allocate(&opt_state
, MDL
)) {
6567 log_error("dhcpv6_relay_forw: no memory for option state.");
6572 * Append the interface-id if present.
6574 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6577 if (!evaluate_option_cache(&a_opt
, packet
,
6579 packet
->options
, NULL
,
6580 &global_scope
, oc
, MDL
)) {
6581 log_error("dhcpv6_relay_forw: error evaluating "
6585 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6586 (unsigned char *)a_opt
.data
,
6588 D6O_INTERFACE_ID
, 0)) {
6589 log_error("dhcpv6_relay_forw: error saving "
6593 data_string_forget(&a_opt
, MDL
);
6597 * Append our encapsulated stuff for caller.
6599 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6600 (unsigned char *)enc_reply
.data
,
6602 D6O_RELAY_MSG
, 0)) {
6603 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
6608 * Get the ERO if any.
6610 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
6615 if (!evaluate_option_cache(&packet_ero
, packet
,
6617 packet
->options
, NULL
,
6618 &global_scope
, oc
, MDL
) ||
6619 (packet_ero
.len
& 1)) {
6620 log_error("dhcpv6_relay_forw: error evaluating ERO.");
6624 /* Decode and apply the ERO. */
6625 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
6626 req
= getUShort(packet_ero
.data
+ i
);
6627 /* Already in the reply? */
6628 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
6631 /* Get it from the packet if present. */
6632 oc
= lookup_option(&dhcpv6_universe
,
6637 if (!evaluate_option_cache(&a_opt
, packet
,
6639 packet
->options
, NULL
,
6640 &global_scope
, oc
, MDL
)) {
6641 log_error("dhcpv6_relay_forw: error "
6642 "evaluating option %u.", req
);
6645 if (!save_option_buffer(&dhcpv6_universe
,
6648 (unsigned char *)a_opt
.data
,
6652 log_error("dhcpv6_relay_forw: error saving "
6656 data_string_forget(&a_opt
, MDL
);
6660 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
6661 sizeof(reply_data
) - reply_ofs
,
6663 required_opts_agent
, &packet_ero
);
6666 * Return our reply to the caller.
6668 reply_ret
->len
= reply_ofs
;
6669 reply_ret
->buffer
= NULL
;
6670 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
6671 log_fatal("No memory to store reply.");
6673 reply_ret
->data
= reply_ret
->buffer
->data
;
6674 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
6677 if (opt_state
!= NULL
)
6678 option_state_dereference(&opt_state
, MDL
);
6679 if (a_opt
.data
!= NULL
) {
6680 data_string_forget(&a_opt
, MDL
);
6682 if (packet_ero
.data
!= NULL
) {
6683 data_string_forget(&packet_ero
, MDL
);
6685 if (enc_reply
.data
!= NULL
) {
6686 data_string_forget(&enc_reply
, MDL
);
6688 if (enc_opt_data
.data
!= NULL
) {
6689 data_string_forget(&enc_opt_data
, MDL
);
6691 if (enc_packet
!= NULL
) {
6692 packet_dereference(&enc_packet
, MDL
);
6697 /* \brief Internal processing of a relayed DHCPv4-query
6698 * (DHCPv4 server side)
6700 * Code copied from \ref dhcpv6_relay_forw() which itself is
6701 * from \ref do_packet6().
6703 * \param reply_ret pointer to the response
6704 * \param packet the query
6707 dhcp4o6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
6708 struct option_cache
*oc
;
6709 struct data_string enc_opt_data
;
6710 struct packet
*enc_packet
;
6711 unsigned char msg_type
;
6712 const struct dhcpv6_relay_packet
*relay
;
6713 const struct dhcpv4_over_dhcpv6_packet
*msg
;
6714 struct data_string enc_reply
;
6715 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6716 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6717 struct data_string a_opt
, packet_ero
;
6718 struct option_state
*opt_state
;
6719 static char reply_data
[65536];
6720 struct dhcpv6_relay_packet
*reply
;
6724 * Initialize variables for early exit.
6727 memset(&a_opt
, 0, sizeof(a_opt
));
6728 memset(&packet_ero
, 0, sizeof(packet_ero
));
6729 memset(&enc_reply
, 0, sizeof(enc_reply
));
6730 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
6734 * Get our encapsulated relay message.
6736 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
6738 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
6739 link_addr
, sizeof(link_addr
));
6740 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
6741 peer_addr
, sizeof(peer_addr
));
6742 log_info("Relay-forward from %s with link address=%s and "
6743 "peer address=%s missing Relay Message option.",
6744 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
6748 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
6749 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
6750 log_error("dhcp4o6_relay_forw: error evaluating "
6751 "relayed message.");
6755 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
6756 log_error("dhcp4o6_relay_forw: "
6757 "encapsulated packet too short.");
6762 * Build a packet structure from this encapsulated packet.
6764 if (!packet_allocate(&enc_packet
, MDL
)) {
6765 log_error("dhcp4o6_relay_forw: "
6766 "no memory for encapsulated packet.");
6770 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
6771 log_error("dhcp4o6_relay_forw: "
6772 "no memory for encapsulated packet's options.");
6776 enc_packet
->client_port
= packet
->client_port
;
6777 enc_packet
->client_addr
= packet
->client_addr
;
6778 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
6779 enc_packet
->dhcpv6_container_packet
= packet
;
6781 msg_type
= enc_opt_data
.data
[0];
6782 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
6783 (msg_type
== DHCPV6_RELAY_REPL
)) {
6784 int relaylen
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6785 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
6786 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
6788 /* relay-specific data */
6789 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
6790 memcpy(&enc_packet
->dhcpv6_link_address
,
6791 relay
->link_address
, sizeof(relay
->link_address
));
6792 memcpy(&enc_packet
->dhcpv6_peer_address
,
6793 relay
->peer_address
, sizeof(relay
->peer_address
));
6795 if (!parse_option_buffer(enc_packet
->options
,
6797 enc_opt_data
.len
- relaylen
,
6798 &dhcpv6_universe
)) {
6799 /* no logging here, as parse_option_buffer() logs all
6800 cases where it fails */
6803 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
6804 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
6806 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
6807 msg
= (struct dhcpv4_over_dhcpv6_packet
*)enc_opt_data
.data
;
6808 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
6810 /* message-specific data */
6811 memcpy(enc_packet
->dhcp4o6_flags
,
6813 sizeof(enc_packet
->dhcp4o6_flags
));
6815 if (!parse_option_buffer(enc_packet
->options
,
6817 enc_opt_data
.len
- msglen
,
6818 &dhcpv6_universe
)) {
6819 /* no logging here, as parse_option_buffer() logs all
6820 cases where it fails */
6824 log_error("dhcp4o6_relay_forw: unexpected message of type %d.",
6830 * This is recursive. It is possible to exceed maximum packet size.
6831 * XXX: This will cause the packet send to fail.
6833 build_dhcpv6_reply(&enc_reply
, enc_packet
);
6836 * If we got no encapsulated data, then it is discarded, and
6837 * our reply-forw is also discarded.
6839 if (enc_reply
.data
== NULL
) {
6844 * Now we can use the reply_data buffer.
6845 * Packet header stuff all comes from the forward message.
6847 reply
= (struct dhcpv6_relay_packet
*)reply_data
;
6848 reply
->msg_type
= DHCPV6_RELAY_REPL
;
6849 reply
->hop_count
= packet
->dhcpv6_hop_count
;
6850 memcpy(reply
->link_address
, &packet
->dhcpv6_link_address
,
6851 sizeof(reply
->link_address
));
6852 memcpy(reply
->peer_address
, &packet
->dhcpv6_peer_address
,
6853 sizeof(reply
->peer_address
));
6854 reply_ofs
= (int)(offsetof(struct dhcpv6_relay_packet
, options
));
6857 * Get the reply option state.
6859 if (!option_state_allocate(&opt_state
, MDL
)) {
6860 log_error("dhcp4o6_relay_forw: no memory for option state.");
6865 * Append the interface-id if present.
6867 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
6870 if (!evaluate_option_cache(&a_opt
, packet
,
6872 packet
->options
, NULL
,
6873 &global_scope
, oc
, MDL
)) {
6874 log_error("dhcp4o6_relay_forw: error evaluating "
6878 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6879 (unsigned char *)a_opt
.data
,
6881 D6O_INTERFACE_ID
, 0)) {
6882 log_error("dhcp4o6_relay_forw: error saving "
6886 data_string_forget(&a_opt
, MDL
);
6890 * Append our encapsulated stuff for caller.
6892 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
6893 (unsigned char *)enc_reply
.data
,
6895 D6O_RELAY_MSG
, 0)) {
6896 log_error("dhcp4o6_relay_forw: error saving Relay MSG.");
6901 * Get the ERO if any.
6903 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ERO
);
6908 if (!evaluate_option_cache(&packet_ero
, packet
,
6910 packet
->options
, NULL
,
6911 &global_scope
, oc
, MDL
) ||
6912 (packet_ero
.len
& 1)) {
6913 log_error("dhcp4o6_relay_forw: error evaluating ERO.");
6917 /* Decode and apply the ERO. */
6918 for (i
= 0; i
< packet_ero
.len
; i
+= 2) {
6919 req
= getUShort(packet_ero
.data
+ i
);
6920 /* Already in the reply? */
6921 oc
= lookup_option(&dhcpv6_universe
, opt_state
, req
);
6924 /* Get it from the packet if present. */
6925 oc
= lookup_option(&dhcpv6_universe
,
6930 if (!evaluate_option_cache(&a_opt
, packet
,
6932 packet
->options
, NULL
,
6933 &global_scope
, oc
, MDL
)) {
6934 log_error("dhcp4o6_relay_forw: error "
6935 "evaluating option %u.", req
);
6938 if (!save_option_buffer(&dhcpv6_universe
,
6941 (unsigned char *)a_opt
.data
,
6945 log_error("dhcp4o6_relay_forw: error saving "
6949 data_string_forget(&a_opt
, MDL
);
6953 reply_ofs
+= store_options6(reply_data
+ reply_ofs
,
6954 sizeof(reply_data
) - reply_ofs
,
6956 required_opts_agent
, &packet_ero
);
6959 * Return our reply to the caller.
6961 reply_ret
->len
= reply_ofs
;
6962 reply_ret
->buffer
= NULL
;
6963 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
6964 log_fatal("No memory to store reply.");
6966 reply_ret
->data
= reply_ret
->buffer
->data
;
6967 memcpy(reply_ret
->buffer
->data
, reply_data
, reply_ofs
);
6970 if (opt_state
!= NULL
)
6971 option_state_dereference(&opt_state
, MDL
);
6972 if (a_opt
.data
!= NULL
) {
6973 data_string_forget(&a_opt
, MDL
);
6975 if (packet_ero
.data
!= NULL
) {
6976 data_string_forget(&packet_ero
, MDL
);
6978 if (enc_reply
.data
!= NULL
) {
6979 data_string_forget(&enc_reply
, MDL
);
6981 if (enc_opt_data
.data
!= NULL
) {
6982 data_string_forget(&enc_opt_data
, MDL
);
6984 if (enc_packet
!= NULL
) {
6985 packet_dereference(&enc_packet
, MDL
);
6990 * \brief Internal processing of a DHCPv4-query
6991 * (DHCPv4 server function)
6993 * Code copied from \ref do_packet().
6995 * \param reply_ret pointer to the response
6996 * \param packet the query
6999 dhcp4o6_dhcpv4_query(struct data_string
*reply_ret
, struct packet
*packet
) {
7000 struct option_cache
*oc
;
7001 struct data_string enc_opt_data
;
7002 struct packet
*enc_packet
;
7003 struct data_string enc_response
;
7004 struct option_state
*opt_state
;
7005 static char response_data
[65536];
7006 struct dhcpv4_over_dhcpv6_packet
*response
;
7010 * Initialize variables for early exit.
7013 memset(&enc_response
, 0, sizeof(enc_response
));
7014 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
7018 * Get our encapsulated relay message.
7020 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_DHCPV4_MSG
);
7022 log_info("DHCPv4-query from %s missing DHCPv4 Message option.",
7023 piaddr(packet
->client_addr
));
7027 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
7028 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
7029 log_error("dhcp4o6_dhcpv4_query: error evaluating "
7034 if (enc_opt_data
.len
< DHCP_FIXED_NON_UDP
) {
7035 log_error("dhcp4o6_dhcpv4_query: DHCPv4 packet too short.");
7040 * Build a packet structure from this encapsulated packet.
7042 if (!packet_allocate(&enc_packet
, MDL
)) {
7043 log_error("dhcp4o6_dhcpv4_query: "
7044 "no memory for encapsulated packet.");
7048 enc_packet
->raw
= (struct dhcp_packet
*)enc_opt_data
.data
;
7049 enc_packet
->packet_length
= enc_opt_data
.len
;
7050 enc_packet
->dhcp4o6_response
= &enc_response
;
7051 enc_packet
->client_port
= packet
->client_port
;
7052 enc_packet
->client_addr
= packet
->client_addr
;
7053 interface_reference(&enc_packet
->interface
, packet
->interface
, MDL
);
7054 enc_packet
->dhcpv6_container_packet
= packet
;
7055 if (packet
->dhcp4o6_flags
[0] & DHCP4O6_QUERY_UNICAST
)
7056 enc_packet
->unicast
= 1;
7058 if (enc_packet
->raw
->hlen
> sizeof(enc_packet
->raw
->chaddr
)) {
7059 log_info("dhcp4o6_dhcpv4_query: "
7060 "discarding packet with bogus hlen.");
7064 /* Allocate packet->options now so it is non-null for all packets */
7065 if (!option_state_allocate (&enc_packet
->options
, MDL
)) {
7066 log_error("dhcp4o6_dhcpv4_query: no memory for options.");
7070 /* If there's an option buffer, try to parse it. */
7071 if (enc_packet
->packet_length
>= DHCP_FIXED_NON_UDP
+ 4) {
7072 struct option_cache
*op
;
7073 if (!parse_options(enc_packet
)) {
7074 if (enc_packet
->options
)
7075 option_state_dereference
7076 (&enc_packet
->options
, MDL
);
7077 packet_dereference (&enc_packet
, MDL
);
7081 if (enc_packet
->options_valid
&&
7082 (op
= lookup_option(&dhcp_universe
,
7083 enc_packet
->options
,
7084 DHO_DHCP_MESSAGE_TYPE
))) {
7085 struct data_string dp
;
7086 memset(&dp
, 0, sizeof dp
);
7087 evaluate_option_cache(&dp
, enc_packet
, NULL
, NULL
,
7088 enc_packet
->options
, NULL
,
7091 enc_packet
->packet_type
= dp
.data
[0];
7093 enc_packet
->packet_type
= 0;
7094 data_string_forget(&dp
, MDL
);
7098 if (validate_packet(enc_packet
) != 0) {
7099 if (enc_packet
->packet_type
)
7105 /* If the caller kept the packet, they'll have upped the refcnt. */
7106 packet_dereference(&enc_packet
, MDL
);
7109 * If we got no response data, then it is discarded, and
7110 * our DHCPv4-response is also discarded.
7112 if (enc_response
.data
== NULL
) {
7117 * Now we can use the response_data buffer.
7119 response
= (struct dhcpv4_over_dhcpv6_packet
*)response_data
;
7120 response
->msg_type
= DHCPV6_DHCPV4_RESPONSE
;
7121 response
->flags
[0] = response
->flags
[1] = response
->flags
[2] = 0;
7123 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7126 * Get the response option state.
7128 if (!option_state_allocate(&opt_state
, MDL
)) {
7129 log_error("dhcp4o6_dhcpv4_query: no memory for option state.");
7134 * Append our encapsulated stuff for caller.
7136 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
7137 (unsigned char *)enc_response
.data
,
7139 D6O_DHCPV4_MSG
, 0)) {
7140 log_error("dhcp4o6_dhcpv4_query: error saving DHCPv4 MSG.");
7144 response_ofs
+= store_options6(response_data
+ response_ofs
,
7145 sizeof(response_data
) - response_ofs
,
7147 required_opts_4o6
, NULL
);
7150 * Return our response to the caller.
7152 reply_ret
->len
= response_ofs
;
7153 reply_ret
->buffer
= NULL
;
7154 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
7155 log_fatal("dhcp4o6_dhcpv4_query: no memory to store reply.");
7157 reply_ret
->data
= reply_ret
->buffer
->data
;
7158 memcpy(reply_ret
->buffer
->data
, response_data
, response_ofs
);
7161 if (opt_state
!= NULL
)
7162 option_state_dereference(&opt_state
, MDL
);
7163 if (enc_response
.data
!= NULL
) {
7164 data_string_forget(&enc_response
, MDL
);
7166 if (enc_opt_data
.data
!= NULL
) {
7167 data_string_forget(&enc_opt_data
, MDL
);
7169 if (enc_packet
!= NULL
) {
7170 packet_dereference(&enc_packet
, MDL
);
7175 * \brief Forward a DHCPv4-query message to the DHCPv4 side
7176 * (DHCPv6 server function)
7178 * Format: interface:16 + address:16 + DHCPv6 DHCPv4-query message
7180 * \brief packet the DHCPv6 DHCPv4-query message
7182 static void forw_dhcpv4_query(struct packet
*packet
) {
7183 struct data_string ds
;
7187 /* Get the initial message. */
7188 while (packet
->dhcpv6_container_packet
!= NULL
)
7189 packet
= packet
->dhcpv6_container_packet
;
7191 /* Check the initial message. */
7192 if ((packet
->raw
== NULL
) ||
7193 (packet
->client_addr
.len
!= 16) ||
7194 (packet
->interface
== NULL
)) {
7195 log_error("forw_dhcpv4_query: can't find initial message.");
7200 len
= packet
->packet_length
+ 32;
7201 memset(&ds
, 0, sizeof(ds
));
7202 if (!buffer_allocate(&ds
.buffer
, len
, MDL
)) {
7203 log_error("forw_dhcpv4_query: "
7204 "no memory for encapsulating packet.");
7207 ds
.data
= ds
.buffer
->data
;
7210 /* Fill the buffer. */
7211 strncpy((char *)ds
.buffer
->data
, packet
->interface
->name
, 16);
7212 memcpy(ds
.buffer
->data
+ 16,
7213 packet
->client_addr
.iabuf
, 16);
7214 memcpy(ds
.buffer
->data
+ 32,
7215 (unsigned char *)packet
->raw
,
7216 packet
->packet_length
);
7218 /* Forward to the DHCPv4 server. */
7219 cc
= send(dhcp4o6_fd
, ds
.data
, ds
.len
, 0);
7221 log_error("forw_dhcpv4_query: send(): %m");
7222 data_string_forget(&ds
, MDL
);
7227 dhcpv6_discard(struct packet
*packet
) {
7228 /* INSIST(packet->msg_type > 0); */
7229 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
7231 log_debug("Discarding %s from %s; message type not handled by server",
7232 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7233 piaddr(packet
->client_addr
));
7237 build_dhcpv6_reply(struct data_string
*reply
, struct packet
*packet
) {
7238 memset(reply
, 0, sizeof(*reply
));
7240 /* I would like to classify the client once here, but
7241 * as I don't want to classify all of the incoming packets
7242 * I need to do it before handling specific types.
7243 * We don't need to classify if we are tossing the packet
7244 * or if it is a relay - the classification step will get
7245 * done when we process the inner client packet.
7248 switch (packet
->dhcpv6_msg_type
) {
7249 case DHCPV6_SOLICIT
:
7250 classify_client(packet
);
7251 dhcpv6_solicit(reply
, packet
);
7253 case DHCPV6_ADVERTISE
:
7254 dhcpv6_discard(packet
);
7256 case DHCPV6_REQUEST
:
7257 classify_client(packet
);
7258 dhcpv6_request(reply
, packet
);
7260 case DHCPV6_CONFIRM
:
7261 classify_client(packet
);
7262 dhcpv6_confirm(reply
, packet
);
7265 classify_client(packet
);
7266 dhcpv6_renew(reply
, packet
);
7269 classify_client(packet
);
7270 dhcpv6_rebind(reply
, packet
);
7273 dhcpv6_discard(packet
);
7275 case DHCPV6_RELEASE
:
7276 classify_client(packet
);
7277 dhcpv6_release(reply
, packet
);
7279 case DHCPV6_DECLINE
:
7280 classify_client(packet
);
7281 dhcpv6_decline(reply
, packet
);
7283 case DHCPV6_RECONFIGURE
:
7284 dhcpv6_discard(packet
);
7286 case DHCPV6_INFORMATION_REQUEST
:
7287 classify_client(packet
);
7288 dhcpv6_information_request(reply
, packet
);
7290 case DHCPV6_RELAY_FORW
:
7292 if (dhcpv4_over_dhcpv6
&& (local_family
== AF_INET
))
7293 dhcp4o6_relay_forw(reply
, packet
);
7295 #endif /* DHCP4o6 */
7296 dhcpv6_relay_forw(reply
, packet
);
7298 case DHCPV6_RELAY_REPL
:
7299 dhcpv6_discard(packet
);
7301 case DHCPV6_LEASEQUERY
:
7302 classify_client(packet
);
7303 dhcpv6_leasequery(reply
, packet
);
7305 case DHCPV6_LEASEQUERY_REPLY
:
7306 dhcpv6_discard(packet
);
7308 case DHCPV6_DHCPV4_QUERY
:
7310 if (dhcpv4_over_dhcpv6
) {
7311 if (local_family
== AF_INET6
) {
7312 forw_dhcpv4_query(packet
);
7314 dhcp4o6_dhcpv4_query(reply
, packet
);
7317 #endif /* DHCP4o6 */
7318 dhcpv6_discard(packet
);
7320 case DHCPV6_DHCPV4_RESPONSE
:
7321 dhcpv6_discard(packet
);
7324 /* XXX: would be nice if we had "notice" level,
7325 as syslog, for this */
7326 log_info("Discarding unknown DHCPv6 message type %d "
7327 "from %s", packet
->dhcpv6_msg_type
,
7328 piaddr(packet
->client_addr
));
7333 log_packet_in(const struct packet
*packet
) {
7334 struct data_string s
;
7336 char tmp_addr
[INET6_ADDRSTRLEN
];
7339 memset(&s
, 0, sizeof(s
));
7341 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
7342 data_string_sprintfa(&s
, "%s message from %s port %d",
7343 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7344 piaddr(packet
->client_addr
),
7345 ntohs(packet
->client_port
));
7347 data_string_sprintfa(&s
,
7348 "Unknown message type %d from %s port %d",
7349 packet
->dhcpv6_msg_type
,
7350 piaddr(packet
->client_addr
),
7351 ntohs(packet
->client_port
));
7353 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7354 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7355 addr
= &packet
->dhcpv6_link_address
;
7356 data_string_sprintfa(&s
, ", link address %s",
7357 inet_ntop(AF_INET6
, addr
,
7358 tmp_addr
, sizeof(tmp_addr
)));
7359 addr
= &packet
->dhcpv6_peer_address
;
7360 data_string_sprintfa(&s
, ", peer address %s",
7361 inet_ntop(AF_INET6
, addr
,
7362 tmp_addr
, sizeof(tmp_addr
)));
7363 } else if ((packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_QUERY
) &&
7364 (packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_RESPONSE
)) {
7366 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
7367 data_string_sprintfa(&s
, ", transaction ID 0x%06X", tid
);
7370 oc = lookup_option(&dhcpv6_universe, packet->options,
7373 memset(&tmp_ds, 0, sizeof(tmp_ds_));
7374 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
7375 packet->options, NULL,
7376 &global_scope, oc, MDL)) {
7377 log_error("Error evaluating Client Identifier");
7379 data_strint_sprintf(&s, ", client ID %s",
7381 data_string_forget(&tmp_ds, MDL);
7387 log_info("%s", s
.data
);
7389 data_string_forget(&s
, MDL
);
7393 dhcpv6(struct packet
*packet
) {
7394 struct data_string reply
;
7395 struct sockaddr_in6 to_addr
;
7399 * Log a message that we received this packet.
7401 log_packet_in(packet
);
7404 * Build our reply packet.
7406 build_dhcpv6_reply(&reply
, packet
);
7408 if (reply
.data
!= NULL
) {
7410 * Send our reply, if we have one.
7412 memset(&to_addr
, 0, sizeof(to_addr
));
7413 to_addr
.sin6_family
= AF_INET6
;
7414 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7415 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7416 to_addr
.sin6_port
= local_port
;
7418 to_addr
.sin6_port
= remote_port
;
7421 #if defined (REPLY_TO_SOURCE_PORT)
7423 * This appears to have been included for testing so we would
7424 * not need a root client, but was accidently left in the
7425 * final code. We continue to include it in case
7426 * some users have come to rely upon it, but leave
7427 * it off by default as it's a bad idea.
7429 to_addr
.sin6_port
= packet
->client_port
;
7432 memcpy(&to_addr
.sin6_addr
, packet
->client_addr
.iabuf
,
7433 sizeof(to_addr
.sin6_addr
));
7435 log_info("Sending %s to %s port %d",
7436 dhcpv6_type_names
[reply
.data
[0]],
7437 piaddr(packet
->client_addr
),
7438 ntohs(to_addr
.sin6_port
));
7440 send_ret
= send_packet6(packet
->interface
,
7441 reply
.data
, reply
.len
, &to_addr
);
7442 if (send_ret
!= reply
.len
) {
7443 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
7444 send_ret
, reply
.len
);
7446 data_string_forget(&reply
, MDL
);
7452 * \brief Receive a DHCPv4-query message from the DHCPv6 side
7453 * (DHCPv4 server function)
7455 * Receive a message with a DHCPv4-query inside from the DHCPv6 server.
7456 * (code copied from \ref do_packet6() \ref and dhcpv6())
7458 * Format: interface:16 + address:16 + DHCPv6 DHCPv4-query message
7460 * \param raw the DHCPv6 DHCPv4-query message raw content
7462 static void recv_dhcpv4_query(struct data_string
*raw
) {
7463 struct interface_info
*ip
;
7466 struct packet
*packet
;
7467 unsigned char msg_type
;
7468 const struct dhcpv6_relay_packet
*relay
;
7469 const struct dhcpv4_over_dhcpv6_packet
*msg
;
7470 struct data_string reply
;
7471 struct data_string ds
;
7475 memset(name
, 0, sizeof(name
));
7476 memcpy(name
, raw
->data
, 16);
7477 for (ip
= interfaces
; ip
!= NULL
; ip
= ip
->next
) {
7478 if (!strcmp(name
, ip
->name
))
7482 log_error("recv_dhcpv4_query: can't find interface %s.",
7488 memcpy(iaddr
.iabuf
, raw
->data
+ 16, 16);
7491 * From do_packet6().
7494 if (!packet6_len_okay((char *)raw
->data
+ 32, raw
->len
- 32)) {
7495 log_error("recv_dhcpv4_query: "
7496 "short packet from %s, len %d, dropped",
7497 piaddr(iaddr
), raw
->len
- 32);
7502 * Build a packet structure.
7505 if (!packet_allocate(&packet
, MDL
)) {
7506 log_error("recv_dhcpv4_query: no memory for packet.");
7510 if (!option_state_allocate(&packet
->options
, MDL
)) {
7511 log_error("recv_dhcpv4_query: no memory for options.");
7512 packet_dereference(&packet
, MDL
);
7516 packet
->raw
= (struct dhcp_packet
*)(raw
->data
+ 32);
7517 packet
->packet_length
= raw
->len
- 32;
7518 packet
->client_port
= remote_port
;
7519 packet
->client_addr
= iaddr
;
7520 interface_reference(&packet
->interface
, ip
, MDL
);
7522 msg_type
= raw
->data
[32];
7523 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
7524 (msg_type
== DHCPV6_RELAY_REPL
)) {
7526 (int)(offsetof(struct dhcpv6_relay_packet
, options
));
7527 relay
= (const struct dhcpv6_relay_packet
*)(raw
->data
+ 32);
7528 packet
->dhcpv6_msg_type
= relay
->msg_type
;
7530 /* relay-specific data */
7531 packet
->dhcpv6_hop_count
= relay
->hop_count
;
7532 memcpy(&packet
->dhcpv6_link_address
,
7533 relay
->link_address
, sizeof(relay
->link_address
));
7534 memcpy(&packet
->dhcpv6_peer_address
,
7535 relay
->peer_address
, sizeof(relay
->peer_address
));
7537 if (!parse_option_buffer(packet
->options
,
7539 raw
->len
- 32 - relaylen
,
7540 &dhcpv6_universe
)) {
7541 /* no logging here, as parse_option_buffer() logs all
7542 cases where it fails */
7543 packet_dereference(&packet
, MDL
);
7546 } else if ((msg_type
== DHCPV6_DHCPV4_QUERY
) ||
7547 (msg_type
== DHCPV6_DHCPV4_RESPONSE
)) {
7549 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet
, options
));
7550 msg
= (struct dhcpv4_over_dhcpv6_packet
*)(raw
->data
+ 32);
7551 packet
->dhcpv6_msg_type
= msg
->msg_type
;
7553 /* message-specific data */
7554 memcpy(packet
->dhcp4o6_flags
, msg
->flags
,
7555 sizeof(packet
->dhcp4o6_flags
));
7557 if (!parse_option_buffer(packet
->options
,
7559 raw
->len
- 32 - msglen
,
7560 &dhcpv6_universe
)) {
7561 /* no logging here, as parse_option_buffer() logs all
7562 cases where it fails */
7563 packet_dereference(&packet
, MDL
);
7567 log_error("recv_dhcpv4_query: unexpected message of type %d.",
7569 packet_dereference(&packet
, MDL
);
7578 * Log a message that we received this packet.
7580 /* log_packet_in(packet); */
7581 memset(&ds
, 0, sizeof(ds
));
7582 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
7583 data_string_sprintfa(&ds
, "%s message from %s",
7584 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
7585 piaddr(packet
->client_addr
));
7587 data_string_sprintfa(&ds
,
7588 "Unknown message type %d from %s",
7589 packet
->dhcpv6_msg_type
,
7590 piaddr(packet
->client_addr
));
7592 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
7593 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
7594 char tmp_addr
[INET6_ADDRSTRLEN
];
7597 addr
= &packet
->dhcpv6_link_address
;
7598 data_string_sprintfa(&ds
, ", link address %s",
7599 inet_ntop(AF_INET6
, addr
,
7600 tmp_addr
, sizeof(tmp_addr
)));
7601 addr
= &packet
->dhcpv6_peer_address
;
7602 data_string_sprintfa(&ds
, ", peer address %s",
7603 inet_ntop(AF_INET6
, addr
,
7604 tmp_addr
, sizeof(tmp_addr
)));
7605 } else if ((packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_QUERY
) &&
7606 (packet
->dhcpv6_msg_type
!= DHCPV6_DHCPV4_RESPONSE
)) {
7609 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
7610 data_string_sprintfa(&ds
, ", transaction ID 0x%06X", tid
);
7612 log_info("%s", ds
.data
);
7613 data_string_forget(&ds
, MDL
);
7616 * Build our reply packet.
7618 build_dhcpv6_reply(&reply
, packet
);
7620 packet_dereference(&packet
, MDL
);
7622 if (reply
.data
== NULL
)
7626 * Forward the response.
7628 len
= reply
.len
+ 32;
7629 memset(&ds
, 0, sizeof(ds
));
7630 if (!buffer_allocate(&ds
.buffer
, len
, MDL
)) {
7631 log_error("recv_dhcpv4_query: no memory.");
7634 ds
.data
= ds
.buffer
->data
;
7637 memcpy(ds
.buffer
->data
, name
, 16);
7638 memcpy(ds
.buffer
->data
+ 16, iaddr
.iabuf
, 16);
7639 memcpy(ds
.buffer
->data
+ 32, reply
.data
, reply
.len
);
7640 cc
= send(dhcp4o6_fd
, ds
.data
, ds
.len
, 0);
7642 log_error("recv_dhcpv4_query: send(): %m");
7643 data_string_forget(&ds
, MDL
);
7645 #endif /* DHCP4o6 */
7648 seek_shared_host(struct host_decl
**hp
, struct shared_network
*shared
) {
7649 struct host_decl
*nofixed
= NULL
;
7650 struct host_decl
*seek
, *hold
= NULL
;
7653 * Seek forward through fixed addresses for the right link.
7655 * Note: how to do this for fixed prefixes???
7657 host_reference(&hold
, *hp
, MDL
);
7658 host_dereference(hp
, MDL
);
7660 while (seek
!= NULL
) {
7661 if (seek
->fixed_addr
== NULL
)
7663 else if (fixed_matches_shared(seek
, shared
))
7666 seek
= seek
->n_ipaddr
;
7669 if ((seek
== NULL
) && (nofixed
!= NULL
))
7673 host_reference(hp
, seek
, MDL
);
7676 static isc_boolean_t
7677 fixed_matches_shared(struct host_decl
*host
, struct shared_network
*shared
) {
7678 struct subnet
*subnet
;
7679 struct data_string addr
;
7680 isc_boolean_t matched
;
7683 if (host
->fixed_addr
== NULL
)
7686 memset(&addr
, 0, sizeof(addr
));
7687 if (!evaluate_option_cache(&addr
, NULL
, NULL
, NULL
, NULL
, NULL
,
7688 &global_scope
, host
->fixed_addr
, MDL
))
7691 if (addr
.len
< 16) {
7692 data_string_forget(&addr
, MDL
);
7697 memcpy(fixed
.iabuf
, addr
.data
, 16);
7699 matched
= ISC_FALSE
;
7700 for (subnet
= shared
->subnets
; subnet
!= NULL
;
7701 subnet
= subnet
->next_sibling
) {
7702 if (addr_eq(subnet_number(fixed
, subnet
->netmask
),
7709 data_string_forget(&addr
, MDL
);
7715 * \brief Constructs a REPLY with status of UseMulticast to a given packet
7717 * Per RFC 3315 Secs 18.2.1,3,6 & 7, when a server rejects a client's
7718 * unicast-sent packet, the response must only contain the client id,
7719 * server id, and a status code option of 5 (UseMulticast). This function
7720 * constructs such a packet and returns it as a data_string.
7722 * \param reply_ret = data_string which will receive the newly constructed
7724 * \param packet = client request which is being rejected
7725 * \param client_id = data_string which contains the client id
7726 * \param server_id = data_string which which contains the server id
7730 unicast_reject(struct data_string
*reply_ret
,
7731 struct packet
*packet
,
7732 const struct data_string
*client_id
,
7733 const struct data_string
*server_id
)
7735 struct reply_state reply
;
7736 memset(&reply
, 0x0, sizeof(struct reply_state
));
7738 /* Locate the client. */
7739 if (shared_network_from_packet6(&reply
.shared
, packet
)
7741 log_error("unicast_reject: could not locate client.");
7745 /* Initialize the reply. */
7746 packet_reference(&reply
.packet
, packet
, MDL
);
7747 data_string_copy(&reply
.client_id
, client_id
, MDL
);
7749 if (start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
7750 &reply
.buf
.reply
)) {
7751 /* Set the UseMulticast status code. */
7752 if (!set_status_code(STATUS_UseMulticast
,
7753 "Unicast not allowed by server.",
7755 log_error("unicast_reject: Unable to set status code.");
7757 /* Set write cursor to just past the reply header. */
7758 reply
.cursor
= REPLY_OPTIONS_INDEX
;
7759 reply
.cursor
+= store_options6(((char *)reply
.buf
.data
7765 unicast_reject_opts
,
7768 /* Return our reply to the caller. */
7769 reply_ret
->len
= reply
.cursor
;
7770 reply_ret
->buffer
= NULL
;
7771 if (!buffer_allocate(&reply_ret
->buffer
,
7772 reply
.cursor
, MDL
)) {
7773 log_fatal("unicast_reject:"
7774 "No memory to store Reply.");
7777 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
,
7779 reply_ret
->data
= reply_ret
->buffer
->data
;
7785 if (reply
.shared
!= NULL
)
7786 shared_network_dereference(&reply
.shared
, MDL
);
7787 if (reply
.opt_state
!= NULL
)
7788 option_state_dereference(&reply
.opt_state
, MDL
);
7789 if (reply
.packet
!= NULL
)
7790 packet_dereference(&reply
.packet
, MDL
);
7791 if (reply
.client_id
.data
!= NULL
)
7792 data_string_forget(&reply
.client_id
, MDL
);
7797 * \brief Checks if the dhcp6.unicast option has been defined
7799 * Scans the option space for the presence of the dhcp6.unicast option. The
7800 * function attempts to map the inbound packet to a shared network first
7801 * by an ip address specified via an D6O_IA_XX option and if that fails then
7802 * by the packet's source information (e.g. relay link, link, or interace).
7803 * Once the packet is mapped to a shared network, the function executes all
7804 * statements from the network's group outward into a local option cache.
7805 * The option cache is then scanned for the presence of unicast option. If
7806 * the packet cannot be mapped to a shared network, the function returns
7808 * \param packet inbound packet from the client
7810 * \return ISC_TRUE if the dhcp6.unicast option is defined, false otherwise.
7814 is_unicast_option_defined(struct packet
*packet
) {
7815 isc_boolean_t is_defined
= ISC_FALSE
;
7816 struct option_state
*opt_state
= NULL
;
7817 struct option_cache
*oc
= NULL
;
7818 struct shared_network
*shared
= NULL
;
7820 if (!option_state_allocate(&opt_state
, MDL
)) {
7821 log_fatal("is_unicast_option_defined:"
7822 "No memory for option state.");
7825 /* We try to map the packet to a network first by an IA_XX value.
7826 * If that fails, we try by packet source. */
7827 if (((shared_network_from_requested_addr(&shared
, packet
)
7828 != ISC_R_SUCCESS
) &&
7829 (shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
))
7830 || (shared
== NULL
)) {
7831 /* @todo what would this really mean? I think wrong network
7832 * logic will catch it */
7833 log_error("is_unicast_option_defined:"
7834 "cannot attribute packet to a network.");
7838 /* Now that we've mapped it to a network, execute statments to that
7839 * scope, looking for the unicast option. We don't care about the
7840 * value of the option, only whether or not it is defined. */
7841 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
, opt_state
,
7842 &global_scope
, shared
->group
, NULL
, NULL
);
7844 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_UNICAST
);
7845 is_defined
= (oc
!= NULL
? ISC_TRUE
: ISC_FALSE
);
7846 log_debug("is_unicast_option_defined: option found : %d", is_defined
);
7848 if (shared
!= NULL
) {
7849 shared_network_dereference(&shared
, MDL
);
7852 if (opt_state
!= NULL
) {
7853 option_state_dereference(&opt_state
, MDL
);
7856 return (is_defined
);
7861 * \brief Maps a packet to a shared network based on the requested IP address
7863 * The function attempts to find a subnet that matches the first requested IP
7864 * address contained within the given packet. Note that it looks first for
7865 * D6O_IA_NAs, then D6O_IA_PDs and lastly D6O_IA_TAs. If a matching network is
7866 * found, a reference to it is returned in the parameter, shared.
7868 * \param shared shared_network pointer which will receive the matching network
7869 * \param packet inbound packet from the client
7871 * \return ISC_R_SUCCESS if the packet can be mapped to a shared_network.
7875 shared_network_from_requested_addr (struct shared_network
**shared
,
7876 struct packet
* packet
) {
7878 struct subnet
* subnet
= NULL
;
7879 isc_result_t status
= ISC_R_FAILURE
;
7881 /* Try to match first IA_ address or prefix we find to a subnet. In
7882 * theory all IA_ values in a given request are supposed to be in the
7883 * same subnet so we only need to try one right? */
7884 if ((get_first_ia_addr_val(packet
, D6O_IA_NA
, &iaddr
) != ISC_R_SUCCESS
)
7885 && (get_first_ia_addr_val(packet
, D6O_IA_PD
, &iaddr
)
7887 && (get_first_ia_addr_val(packet
, D6O_IA_TA
, &iaddr
)
7888 != ISC_R_SUCCESS
)) {
7889 /* we found nothing to match against */
7890 log_debug("share_network_from_request_addr: nothing to match");
7891 return (ISC_R_FAILURE
);
7894 if (!find_subnet(&subnet
, iaddr
, MDL
)) {
7895 log_debug("shared_network_from_requested_addr:"
7896 "No subnet found for addr %s.", piaddr(iaddr
));
7898 status
= shared_network_reference(shared
,
7899 subnet
->shared_network
, MDL
);
7900 subnet_dereference(&subnet
, MDL
);
7901 log_debug("shared_network_from_requested_addr:"
7902 " found shared network %s for address %s.",
7903 ((*shared
)->name
? (*shared
)->name
: "unnamed"),
7908 return (ISC_R_FAILURE
);
7913 * \brief Retrieves the first IP address from a given packet of a given type
7915 * Search a packet for options of a given type (D6O_IA_AN, D6O_IA_PD, or
7916 * D6O_IA_TA) for the first non-blank IA_XX value and return its IP address
7919 * \param packet packet received from the client
7920 * \param addr_type the address option type (D6O_IA_NA , D6O_IA_PD, or
7921 * D6O_IP_TA) to look for within the packet.
7922 * \param iaddr pointer to the iaddr structure which will receive the extracted
7925 * \return ISC_R_SUCCESS if an address was succesfully extracted, ISC_R_FALURE
7930 get_first_ia_addr_val (struct packet
* packet
, int addr_type
,
7931 struct iaddr
* iaddr
) {
7932 struct option_cache
*ia
;
7933 struct option_cache
*oc
= NULL
;
7934 struct data_string cli_enc_opt_data
;
7935 struct option_state
*cli_enc_opt_state
;
7936 int addr_opt_offset
;
7938 int addr_opt_data_len
;
7941 isc_result_t status
= ISC_R_FAILURE
;
7942 memset(iaddr
, 0, sizeof(struct iaddr
));
7944 /* Set up address type specifics */
7945 switch (addr_type
) {
7947 addr_opt_offset
= IA_NA_OFFSET
;
7948 addr_opt
= D6O_IAADDR
;
7949 addr_opt_data_len
= 24;
7953 addr_opt_offset
= IA_TA_OFFSET
;
7954 addr_opt
= D6O_IAADDR
;
7955 addr_opt_data_len
= 24;
7959 addr_opt_offset
= IA_PD_OFFSET
;
7960 addr_opt
= D6O_IAPREFIX
;
7961 addr_opt_data_len
= 25;
7965 /* shouldn't be here */
7966 log_error ("get_first_ia_addr_val: invalid opt type %d",
7968 return (ISC_R_FAILURE
);
7971 /* Find the first, non-blank IA_XX value within an D6O_IA_XX option. */
7972 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, addr_type
);
7973 ia
!= NULL
&& oc
== NULL
; ia
= ia
->next
) {
7974 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
7976 packet
, ia
, addr_opt_offset
)) {
7977 log_debug ("get_first_ia_addr_val:"
7978 " couldn't unroll enclosing option");
7979 return (ISC_R_FAILURE
);
7982 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
7985 /* no address given for this IA, ignore */
7986 option_state_dereference(&cli_enc_opt_state
, MDL
);
7987 data_string_forget(&cli_enc_opt_data
, MDL
);
7991 /* If we found a non-blank IA_XX then extract its ip address. */
7993 struct data_string iaddr_str
;
7995 memset(&iaddr_str
, 0, sizeof(iaddr_str
));
7996 if (!evaluate_option_cache(&iaddr_str
, packet
, NULL
, NULL
,
7997 packet
->options
, NULL
, &global_scope
,
7999 log_error("get_first_ia_addr_val: "
8000 "error evaluating IA_XX option.");
8002 if (iaddr_str
.len
!= addr_opt_data_len
) {
8003 log_error("shared_network_from_requested_addr:"
8004 " invalid length %d, expected %d",
8005 iaddr_str
.len
, addr_opt_data_len
);
8008 memcpy (iaddr
->iabuf
,
8009 iaddr_str
.data
+ ip_addr_offset
, 16);
8010 status
= ISC_R_SUCCESS
;
8012 data_string_forget(&iaddr_str
, MDL
);
8015 option_state_dereference(&cli_enc_opt_state
, MDL
);
8016 data_string_forget(&cli_enc_opt_data
, MDL
);
8023 * \brief Calculates the reply T1/T2 times and stuffs them in outbound buffer
8025 * T1/T2 time selection is kind of weird. We actually use DHCP * (v4) scoped
8026 * options, dhcp-renewal-time and dhcp-rebinding-time, as handy existing places
8027 * where these can be configured by an administrator. A value of zero tells the
8028 * client it may choose its own value.
8030 * When those options are not defined, the values will be set to zero unless
8031 * the global option, dhcpv6-set-tee-times is enabled. When this option is
8032 * enabled the values are calculated as recommended by RFC 3315, Section 22.4:
8034 * T1 will be set to 0.5 times the shortest preferred lifetime
8035 * in the IA_XX option. If the "shortest" preferred lifetime is
8036 * 0xFFFFFFFF, T1 will set to 0xFFFFFFFF.
8038 * T2 will be set to 0.8 times the shortest preferred lifetime
8039 * in the IA_XX option. If the "shortest" preferred lifetime is
8040 * 0xFFFFFFFF, T2 will set to 0xFFFFFFFF.
8042 * Note that dhcpv6-set-tee-times is intended to be transitional and will
8043 * likely be removed in 4.4.0, leaving the behavior as getting the values
8044 * either from the configured parameters (if you want zeros, define them as
8045 * zeros) or by calculating them per the RFC.
8047 * \param reply - pointer to the reply_state structure
8048 * \param ia_cursor - offset of the beginning of the IA_XX option within the
8049 * reply's outbound data buffer
8052 set_reply_tee_times(struct reply_state
* reply
, unsigned ia_cursor
)
8054 struct option_cache
*oc
;
8057 /* Found out if calculated values are enabled. */
8058 oc
= lookup_option(&server_universe
, reply
->opt_state
,
8059 SV_DHCPV6_SET_TEE_TIMES
);
8060 set_tee_times
= (oc
&&
8061 evaluate_boolean_option_cache(NULL
, reply
->packet
,
8063 reply
->packet
->options
,
8065 &global_scope
, oc
, MDL
));
8067 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
8068 DHO_DHCP_RENEWAL_TIME
);
8070 /* dhcp-renewal-time is defined, use it */
8071 struct data_string data
;
8072 memset(&data
, 0x00, sizeof(data
));
8074 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
8075 reply
->packet
->options
,
8076 reply
->opt_state
, &global_scope
,
8079 log_error("Invalid renewal time.");
8082 reply
->renew
= getULong(data
.data
);
8085 if (data
.data
!= NULL
)
8086 data_string_forget(&data
, MDL
);
8087 } else if (set_tee_times
) {
8088 /* Setting them is enabled so T1 is either infinite or
8089 * 0.5 * the shortest preferred lifetime in the IA_XX */
8090 if (reply
->min_prefer
== INFINITE_TIME
)
8091 reply
->renew
= INFINITE_TIME
;
8093 reply
->renew
= reply
->min_prefer
/ 2;
8095 /* Default is to let the client choose */
8099 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
8102 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
8103 DHO_DHCP_REBINDING_TIME
);
8105 /* dhcp-rebinding-time is defined, use it */
8106 struct data_string data
;
8107 memset(&data
, 0x00, sizeof(data
));
8109 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
8110 reply
->packet
->options
,
8111 reply
->opt_state
, &global_scope
,
8114 log_error("Invalid rebinding time.");
8117 reply
->rebind
= getULong(data
.data
);
8120 if (data
.data
!= NULL
)
8121 data_string_forget(&data
, MDL
);
8122 } else if (set_tee_times
) {
8123 /* Setting them is enabled so T2 is either infinite or
8124 * 0.8 * the shortest preferred lifetime in the reply */
8125 if (reply
->min_prefer
== INFINITE_TIME
)
8126 reply
->rebind
= INFINITE_TIME
;
8128 reply
->rebind
= (reply
->min_prefer
/ 5) * 4;
8130 /* Default is to let the client choose */
8134 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);