2 * Copyright (C) 2006-2007 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.
22 * We use print_hex_1() to output DUID values. We could actually output
23 * the DUID with more information... MAC address if using type 1 or 3,
24 * and so on. However, RFC 3315 contains Grave Warnings against actually
25 * attempting to understand a DUID.
29 * TODO: gettext() or other method of localization for the messages
30 * for status codes (and probably for log formats eventually)
31 * TODO: refactoring (simplify, simplify, simplify)
32 * TODO: support multiple shared_networks on each interface (this
33 * will allow the server to issue multiple IPv6 addresses to
38 * DHCPv6 Reply workflow assist. A Reply packet is built by various
39 * different functions; this gives us one location where we keep state
43 /* root level persistent state */
44 struct shared_network
*shared
;
45 struct host_decl
*host
;
46 struct option_state
*opt_state
;
47 struct packet
*packet
;
48 struct data_string client_id
;
50 /* IA level persistent state */
52 unsigned client_resources
;
53 isc_boolean_t ia_addrs_included
;
54 isc_boolean_t static_lease
;
56 struct ia_na
*old_ia_na
;
57 struct option_state
*reply_ia
;
58 struct data_string fixed
;
60 /* IAADDR level persistent state */
64 * "t1", "t2", preferred, and valid lifetimes records for calculating
65 * t1 and t2 (min/max).
67 u_int32_t renew
, rebind
, prefer
, valid
;
69 /* Client-requested valid and preferred lifetimes. */
70 u_int32_t client_valid
, client_prefer
;
72 /* Chosen values to transmit for valid and preferred lifetimes. */
73 u_int32_t send_valid
, send_prefer
;
75 /* Index into the data field that has been consumed. */
79 unsigned char data
[65536];
80 struct dhcpv6_packet reply
;
85 * Prototypes local to this file.
87 static int get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
88 struct data_string
*enc_opt_data
,
89 struct packet
*packet
,
90 struct option_cache
*oc
,
92 static void build_dhcpv6_reply(struct data_string
*, struct packet
*);
93 static isc_result_t
shared_network_from_packet6(struct shared_network
**shared
,
94 struct packet
*packet
);
95 static void seek_shared_host(struct host_decl
**hp
,
96 struct shared_network
*shared
);
97 static isc_boolean_t
fixed_matches_shared(struct host_decl
*host
,
98 struct shared_network
*shared
);
99 static isc_result_t
reply_process_ia_na(struct reply_state
*reply
,
100 struct option_cache
*ia
);
101 static isc_result_t
reply_process_addr(struct reply_state
*reply
,
102 struct option_cache
*addr
);
103 static isc_boolean_t
address_is_owned(struct reply_state
*reply
,
105 static isc_result_t
reply_process_try_addr(struct reply_state
*reply
,
107 static isc_result_t
find_client_address(struct reply_state
*reply
);
108 static isc_result_t
reply_process_is_addressed(struct reply_state
*reply
,
109 struct binding_scope
**scope
,
110 struct group
*group
);
111 static isc_result_t
reply_process_send_addr(struct reply_state
*reply
,
113 static struct iaaddr
*lease_compare(struct iaaddr
*alpha
, struct iaaddr
*beta
);
116 * DUID time starts 2000-01-01.
117 * This constant is the number of seconds since 1970-01-01,
118 * when the Unix epoch began.
120 #define DUID_TIME_EPOCH 946684800
123 * This function returns the time since DUID time start for the
124 * given time_t value.
127 duid_time(time_t when
) {
129 * This time is modulo 2^32.
131 while ((when
- DUID_TIME_EPOCH
) > 4294967295u) {
132 /* use 2^31 to avoid spurious compiler warnings */
137 return when
- DUID_TIME_EPOCH
;
144 * This must remain the same for the lifetime of this server, because
145 * clients return the server DUID that we sent them in Request packets.
147 * We pick the server DUID like this:
149 * 1. Check dhcpd.conf - any value the administrator has configured
150 * overrides any possible values.
151 * 2. Check the leases.txt - we want to use the previous value if
153 * 3. Check if dhcpd.conf specifies a type of server DUID to use,
154 * and generate that type.
155 * 4. Generate a type 1 (time + hardware address) DUID.
157 static struct data_string server_duid
;
160 * Check if the server_duid has been set.
163 server_duid_isset(void) {
164 return (server_duid
.data
!= NULL
);
168 * Return the server_duid.
171 copy_server_duid(struct data_string
*ds
, const char *file
, int line
) {
172 data_string_copy(ds
, &server_duid
, file
, line
);
176 * Set the server DUID to a specified value. This is used when
177 * the server DUID is stored in persistent memory (basically the
181 set_server_duid(struct data_string
*new_duid
) {
182 /* INSIST(new_duid != NULL); */
183 /* INSIST(new_duid->data != NULL); */
185 if (server_duid_isset()) {
186 data_string_forget(&server_duid
, MDL
);
188 data_string_copy(&server_duid
, new_duid
, MDL
);
193 * Set the server DUID based on the D6O_SERVERID option. This handles
194 * the case where the administrator explicitly put it in the dhcpd.conf
198 set_server_duid_from_option(void) {
199 struct option_state
*opt_state
;
200 struct option_cache
*oc
;
201 struct data_string option_duid
;
202 isc_result_t ret_val
;
205 if (!option_state_allocate(&opt_state
, MDL
)) {
206 log_fatal("No memory for server DUID.");
209 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
,
210 opt_state
, &global_scope
, root_group
, NULL
);
212 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
214 ret_val
= ISC_R_NOTFOUND
;
216 memset(&option_duid
, 0, sizeof(option_duid
));
217 if (!evaluate_option_cache(&option_duid
, NULL
, NULL
, NULL
,
218 opt_state
, NULL
, &global_scope
,
220 ret_val
= ISC_R_UNEXPECTED
;
222 set_server_duid(&option_duid
);
223 data_string_forget(&option_duid
, MDL
);
224 ret_val
= ISC_R_SUCCESS
;
228 option_state_dereference(&opt_state
, MDL
);
234 * DUID layout, as defined in RFC 3315, section 9.
236 * We support type 1 (hardware address plus time) and type 3 (hardware
239 * We can support type 2 for specific vendors in the future, if they
240 * publish the specification. And of course there may be additional
243 static int server_duid_type
= DUID_LLT
;
249 set_server_duid_type(int type
) {
250 server_duid_type
= type
;
254 * Generate a new server DUID. This is done if there was no DUID in
255 * the leases.txt or in the dhcpd.conf file.
258 generate_new_server_duid(void) {
259 struct interface_info
*p
;
261 struct data_string generated_duid
;
264 * Verify we have a type that we support.
266 if ((server_duid_type
!= DUID_LL
) && (server_duid_type
!= DUID_LLT
)) {
267 log_error("Invalid DUID type %d specified, "
268 "only LL and LLT types supported", server_duid_type
);
269 return ISC_R_INVALIDARG
;
273 * Find an interface with a hardware address.
276 for (p
= interfaces
; p
!= NULL
; p
= p
->next
) {
277 if (p
->hw_address
.hlen
> 0) {
282 return ISC_R_UNEXPECTED
;
288 memset(&generated_duid
, 0, sizeof(generated_duid
));
289 if (server_duid_type
== DUID_LLT
) {
290 time_val
= duid_time(time(NULL
));
291 generated_duid
.len
= 8 + p
->hw_address
.hlen
- 1;
292 if (!buffer_allocate(&generated_duid
.buffer
,
293 generated_duid
.len
, MDL
)) {
294 log_fatal("No memory for server DUID.");
296 generated_duid
.data
= generated_duid
.buffer
->data
;
297 putUShort(generated_duid
.buffer
->data
, DUID_LLT
);
298 putUShort(generated_duid
.buffer
->data
+ 2,
299 p
->hw_address
.hbuf
[0]);
300 putULong(generated_duid
.buffer
->data
+ 4, time_val
);
301 memcpy(generated_duid
.buffer
->data
+ 8,
302 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
303 } else if (server_duid_type
== DUID_LL
) {
304 generated_duid
.len
= 4 + p
->hw_address
.hlen
- 1;
305 if (!buffer_allocate(&generated_duid
.buffer
,
306 generated_duid
.len
, MDL
)) {
307 log_fatal("No memory for server DUID.");
309 generated_duid
.data
= generated_duid
.buffer
->data
;
310 putUShort(generated_duid
.buffer
->data
, DUID_LL
);
311 putUShort(generated_duid
.buffer
->data
+ 2,
312 p
->hw_address
.hbuf
[0]);
313 memcpy(generated_duid
.buffer
->data
+4,
314 p
->hw_address
.hbuf
+1, p
->hw_address
.hlen
-1);
316 log_fatal("Unsupported server DUID type %d.", server_duid_type
);
319 set_server_duid(&generated_duid
);
320 data_string_forget(&generated_duid
, MDL
);
322 return ISC_R_SUCCESS
;
326 * Get the client identifier from the packet.
329 get_client_id(struct packet
*packet
, struct data_string
*client_id
) {
330 struct option_cache
*oc
;
333 * Verify our client_id structure is empty.
335 if ((client_id
->data
!= NULL
) || (client_id
->len
!= 0)) {
336 return ISC_R_INVALIDARG
;
339 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_CLIENTID
);
341 return ISC_R_NOTFOUND
;
344 if (!evaluate_option_cache(client_id
, packet
, NULL
, NULL
,
345 packet
->options
, NULL
,
346 &global_scope
, oc
, MDL
)) {
347 return ISC_R_FAILURE
;
350 return ISC_R_SUCCESS
;
354 * Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
356 * Servers MUST discard any Solicit messages that do not include a
357 * Client Identifier option or that do include a Server Identifier
361 valid_client_msg(struct packet
*packet
, struct data_string
*client_id
) {
363 struct option_cache
*oc
;
364 struct data_string data
;
367 memset(client_id
, 0, sizeof(*client_id
));
368 memset(&data
, 0, sizeof(data
));
370 switch (get_client_id(packet
, client_id
)) {
374 log_debug("Discarding %s from %s; "
375 "client identifier missing",
376 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
377 piaddr(packet
->client_addr
));
380 log_error("Error processing %s from %s; "
381 "unable to evaluate Client Identifier",
382 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
383 piaddr(packet
->client_addr
));
388 * Required by RFC 3315, section 15.
390 if (packet
->unicast
) {
391 log_debug("Discarding %s from %s; packet sent unicast "
393 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
394 piaddr(packet
->client_addr
),
395 print_hex_1(client_id
->len
, client_id
->data
, 60));
400 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
402 if (evaluate_option_cache(&data
, packet
, NULL
, NULL
,
403 packet
->options
, NULL
,
404 &global_scope
, oc
, MDL
)) {
405 log_debug("Discarding %s from %s; "
406 "server identifier found "
407 "(CLIENTID %s, SERVERID %s)",
408 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
409 piaddr(packet
->client_addr
),
410 print_hex_1(client_id
->len
,
411 client_id
->data
, 60),
412 print_hex_2(data
.len
,
415 log_debug("Discarding %s from %s; "
416 "server identifier found "
418 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
419 print_hex_1(client_id
->len
,
420 client_id
->data
, 60),
421 piaddr(packet
->client_addr
));
431 data_string_forget(&data
, MDL
);
434 if (client_id
->len
> 0) {
435 data_string_forget(client_id
, MDL
);
442 * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
443 * 15.9 (slightly different wording, but same meaning):
445 * Servers MUST discard any received Request message that meet any of
446 * the following conditions:
448 * - the message does not include a Server Identifier option.
449 * - the contents of the Server Identifier option do not match the
451 * - the message does not include a Client Identifier option.
454 valid_client_resp(struct packet
*packet
,
455 struct data_string
*client_id
,
456 struct data_string
*server_id
)
459 struct option_cache
*oc
;
461 /* INSIST((duid.data != NULL) && (duid.len > 0)); */
464 memset(client_id
, 0, sizeof(*client_id
));
465 memset(server_id
, 0, sizeof(*server_id
));
467 switch (get_client_id(packet
, client_id
)) {
471 log_debug("Discarding %s from %s; "
472 "client identifier missing",
473 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
474 piaddr(packet
->client_addr
));
477 log_error("Error processing %s from %s; "
478 "unable to evaluate Client Identifier",
479 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
480 piaddr(packet
->client_addr
));
484 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
486 log_debug("Discarding %s from %s: "
487 "server identifier missing (CLIENTID %s)",
488 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
489 piaddr(packet
->client_addr
),
490 print_hex_1(client_id
->len
, client_id
->data
, 60));
493 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
494 packet
->options
, NULL
,
495 &global_scope
, oc
, MDL
)) {
496 log_error("Error processing %s from %s; "
497 "unable to evaluate Server Identifier (CLIENTID %s)",
498 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
499 piaddr(packet
->client_addr
),
500 print_hex_1(client_id
->len
, client_id
->data
, 60));
503 if ((server_duid
.len
!= server_id
->len
) ||
504 (memcmp(server_duid
.data
, server_id
->data
, server_duid
.len
) != 0)) {
505 log_debug("Discarding %s from %s; "
506 "not our server identifier "
507 "(CLIENTID %s, SERVERID %s, server DUID %s)",
508 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
509 piaddr(packet
->client_addr
),
510 print_hex_1(client_id
->len
, client_id
->data
, 60),
511 print_hex_2(server_id
->len
, server_id
->data
, 60),
512 print_hex_3(server_duid
.len
, server_duid
.data
, 60));
521 if (server_id
->len
> 0) {
522 data_string_forget(server_id
, MDL
);
524 if (client_id
->len
> 0) {
525 data_string_forget(client_id
, MDL
);
532 * Information request validation, defined in RFC 3315, section 15.12:
534 * Servers MUST discard any received Information-request message that
535 * meets any of the following conditions:
537 * - The message includes a Server Identifier option and the DUID in
538 * the option does not match the server's DUID.
540 * - The message includes an IA option.
543 valid_client_info_req(struct packet
*packet
, struct data_string
*server_id
) {
545 struct option_cache
*oc
;
546 struct data_string client_id
;
547 char client_id_str
[80]; /* print_hex_1() uses maximum 60 characters,
548 plus a few more for extra information */
551 memset(server_id
, 0, sizeof(*server_id
));
554 * Make a string that we can print out to give more
555 * information about the client if we need to.
557 * By RFC 3315, Section 18.1.5 clients SHOULD have a
558 * client-id on an Information-request packet, but it
559 * is not strictly necessary.
561 if (get_client_id(packet
, &client_id
) == ISC_R_SUCCESS
) {
562 snprintf(client_id_str
, sizeof(client_id_str
), " (CLIENTID %s)",
563 print_hex_1(client_id
.len
, client_id
.data
, 60));
564 data_string_forget(&client_id
, MDL
);
566 client_id_str
[0] = '\0';
570 * Required by RFC 3315, section 15.
572 if (packet
->unicast
) {
573 log_debug("Discarding %s from %s; packet sent unicast%s",
574 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
575 piaddr(packet
->client_addr
), client_id_str
);
579 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
581 log_debug("Discarding %s from %s; "
582 "IA_NA option present%s",
583 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
584 piaddr(packet
->client_addr
), client_id_str
);
587 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
589 log_debug("Discarding %s from %s; "
590 "IA_TA option present%s",
591 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
592 piaddr(packet
->client_addr
), client_id_str
);
595 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_PD
);
597 log_debug("Discarding %s from %s; "
598 "IA_PD option present%s",
599 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
600 piaddr(packet
->client_addr
), client_id_str
);
604 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_SERVERID
);
606 if (!evaluate_option_cache(server_id
, packet
, NULL
, NULL
,
607 packet
->options
, NULL
,
608 &global_scope
, oc
, MDL
)) {
609 log_error("Error processing %s from %s; "
610 "unable to evaluate Server Identifier%s",
611 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
612 piaddr(packet
->client_addr
), client_id_str
);
615 if ((server_duid
.len
!= server_id
->len
) ||
616 (memcmp(server_duid
.data
, server_id
->data
,
617 server_duid
.len
) != 0)) {
618 log_debug("Discarding %s from %s; "
619 "not our server identifier "
620 "(SERVERID %s, server DUID %s)%s",
621 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
622 piaddr(packet
->client_addr
),
623 print_hex_1(server_id
->len
,
624 server_id
->data
, 60),
625 print_hex_2(server_duid
.len
,
626 server_duid
.data
, 60),
637 if (server_id
->len
> 0) {
638 data_string_forget(server_id
, MDL
);
645 * Options that we want to send, in addition to what was requested
648 static const int required_opts
[] = {
655 static const int required_opts_solicit
[] = {
668 static const int required_opts_IA_NA
[] = {
675 static const int required_opts_IA_TA[] = {
681 static const int required_opts_IA_PD[] = {
688 static const int required_opts_STATUS_CODE
[] = {
694 * Extracts from packet contents an IA_* option, storing the IA structure
695 * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
696 * in enc_opt_state for later lookup and evaluation. The 'offset' indicates
697 * where in the IA_* the DHCPv6 options commence.
700 get_encapsulated_IA_state(struct option_state
**enc_opt_state
,
701 struct data_string
*enc_opt_data
,
702 struct packet
*packet
,
703 struct option_cache
*oc
,
707 * Get the raw data for the encapsulated options.
709 memset(enc_opt_data
, 0, sizeof(*enc_opt_data
));
710 if (!evaluate_option_cache(enc_opt_data
, packet
,
711 NULL
, NULL
, packet
->options
, NULL
,
712 &global_scope
, oc
, MDL
)) {
713 log_error("get_encapsulated_IA_state: "
714 "error evaluating raw option.");
717 if (enc_opt_data
->len
< offset
) {
718 log_error("get_encapsulated_IA_state: raw option too small.");
719 data_string_forget(enc_opt_data
, MDL
);
724 * Now create the option state structure, and pass it to the
725 * function that parses options.
727 *enc_opt_state
= NULL
;
728 if (!option_state_allocate(enc_opt_state
, MDL
)) {
729 log_error("get_encapsulated_IA_state: no memory for options.");
730 data_string_forget(enc_opt_data
, MDL
);
733 if (!parse_option_buffer(*enc_opt_state
,
734 enc_opt_data
->data
+ offset
,
735 enc_opt_data
->len
- offset
,
737 log_error("get_encapsulated_IA_state: error parsing options.");
738 option_state_dereference(enc_opt_state
, MDL
);
739 data_string_forget(enc_opt_data
, MDL
);
747 set_status_code(u_int16_t status_code
, const char *status_message
,
748 struct option_state
*opt_state
)
750 struct data_string d
;
753 memset(&d
, 0, sizeof(d
));
754 d
.len
= sizeof(status_code
) + strlen(status_message
);
755 if (!buffer_allocate(&d
.buffer
, d
.len
, MDL
)) {
756 log_fatal("set_status_code: no memory for status code.");
758 d
.data
= d
.buffer
->data
;
759 putUShort(d
.buffer
->data
, status_code
);
760 memcpy(d
.buffer
->data
+ sizeof(status_code
),
761 status_message
, d
.len
- sizeof(status_code
));
762 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
763 d
.buffer
, (unsigned char *)d
.data
, d
.len
,
764 D6O_STATUS_CODE
, 0)) {
765 log_error("set_status_code: error saving status code.");
770 data_string_forget(&d
, MDL
);
775 * We have a set of operations we do to set up the reply packet, which
776 * is the same for many message types.
779 start_reply(struct packet
*packet
,
780 const struct data_string
*client_id
,
781 const struct data_string
*server_id
,
782 struct option_state
**opt_state
,
783 struct dhcpv6_packet
*reply
)
785 struct option_cache
*oc
;
786 const unsigned char *server_id_data
;
790 * Build our option state for reply.
793 if (!option_state_allocate(opt_state
, MDL
)) {
794 log_error("start_reply: no memory for option_state.");
797 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
798 packet
->options
, *opt_state
,
799 &global_scope
, root_group
, NULL
);
802 * A small bit of special handling for Solicit messages.
804 * We could move the logic into a flag, but for now just check
807 if (packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) {
808 reply
->msg_type
= DHCPV6_ADVERTISE
;
812 * - this message type supports rapid commit (Solicit), and
813 * - the server is configured to supply a rapid commit, and
814 * - the client requests a rapid commit,
815 * Then we add a rapid commit option, and send Reply (instead
818 oc
= lookup_option(&dhcpv6_universe
,
819 *opt_state
, D6O_RAPID_COMMIT
);
821 oc
= lookup_option(&dhcpv6_universe
,
822 packet
->options
, D6O_RAPID_COMMIT
);
824 if (!save_option_buffer(&dhcpv6_universe
,
826 (unsigned char *)"", 0,
827 D6O_RAPID_COMMIT
, 0)) {
828 log_error("start_reply: error saving "
829 "RAPID_COMMIT option.");
833 reply
->msg_type
= DHCPV6_REPLY
;
837 reply
->msg_type
= DHCPV6_REPLY
;
840 * Use the client's transaction identifier for the reply.
842 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
843 sizeof(reply
->transaction_id
));
846 * RFC 3315, section 18.2 says we need server identifier and
849 * If the server ID is defined via the configuration file, then
850 * it will already be present in the option state at this point,
851 * so we don't need to set it.
853 * If we have a server ID passed in from the caller,
854 * use that, otherwise use the global DUID.
856 oc
= lookup_option(&dhcpv6_universe
, *opt_state
, D6O_SERVERID
);
858 if (server_id
== NULL
) {
859 server_id_data
= server_duid
.data
;
860 server_id_len
= server_duid
.len
;
862 server_id_data
= server_id
->data
;
863 server_id_len
= server_id
->len
;
865 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
866 NULL
, (unsigned char *)server_id_data
,
867 server_id_len
, D6O_SERVERID
, 0)) {
868 log_error("start_reply: "
869 "error saving server identifier.");
874 if (client_id
->buffer
!= NULL
) {
875 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
877 (unsigned char *)client_id
->data
,
880 log_error("start_reply: error saving "
881 "client identifier.");
887 * If the client accepts reconfiguration, let it know that we
890 * Note: we don't actually do this yet, but DOCSIS requires we
893 oc
= lookup_option(&dhcpv6_universe
, packet
->options
,
896 if (!save_option_buffer(&dhcpv6_universe
, *opt_state
,
897 NULL
, (unsigned char *)"", 0,
898 D6O_RECONF_ACCEPT
, 0)) {
899 log_error("start_reply: "
900 "error saving RECONF_ACCEPT option.");
901 option_state_dereference(opt_state
, MDL
);
910 * Try to get the IPv6 address the client asked for from the
913 * addr is the result (should be a pointer to NULL on entry)
914 * pool is the pool to search in
915 * requested_addr is the address the client wants
918 try_client_v6_address(struct iaaddr
**addr
,
919 struct ipv6_pool
*pool
,
920 const struct data_string
*requested_addr
)
922 struct in6_addr tmp_addr
;
925 if (requested_addr
->len
< sizeof(tmp_addr
)) {
926 return ISC_R_INVALIDARG
;
928 memcpy(&tmp_addr
, requested_addr
->data
, sizeof(tmp_addr
));
929 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr
)) {
930 return ISC_R_FAILURE
;
933 if (!ipv6_addr_in_pool(&tmp_addr
, pool
)) {
934 return ISC_R_FAILURE
;
937 if (lease6_exists(pool
, &tmp_addr
)) {
938 return ISC_R_ADDRINUSE
;
941 result
= iaaddr_allocate(addr
, MDL
);
942 if (result
!= ISC_R_SUCCESS
) {
945 (*addr
)->addr
= tmp_addr
;
947 result
= add_lease6(pool
, *addr
, 0);
948 if (result
!= ISC_R_SUCCESS
) {
949 iaaddr_dereference(addr
, MDL
);
955 * Get an IPv6 address for the client.
957 * addr is the result (should be a pointer to NULL on entry)
958 * packet is the information about the packet from the client
959 * requested_iaaddr is a hint from the client
960 * client_id is the DUID for the client
963 pick_v6_address(struct iaaddr
**addr
, struct shared_network
*shared_network
,
964 const struct data_string
*client_id
)
969 unsigned int attempts
;
970 char tmp_buf
[INET6_ADDRSTRLEN
];
973 * No pools, we're done.
975 if (shared_network
->ipv6_pools
== NULL
) {
976 log_debug("Unable to pick client address: "
977 "no IPv6 pools on this shared network");
978 return ISC_R_NORESOURCES
;
982 * Otherwise try to get a lease from the first subnet possible.
984 * We start looking at the last pool we allocated from, unless
985 * it had a collision trying to allocate an address. This will
986 * tend to move us into less-filled pools.
988 start_pool
= shared_network
->last_ipv6_pool
;
992 p
= shared_network
->ipv6_pools
[i
];
993 if (activate_lease6(p
, addr
, &attempts
,
994 client_id
, 0) == ISC_R_SUCCESS
) {
996 * Record the pool used (or next one if there
1001 if (shared_network
->ipv6_pools
[i
] == NULL
) {
1005 shared_network
->last_ipv6_pool
= i
;
1007 log_debug("Picking pool address %s",
1008 inet_ntop(AF_INET6
, &((*addr
)->addr
),
1009 tmp_buf
, sizeof(tmp_buf
)));
1010 return ISC_R_SUCCESS
;
1014 if (shared_network
->ipv6_pools
[i
] == NULL
) {
1017 } while (i
!= start_pool
);
1020 * If we failed to pick an IPv6 address from any of the subnets.
1021 * Presumably that means we have no addresses for the client.
1023 log_debug("Unable to pick client address: no addresses available");
1024 return ISC_R_NORESOURCES
;
1028 * lease_to_client() is called from several messages to construct a
1029 * reply that contains all that we know about the client's correct lease
1030 * (or projected lease).
1032 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1033 * send what we "may" give them on a request.
1035 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1036 * the client should really use).
1038 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1039 * Rebind out any "wrong" addresses the client sends. This means we send
1040 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1041 * possibly send the address with zeroed lifetimes.
1043 * Information-Request - No binding.
1045 * The basic structure is to traverse the client-supplied data first, and
1046 * validate and echo back any contents that can be. If the client-supplied
1047 * data does not error out (on renew/rebind as above), but we did not send
1048 * any addresses, attempt to allocate one.
1050 /* TODO: look at client hints for lease times */
1052 lease_to_client(struct data_string
*reply_ret
,
1053 struct packet
*packet
,
1054 const struct data_string
*client_id
,
1055 const struct data_string
*server_id
)
1057 static struct reply_state reply
;
1058 struct option_cache
*oc
;
1059 struct data_string packet_oro
;
1060 isc_boolean_t no_addrs_avail
;
1062 /* Locate the client. */
1063 if (shared_network_from_packet6(&reply
.shared
,
1064 packet
) != ISC_R_SUCCESS
)
1068 * Initialize the reply.
1070 packet_reference(&reply
.packet
, packet
, MDL
);
1071 data_string_copy(&reply
.client_id
, client_id
, MDL
);
1073 if (!start_reply(packet
, client_id
, server_id
, &reply
.opt_state
,
1077 /* Set the write cursor to just past the reply header. */
1078 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1081 * Get the ORO from the packet, if any.
1083 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_ORO
);
1084 memset(&packet_oro
, 0, sizeof(packet_oro
));
1086 if (!evaluate_option_cache(&packet_oro
, packet
,
1088 packet
->options
, NULL
,
1089 &global_scope
, oc
, MDL
)) {
1090 log_error("lease_to_client: error evaluating ORO.");
1096 * Find a host record that matches from the packet, if any, and is
1097 * valid for the shared network the client is on.
1099 if (find_hosts_by_option(&reply
.host
, packet
, packet
->options
, MDL
)) {
1100 seek_shared_host(&reply
.host
, reply
.shared
);
1103 if ((reply
.host
== NULL
) &&
1104 find_hosts_by_uid(&reply
.host
, client_id
->data
, client_id
->len
,
1106 seek_shared_host(&reply
.host
, reply
.shared
);
1109 /* Process the client supplied IA_NA's onto the reply buffer. */
1111 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
1112 no_addrs_avail
= ISC_FALSE
;
1113 for (; oc
!= NULL
; oc
= oc
->next
) {
1114 isc_result_t status
;
1116 /* Start counting resources (addresses) offered. */
1117 reply
.client_resources
= 0;
1118 reply
.ia_addrs_included
= ISC_FALSE
;
1120 status
= reply_process_ia_na(&reply
, oc
);
1123 * We continue to try other IA's whether we can address
1124 * this one or not. Any other result is an immediate fail.
1126 if ((status
!= ISC_R_SUCCESS
) &&
1127 (status
!= ISC_R_NORESOURCES
))
1131 * If any address can be given to any IA, then do not set the
1132 * NoAddrsAvail status code.
1134 if (reply
.client_resources
== 0)
1135 no_addrs_avail
= ISC_TRUE
;
1138 /* Do IA_TA and IA_PD */
1141 * Make no reply if we gave no resources and is not
1142 * for Information-Request.
1144 if ((reply
.ia_count
== 0) &&
1145 (packet
->dhcpv6_msg_type
!= DHCPV6_INFORMATION_REQUEST
))
1149 * RFC3315 section 17.2.2 (Solicit):
1151 * If the server will not assign any addresses to any IAs in a
1152 * subsequent Request from the client, the server MUST send an
1153 * Advertise message to the client that includes only a Status
1154 * Code option with code NoAddrsAvail and a status message for
1155 * the user, a Server Identifier option with the server's DUID,
1156 * and a Client Identifier option with the client's DUID.
1158 * Section 18.2.1 (Request):
1160 * If the server cannot assign any addresses to an IA in the
1161 * message from the client, the server MUST include the IA in
1162 * the Reply message with no addresses in the IA and a Status
1163 * Code option in the IA containing status code NoAddrsAvail.
1165 * Section 18.2.3 (Renew):
1167 * The server may choose to change the list of addresses and
1168 * the lifetimes of addresses in IAs that are returned to the
1171 * Section 18.2.4 (Rebind):
1173 * Absolutely nothing.
1177 * Solicit and Request are fairly explicit; we send NoAddrsAvail.
1178 * We handle SOLICIT here and REQUEST in the reply_process_ia_na()
1179 * function (because SOLICIT only counts if we never get around to
1182 * Renew and Rebind are totally undefined. If we send a reply with
1183 * empty IA's, however, the client will stop renewing or rebinding,
1184 * and this is a problem if they could have gotten addressed from
1185 * another server. So we ignore client packets...they will eventually
1186 * time out in the worst case.
1188 if (no_addrs_avail
&&
1189 (reply
.packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
))
1191 /* Set the NoAddrsAvail status code. */
1192 if (!set_status_code(STATUS_NoAddrsAvail
,
1193 "No addresses available for this "
1194 "interface.", reply
.opt_state
)) {
1195 log_error("lease_to_client: Unable to set "
1196 "NoAddrsAvail status code.");
1200 /* Rewind the cursor to the start. */
1201 reply
.cursor
= REPLY_OPTIONS_INDEX
;
1204 * Produce an advertise that includes;
1210 reply
.buf
.reply
.msg_type
= DHCPV6_ADVERTISE
;
1211 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+
1215 reply
.opt_state
, reply
.packet
,
1218 } else if (no_addrs_avail
&&
1219 (reply
.packet
->dhcpv6_msg_type
!= DHCPV6_REQUEST
))
1224 * Having stored the client's IA_NA's, store any options that
1225 * will fit in the remaining space.
1227 reply
.cursor
+= store_options6((char *)reply
.buf
.data
+
1231 reply
.opt_state
, reply
.packet
,
1232 required_opts_solicit
,
1236 /* Return our reply to the caller. */
1237 reply_ret
->len
= reply
.cursor
;
1238 reply_ret
->buffer
= NULL
;
1239 if (!buffer_allocate(&reply_ret
->buffer
, reply
.cursor
, MDL
)) {
1240 log_fatal("No memory to store Reply.");
1242 memcpy(reply_ret
->buffer
->data
, reply
.buf
.data
, reply
.cursor
);
1243 reply_ret
->data
= reply_ret
->buffer
->data
;
1247 if (reply
.shared
!= NULL
)
1248 shared_network_dereference(&reply
.shared
, MDL
);
1249 if (reply
.host
!= NULL
)
1250 host_dereference(&reply
.host
, MDL
);
1251 if (reply
.opt_state
!= NULL
)
1252 option_state_dereference(&reply
.opt_state
, MDL
);
1253 if (reply
.packet
!= NULL
)
1254 packet_dereference(&reply
.packet
, MDL
);
1255 if (reply
.client_id
.data
!= NULL
)
1256 data_string_forget(&reply
.client_id
, MDL
);
1257 reply
.renew
= reply
.rebind
= reply
.prefer
= reply
.valid
= 0;
1261 /* Process a client-supplied IA_NA. This may append options to the tail of
1262 * the reply packet being built in the reply_state structure.
1265 reply_process_ia_na(struct reply_state
*reply
, struct option_cache
*ia
) {
1266 isc_result_t status
= ISC_R_SUCCESS
;
1269 struct option_state
*packet_ia
;
1270 struct option_cache
*oc
;
1271 struct data_string ia_data
, data
;
1272 isc_boolean_t lease_in_database
;
1274 /* Initialize values that will get cleaned up on return. */
1276 memset(&ia_data
, 0, sizeof(ia_data
));
1277 memset(&data
, 0, sizeof(data
));
1278 lease_in_database
= ISC_FALSE
;
1280 * Note that find_client_address() may set reply->lease.
1283 /* Make sure there is at least room for the header. */
1284 if ((reply
->cursor
+ IA_NA_OFFSET
+ 4) > sizeof(reply
->buf
)) {
1285 log_error("reply_process_ia_na: Reply too long for IA.");
1286 return ISC_R_NOSPACE
;
1290 /* Fetch the IA_NA contents. */
1291 if (!get_encapsulated_IA_state(&packet_ia
, &ia_data
, reply
->packet
,
1292 ia
, IA_NA_OFFSET
)) {
1293 log_error("reply_process_ia_na: error evaluating ia_na");
1294 status
= ISC_R_FAILURE
;
1298 /* Extract IA_NA header contents. */
1299 iaid
= getULong(ia_data
.data
);
1300 reply
->renew
= getULong(ia_data
.data
+ 4);
1301 reply
->rebind
= getULong(ia_data
.data
+ 8);
1303 /* Create an IA_NA structure. */
1304 if (ia_na_allocate(&reply
->ia_na
, iaid
, (char *)reply
->client_id
.data
,
1305 reply
->client_id
.len
, MDL
) != ISC_R_SUCCESS
) {
1306 log_error("lease_to_client: no memory for ia_na.");
1307 status
= ISC_R_NOMEMORY
;
1310 reply
->ia_na
->ia_type
= D6O_IA_NA
;
1312 /* Cache pre-existing IA, if any. */
1313 ia_na_hash_lookup(&reply
->old_ia_na
, ia_na_active
,
1314 (unsigned char *)reply
->ia_na
->iaid_duid
.data
,
1315 reply
->ia_na
->iaid_duid
.len
, MDL
);
1318 * Create an option cache to carry the IA_NA option contents, and
1319 * execute any user-supplied values into it.
1321 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
1322 status
= ISC_R_NOMEMORY
;
1326 /* Check & cache the fixed host record. */
1327 if ((reply
->host
!= NULL
) && (reply
->host
->fixed_addr
!= NULL
)) {
1328 if (!evaluate_option_cache(&reply
->fixed
, NULL
, NULL
, NULL
,
1329 NULL
, NULL
, &global_scope
,
1330 reply
->host
->fixed_addr
, MDL
)) {
1331 log_error("reply_process_ia_na: unable to evaluate "
1333 status
= ISC_R_FAILURE
;
1337 if (reply
->fixed
.len
< 16) {
1338 log_error("reply_process_ia_na: invalid fixed address.");
1339 status
= ISC_R_INVALIDARG
;
1343 reply
->static_lease
= ISC_TRUE
;
1345 reply
->static_lease
= ISC_FALSE
;
1348 * Save the cursor position at the start of the IA, so we can
1349 * set length and adjust t1/t2 values later. We write a temporary
1350 * header out now just in case we decide to adjust the packet
1351 * within sub-process functions.
1353 ia_cursor
= reply
->cursor
;
1355 /* Initialize the IA_NA header. First the code. */
1356 putUShort(reply
->buf
.data
+ reply
->cursor
, (unsigned)D6O_IA_NA
);
1359 /* Then option length. */
1360 putUShort(reply
->buf
.data
+ reply
->cursor
, 0x0Cu
);
1363 /* Then IA_NA header contents; IAID. */
1364 putULong(reply
->buf
.data
+ reply
->cursor
, iaid
);
1367 /* We store the client's t1 for now, and may over-ride it later. */
1368 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->renew
);
1371 /* We store the client's t2 for now, and may over-ride it later. */
1372 putULong(reply
->buf
.data
+ reply
->cursor
, reply
->rebind
);
1376 * For each address in this IA_NA, decide what to do about
1379 oc
= lookup_option(&dhcpv6_universe
, packet_ia
, D6O_IAADDR
);
1380 reply
->valid
= reply
->prefer
= 0xffffffff;
1381 reply
->client_valid
= reply
->client_prefer
= 0;
1382 for (; oc
!= NULL
; oc
= oc
->next
) {
1383 status
= reply_process_addr(reply
, oc
);
1386 * Canceled means we did not allocate addresses to the
1387 * client, but we're "done" with this IA - we set a status
1388 * code. So transmit this reply, e.g., move on to the next
1391 if (status
== ISC_R_CANCELED
)
1394 if ((status
!= ISC_R_SUCCESS
) && (status
!= ISC_R_ADDRINUSE
))
1401 * If we fell through the above and never gave the client
1402 * an address, give it one now.
1404 if ((status
!= ISC_R_CANCELED
) && (reply
->client_resources
== 0)) {
1405 status
= find_client_address(reply
);
1407 if (status
== ISC_R_NORESOURCES
) {
1408 switch (reply
->packet
->dhcpv6_msg_type
) {
1409 case DHCPV6_SOLICIT
:
1411 * Solicit is handled by the caller, because
1412 * it has to be the sum of all the IA's.
1416 case DHCPV6_REQUEST
:
1417 /* Section 18.2.1 (Request):
1419 * If the server cannot assign any addresses to
1420 * an IA in the message from the client, the
1421 * server MUST include the IA in the Reply
1422 * message with no addresses in the IA and a
1423 * Status Code option in the IA containing
1424 * status code NoAddrsAvail.
1426 option_state_dereference(&reply
->reply_ia
, MDL
);
1427 if (!option_state_allocate(&reply
->reply_ia
,
1430 log_error("reply_process_ia_na: No "
1431 "memory for option state "
1433 status
= ISC_R_NOMEMORY
;
1437 if (!set_status_code(STATUS_NoAddrsAvail
,
1438 "No addresses available "
1439 "for this interface.",
1441 log_error("reply_process_ia_na: Unable "
1442 "to set NoAddrsAvail status "
1444 status
= ISC_R_FAILURE
;
1448 status
= ISC_R_SUCCESS
;
1453 * RFC 3315 does not tell us to emit a status
1454 * code in this condition, or anything else.
1456 * If we included non-allocated addresses
1457 * (zeroed lifetimes) in an IA, then the client
1458 * will deconfigure them.
1460 * So we want to include the IA even if we
1461 * can't give it a new address if it includes
1462 * zeroed lifetime addresses.
1464 * We don't want to include the IA if we
1465 * provide zero addresses including zeroed
1466 * lifetimes...if we did, the client would
1467 * reset its renew/rebind behaviour. If we do
1468 * not, the client may get a success off
1471 if (reply
->ia_addrs_included
)
1472 status
= ISC_R_SUCCESS
;
1479 if (status
!= ISC_R_SUCCESS
)
1483 reply
->cursor
+= store_options6((char *)reply
->buf
.data
+ reply
->cursor
,
1484 sizeof(reply
->buf
) - reply
->cursor
,
1485 reply
->reply_ia
, reply
->packet
,
1486 required_opts_IA_NA
, NULL
);
1488 /* Reset the length of this IA to match what was just written. */
1489 putUShort(reply
->buf
.data
+ ia_cursor
+ 2,
1490 reply
->cursor
- (ia_cursor
+ 4));
1493 * T1/T2 time selection is kind of weird. We actually use DHCP
1494 * (v4) scoped options as handy existing places where these might
1495 * be configured by an administrator. A value of zero tells the
1496 * client it may choose its own renewal time.
1499 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
1500 DHO_DHCP_RENEWAL_TIME
);
1502 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
1503 reply
->packet
->options
,
1504 reply
->opt_state
, &global_scope
,
1507 log_error("Invalid renewal time.");
1509 reply
->renew
= getULong(data
.data
);
1512 if (data
.data
!= NULL
)
1513 data_string_forget(&data
, MDL
);
1515 putULong(reply
->buf
.data
+ ia_cursor
+ 8, reply
->renew
);
1519 oc
= lookup_option(&dhcp_universe
, reply
->opt_state
,
1520 DHO_DHCP_REBINDING_TIME
);
1522 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
1523 reply
->packet
->options
,
1524 reply
->opt_state
, &global_scope
,
1527 log_error("Invalid rebinding time.");
1529 reply
->rebind
= getULong(data
.data
);
1532 if (data
.data
!= NULL
)
1533 data_string_forget(&data
, MDL
);
1535 putULong(reply
->buf
.data
+ ia_cursor
+ 12, reply
->rebind
);
1538 * If this is not a 'soft' binding, consume the new changes into
1539 * the database (if any have been attached to the ia_na).
1541 * Loop through the assigned dynamic addresses, referencing the
1542 * leases onto this IA_NA rather than any old ones, and updating
1543 * pool timers for each (if any).
1545 if ((status
!= ISC_R_CANCELED
) && !reply
->static_lease
&&
1546 (reply
->buf
.reply
.msg_type
== DHCPV6_REPLY
) &&
1547 (reply
->ia_na
->num_iaaddr
!= 0)) {
1549 struct data_string
*ia_id
;
1552 for (i
= 0 ; i
< reply
->ia_na
->num_iaaddr
; i
++) {
1553 tmp
= reply
->ia_na
->iaaddr
[i
];
1555 if (tmp
->ia_na
!= NULL
)
1556 ia_na_dereference(&tmp
->ia_na
, MDL
);
1557 ia_na_reference(&tmp
->ia_na
, reply
->ia_na
, MDL
);
1559 schedule_lease_timeout(tmp
->ipv6_pool
);
1562 * If this constitutes a 'hard' binding, perform ddns
1565 oc
= lookup_option(&server_universe
, reply
->opt_state
,
1568 evaluate_boolean_option_cache(NULL
, reply
->packet
,
1570 reply
->packet
->options
,
1574 ddns_updates(reply
->packet
, NULL
, NULL
,
1575 tmp
, NULL
, reply
->opt_state
);
1579 /* Remove any old ia_na from the hash. */
1580 if (reply
->old_ia_na
!= NULL
) {
1581 ia_id
= &reply
->old_ia_na
->iaid_duid
;
1582 ia_na_hash_delete(ia_na_active
,
1583 (unsigned char *)ia_id
->data
,
1585 ia_na_dereference(&reply
->old_ia_na
, MDL
);
1588 /* Put new ia_na into the hash. */
1589 ia_id
= &reply
->ia_na
->iaid_duid
;
1590 ia_na_hash_add(ia_na_active
, (unsigned char *)ia_id
->data
,
1591 ia_id
->len
, reply
->ia_na
, MDL
);
1593 write_ia(reply
->ia_na
);
1596 * Note that we wrote the lease into the database,
1597 * so that we know not to release it when we're done
1598 * with this function.
1600 lease_in_database
= ISC_TRUE
;
1603 * If this is a soft binding, we will check to see if we are
1604 * suggesting the existing database entry to the client.
1606 } else if ((status
!= ISC_R_CANCELED
) && !reply
->static_lease
&&
1607 (reply
->old_ia_na
!= NULL
)) {
1608 if (ia_na_equal(reply
->old_ia_na
, reply
->ia_na
)) {
1609 lease_in_database
= ISC_TRUE
;
1614 if (packet_ia
!= NULL
)
1615 option_state_dereference(&packet_ia
, MDL
);
1616 if (reply
->reply_ia
!= NULL
)
1617 option_state_dereference(&reply
->reply_ia
, MDL
);
1618 if (ia_data
.data
!= NULL
)
1619 data_string_forget(&ia_data
, MDL
);
1620 if (data
.data
!= NULL
)
1621 data_string_forget(&data
, MDL
);
1622 if (reply
->ia_na
!= NULL
)
1623 ia_na_dereference(&reply
->ia_na
, MDL
);
1624 if (reply
->old_ia_na
!= NULL
)
1625 ia_na_dereference(&reply
->old_ia_na
, MDL
);
1626 if (reply
->lease
!= NULL
) {
1627 if (!lease_in_database
) {
1628 release_lease6(reply
->lease
->ipv6_pool
, reply
->lease
);
1630 iaaddr_dereference(&reply
->lease
, MDL
);
1632 if (reply
->fixed
.data
!= NULL
)
1633 data_string_forget(&reply
->fixed
, MDL
);
1636 * ISC_R_CANCELED is a status code used by the addr processing to
1637 * indicate we're replying with a status code. This is still a
1638 * success at higher layers.
1640 return((status
== ISC_R_CANCELED
) ? ISC_R_SUCCESS
: status
);
1644 * Process an IAADDR within a given IA_NA, storing any IAADDR reply contents
1645 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
1646 * in the event we are replying with a status code and do not wish to process
1647 * more IAADDRs within this IA.
1650 reply_process_addr(struct reply_state
*reply
, struct option_cache
*addr
) {
1651 u_int32_t pref_life
, valid_life
;
1652 struct binding_scope
**scope
;
1653 struct group
*group
;
1654 struct subnet
*subnet
;
1655 struct iaddr tmp_addr
;
1656 struct option_cache
*oc
;
1657 struct data_string iaaddr
, data
;
1658 isc_result_t status
= ISC_R_SUCCESS
;
1660 /* Initializes values that will be cleaned up. */
1661 memset(&iaaddr
, 0, sizeof(iaaddr
));
1662 memset(&data
, 0, sizeof(data
));
1663 /* Note that reply->lease may be set by address_is_owned() */
1666 * There is no point trying to process an incoming address if there
1667 * is no room for an outgoing address.
1669 if ((reply
->cursor
+ 28) > sizeof(reply
->buf
)) {
1670 log_error("reply_process_addr: Out of room for address.");
1671 return ISC_R_NOSPACE
;
1674 /* Extract this IAADDR option. */
1675 if (!evaluate_option_cache(&iaaddr
, reply
->packet
, NULL
, NULL
,
1676 reply
->packet
->options
, NULL
, &global_scope
,
1678 (iaaddr
.len
< IAADDR_OFFSET
)) {
1679 log_error("reply_process_addr: error evaluating IAADDR.");
1680 status
= ISC_R_FAILURE
;
1684 /* The first 16 bytes are the IPv6 address. */
1685 pref_life
= getULong(iaaddr
.data
+ 16);
1686 valid_life
= getULong(iaaddr
.data
+ 20);
1688 if ((reply
->client_valid
== 0) ||
1689 (reply
->client_valid
> valid_life
))
1690 reply
->client_valid
= valid_life
;
1692 if ((reply
->client_prefer
== 0) ||
1693 (reply
->client_prefer
> pref_life
))
1694 reply
->client_prefer
= pref_life
;
1697 * Clients may choose to send :: as an address, with the idea to give
1698 * hints about preferred-lifetime or valid-lifetime.
1701 memset(tmp_addr
.iabuf
, 0, 16);
1702 if (!memcmp(iaaddr
.data
, tmp_addr
.iabuf
, 16)) {
1703 /* Status remains success; we just ignore this one. */
1707 /* tmp_addr len remains 16 */
1708 memcpy(tmp_addr
.iabuf
, iaaddr
.data
, 16);
1711 * Verify that this address is on the client's network.
1713 for (subnet
= reply
->shared
->subnets
; subnet
!= NULL
;
1714 subnet
= subnet
->next_sibling
) {
1715 if (addr_eq(subnet_number(tmp_addr
, subnet
->netmask
),
1720 /* Address not found on shared network. */
1721 if (subnet
== NULL
) {
1722 /* Ignore this address on 'soft' bindings. */
1723 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
)
1724 /* status remains success */
1728 * RFC3315 section 18.2.1:
1730 * If the server finds that the prefix on one or more IP
1731 * addresses in any IA in the message from the client is not
1732 * appropriate for the link to which the client is connected,
1733 * the server MUST return the IA to the client with a Status
1734 * Code option with the value NotOnLink.
1736 if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) {
1737 /* Rewind the IA_NA to empty. */
1738 option_state_dereference(&reply
->reply_ia
, MDL
);
1739 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
1740 log_error("reply_process_addr: No memory for "
1741 "option state wipe.");
1742 status
= ISC_R_NOMEMORY
;
1746 /* Append a NotOnLink status code. */
1747 if (!set_status_code(STATUS_NotOnLink
,
1748 "Address not for use on this "
1749 "link.", reply
->reply_ia
)) {
1750 log_error("reply_process_addr: Failure "
1751 "setting status code.");
1752 status
= ISC_R_FAILURE
;
1756 /* Fin (no more IAADDRs). */
1757 status
= ISC_R_CANCELED
;
1762 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
1764 * If the server finds that any of the addresses are not
1765 * appropriate for the link to which the client is attached,
1766 * the server returns the address to the client with lifetimes
1769 if ((reply
->packet
->dhcpv6_msg_type
!= DHCPV6_RENEW
) &&
1770 (reply
->packet
->dhcpv6_msg_type
!= DHCPV6_REBIND
)) {
1771 log_error("It is impossible to lease a client that is "
1772 "not sending a solicit, request, renew, or "
1774 status
= ISC_R_FAILURE
;
1778 reply
->send_prefer
= reply
->send_valid
= 0;
1782 /* Verify the address belongs to the client. */
1783 if (!address_is_owned(reply
, &tmp_addr
)) {
1785 * For solicit and request, any addresses included are
1786 * 'requested' addresses. For rebind, we actually have
1787 * no direction on what to do from 3315 section 18.2.4!
1788 * So I think the best bet is to try and give it out, and if
1789 * we can't, zero lifetimes.
1791 if ((reply
->packet
->dhcpv6_msg_type
== DHCPV6_SOLICIT
) ||
1792 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REQUEST
) ||
1793 (reply
->packet
->dhcpv6_msg_type
== DHCPV6_REBIND
)) {
1794 status
= reply_process_try_addr(reply
, &tmp_addr
);
1796 /* Either error out or skip this address. */
1797 if ((status
!= ISC_R_SUCCESS
) &&
1798 (status
!= ISC_R_ADDRINUSE
))
1801 if (reply
->lease
== NULL
) {
1802 if (reply
->packet
->dhcpv6_msg_type
==
1804 reply
->send_prefer
= 0;
1805 reply
->send_valid
= 0;
1809 /* status remains success - ignore */
1813 * RFC3315 section 18.2.3:
1815 * If the server cannot find a client entry for the IA the
1816 * server returns the IA containing no addresses with a Status
1817 * Code option set to NoBinding in the Reply message.
1819 } else if (reply
->packet
->dhcpv6_msg_type
== DHCPV6_RENEW
) {
1820 /* Rewind the IA_NA to empty. */
1821 option_state_dereference(&reply
->reply_ia
, MDL
);
1822 if (!option_state_allocate(&reply
->reply_ia
, MDL
)) {
1823 log_error("reply_process_addr: No memory for "
1824 "option state wipe.");
1825 status
= ISC_R_NOMEMORY
;
1829 /* Append a NoBinding status code. */
1830 if (!set_status_code(STATUS_NoBinding
,
1831 "Address not bound to this "
1832 "interface.", reply
->reply_ia
)) {
1833 log_error("reply_process_addr: Unable to "
1834 "attach status code.");
1835 status
= ISC_R_FAILURE
;
1839 /* Fin (no more IAADDRs). */
1840 status
= ISC_R_CANCELED
;
1843 log_error("It is impossible to lease a client that is "
1844 "not sending a solicit, request, renew, or "
1846 status
= ISC_R_FAILURE
;
1851 if (reply
->static_lease
) {
1852 if (reply
->host
== NULL
)
1853 log_fatal("Impossible condition at %s:%d.", MDL
);
1855 scope
= &global_scope
;
1856 group
= reply
->host
->group
;
1858 if (reply
->lease
== NULL
)
1859 log_fatal("Impossible condition at %s:%d.", MDL
);
1861 scope
= &reply
->lease
->scope
;
1862 group
= reply
->shared
->group
;
1866 * If client_resources is nonzero, then the reply_process_is_addressed
1867 * function has executed configuration state into the reply option
1868 * cache. We will use that valid cache to derive configuration for
1869 * whether or not to engage in additional addresses, and similar.
1871 if (reply
->client_resources
!= 0) {
1875 * Does this client have "enough" addresses already? Default
1876 * to one. Everybody gets one, and one should be enough for
1879 oc
= lookup_option(&server_universe
, reply
->opt_state
,
1880 SV_LIMIT_ADDRS_PER_IA
);
1882 if (!evaluate_option_cache(&data
, reply
->packet
,
1884 reply
->packet
->options
,
1888 log_error("reply_process_addr: unable to "
1889 "evaluate addrs-per-ia value.");
1890 status
= ISC_R_FAILURE
;
1894 limit
= getULong(data
.data
);
1895 data_string_forget(&data
, MDL
);
1899 * If we wish to limit the client to a certain number of
1900 * addresses, then omit the address from the reply.
1902 if (reply
->client_resources
>= limit
)
1906 status
= reply_process_is_addressed(reply
, scope
, group
);
1907 if (status
!= ISC_R_SUCCESS
)
1911 status
= reply_process_send_addr(reply
, &tmp_addr
);
1914 if (iaaddr
.data
!= NULL
)
1915 data_string_forget(&iaaddr
, MDL
);
1916 if (data
.data
!= NULL
)
1917 data_string_forget(&data
, MDL
);
1918 if (reply
->lease
!= NULL
)
1919 iaaddr_dereference(&reply
->lease
, MDL
);
1925 * Verify the address belongs to the client. If we've got a host
1926 * record with a fixed address, it has to be the assigned address
1927 * (fault out all else). Otherwise it's a dynamic address, so lookup
1928 * that address and make sure it belongs to this DUID:IAID pair.
1930 static isc_boolean_t
1931 address_is_owned(struct reply_state
*reply
, struct iaddr
*addr
) {
1935 * This faults out addresses that don't match fixed addresses.
1937 if (reply
->static_lease
) {
1938 if (reply
->fixed
.data
== NULL
)
1939 log_fatal("Impossible condition at %s:%d.", MDL
);
1941 if (memcmp(addr
->iabuf
, reply
->fixed
.data
, 16) == 0)
1947 if ((reply
->old_ia_na
== NULL
) || (reply
->old_ia_na
->num_iaaddr
== 0))
1950 for (i
= 0 ; i
< reply
->old_ia_na
->num_iaaddr
; i
++) {
1953 tmp
= reply
->old_ia_na
->iaaddr
[i
];
1955 if (memcmp(addr
->iabuf
, &tmp
->addr
, 16) == 0) {
1956 iaaddr_reference(&reply
->lease
, tmp
, MDL
);
1965 * This function only returns failure on 'hard' failures. If it succeeds,
1966 * it will leave a lease structure behind.
1969 reply_process_try_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
1970 isc_result_t status
= ISC_R_FAILURE
;
1971 struct ipv6_pool
*pool
;
1973 struct data_string data_addr
;
1975 if ((reply
== NULL
) || (reply
->shared
== NULL
) ||
1976 (reply
->shared
->ipv6_pools
== NULL
) || (addr
== NULL
) ||
1977 (reply
->lease
!= NULL
))
1978 return ISC_R_INVALIDARG
;
1980 memset(&data_addr
, 0, sizeof(data_addr
));
1981 data_addr
.len
= addr
->len
;
1982 data_addr
.data
= addr
->iabuf
;
1984 for (i
= 0 ; (pool
= reply
->shared
->ipv6_pools
[i
]) != NULL
; i
++) {
1985 status
= try_client_v6_address(&reply
->lease
, pool
,
1987 if (status
== ISC_R_SUCCESS
)
1991 /* Note that this is just pedantry. There is no allocation to free. */
1992 data_string_forget(&data_addr
, MDL
);
1993 /* Return just the most recent status... */
1997 /* Look around for an address to give the client. First, look through the
1998 * old IA for addresses we can extend. Second, try to allocate a new address.
1999 * Finally, actually add that address into the current reply IA.
2002 find_client_address(struct reply_state
*reply
) {
2003 struct iaddr send_addr
;
2004 isc_result_t status
= ISC_R_NORESOURCES
;
2005 struct iaaddr
*lease
, *best_lease
= NULL
;
2006 struct binding_scope
**scope
;
2007 struct group
*group
;
2010 if (reply
->host
!= NULL
)
2011 group
= reply
->host
->group
;
2013 group
= reply
->shared
->group
;
2015 if (reply
->static_lease
) {
2016 if (reply
->host
== NULL
)
2017 return ISC_R_INVALIDARG
;
2020 memcpy(send_addr
.iabuf
, reply
->fixed
.data
, 16);
2022 status
= ISC_R_SUCCESS
;
2023 scope
= &global_scope
;
2027 if (reply
->old_ia_na
!= NULL
) {
2028 for (i
= 0 ; i
< reply
->old_ia_na
->num_iaaddr
; i
++) {
2029 lease
= reply
->old_ia_na
->iaaddr
[i
];
2031 best_lease
= lease_compare(lease
, best_lease
);
2035 /* Try to pick a new address if we didn't find one, or if we found an
2038 if ((best_lease
== NULL
) || (best_lease
->state
== FTS_ABANDONED
)) {
2039 status
= pick_v6_address(&reply
->lease
, reply
->shared
,
2041 } else if (best_lease
!= NULL
) {
2042 iaaddr_reference(&reply
->lease
, best_lease
, MDL
);
2043 status
= ISC_R_SUCCESS
;
2046 /* Pick the abandoned lease as a last resort. */
2047 if ((status
== ISC_R_NORESOURCES
) && (best_lease
!= NULL
)) {
2048 /* I don't see how this is supposed to be done right now. */
2049 log_error("Reclaiming abandoned addresses is not yet "
2050 "supported. Treating this as an out of space "
2052 /* lease_reference(&reply->lease, best_lease, MDL); */
2055 /* Give up now if we didn't find a lease. */
2056 if (status
!= ISC_R_SUCCESS
)
2059 if (reply
->lease
== NULL
)
2060 log_fatal("Impossible condition at %s:%d.", MDL
);
2062 scope
= &reply
->lease
->scope
;
2063 group
= reply
->shared
->group
;
2066 memcpy(send_addr
.iabuf
, &reply
->lease
->addr
, 16);
2069 status
= reply_process_is_addressed(reply
, scope
, group
);
2070 if (status
!= ISC_R_SUCCESS
)
2073 status
= reply_process_send_addr(reply
, &send_addr
);
2077 /* Once an address is found for a client, perform several common functions;
2078 * Calculate and store valid and preferred lease times, draw client options
2079 * into the option state.
2082 reply_process_is_addressed(struct reply_state
*reply
,
2083 struct binding_scope
**scope
, struct group
*group
)
2085 isc_result_t status
= ISC_R_SUCCESS
;
2086 struct data_string data
;
2087 struct option_cache
*oc
;
2089 /* Initialize values we will cleanup. */
2090 memset(&data
, 0, sizeof(data
));
2092 /* Execute relevant options into root scope. */
2093 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
2094 reply
->packet
->options
, reply
->opt_state
,
2095 scope
, group
, root_group
);
2097 /* Determine valid lifetime. */
2098 if (reply
->client_valid
== 0)
2099 reply
->send_valid
= DEFAULT_DEFAULT_LEASE_TIME
;
2101 reply
->send_valid
= reply
->client_valid
;
2103 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2104 SV_DEFAULT_LEASE_TIME
);
2106 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
2107 reply
->packet
->options
,
2111 log_error("reply_process_is_addressed: unable to "
2112 "evaluate default lease time");
2113 status
= ISC_R_FAILURE
;
2117 reply
->send_valid
= getULong(data
.data
);
2118 data_string_forget(&data
, MDL
);
2121 if (reply
->client_prefer
== 0)
2122 reply
->send_prefer
= reply
->send_valid
;
2124 reply
->send_prefer
= reply
->client_prefer
;
2126 if (reply
->send_prefer
>= reply
->send_valid
)
2127 reply
->send_prefer
= (reply
->send_valid
/ 2) +
2128 (reply
->send_valid
/ 8);
2130 oc
= lookup_option(&server_universe
, reply
->opt_state
,
2131 SV_PREFER_LIFETIME
);
2133 if (!evaluate_option_cache(&data
, reply
->packet
, NULL
, NULL
,
2134 reply
->packet
->options
,
2138 log_error("reply_process_is_addressed: unable to "
2139 "evaluate preferred lease time");
2140 status
= ISC_R_FAILURE
;
2144 reply
->send_prefer
= getULong(data
.data
);
2145 data_string_forget(&data
, MDL
);
2148 /* Note lowest values for later calculation of renew/rebind times. */
2149 if (reply
->prefer
> reply
->send_prefer
)
2150 reply
->prefer
= reply
->send_prefer
;
2152 if (reply
->valid
> reply
->send_valid
)
2153 reply
->valid
= reply
->send_valid
;
2157 * XXX: Old 4.0.0 alpha code would change the host {} record
2158 * XXX: uid upon lease assignment. This was intended to cover the
2159 * XXX: case where a client first identifies itself using vendor
2160 * XXX: options in a solicit, or request, but later neglects to include
2161 * XXX: these options in a Renew or Rebind. It is not clear that this
2162 * XXX: is required, and has some startling ramifications (such as
2163 * XXX: how to recover this dynamic host {} state across restarts).
2165 if (reply
->host
!= NULL
)
2166 change_host_uid(host
, reply
->client_id
->data
,
2167 reply
->client_id
->len
);
2170 /* Perform dynamic lease related update work. */
2171 if (reply
->lease
!= NULL
) {
2172 /* Advance (or rewind) the valid lifetime. */
2173 reply
->lease
->valid_lifetime_end_time
= cur_time
+
2175 renew_lease6(reply
->lease
->ipv6_pool
, reply
->lease
);
2177 status
= ia_na_add_iaaddr(reply
->ia_na
, reply
->lease
, MDL
);
2178 if (status
!= ISC_R_SUCCESS
) {
2179 log_fatal("reply_process_addr: Unable to attach lease "
2180 "to new IA: %s", isc_result_totext(status
));
2184 * If this is a new lease, make sure it is attached somewhere.
2186 if (reply
->lease
->ia_na
== NULL
) {
2187 ia_na_reference(&reply
->lease
->ia_na
, reply
->ia_na
,
2192 /* Bring a copy of the relevant options into the IA scope. */
2193 execute_statements_in_scope(NULL
, reply
->packet
, NULL
, NULL
,
2194 reply
->packet
->options
, reply
->reply_ia
,
2195 scope
, group
, root_group
);
2198 if (data
.data
!= NULL
)
2199 data_string_forget(&data
, MDL
);
2201 if (status
== ISC_R_SUCCESS
)
2202 reply
->client_resources
++;
2207 /* Simply send an IAADDR within the IA_NA scope as described. */
2209 reply_process_send_addr(struct reply_state
*reply
, struct iaddr
*addr
) {
2210 isc_result_t status
= ISC_R_SUCCESS
;
2211 struct data_string data
;
2213 memset(&data
, 0, sizeof(data
));
2215 /* Now append the lease. */
2216 data
.len
= IAADDR_OFFSET
;
2217 if (!buffer_allocate(&data
.buffer
, data
.len
, MDL
)) {
2218 log_error("reply_process_send_addr: out of memory allocating "
2219 "new IAADDR buffer.");
2220 status
= ISC_R_NOMEMORY
;
2223 data
.data
= data
.buffer
->data
;
2225 memcpy(data
.buffer
->data
, addr
->iabuf
, 16);
2226 putULong(data
.buffer
->data
+ 16, reply
->send_prefer
);
2227 putULong(data
.buffer
->data
+ 20, reply
->send_valid
);
2229 if (!append_option_buffer(&dhcpv6_universe
, reply
->reply_ia
,
2230 data
.buffer
, data
.buffer
->data
,
2231 data
.len
, D6O_IAADDR
, 0)) {
2232 log_error("reply_process_send_addr: unable to save IAADDR "
2234 status
= ISC_R_FAILURE
;
2238 reply
->ia_addrs_included
= ISC_TRUE
;
2241 if (data
.data
!= NULL
)
2242 data_string_forget(&data
, MDL
);
2247 /* Choose the better of two leases. */
2248 static struct iaaddr
*
2249 lease_compare(struct iaaddr
*alpha
, struct iaaddr
*beta
) {
2255 switch(alpha
->state
) {
2257 switch(beta
->state
) {
2259 /* Choose the lease with the longest lifetime (most
2260 * likely the most recently allocated).
2262 if (alpha
->valid_lifetime_end_time
<
2263 beta
->valid_lifetime_end_time
)
2273 log_fatal("Impossible condition at %s:%d.", MDL
);
2278 switch (beta
->state
) {
2283 /* Choose the most recently expired lease. */
2284 if (alpha
->valid_lifetime_end_time
<
2285 beta
->valid_lifetime_end_time
)
2294 log_fatal("Impossible condition at %s:%d.", MDL
);
2299 switch (beta
->state
) {
2305 /* Choose the lease that was abandoned longest ago. */
2306 if (alpha
->valid_lifetime_end_time
<
2307 beta
->valid_lifetime_end_time
)
2311 log_fatal("Impossible condition at %s:%d.", MDL
);
2316 log_fatal("Impossible condition at %s:%d.", MDL
);
2319 log_fatal("Triple impossible condition at %s:%d.", MDL
);
2324 * Solicit is how a client starts requesting addresses.
2326 * If the client asks for rapid commit, and we support it, we will
2327 * allocate the addresses and reply.
2329 * Otherwise we will send an advertise message.
2333 dhcpv6_solicit(struct data_string
*reply_ret
, struct packet
*packet
) {
2334 struct data_string client_id
;
2337 * Validate our input.
2339 if (!valid_client_msg(packet
, &client_id
)) {
2343 lease_to_client(reply_ret
, packet
, &client_id
, NULL
);
2348 data_string_forget(&client_id
, MDL
);
2352 * Request is how a client actually requests addresses.
2354 * Very similar to Solicit handling, except the server DUID is required.
2357 /* TODO: reject unicast messages, unless we set unicast option */
2359 dhcpv6_request(struct data_string
*reply_ret
, struct packet
*packet
) {
2360 struct data_string client_id
;
2361 struct data_string server_id
;
2364 * Validate our input.
2366 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
2373 lease_to_client(reply_ret
, packet
, &client_id
, &server_id
);
2378 data_string_forget(&client_id
, MDL
);
2379 data_string_forget(&server_id
, MDL
);
2382 /* Find a DHCPv6 packet's shared network from hints in the packet.
2385 shared_network_from_packet6(struct shared_network
**shared
,
2386 struct packet
*packet
)
2388 const struct packet
*chk_packet
;
2389 const struct in6_addr
*link_addr
, *first_link_addr
;
2390 struct iaddr tmp_addr
;
2391 struct subnet
*subnet
;
2392 isc_result_t status
;
2394 if ((shared
== NULL
) || (*shared
!= NULL
) || (packet
== NULL
))
2395 return ISC_R_INVALIDARG
;
2398 * First, find the link address where the packet from the client
2399 * first appeared (if this packet was relayed).
2401 first_link_addr
= NULL
;
2402 chk_packet
= packet
->dhcpv6_container_packet
;
2403 while (chk_packet
!= NULL
) {
2404 link_addr
= &chk_packet
->dhcpv6_link_address
;
2405 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
2406 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
2407 first_link_addr
= link_addr
;
2409 chk_packet
= chk_packet
->dhcpv6_container_packet
;
2413 * If there is a relayed link address, find the subnet associated
2414 * with that, and use that to get the appropriate
2417 if (first_link_addr
!= NULL
) {
2418 tmp_addr
.len
= sizeof(*first_link_addr
);
2419 memcpy(tmp_addr
.iabuf
,
2420 first_link_addr
, sizeof(*first_link_addr
));
2422 if (!find_subnet(&subnet
, tmp_addr
, MDL
)) {
2423 log_debug("No subnet found for link-address %s.",
2425 return ISC_R_NOTFOUND
;
2427 status
= shared_network_reference(shared
,
2428 subnet
->shared_network
, MDL
);
2429 subnet_dereference(&subnet
, MDL
);
2432 * If there is no link address, we will use the interface
2433 * that this packet came in on to pick the shared_network.
2436 status
= shared_network_reference(shared
,
2437 packet
->interface
->shared_network
,
2445 * When a client thinks it might be on a new link, it sends a
2448 * From RFC3315 section 18.2.2:
2450 * When the server receives a Confirm message, the server determines
2451 * whether the addresses in the Confirm message are appropriate for the
2452 * link to which the client is attached. If all of the addresses in the
2453 * Confirm message pass this test, the server returns a status of
2454 * Success. If any of the addresses do not pass this test, the server
2455 * returns a status of NotOnLink. If the server is unable to perform
2456 * this test (for example, the server does not have information about
2457 * prefixes on the link to which the client is connected), or there were
2458 * no addresses in any of the IAs sent by the client, the server MUST
2459 * NOT send a reply to the client.
2463 dhcpv6_confirm(struct data_string
*reply_ret
, struct packet
*packet
) {
2464 struct shared_network
*shared
;
2465 struct subnet
*subnet
;
2466 struct option_cache
*ia
, *ta
, *oc
;
2467 struct data_string cli_enc_opt_data
, iaaddr
, client_id
, packet_oro
;
2468 struct option_state
*cli_enc_opt_state
, *opt_state
;
2469 struct iaddr cli_addr
;
2471 isc_boolean_t inappropriate
, has_addrs
;
2472 char reply_data
[65536];
2473 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
2474 int reply_ofs
= (int)((char *)reply
->options
- (char *)reply
);
2477 * Basic client message validation.
2479 memset(&client_id
, 0, sizeof(client_id
));
2480 if (!valid_client_msg(packet
, &client_id
)) {
2484 /* Do not process Confirms that do not have IA's we do not recognize.
2486 ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
2487 ta
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_TA
);
2488 if ((ia
== NULL
) && (ta
== NULL
))
2492 * Bit of variable initialization.
2494 opt_state
= cli_enc_opt_state
= NULL
;
2495 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
2496 memset(&iaaddr
, 0, sizeof(iaaddr
));
2497 memset(&packet_oro
, 0, sizeof(packet_oro
));
2499 /* Determine what shared network the client is connected to. We
2500 * must not respond if we don't have any information about the
2501 * network the client is on.
2504 if ((shared_network_from_packet6(&shared
, packet
) != ISC_R_SUCCESS
) ||
2508 /* If there are no recorded subnets, then we have no
2509 * information about this subnet - ignore Confirms.
2511 subnet
= shared
->subnets
;
2515 /* Are the addresses in all the IA's appropriate for that link? */
2516 has_addrs
= inappropriate
= ISC_FALSE
;
2518 while(!inappropriate
) {
2519 /* If we've reached the end of the IA_NA pass, move to the
2522 if ((pass
== D6O_IA_NA
) && (ia
== NULL
)) {
2527 /* If we've reached the end of all passes, we're done. */
2531 if (((pass
== D6O_IA_NA
) &&
2532 !get_encapsulated_IA_state(&cli_enc_opt_state
,
2534 packet
, ia
, IA_NA_OFFSET
)) ||
2535 ((pass
== D6O_IA_TA
) &&
2536 !get_encapsulated_IA_state(&cli_enc_opt_state
,
2538 packet
, ia
, IA_TA_OFFSET
))) {
2542 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
2545 for ( ; oc
!= NULL
; oc
= oc
->next
) {
2546 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
2547 packet
->options
, NULL
,
2548 &global_scope
, oc
, MDL
) ||
2549 (iaaddr
.len
< IAADDR_OFFSET
)) {
2550 log_error("dhcpv6_confirm: "
2551 "error evaluating IAADDR.");
2555 /* Copy out the IPv6 address for processing. */
2557 memcpy(cli_addr
.iabuf
, iaaddr
.data
, 16);
2559 data_string_forget(&iaaddr
, MDL
);
2561 /* Record that we've processed at least one address. */
2562 has_addrs
= ISC_TRUE
;
2564 /* Find out if any subnets cover this address. */
2565 for (subnet
= shared
->subnets
; subnet
!= NULL
;
2566 subnet
= subnet
->next_sibling
) {
2567 if (addr_eq(subnet_number(cli_addr
,
2573 /* If we reach the end of the subnet list, and no
2574 * subnet matches the client address, then it must
2575 * be inappropriate to the link (so far as our
2576 * configuration says). Once we've found one
2577 * inappropriate address, there is no reason to
2578 * continue searching.
2580 if (subnet
== NULL
) {
2581 inappropriate
= ISC_TRUE
;
2586 option_state_dereference(&cli_enc_opt_state
, MDL
);
2587 data_string_forget(&cli_enc_opt_data
, MDL
);
2589 /* Advance to the next IA_*. */
2593 /* If the client supplied no addresses, do not reply. */
2600 if (!start_reply(packet
, &client_id
, NULL
, &opt_state
, reply
)) {
2607 if (inappropriate
) {
2608 if (!set_status_code(STATUS_NotOnLink
,
2609 "Some of the addresses are not on link.",
2614 if (!set_status_code(STATUS_Success
,
2615 "All addresses still on link.",
2622 * Only one option: add it.
2624 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
2625 sizeof(reply_data
)-reply_ofs
,
2627 required_opts
, &packet_oro
);
2630 * Return our reply to the caller.
2632 reply_ret
->len
= reply_ofs
;
2633 reply_ret
->buffer
= NULL
;
2634 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
2635 log_fatal("No memory to store reply.");
2637 reply_ret
->data
= reply_ret
->buffer
->data
;
2638 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
2641 /* Cleanup any stale data strings. */
2642 if (cli_enc_opt_data
.buffer
!= NULL
)
2643 data_string_forget(&cli_enc_opt_data
, MDL
);
2644 if (iaaddr
.buffer
!= NULL
)
2645 data_string_forget(&iaaddr
, MDL
);
2646 if (client_id
.buffer
!= NULL
)
2647 data_string_forget(&client_id
, MDL
);
2648 if (packet_oro
.buffer
!= NULL
)
2649 data_string_forget(&packet_oro
, MDL
);
2651 /* Release any stale option states. */
2652 if (cli_enc_opt_state
!= NULL
)
2653 option_state_dereference(&cli_enc_opt_state
, MDL
);
2654 if (opt_state
!= NULL
)
2655 option_state_dereference(&opt_state
, MDL
);
2659 * Renew is when a client wants to extend its lease, at time T1.
2661 * We handle this the same as if the client wants a new lease, except
2662 * for the error code of when addresses don't match.
2665 /* TODO: reject unicast messages, unless we set unicast option */
2667 dhcpv6_renew(struct data_string
*reply
, struct packet
*packet
) {
2668 struct data_string client_id
;
2669 struct data_string server_id
;
2672 * Validate the request.
2674 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
2681 lease_to_client(reply
, packet
, &client_id
, &server_id
);
2686 data_string_forget(&server_id
, MDL
);
2687 data_string_forget(&client_id
, MDL
);
2691 * Rebind is when a client wants to extend its lease, at time T2.
2693 * We handle this the same as if the client wants a new lease, except
2694 * for the error code of when addresses don't match.
2698 dhcpv6_rebind(struct data_string
*reply
, struct packet
*packet
) {
2699 struct data_string client_id
;
2701 if (!valid_client_msg(packet
, &client_id
)) {
2705 lease_to_client(reply
, packet
, &client_id
, NULL
);
2707 data_string_forget(&client_id
, MDL
);
2711 ia_na_match_decline(const struct data_string
*client_id
,
2712 const struct data_string
*iaaddr
,
2713 struct iaaddr
*lease
)
2715 char tmp_addr
[INET6_ADDRSTRLEN
];
2717 log_error("Client %s reports address %s is "
2718 "already in use by another host!",
2719 print_hex_1(client_id
->len
, client_id
->data
, 60),
2720 inet_ntop(AF_INET6
, iaaddr
->data
,
2721 tmp_addr
, sizeof(tmp_addr
)));
2722 if (lease
!= NULL
) {
2723 decline_lease6(lease
->ipv6_pool
, lease
);
2724 write_ia(lease
->ia_na
);
2729 ia_na_nomatch_decline(const struct data_string
*client_id
,
2730 const struct data_string
*iaaddr
,
2731 u_int32_t
*ia_na_id
,
2732 struct packet
*packet
,
2737 char tmp_addr
[INET6_ADDRSTRLEN
];
2738 struct option_state
*host_opt_state
;
2741 log_info("Client %s declines address %s, which is not offered to it.",
2742 print_hex_1(client_id
->len
, client_id
->data
, 60),
2743 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
2746 * Create state for this IA_NA.
2748 host_opt_state
= NULL
;
2749 if (!option_state_allocate(&host_opt_state
, MDL
)) {
2750 log_error("ia_na_nomatch_decline: out of memory "
2751 "allocating option_state.");
2755 if (!set_status_code(STATUS_NoBinding
, "Decline for unknown address.",
2761 * Insure we have enough space
2763 if (reply_len
< (*reply_ofs
+ 16)) {
2764 log_error("ia_na_nomatch_decline: "
2765 "out of space for reply packet.");
2770 * Put our status code into the reply packet.
2772 len
= store_options6(reply_data
+(*reply_ofs
)+16,
2773 reply_len
-(*reply_ofs
)-16,
2774 host_opt_state
, packet
,
2775 required_opts_STATUS_CODE
, NULL
);
2778 * Store the non-encapsulated option data for this
2779 * IA_NA into our reply packet. Defined in RFC 3315,
2783 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
2785 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
2786 /* IA_NA, copied from the client */
2787 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
2788 /* t1 and t2, odd that we need them, but here it is */
2789 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
2790 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
2793 * Get ready for next IA_NA.
2795 *reply_ofs
+= (len
+ 16);
2798 option_state_dereference(&host_opt_state
, MDL
);
2802 iterate_over_ia_na(struct data_string
*reply_ret
,
2803 struct packet
*packet
,
2804 const struct data_string
*client_id
,
2805 const struct data_string
*server_id
,
2806 const char *packet_type
,
2807 void (*ia_na_match
)(),
2808 void (*ia_na_nomatch
)())
2810 struct option_state
*opt_state
;
2811 struct host_decl
*packet_host
;
2812 struct option_cache
*ia
;
2813 struct option_cache
*oc
;
2814 /* cli_enc_... variables come from the IA_NA/IA_TA options */
2815 struct data_string cli_enc_opt_data
;
2816 struct option_state
*cli_enc_opt_state
;
2817 struct host_decl
*host
;
2818 struct option_state
*host_opt_state
;
2819 struct data_string iaaddr
;
2820 struct data_string fixed_addr
;
2821 int iaaddr_is_found
;
2822 char reply_data
[65536];
2823 struct dhcpv6_packet
*reply
= (struct dhcpv6_packet
*)reply_data
;
2824 int reply_ofs
= (int)((char *)reply
->options
- (char *)reply
);
2825 char status_msg
[32];
2826 struct iaaddr
*lease
;
2827 struct ia_na
*existing_ia_na
;
2829 struct data_string key
;
2833 * Initialize to empty values, in case we have to exit early.
2836 memset(&cli_enc_opt_data
, 0, sizeof(cli_enc_opt_data
));
2837 cli_enc_opt_state
= NULL
;
2838 memset(&iaaddr
, 0, sizeof(iaaddr
));
2839 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
2840 host_opt_state
= NULL
;
2844 * Find the host record that matches from the packet, if any.
2847 if (!find_hosts_by_uid(&packet_host
,
2848 client_id
->data
, client_id
->len
, MDL
)) {
2851 * Note: In general, we don't expect a client to provide
2852 * enough information to match by option for these
2853 * types of messages, but if we don't have a UID
2854 * match we can check anyway.
2856 if (!find_hosts_by_option(&packet_host
,
2857 packet
, packet
->options
, MDL
)) {
2863 * Set our reply information.
2865 reply
->msg_type
= DHCPV6_REPLY
;
2866 memcpy(reply
->transaction_id
, packet
->dhcpv6_transaction_id
,
2867 sizeof(reply
->transaction_id
));
2870 * Build our option state for reply.
2873 if (!option_state_allocate(&opt_state
, MDL
)) {
2874 log_error("iterate_over_ia_na: no memory for option_state.");
2877 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
2878 packet
->options
, opt_state
,
2879 &global_scope
, root_group
, NULL
);
2882 * RFC 3315, section 18.2.7 tells us which options to include.
2884 oc
= lookup_option(&dhcpv6_universe
, opt_state
, D6O_SERVERID
);
2886 if (!save_option_buffer(&dhcpv6_universe
, opt_state
, NULL
,
2887 (unsigned char *)server_duid
.data
,
2888 server_duid
.len
, D6O_SERVERID
, 0)) {
2889 log_error("iterate_over_ia_na: "
2890 "error saving server identifier.");
2895 if (!save_option_buffer(&dhcpv6_universe
, opt_state
,
2897 (unsigned char *)client_id
->data
,
2900 log_error("iterate_over_ia_na: "
2901 "error saving client identifier.");
2905 snprintf(status_msg
, sizeof(status_msg
), "%s received.", packet_type
);
2906 if (!set_status_code(STATUS_Success
, status_msg
, opt_state
)) {
2911 * Add our options that are not associated with any IA_NA or IA_TA.
2913 reply_ofs
+= store_options6(reply_data
+reply_ofs
,
2914 sizeof(reply_data
)-reply_ofs
,
2916 required_opts
, NULL
);
2919 * Loop through the IA_NA reported by the client, and deal with
2920 * addresses reported as already in use.
2922 for (ia
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_IA_NA
);
2923 ia
!= NULL
; ia
= ia
->next
) {
2924 iaaddr_is_found
= 0;
2926 if (!get_encapsulated_IA_state(&cli_enc_opt_state
,
2928 packet
, ia
, IA_NA_OFFSET
)) {
2932 iaid
= getULong(cli_enc_opt_data
.data
);
2935 * XXX: It is possible that we can get multiple addresses
2936 * sent by the client. We don't send multiple
2937 * addresses, so this indicates a client error.
2938 * We should check for multiple IAADDR options, log
2939 * if found, and set as an error.
2941 oc
= lookup_option(&dhcpv6_universe
, cli_enc_opt_state
,
2944 /* no address given for this IA, ignore */
2945 option_state_dereference(&cli_enc_opt_state
, MDL
);
2946 data_string_forget(&cli_enc_opt_data
, MDL
);
2950 memset(&iaaddr
, 0, sizeof(iaaddr
));
2951 if (!evaluate_option_cache(&iaaddr
, packet
, NULL
, NULL
,
2952 packet
->options
, NULL
,
2953 &global_scope
, oc
, MDL
)) {
2954 log_error("iterate_over_ia_na: "
2955 "error evaluating IAADDR.");
2960 * Now we need to figure out which host record matches
2961 * this IA_NA and IAADDR.
2963 * XXX: We don't currently track IA_NA separately, but
2964 * we will need to do this!
2967 if (!find_hosts_by_option(&host
, packet
,
2968 cli_enc_opt_state
, MDL
)) {
2969 if (packet_host
!= NULL
) {
2975 while (host
!= NULL
) {
2976 if (host
->fixed_addr
!= NULL
) {
2977 if (!evaluate_option_cache(&fixed_addr
, NULL
,
2979 NULL
, &global_scope
,
2982 log_error("iterate_over_ia_na: error "
2983 "evaluating host address.");
2986 if ((iaaddr
.len
>= 16) &&
2987 !memcmp(fixed_addr
.data
, iaaddr
.data
, 16)) {
2988 data_string_forget(&fixed_addr
, MDL
);
2991 data_string_forget(&fixed_addr
, MDL
);
2993 host
= host
->n_ipaddr
;
2996 if ((host
== NULL
) && (iaaddr
.len
>= IAADDR_OFFSET
)) {
2998 * Find existing IA_NA.
3000 if (ia_make_key(&key
, iaid
,
3001 (char *)client_id
->data
,
3003 MDL
) != ISC_R_SUCCESS
) {
3004 log_fatal("iterate_over_ia_na: no memory for "
3008 existing_ia_na
= NULL
;
3009 if (ia_na_hash_lookup(&existing_ia_na
, ia_na_active
,
3010 (unsigned char *)key
.data
,
3013 * Make sure this address is in the IA_NA.
3015 for (i
=0; i
<existing_ia_na
->num_iaaddr
; i
++) {
3017 struct in6_addr
*in6_addr
;
3019 tmp
= existing_ia_na
->iaaddr
[i
];
3020 in6_addr
= &tmp
->addr
;
3021 if (memcmp(in6_addr
,
3022 iaaddr
.data
, 16) == 0) {
3023 iaaddr_reference(&lease
,
3030 data_string_forget(&key
, MDL
);
3033 if ((host
!= NULL
) || (lease
!= NULL
)) {
3034 ia_na_match(client_id
, &iaaddr
, lease
);
3036 ia_na_nomatch(client_id
, &iaaddr
,
3037 (u_int32_t
*)cli_enc_opt_data
.data
,
3038 packet
, reply_data
, &reply_ofs
,
3039 sizeof(reply_data
));
3042 if (lease
!= NULL
) {
3043 iaaddr_dereference(&lease
, MDL
);
3046 data_string_forget(&iaaddr
, MDL
);
3047 option_state_dereference(&cli_enc_opt_state
, MDL
);
3048 data_string_forget(&cli_enc_opt_data
, MDL
);
3052 * Return our reply to the caller.
3054 reply_ret
->len
= reply_ofs
;
3055 reply_ret
->buffer
= NULL
;
3056 if (!buffer_allocate(&reply_ret
->buffer
, reply_ofs
, MDL
)) {
3057 log_fatal("No memory to store reply.");
3059 reply_ret
->data
= reply_ret
->buffer
->data
;
3060 memcpy(reply_ret
->buffer
->data
, reply
, reply_ofs
);
3063 if (lease
!= NULL
) {
3064 iaaddr_dereference(&lease
, MDL
);
3066 if (host_opt_state
!= NULL
) {
3067 option_state_dereference(&host_opt_state
, MDL
);
3069 if (fixed_addr
.buffer
!= NULL
) {
3070 data_string_forget(&fixed_addr
, MDL
);
3072 if (iaaddr
.buffer
!= NULL
) {
3073 data_string_forget(&iaaddr
, MDL
);
3075 if (cli_enc_opt_state
!= NULL
) {
3076 option_state_dereference(&cli_enc_opt_state
, MDL
);
3078 if (cli_enc_opt_data
.buffer
!= NULL
) {
3079 data_string_forget(&cli_enc_opt_data
, MDL
);
3081 if (opt_state
!= NULL
) {
3082 option_state_dereference(&opt_state
, MDL
);
3087 * Decline means a client has detected that something else is using an
3088 * address we gave it.
3090 * Since we're only dealing with fixed leases for now, there's not
3091 * much we can do, other that log the occurrence.
3093 * When we start issuing addresses from pools, then we will have to
3094 * record our declined addresses and issue another. In general with
3095 * IPv6 there is no worry about DoS by clients exhausting space, but
3096 * we still need to be aware of this possibility.
3099 /* TODO: reject unicast messages, unless we set unicast option */
3102 dhcpv6_decline(struct data_string
*reply
, struct packet
*packet
) {
3103 struct data_string client_id
;
3104 struct data_string server_id
;
3107 * Validate our input.
3109 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
3114 * And operate on each IA_NA in this packet.
3116 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
, "Decline",
3117 ia_na_match_decline
, ia_na_nomatch_decline
);
3121 ia_na_match_release(const struct data_string
*client_id
,
3122 const struct data_string
*iaaddr
,
3123 struct iaaddr
*lease
)
3125 char tmp_addr
[INET6_ADDRSTRLEN
];
3127 log_info("Client %s releases address %s",
3128 print_hex_1(client_id
->len
, client_id
->data
, 60),
3129 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
3130 if (lease
!= NULL
) {
3131 release_lease6(lease
->ipv6_pool
, lease
);
3132 write_ia(lease
->ia_na
);
3137 ia_na_nomatch_release(const struct data_string
*client_id
,
3138 const struct data_string
*iaaddr
,
3139 u_int32_t
*ia_na_id
,
3140 struct packet
*packet
,
3145 char tmp_addr
[INET6_ADDRSTRLEN
];
3146 struct option_state
*host_opt_state
;
3149 log_info("Client %s releases address %s, which is not leased to it.",
3150 print_hex_1(client_id
->len
, client_id
->data
, 60),
3151 inet_ntop(AF_INET6
, iaaddr
->data
, tmp_addr
, sizeof(tmp_addr
)));
3154 * Create state for this IA_NA.
3156 host_opt_state
= NULL
;
3157 if (!option_state_allocate(&host_opt_state
, MDL
)) {
3158 log_error("ia_na_nomatch_release: out of memory "
3159 "allocating option_state.");
3163 if (!set_status_code(STATUS_NoBinding
,
3164 "Release for non-leased address.",
3170 * Insure we have enough space
3172 if (reply_len
< (*reply_ofs
+ 16)) {
3173 log_error("ia_na_nomatch_release: "
3174 "out of space for reply packet.");
3179 * Put our status code into the reply packet.
3181 len
= store_options6(reply_data
+(*reply_ofs
)+16,
3182 reply_len
-(*reply_ofs
)-16,
3183 host_opt_state
, packet
,
3184 required_opts_STATUS_CODE
, NULL
);
3187 * Store the non-encapsulated option data for this
3188 * IA_NA into our reply packet. Defined in RFC 3315,
3192 putUShort((unsigned char *)reply_data
+(*reply_ofs
), D6O_IA_NA
);
3194 putUShort((unsigned char *)reply_data
+(*reply_ofs
)+2, len
+ 12);
3195 /* IA_NA, copied from the client */
3196 memcpy(reply_data
+(*reply_ofs
)+4, ia_na_id
, 4);
3197 /* t1 and t2, odd that we need them, but here it is */
3198 putULong((unsigned char *)reply_data
+(*reply_ofs
)+8, 0);
3199 putULong((unsigned char *)reply_data
+(*reply_ofs
)+12, 0);
3202 * Get ready for next IA_NA.
3204 *reply_ofs
+= (len
+ 16);
3207 option_state_dereference(&host_opt_state
, MDL
);
3211 * Release means a client is done with the addresses.
3214 /* TODO: reject unicast messages, unless we set unicast option */
3216 dhcpv6_release(struct data_string
*reply
, struct packet
*packet
) {
3217 struct data_string client_id
;
3218 struct data_string server_id
;
3221 * Validate our input.
3223 if (!valid_client_resp(packet
, &client_id
, &server_id
)) {
3228 * And operate on each IA_NA in this packet.
3230 iterate_over_ia_na(reply
, packet
, &client_id
, &server_id
, "Release",
3231 ia_na_match_release
, ia_na_nomatch_release
);
3233 data_string_forget(&server_id
, MDL
);
3234 data_string_forget(&client_id
, MDL
);
3238 * Information-Request is used by clients who have obtained an address
3239 * from other means, but want configuration information from the server.
3243 dhcpv6_information_request(struct data_string
*reply
, struct packet
*packet
) {
3244 struct data_string client_id
;
3245 struct data_string server_id
;
3248 * Validate our input.
3250 if (!valid_client_info_req(packet
, &server_id
)) {
3255 * Get our client ID, if there is one.
3257 memset(&client_id
, 0, sizeof(client_id
));
3258 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
) {
3259 data_string_forget(&client_id
, MDL
);
3263 * Use the lease_to_client() function. This will work fine,
3264 * because the valid_client_info_req() insures that we
3265 * don't have any IA_NA or IA_TA that would cause us to
3266 * allocate addresses to the client.
3268 lease_to_client(reply
, packet
, &client_id
,
3269 server_id
.data
!= NULL
? &server_id
: NULL
);
3274 if (client_id
.data
!= NULL
) {
3275 data_string_forget(&client_id
, MDL
);
3277 data_string_forget(&server_id
, MDL
);
3281 * The Relay-forw message is sent by relays. It typically contains a
3282 * single option, which encapsulates an entire packet.
3284 * We need to build an encapsulated reply.
3287 /* XXX: this is very, very similar to do_packet6(), and should probably
3288 be combined in a clever way */
3290 dhcpv6_relay_forw(struct data_string
*reply_ret
, struct packet
*packet
) {
3291 struct dhcpv6_relay_packet reply
;
3292 struct option_cache
*oc
;
3293 struct data_string enc_opt_data
;
3294 struct packet
*enc_packet
;
3295 unsigned char msg_type
;
3296 const struct dhcpv6_packet
*msg
;
3297 const struct dhcpv6_relay_packet
*relay
;
3298 struct data_string enc_reply
;
3299 char link_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
3300 char peer_addr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
3301 struct data_string interface_id
;
3304 * Initialize variables for early exit.
3306 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
3308 memset(&enc_reply
, 0, sizeof(enc_reply
));
3309 memset(&interface_id
, 0, sizeof(interface_id
));
3312 * Get our encapsulated relay message.
3314 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_RELAY_MSG
);
3316 inet_ntop(AF_INET6
, &packet
->dhcpv6_link_address
,
3317 link_addr
, sizeof(link_addr
));
3318 inet_ntop(AF_INET6
, &packet
->dhcpv6_peer_address
,
3319 peer_addr
, sizeof(peer_addr
));
3320 log_info("Relay-forward from %s with link address=%s and "
3321 "peer address=%s missing Relay Message option.",
3322 piaddr(packet
->client_addr
), link_addr
, peer_addr
);
3326 memset(&enc_opt_data
, 0, sizeof(enc_opt_data
));
3327 if (!evaluate_option_cache(&enc_opt_data
, NULL
, NULL
, NULL
,
3328 NULL
, NULL
, &global_scope
, oc
, MDL
)) {
3329 log_error("dhcpv6_forw_relay: error evaluating "
3330 "relayed message.");
3334 if (!packet6_len_okay((char *)enc_opt_data
.data
, enc_opt_data
.len
)) {
3335 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
3340 * Build a packet structure from this encapsulated packet.
3343 if (!packet_allocate(&enc_packet
, MDL
)) {
3344 log_error("dhcpv6_forw_relay: "
3345 "no memory for encapsulated packet.");
3349 if (!option_state_allocate(&enc_packet
->options
, MDL
)) {
3350 log_error("dhcpv6_forw_relay: "
3351 "no memory for encapsulated packet's options.");
3355 enc_packet
->client_port
= packet
->client_port
;
3356 enc_packet
->client_addr
= packet
->client_addr
;
3357 enc_packet
->dhcpv6_container_packet
= packet
;
3359 msg_type
= enc_opt_data
.data
[0];
3360 if ((msg_type
== DHCPV6_RELAY_FORW
) ||
3361 (msg_type
== DHCPV6_RELAY_REPL
)) {
3362 relay
= (struct dhcpv6_relay_packet
*)enc_opt_data
.data
;
3363 enc_packet
->dhcpv6_msg_type
= relay
->msg_type
;
3365 /* relay-specific data */
3366 enc_packet
->dhcpv6_hop_count
= relay
->hop_count
;
3367 memcpy(&enc_packet
->dhcpv6_link_address
,
3368 relay
->link_address
, sizeof(relay
->link_address
));
3369 memcpy(&enc_packet
->dhcpv6_peer_address
,
3370 relay
->peer_address
, sizeof(relay
->peer_address
));
3372 if (!parse_option_buffer(enc_packet
->options
,
3374 enc_opt_data
.len
-sizeof(*relay
),
3375 &dhcpv6_universe
)) {
3376 /* no logging here, as parse_option_buffer() logs all
3377 cases where it fails */
3381 msg
= (struct dhcpv6_packet
*)enc_opt_data
.data
;
3382 enc_packet
->dhcpv6_msg_type
= msg
->msg_type
;
3384 /* message-specific data */
3385 memcpy(enc_packet
->dhcpv6_transaction_id
,
3386 msg
->transaction_id
,
3387 sizeof(enc_packet
->dhcpv6_transaction_id
));
3389 if (!parse_option_buffer(enc_packet
->options
,
3391 enc_opt_data
.len
-sizeof(*msg
),
3392 &dhcpv6_universe
)) {
3393 /* no logging here, as parse_option_buffer() logs all
3394 cases where it fails */
3400 * This is recursive. It is possible to exceed maximum packet size.
3401 * XXX: This will cause the packet send to fail.
3403 build_dhcpv6_reply(&enc_reply
, enc_packet
);
3406 * If we got no encapsulated data, then it is discarded, and
3407 * our reply-forw is also discarded.
3409 if (enc_reply
.data
== NULL
) {
3414 * Append the interface-id if present
3416 oc
= lookup_option(&dhcpv6_universe
, packet
->options
, D6O_INTERFACE_ID
);
3418 memset(&interface_id
, 0, sizeof(interface_id
));
3419 if (!evaluate_option_cache(&interface_id
, NULL
, NULL
, NULL
,
3420 NULL
, NULL
, &global_scope
,
3422 log_error("dhcpv6_forw_relay: error evaluating "
3429 * Packet header stuff all comes from the forward message.
3431 reply
.msg_type
= DHCPV6_RELAY_REPL
;
3432 reply
.hop_count
= packet
->dhcpv6_hop_count
;
3433 memcpy(reply
.link_address
, &packet
->dhcpv6_link_address
,
3434 sizeof(reply
.link_address
));
3435 memcpy(reply
.peer_address
, &packet
->dhcpv6_peer_address
,
3436 sizeof(reply
.peer_address
));
3439 * Copy our encapsulated stuff for caller.
3441 reply_ret
->len
= sizeof(reply
) + 4 + enc_reply
.len
;
3442 if (interface_id
.data
!= NULL
) {
3443 reply_ret
->len
+= 4 + interface_id
.len
;
3446 * XXX: We should not allow this to happen, perhaps by letting
3447 * build_dhcp_reply() know our space remaining.
3449 if (reply_ret
->len
>= 65536) {
3450 log_error("dhcpv6_forw_relay: RELAY-REPL too big (%d bytes)",
3454 reply_ret
->buffer
= NULL
;
3455 if (!buffer_allocate(&reply_ret
->buffer
, reply_ret
->len
, MDL
)) {
3456 log_fatal("No memory to store reply.");
3458 reply_ret
->data
= reply_ret
->buffer
->data
;
3459 memcpy(reply_ret
->buffer
->data
, &reply
, sizeof(reply
));
3460 putShort(reply_ret
->buffer
->data
+sizeof(reply
), D6O_RELAY_MSG
);
3461 putShort(reply_ret
->buffer
->data
+sizeof(reply
)+2, enc_reply
.len
);
3462 memcpy(reply_ret
->buffer
->data
+sizeof(reply
)+4,
3463 enc_reply
.data
, enc_reply
.len
);
3464 if (interface_id
.data
!= NULL
) {
3465 putShort(reply_ret
->buffer
->data
+sizeof(reply
)+4+enc_reply
.len
,
3467 putShort(reply_ret
->buffer
->data
+sizeof(reply
)+6+enc_reply
.len
,
3469 memcpy(reply_ret
->buffer
->data
+sizeof(reply
)+8+enc_reply
.len
,
3470 interface_id
.data
, interface_id
.len
);
3474 if (interface_id
.data
!= NULL
) {
3475 data_string_forget(&interface_id
, MDL
);
3477 if (enc_reply
.data
!= NULL
) {
3478 data_string_forget(&enc_reply
, MDL
);
3480 if (enc_opt_data
.data
!= NULL
) {
3481 data_string_forget(&enc_opt_data
, MDL
);
3483 if (enc_packet
!= NULL
) {
3484 packet_dereference(&enc_packet
, MDL
);
3489 dhcpv6_discard(struct packet
*packet
) {
3490 /* INSIST(packet->msg_type > 0); */
3491 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
3493 log_debug("Discarding %s from %s; message type not handled by server",
3494 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
3495 piaddr(packet
->client_addr
));
3499 build_dhcpv6_reply(struct data_string
*reply
, struct packet
*packet
) {
3500 memset(reply
, 0, sizeof(*reply
));
3501 switch (packet
->dhcpv6_msg_type
) {
3502 case DHCPV6_SOLICIT
:
3503 dhcpv6_solicit(reply
, packet
);
3505 case DHCPV6_ADVERTISE
:
3506 dhcpv6_discard(packet
);
3508 case DHCPV6_REQUEST
:
3509 dhcpv6_request(reply
, packet
);
3511 case DHCPV6_CONFIRM
:
3512 dhcpv6_confirm(reply
, packet
);
3515 dhcpv6_renew(reply
, packet
);
3518 dhcpv6_rebind(reply
, packet
);
3521 dhcpv6_discard(packet
);
3523 case DHCPV6_RELEASE
:
3524 dhcpv6_release(reply
, packet
);
3526 case DHCPV6_DECLINE
:
3527 dhcpv6_decline(reply
, packet
);
3529 case DHCPV6_RECONFIGURE
:
3530 dhcpv6_discard(packet
);
3532 case DHCPV6_INFORMATION_REQUEST
:
3533 dhcpv6_information_request(reply
, packet
);
3535 case DHCPV6_RELAY_FORW
:
3536 dhcpv6_relay_forw(reply
, packet
);
3538 case DHCPV6_RELAY_REPL
:
3539 dhcpv6_discard(packet
);
3542 /* XXX: would be nice if we had "notice" level,
3543 as syslog, for this */
3544 log_info("Discarding unknown DHCPv6 message type %d "
3545 "from %s", packet
->dhcpv6_msg_type
,
3546 piaddr(packet
->client_addr
));
3551 log_packet_in(const struct packet
*packet
) {
3552 struct data_string s
;
3554 char tmp_addr
[INET6_ADDRSTRLEN
];
3557 memset(&s
, 0, sizeof(s
));
3559 if (packet
->dhcpv6_msg_type
< dhcpv6_type_name_max
) {
3560 data_string_sprintfa(&s
, "%s message from %s port %d",
3561 dhcpv6_type_names
[packet
->dhcpv6_msg_type
],
3562 piaddr(packet
->client_addr
),
3563 ntohs(packet
->client_port
));
3565 data_string_sprintfa(&s
,
3566 "Unknown message type %d from %s port %d",
3567 packet
->dhcpv6_msg_type
,
3568 piaddr(packet
->client_addr
),
3569 ntohs(packet
->client_port
));
3571 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
3572 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
3573 addr
= &packet
->dhcpv6_link_address
;
3574 data_string_sprintfa(&s
, ", link address %s",
3575 inet_ntop(AF_INET6
, addr
,
3576 tmp_addr
, sizeof(tmp_addr
)));
3577 addr
= &packet
->dhcpv6_peer_address
;
3578 data_string_sprintfa(&s
, ", peer address %s",
3579 inet_ntop(AF_INET6
, addr
,
3580 tmp_addr
, sizeof(tmp_addr
)));
3583 memcpy(((char *)&tid
)+1, packet
->dhcpv6_transaction_id
, 3);
3584 data_string_sprintfa(&s
, ", transaction ID 0x%06X", tid
);
3587 oc = lookup_option(&dhcpv6_universe, packet->options,
3590 memset(&tmp_ds, 0, sizeof(tmp_ds_));
3591 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
3592 packet->options, NULL,
3593 &global_scope, oc, MDL)) {
3594 log_error("Error evaluating Client Identifier");
3596 data_strint_sprintf(&s, ", client ID %s",
3598 data_string_forget(&tmp_ds, MDL);
3604 log_info("%s", s
.data
);
3606 data_string_forget(&s
, MDL
);
3610 dhcpv6(struct packet
*packet
) {
3611 struct data_string reply
;
3612 struct sockaddr_in6 to_addr
;
3616 * Log a message that we received this packet.
3618 log_packet_in(packet
);
3621 * Build our reply packet.
3623 build_dhcpv6_reply(&reply
, packet
);
3625 if (reply
.data
!= NULL
) {
3627 * Send our reply, if we have one.
3629 memset(&to_addr
, 0, sizeof(to_addr
));
3630 to_addr
.sin6_family
= AF_INET6
;
3631 if ((packet
->dhcpv6_msg_type
== DHCPV6_RELAY_FORW
) ||
3632 (packet
->dhcpv6_msg_type
== DHCPV6_RELAY_REPL
)) {
3633 to_addr
.sin6_port
= local_port
;
3635 to_addr
.sin6_port
= remote_port
;
3637 /* For testing, we reply to the sending port, so we don't need a root client */
3638 to_addr
.sin6_port
= packet
->client_port
;
3639 memcpy(&to_addr
.sin6_addr
, packet
->client_addr
.iabuf
,
3640 sizeof(to_addr
.sin6_addr
));
3642 log_info("Sending %s to %s port %d",
3643 dhcpv6_type_names
[reply
.data
[0]],
3644 piaddr(packet
->client_addr
),
3645 ntohs(to_addr
.sin6_port
));
3647 send_ret
= send_packet6(packet
->interface
,
3648 reply
.data
, reply
.len
, &to_addr
);
3649 if (send_ret
!= reply
.len
) {
3650 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
3651 send_ret
, reply
.len
);
3653 data_string_forget(&reply
, MDL
);
3658 seek_shared_host(struct host_decl
**hp
, struct shared_network
*shared
) {
3659 struct host_decl
*nofixed
= NULL
;
3660 struct host_decl
*seek
, *hold
= NULL
;
3663 * Seek forward through fixed addresses for the right broadcast
3666 host_reference(&hold
, *hp
, MDL
);
3667 host_dereference(hp
, MDL
);
3669 while (seek
!= NULL
) {
3670 if (seek
->fixed_addr
== NULL
)
3672 else if (fixed_matches_shared(seek
, shared
))
3675 seek
= seek
->n_ipaddr
;
3678 if ((seek
== NULL
) && (nofixed
!= NULL
))
3682 host_reference(hp
, seek
, MDL
);
3685 static isc_boolean_t
3686 fixed_matches_shared(struct host_decl
*host
, struct shared_network
*shared
) {
3687 struct subnet
*subnet
;
3688 struct data_string addr
;
3689 isc_boolean_t matched
;
3692 if (host
->fixed_addr
== NULL
)
3695 memset(&addr
, 0, sizeof(addr
));
3696 if (!evaluate_option_cache(&addr
, NULL
, NULL
, NULL
, NULL
, NULL
,
3697 &global_scope
, host
->fixed_addr
, MDL
))
3700 if (addr
.len
< 16) {
3701 data_string_forget(&addr
, MDL
);
3706 memcpy(fixed
.iabuf
, addr
.data
, 16);
3708 matched
= ISC_FALSE
;
3709 for (subnet
= shared
->subnets
; subnet
!= NULL
;
3710 subnet
= subnet
->next_sibling
) {
3711 if (addr_eq(subnet_number(fixed
, subnet
->netmask
),
3718 data_string_forget(&addr
, MDL
);