2
* Copyright (C) 2006-2008 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 */
53
unsigned client_resources;
54
isc_boolean_t resources_included;
55
isc_boolean_t static_lease;
56
unsigned static_prefixes;
59
struct option_state *reply_ia;
60
struct data_string fixed;
62
/* IAADDR/PREFIX level persistent state */
63
struct iasubopt *lease;
66
* "t1", "t2", preferred, and valid lifetimes records for calculating
67
* t1 and t2 (min/max).
69
u_int32_t renew, rebind, prefer, valid;
71
/* Client-requested valid and preferred lifetimes. */
72
u_int32_t client_valid, client_prefer;
74
/* Chosen values to transmit for valid and preferred lifetimes. */
75
u_int32_t send_valid, send_prefer;
77
/* Preferred prefix length (-1 is any). */
80
/* Index into the data field that has been consumed. */
84
unsigned char data[65536];
85
struct dhcpv6_packet reply;
90
* Prototypes local to this file.
92
static int get_encapsulated_IA_state(struct option_state **enc_opt_state,
93
struct data_string *enc_opt_data,
94
struct packet *packet,
95
struct option_cache *oc,
97
static void build_dhcpv6_reply(struct data_string *, struct packet *);
98
static isc_result_t shared_network_from_packet6(struct shared_network **shared,
99
struct packet *packet);
100
static void seek_shared_host(struct host_decl **hp,
101
struct shared_network *shared);
102
static isc_boolean_t fixed_matches_shared(struct host_decl *host,
103
struct shared_network *shared);
104
static isc_result_t reply_process_ia_na(struct reply_state *reply,
105
struct option_cache *ia);
106
static isc_result_t reply_process_ia_ta(struct reply_state *reply,
107
struct option_cache *ia);
108
static isc_result_t reply_process_addr(struct reply_state *reply,
109
struct option_cache *addr);
110
static isc_boolean_t address_is_owned(struct reply_state *reply,
112
static isc_boolean_t temporary_is_available(struct reply_state *reply,
114
static isc_result_t find_client_temporaries(struct reply_state *reply);
115
static isc_result_t reply_process_try_addr(struct reply_state *reply,
117
static isc_result_t find_client_address(struct reply_state *reply);
118
static isc_result_t reply_process_is_addressed(struct reply_state *reply,
119
struct binding_scope **scope,
120
struct group *group);
121
static isc_result_t reply_process_send_addr(struct reply_state *reply,
123
static struct iasubopt *lease_compare(struct iasubopt *alpha,
124
struct iasubopt *beta);
125
static isc_result_t reply_process_ia_pd(struct reply_state *reply,
126
struct option_cache *ia_pd);
127
static isc_result_t reply_process_prefix(struct reply_state *reply,
128
struct option_cache *pref);
129
static isc_boolean_t prefix_is_owned(struct reply_state *reply,
130
struct iaddrcidrnet *pref);
131
static isc_result_t find_client_prefix(struct reply_state *reply);
132
static isc_result_t reply_process_try_prefix(struct reply_state *reply,
133
struct iaddrcidrnet *pref);
134
static isc_result_t reply_process_is_prefixed(struct reply_state *reply,
135
struct binding_scope **scope,
136
struct group *group);
137
static isc_result_t reply_process_send_prefix(struct reply_state *reply,
138
struct iaddrcidrnet *pref);
139
static struct iasubopt *prefix_compare(struct reply_state *reply,
140
struct iasubopt *alpha,
141
struct iasubopt *beta);
144
* This function returns the time since DUID time start for the
145
* given time_t value.
148
duid_time(time_t when) {
150
* This time is modulo 2^32.
152
while ((when - DUID_TIME_EPOCH) > 4294967295u) {
153
/* use 2^31 to avoid spurious compiler warnings */
158
return when - DUID_TIME_EPOCH;
165
* This must remain the same for the lifetime of this server, because
166
* clients return the server DUID that we sent them in Request packets.
168
* We pick the server DUID like this:
170
* 1. Check dhcpd.conf - any value the administrator has configured
171
* overrides any possible values.
172
* 2. Check the leases.txt - we want to use the previous value if
174
* 3. Check if dhcpd.conf specifies a type of server DUID to use,
175
* and generate that type.
176
* 4. Generate a type 1 (time + hardware address) DUID.
178
static struct data_string server_duid;
181
* Check if the server_duid has been set.
184
server_duid_isset(void) {
185
return (server_duid.data != NULL);
189
* Return the server_duid.
192
copy_server_duid(struct data_string *ds, const char *file, int line) {
193
data_string_copy(ds, &server_duid, file, line);
197
* Set the server DUID to a specified value. This is used when
198
* the server DUID is stored in persistent memory (basically the
202
set_server_duid(struct data_string *new_duid) {
203
/* INSIST(new_duid != NULL); */
204
/* INSIST(new_duid->data != NULL); */
206
if (server_duid_isset()) {
207
data_string_forget(&server_duid, MDL);
209
data_string_copy(&server_duid, new_duid, MDL);
214
* Set the server DUID based on the D6O_SERVERID option. This handles
215
* the case where the administrator explicitly put it in the dhcpd.conf
219
set_server_duid_from_option(void) {
220
struct option_state *opt_state;
221
struct option_cache *oc;
222
struct data_string option_duid;
223
isc_result_t ret_val;
226
if (!option_state_allocate(&opt_state, MDL)) {
227
log_fatal("No memory for server DUID.");
230
execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL,
231
opt_state, &global_scope, root_group, NULL);
233
oc = lookup_option(&dhcpv6_universe, opt_state, D6O_SERVERID);
235
ret_val = ISC_R_NOTFOUND;
237
memset(&option_duid, 0, sizeof(option_duid));
238
if (!evaluate_option_cache(&option_duid, NULL, NULL, NULL,
239
opt_state, NULL, &global_scope,
241
ret_val = ISC_R_UNEXPECTED;
243
set_server_duid(&option_duid);
244
data_string_forget(&option_duid, MDL);
245
ret_val = ISC_R_SUCCESS;
249
option_state_dereference(&opt_state, MDL);
255
* DUID layout, as defined in RFC 3315, section 9.
257
* We support type 1 (hardware address plus time) and type 3 (hardware
260
* We can support type 2 for specific vendors in the future, if they
261
* publish the specification. And of course there may be additional
264
static int server_duid_type = DUID_LLT;
270
set_server_duid_type(int type) {
271
server_duid_type = type;
275
* Generate a new server DUID. This is done if there was no DUID in
276
* the leases.txt or in the dhcpd.conf file.
279
generate_new_server_duid(void) {
280
struct interface_info *p;
282
struct data_string generated_duid;
285
* Verify we have a type that we support.
287
if ((server_duid_type != DUID_LL) && (server_duid_type != DUID_LLT)) {
288
log_error("Invalid DUID type %d specified, "
289
"only LL and LLT types supported", server_duid_type);
290
return ISC_R_INVALIDARG;
294
* Find an interface with a hardware address.
297
for (p = interfaces; p != NULL; p = p->next) {
298
if (p->hw_address.hlen > 0) {
303
return ISC_R_UNEXPECTED;
309
memset(&generated_duid, 0, sizeof(generated_duid));
310
if (server_duid_type == DUID_LLT) {
311
time_val = duid_time(time(NULL));
312
generated_duid.len = 8 + p->hw_address.hlen - 1;
313
if (!buffer_allocate(&generated_duid.buffer,
314
generated_duid.len, MDL)) {
315
log_fatal("No memory for server DUID.");
317
generated_duid.data = generated_duid.buffer->data;
318
putUShort(generated_duid.buffer->data, DUID_LLT);
319
putUShort(generated_duid.buffer->data + 2,
320
p->hw_address.hbuf[0]);
321
putULong(generated_duid.buffer->data + 4, time_val);
322
memcpy(generated_duid.buffer->data + 8,
323
p->hw_address.hbuf+1, p->hw_address.hlen-1);
324
} else if (server_duid_type == DUID_LL) {
325
generated_duid.len = 4 + p->hw_address.hlen - 1;
326
if (!buffer_allocate(&generated_duid.buffer,
327
generated_duid.len, MDL)) {
328
log_fatal("No memory for server DUID.");
330
generated_duid.data = generated_duid.buffer->data;
331
putUShort(generated_duid.buffer->data, DUID_LL);
332
putUShort(generated_duid.buffer->data + 2,
333
p->hw_address.hbuf[0]);
334
memcpy(generated_duid.buffer->data + 4,
335
p->hw_address.hbuf+1, p->hw_address.hlen-1);
337
log_fatal("Unsupported server DUID type %d.", server_duid_type);
340
set_server_duid(&generated_duid);
341
data_string_forget(&generated_duid, MDL);
343
return ISC_R_SUCCESS;
347
* Get the client identifier from the packet.
350
get_client_id(struct packet *packet, struct data_string *client_id) {
351
struct option_cache *oc;
354
* Verify our client_id structure is empty.
356
if ((client_id->data != NULL) || (client_id->len != 0)) {
357
return ISC_R_INVALIDARG;
360
oc = lookup_option(&dhcpv6_universe, packet->options, D6O_CLIENTID);
362
return ISC_R_NOTFOUND;
365
if (!evaluate_option_cache(client_id, packet, NULL, NULL,
366
packet->options, NULL,
367
&global_scope, oc, MDL)) {
368
return ISC_R_FAILURE;
371
return ISC_R_SUCCESS;
375
* Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
377
* Servers MUST discard any Solicit messages that do not include a
378
* Client Identifier option or that do include a Server Identifier
382
valid_client_msg(struct packet *packet, struct data_string *client_id) {
384
struct option_cache *oc;
385
struct data_string data;
388
memset(client_id, 0, sizeof(*client_id));
389
memset(&data, 0, sizeof(data));
391
switch (get_client_id(packet, client_id)) {
395
log_debug("Discarding %s from %s; "
396
"client identifier missing",
397
dhcpv6_type_names[packet->dhcpv6_msg_type],
398
piaddr(packet->client_addr));
401
log_error("Error processing %s from %s; "
402
"unable to evaluate Client Identifier",
403
dhcpv6_type_names[packet->dhcpv6_msg_type],
404
piaddr(packet->client_addr));
409
* Required by RFC 3315, section 15.
411
if (packet->unicast) {
412
log_debug("Discarding %s from %s; packet sent unicast "
414
dhcpv6_type_names[packet->dhcpv6_msg_type],
415
piaddr(packet->client_addr),
416
print_hex_1(client_id->len, client_id->data, 60));
421
oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
423
if (evaluate_option_cache(&data, packet, NULL, NULL,
424
packet->options, NULL,
425
&global_scope, oc, MDL)) {
426
log_debug("Discarding %s from %s; "
427
"server identifier found "
428
"(CLIENTID %s, SERVERID %s)",
429
dhcpv6_type_names[packet->dhcpv6_msg_type],
430
piaddr(packet->client_addr),
431
print_hex_1(client_id->len,
432
client_id->data, 60),
433
print_hex_2(data.len,
436
log_debug("Discarding %s from %s; "
437
"server identifier found "
439
dhcpv6_type_names[packet->dhcpv6_msg_type],
440
print_hex_1(client_id->len,
441
client_id->data, 60),
442
piaddr(packet->client_addr));
452
data_string_forget(&data, MDL);
455
if (client_id->len > 0) {
456
data_string_forget(client_id, MDL);
463
* Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
464
* 15.9 (slightly different wording, but same meaning):
466
* Servers MUST discard any received Request message that meet any of
467
* the following conditions:
469
* - the message does not include a Server Identifier option.
470
* - the contents of the Server Identifier option do not match the
472
* - the message does not include a Client Identifier option.
475
valid_client_resp(struct packet *packet,
476
struct data_string *client_id,
477
struct data_string *server_id)
480
struct option_cache *oc;
482
/* INSIST((duid.data != NULL) && (duid.len > 0)); */
485
memset(client_id, 0, sizeof(*client_id));
486
memset(server_id, 0, sizeof(*server_id));
488
switch (get_client_id(packet, client_id)) {
492
log_debug("Discarding %s from %s; "
493
"client identifier missing",
494
dhcpv6_type_names[packet->dhcpv6_msg_type],
495
piaddr(packet->client_addr));
498
log_error("Error processing %s from %s; "
499
"unable to evaluate Client Identifier",
500
dhcpv6_type_names[packet->dhcpv6_msg_type],
501
piaddr(packet->client_addr));
505
oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
507
log_debug("Discarding %s from %s: "
508
"server identifier missing (CLIENTID %s)",
509
dhcpv6_type_names[packet->dhcpv6_msg_type],
510
piaddr(packet->client_addr),
511
print_hex_1(client_id->len, client_id->data, 60));
514
if (!evaluate_option_cache(server_id, packet, NULL, NULL,
515
packet->options, NULL,
516
&global_scope, oc, MDL)) {
517
log_error("Error processing %s from %s; "
518
"unable to evaluate Server Identifier (CLIENTID %s)",
519
dhcpv6_type_names[packet->dhcpv6_msg_type],
520
piaddr(packet->client_addr),
521
print_hex_1(client_id->len, client_id->data, 60));
524
if ((server_duid.len != server_id->len) ||
525
(memcmp(server_duid.data, server_id->data, server_duid.len) != 0)) {
526
log_debug("Discarding %s from %s; "
527
"not our server identifier "
528
"(CLIENTID %s, SERVERID %s, server DUID %s)",
529
dhcpv6_type_names[packet->dhcpv6_msg_type],
530
piaddr(packet->client_addr),
531
print_hex_1(client_id->len, client_id->data, 60),
532
print_hex_2(server_id->len, server_id->data, 60),
533
print_hex_3(server_duid.len, server_duid.data, 60));
542
if (server_id->len > 0) {
543
data_string_forget(server_id, MDL);
545
if (client_id->len > 0) {
546
data_string_forget(client_id, MDL);
553
* Information request validation, defined in RFC 3315, section 15.12:
555
* Servers MUST discard any received Information-request message that
556
* meets any of the following conditions:
558
* - The message includes a Server Identifier option and the DUID in
559
* the option does not match the server's DUID.
561
* - The message includes an IA option.
564
valid_client_info_req(struct packet *packet, struct data_string *server_id) {
566
struct option_cache *oc;
567
struct data_string client_id;
568
char client_id_str[80]; /* print_hex_1() uses maximum 60 characters,
569
plus a few more for extra information */
572
memset(server_id, 0, sizeof(*server_id));
575
* Make a string that we can print out to give more
576
* information about the client if we need to.
578
* By RFC 3315, Section 18.1.5 clients SHOULD have a
579
* client-id on an Information-request packet, but it
580
* is not strictly necessary.
582
if (get_client_id(packet, &client_id) == ISC_R_SUCCESS) {
583
snprintf(client_id_str, sizeof(client_id_str), " (CLIENTID %s)",
584
print_hex_1(client_id.len, client_id.data, 60));
585
data_string_forget(&client_id, MDL);
587
client_id_str[0] = '\0';
591
* Required by RFC 3315, section 15.
593
if (packet->unicast) {
594
log_debug("Discarding %s from %s; packet sent unicast%s",
595
dhcpv6_type_names[packet->dhcpv6_msg_type],
596
piaddr(packet->client_addr), client_id_str);
600
oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
602
log_debug("Discarding %s from %s; "
603
"IA_NA option present%s",
604
dhcpv6_type_names[packet->dhcpv6_msg_type],
605
piaddr(packet->client_addr), client_id_str);
608
oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_TA);
610
log_debug("Discarding %s from %s; "
611
"IA_TA option present%s",
612
dhcpv6_type_names[packet->dhcpv6_msg_type],
613
piaddr(packet->client_addr), client_id_str);
616
oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
618
log_debug("Discarding %s from %s; "
619
"IA_PD option present%s",
620
dhcpv6_type_names[packet->dhcpv6_msg_type],
621
piaddr(packet->client_addr), client_id_str);
625
oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
627
if (!evaluate_option_cache(server_id, packet, NULL, NULL,
628
packet->options, NULL,
629
&global_scope, oc, MDL)) {
630
log_error("Error processing %s from %s; "
631
"unable to evaluate Server Identifier%s",
632
dhcpv6_type_names[packet->dhcpv6_msg_type],
633
piaddr(packet->client_addr), client_id_str);
636
if ((server_duid.len != server_id->len) ||
637
(memcmp(server_duid.data, server_id->data,
638
server_duid.len) != 0)) {
639
log_debug("Discarding %s from %s; "
640
"not our server identifier "
641
"(SERVERID %s, server DUID %s)%s",
642
dhcpv6_type_names[packet->dhcpv6_msg_type],
643
piaddr(packet->client_addr),
644
print_hex_1(server_id->len,
645
server_id->data, 60),
646
print_hex_2(server_duid.len,
647
server_duid.data, 60),
658
if (server_id->len > 0) {
659
data_string_forget(server_id, MDL);
666
* Options that we want to send, in addition to what was requested
669
static const int required_opts[] = {
676
static const int required_opts_NAA[] = {
682
static const int required_opts_solicit[] = {
694
static const int required_opts_agent[] = {
699
static const int required_opts_IA[] = {
704
static const int required_opts_IA_PD[] = {
709
static const int required_opts_STATUS_CODE[] = {
715
* Extracts from packet contents an IA_* option, storing the IA structure
716
* in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
717
* in enc_opt_state for later lookup and evaluation. The 'offset' indicates
718
* where in the IA_* the DHCPv6 options commence.
721
get_encapsulated_IA_state(struct option_state **enc_opt_state,
722
struct data_string *enc_opt_data,
723
struct packet *packet,
724
struct option_cache *oc,
728
* Get the raw data for the encapsulated options.
730
memset(enc_opt_data, 0, sizeof(*enc_opt_data));
731
if (!evaluate_option_cache(enc_opt_data, packet,
732
NULL, NULL, packet->options, NULL,
733
&global_scope, oc, MDL)) {
734
log_error("get_encapsulated_IA_state: "
735
"error evaluating raw option.");
738
if (enc_opt_data->len < offset) {
739
log_error("get_encapsulated_IA_state: raw option too small.");
740
data_string_forget(enc_opt_data, MDL);
745
* Now create the option state structure, and pass it to the
746
* function that parses options.
748
*enc_opt_state = NULL;
749
if (!option_state_allocate(enc_opt_state, MDL)) {
750
log_error("get_encapsulated_IA_state: no memory for options.");
751
data_string_forget(enc_opt_data, MDL);
754
if (!parse_option_buffer(*enc_opt_state,
755
enc_opt_data->data + offset,
756
enc_opt_data->len - offset,
758
log_error("get_encapsulated_IA_state: error parsing options.");
759
option_state_dereference(enc_opt_state, MDL);
760
data_string_forget(enc_opt_data, MDL);
768
set_status_code(u_int16_t status_code, const char *status_message,
769
struct option_state *opt_state)
771
struct data_string d;
774
memset(&d, 0, sizeof(d));
775
d.len = sizeof(status_code) + strlen(status_message);
776
if (!buffer_allocate(&d.buffer, d.len, MDL)) {
777
log_fatal("set_status_code: no memory for status code.");
779
d.data = d.buffer->data;
780
putUShort(d.buffer->data, status_code);
781
memcpy(d.buffer->data + sizeof(status_code),
782
status_message, d.len - sizeof(status_code));
783
if (!save_option_buffer(&dhcpv6_universe, opt_state,
784
d.buffer, (unsigned char *)d.data, d.len,
785
D6O_STATUS_CODE, 0)) {
786
log_error("set_status_code: error saving status code.");
791
data_string_forget(&d, MDL);
796
* We have a set of operations we do to set up the reply packet, which
797
* is the same for many message types.
800
start_reply(struct packet *packet,
801
const struct data_string *client_id,
802
const struct data_string *server_id,
803
struct option_state **opt_state,
804
struct dhcpv6_packet *reply)
806
struct option_cache *oc;
807
const unsigned char *server_id_data;
811
* Build our option state for reply.
814
if (!option_state_allocate(opt_state, MDL)) {
815
log_error("start_reply: no memory for option_state.");
818
execute_statements_in_scope(NULL, packet, NULL, NULL,
819
packet->options, *opt_state,
820
&global_scope, root_group, NULL);
823
* A small bit of special handling for Solicit messages.
825
* We could move the logic into a flag, but for now just check
828
if (packet->dhcpv6_msg_type == DHCPV6_SOLICIT) {
829
reply->msg_type = DHCPV6_ADVERTISE;
833
* - this message type supports rapid commit (Solicit), and
834
* - the server is configured to supply a rapid commit, and
835
* - the client requests a rapid commit,
836
* Then we add a rapid commit option, and send Reply (instead
839
oc = lookup_option(&dhcpv6_universe,
840
*opt_state, D6O_RAPID_COMMIT);
842
oc = lookup_option(&dhcpv6_universe,
843
packet->options, D6O_RAPID_COMMIT);
845
/* Rapid-commit in action. */
846
reply->msg_type = DHCPV6_REPLY;
848
/* Don't want a rapid-commit in advertise. */
849
delete_option(&dhcpv6_universe,
850
*opt_state, D6O_RAPID_COMMIT);
854
reply->msg_type = DHCPV6_REPLY;
855
/* Delete the rapid-commit from the sent options. */
856
oc = lookup_option(&dhcpv6_universe,
857
*opt_state, D6O_RAPID_COMMIT);
859
delete_option(&dhcpv6_universe,
860
*opt_state, D6O_RAPID_COMMIT);
865
* Use the client's transaction identifier for the reply.
867
memcpy(reply->transaction_id, packet->dhcpv6_transaction_id,
868
sizeof(reply->transaction_id));
871
* RFC 3315, section 18.2 says we need server identifier and
874
* If the server ID is defined via the configuration file, then
875
* it will already be present in the option state at this point,
876
* so we don't need to set it.
878
* If we have a server ID passed in from the caller,
879
* use that, otherwise use the global DUID.
881
oc = lookup_option(&dhcpv6_universe, *opt_state, D6O_SERVERID);
883
if (server_id == NULL) {
884
server_id_data = server_duid.data;
885
server_id_len = server_duid.len;
887
server_id_data = server_id->data;
888
server_id_len = server_id->len;
890
if (!save_option_buffer(&dhcpv6_universe, *opt_state,
891
NULL, (unsigned char *)server_id_data,
892
server_id_len, D6O_SERVERID, 0)) {
893
log_error("start_reply: "
894
"error saving server identifier.");
899
if (client_id->buffer != NULL) {
900
if (!save_option_buffer(&dhcpv6_universe, *opt_state,
902
(unsigned char *)client_id->data,
905
log_error("start_reply: error saving "
906
"client identifier.");
912
* If the client accepts reconfiguration, let it know that we
915
* Note: we don't actually do this yet, but DOCSIS requires we
918
oc = lookup_option(&dhcpv6_universe, packet->options,
921
if (!save_option_buffer(&dhcpv6_universe, *opt_state,
922
NULL, (unsigned char *)"", 0,
923
D6O_RECONF_ACCEPT, 0)) {
924
log_error("start_reply: "
925
"error saving RECONF_ACCEPT option.");
926
option_state_dereference(opt_state, MDL);
935
* Try to get the IPv6 address the client asked for from the
938
* addr is the result (should be a pointer to NULL on entry)
939
* pool is the pool to search in
940
* requested_addr is the address the client wants
943
try_client_v6_address(struct iasubopt **addr,
944
struct ipv6_pool *pool,
945
const struct data_string *requested_addr)
947
struct in6_addr tmp_addr;
950
if (requested_addr->len < sizeof(tmp_addr)) {
951
return ISC_R_INVALIDARG;
953
memcpy(&tmp_addr, requested_addr->data, sizeof(tmp_addr));
954
if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr)) {
955
return ISC_R_FAILURE;
958
if (!ipv6_in_pool(&tmp_addr, pool)) {
959
return ISC_R_FAILURE;
962
if (lease6_exists(pool, &tmp_addr)) {
963
return ISC_R_ADDRINUSE;
966
result = iasubopt_allocate(addr, MDL);
967
if (result != ISC_R_SUCCESS) {
970
(*addr)->addr = tmp_addr;
973
/* Default is soft binding for 2 minutes. */
974
result = add_lease6(pool, *addr, cur_time + 120);
975
if (result != ISC_R_SUCCESS) {
976
iasubopt_dereference(addr, MDL);
982
* Get an IPv6 address for the client.
984
* addr is the result (should be a pointer to NULL on entry)
985
* packet is the information about the packet from the client
986
* requested_iaaddr is a hint from the client
987
* client_id is the DUID for the client
990
pick_v6_address(struct iasubopt **addr, struct shared_network *shared_network,
991
const struct data_string *client_id)
996
unsigned int attempts;
997
char tmp_buf[INET6_ADDRSTRLEN];
1000
* No address pools, we're done.
1002
if (shared_network->ipv6_pools == NULL) {
1003
log_debug("Unable to pick client address: "
1004
"no IPv6 pools on this shared network");
1005
return ISC_R_NORESOURCES;
1008
p = shared_network->ipv6_pools[i];
1010
log_debug("Unable to pick client address: "
1011
"no IPv6 address pools "
1012
"on this shared network");
1013
return ISC_R_NORESOURCES;
1015
if (p->pool_type == D6O_IA_NA) {
1021
* Otherwise try to get a lease from the first subnet possible.
1023
* We start looking at the last pool we allocated from, unless
1024
* it had a collision trying to allocate an address. This will
1025
* tend to move us into less-filled pools.
1027
start_pool = shared_network->last_ipv6_pool;
1031
p = shared_network->ipv6_pools[i];
1032
if ((p->pool_type == D6O_IA_NA) &&
1033
(create_lease6(p, addr, &attempts, client_id,
1034
cur_time + 120) == ISC_R_SUCCESS)) {
1036
* Record the pool used (or next one if there
1041
if (shared_network->ipv6_pools[i] == NULL) {
1045
shared_network->last_ipv6_pool = i;
1047
log_debug("Picking pool address %s",
1048
inet_ntop(AF_INET6, &((*addr)->addr),
1049
tmp_buf, sizeof(tmp_buf)));
1050
return ISC_R_SUCCESS;
1054
if (shared_network->ipv6_pools[i] == NULL) {
1057
} while (i != start_pool);
1060
* If we failed to pick an IPv6 address from any of the subnets.
1061
* Presumably that means we have no addresses for the client.
1063
log_debug("Unable to pick client address: no addresses available");
1064
return ISC_R_NORESOURCES;
1068
* Try to get the IPv6 prefix the client asked for from the
1071
* pref is the result (should be a pointer to NULL on entry)
1072
* pool is the prefix pool to search in
1073
* requested_pref is the address the client wants
1076
try_client_v6_prefix(struct iasubopt **pref,
1077
struct ipv6_pool *pool,
1078
const struct data_string *requested_pref)
1081
struct in6_addr tmp_pref;
1083
isc_result_t result;
1085
if (requested_pref->len < sizeof(tmp_plen) + sizeof(tmp_pref)) {
1086
return ISC_R_INVALIDARG;
1088
tmp_plen = (int) requested_pref->data[0];
1089
if ((tmp_plen < 3) || (tmp_plen > 128)) {
1090
return ISC_R_FAILURE;
1092
memcpy(&tmp_pref, requested_pref->data + 1, sizeof(tmp_pref));
1093
if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref)) {
1094
return ISC_R_FAILURE;
1097
memcpy(&ia.iabuf, &tmp_pref, 16);
1098
if (!is_cidr_mask_valid(&ia, (int) tmp_plen)) {
1099
return ISC_R_FAILURE;
1102
if (((int)tmp_plen != pool->units) ||
1103
!ipv6_in_pool(&tmp_pref, pool)) {
1104
return ISC_R_FAILURE;
1107
if (prefix6_exists(pool, &tmp_pref, tmp_plen)) {
1108
return ISC_R_ADDRINUSE;
1111
result = iasubopt_allocate(pref, MDL);
1112
if (result != ISC_R_SUCCESS) {
1115
(*pref)->addr = tmp_pref;
1116
(*pref)->plen = tmp_plen;
1118
/* Default is soft binding for 2 minutes. */
1119
result = add_lease6(pool, *pref, cur_time + 120);
1120
if (result != ISC_R_SUCCESS) {
1121
iasubopt_dereference(pref, MDL);
1127
* Get an IPv6 prefix for the client.
1129
* pref is the result (should be a pointer to NULL on entry)
1130
* packet is the information about the packet from the client
1131
* requested_iaprefix is a hint from the client
1132
* plen is -1 or the requested prefix length
1133
* client_id is the DUID for the client
1136
pick_v6_prefix(struct iasubopt **pref, int plen,
1137
struct shared_network *shared_network,
1138
const struct data_string *client_id)
1140
struct ipv6_pool *p;
1142
unsigned int attempts;
1143
char tmp_buf[INET6_ADDRSTRLEN];
1146
* No prefix pools, we're done.
1148
if (shared_network->ipv6_pools == NULL) {
1149
log_debug("Unable to pick client prefix: "
1150
"no IPv6 pools on this shared network");
1151
return ISC_R_NORESOURCES;
1154
p = shared_network->ipv6_pools[i];
1156
log_debug("Unable to pick client prefix: "
1157
"no IPv6 prefix pools "
1158
"on this shared network");
1159
return ISC_R_NORESOURCES;
1161
if (p->pool_type == D6O_IA_PD) {
1167
* Otherwise try to get a prefix.
1170
p = shared_network->ipv6_pools[i];
1174
if (p->pool_type != D6O_IA_PD) {
1179
* Try only pools with the requested prefix length if any.
1181
if ((plen >= 0) && (p->units != plen)) {
1185
if (create_prefix6(p, pref, &attempts, client_id,
1186
cur_time + 120) == ISC_R_SUCCESS) {
1187
log_debug("Picking pool prefix %s/%u",
1188
inet_ntop(AF_INET6, &((*pref)->addr),
1189
tmp_buf, sizeof(tmp_buf)),
1190
(unsigned) (*pref)->plen);
1191
return ISC_R_SUCCESS;
1196
* If we failed to pick an IPv6 prefix
1197
* Presumably that means we have no prefixes for the client.
1199
log_debug("Unable to pick client prefix: no prefixes available");
1200
return ISC_R_NORESOURCES;
1204
* lease_to_client() is called from several messages to construct a
1205
* reply that contains all that we know about the client's correct lease
1206
* (or projected lease).
1208
* Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1209
* send what we "may" give them on a request.
1211
* Request - "Hard" binding, but ignore supplied addresses (just provide what
1212
* the client should really use).
1214
* Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1215
* Rebind out any "wrong" addresses the client sends. This means we send
1216
* an empty IA_NA with a status code of NoBinding or NotOnLink or
1217
* possibly send the address with zeroed lifetimes.
1219
* Information-Request - No binding.
1221
* The basic structure is to traverse the client-supplied data first, and
1222
* validate and echo back any contents that can be. If the client-supplied
1223
* data does not error out (on renew/rebind as above), but we did not send
1224
* any addresses, attempt to allocate one.
1226
/* TODO: look at client hints for lease times */
1228
lease_to_client(struct data_string *reply_ret,
1229
struct packet *packet,
1230
const struct data_string *client_id,
1231
const struct data_string *server_id)
1233
static struct reply_state reply;
1234
struct option_cache *oc;
1235
struct data_string packet_oro;
1236
isc_boolean_t no_resources_avail;
1238
/* Locate the client. */
1239
if (shared_network_from_packet6(&reply.shared,
1240
packet) != ISC_R_SUCCESS)
1244
* Initialize the reply.
1246
packet_reference(&reply.packet, packet, MDL);
1247
data_string_copy(&reply.client_id, client_id, MDL);
1249
if (!start_reply(packet, client_id, server_id, &reply.opt_state,
1253
/* Set the write cursor to just past the reply header. */
1254
reply.cursor = REPLY_OPTIONS_INDEX;
1257
* Get the ORO from the packet, if any.
1259
oc = lookup_option(&dhcpv6_universe, packet->options, D6O_ORO);
1260
memset(&packet_oro, 0, sizeof(packet_oro));
1262
if (!evaluate_option_cache(&packet_oro, packet,
1264
packet->options, NULL,
1265
&global_scope, oc, MDL)) {
1266
log_error("lease_to_client: error evaluating ORO.");
1272
* Find a host record that matches from the packet, if any, and is
1273
* valid for the shared network the client is on.
1275
if (find_hosts_by_option(&reply.host, packet, packet->options, MDL)) {
1276
seek_shared_host(&reply.host, reply.shared);
1279
if ((reply.host == NULL) &&
1280
find_hosts_by_uid(&reply.host, client_id->data, client_id->len,
1282
seek_shared_host(&reply.host, reply.shared);
1285
/* Process the client supplied IA's onto the reply buffer. */
1287
oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
1288
no_resources_avail = ISC_FALSE;
1289
for (; oc != NULL ; oc = oc->next) {
1290
isc_result_t status;
1292
/* Start counting resources (addresses) offered. */
1293
reply.client_resources = 0;
1294
reply.resources_included = ISC_FALSE;
1296
status = reply_process_ia_na(&reply, oc);
1299
* We continue to try other IA's whether we can address
1300
* this one or not. Any other result is an immediate fail.
1302
if ((status != ISC_R_SUCCESS) &&
1303
(status != ISC_R_NORESOURCES))
1307
* If any address cannot be given to any IA, then set the
1308
* NoAddrsAvail status code.
1310
if (reply.client_resources == 0)
1311
no_resources_avail = ISC_TRUE;
1313
oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_TA);
1314
for (; oc != NULL ; oc = oc->next) {
1315
isc_result_t status;
1317
/* Start counting resources (addresses) offered. */
1318
reply.client_resources = 0;
1319
reply.resources_included = ISC_FALSE;
1321
status = reply_process_ia_ta(&reply, oc);
1324
* We continue to try other IA's whether we can address
1325
* this one or not. Any other result is an immediate fail.
1327
if ((status != ISC_R_SUCCESS) &&
1328
(status != ISC_R_NORESOURCES))
1332
* If any address cannot be given to any IA, then set the
1333
* NoAddrsAvail status code.
1335
if (reply.client_resources == 0)
1336
no_resources_avail = ISC_TRUE;
1339
/* Same for IA_PD's. */
1341
oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
1342
for (; oc != NULL ; oc = oc->next) {
1343
isc_result_t status;
1345
/* Start counting resources (prefixes) offered. */
1346
reply.client_resources = 0;
1347
reply.resources_included = ISC_FALSE;
1349
status = reply_process_ia_pd(&reply, oc);
1352
* We continue to try other IA_PD's whether we can address
1353
* this one or not. Any other result is an immediate fail.
1355
if ((status != ISC_R_SUCCESS) &&
1356
(status != ISC_R_NORESOURCES))
1360
* If any prefix cannot be given to any IA_PD, then
1361
* set the NoPrefixAvail status code.
1363
if (reply.client_resources == 0)
1364
no_resources_avail = ISC_TRUE;
1368
* Make no reply if we gave no resources and is not
1369
* for Information-Request.
1371
if ((reply.ia_count == 0) && (reply.pd_count == 0)) {
1372
if (reply.packet->dhcpv6_msg_type !=
1373
DHCPV6_INFORMATION_REQUEST)
1377
* Because we only execute statements on a per-IA basis,
1378
* we need to execute statements in any non-IA reply to
1379
* source configuration.
1381
execute_statements_in_scope(NULL, reply.packet, NULL, NULL,
1382
reply.packet->options,
1383
reply.opt_state, &global_scope,
1384
reply.shared->group, root_group);
1388
* RFC3315 section 17.2.2 (Solicit):
1390
* If the server will not assign any addresses to any IAs in a
1391
* subsequent Request from the client, the server MUST send an
1392
* Advertise message to the client that includes only a Status
1393
* Code option with code NoAddrsAvail and a status message for
1394
* the user, a Server Identifier option with the server's DUID,
1395
* and a Client Identifier option with the client's DUID.
1397
* Section 18.2.1 (Request):
1399
* If the server cannot assign any addresses to an IA in the
1400
* message from the client, the server MUST include the IA in
1401
* the Reply message with no addresses in the IA and a Status
1402
* Code option in the IA containing status code NoAddrsAvail.
1404
* Section 18.1.8 (Client Behavior):
1406
* Leave unchanged any information about addresses the client has
1407
* recorded in the IA but that were not included in the IA from
1409
* Sends a Renew/Rebind if the IA is not in the Reply message.
1411
if (no_resources_avail && (reply.ia_count != 0) &&
1412
(reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT))
1414
/* Set the NoAddrsAvail status code. */
1415
if (!set_status_code(STATUS_NoAddrsAvail,
1416
"No addresses available for this "
1417
"interface.", reply.opt_state)) {
1418
log_error("lease_to_client: Unable to set "
1419
"NoAddrsAvail status code.");
1423
/* Rewind the cursor to the start. */
1424
reply.cursor = REPLY_OPTIONS_INDEX;
1427
* Produce an advertise that includes only:
1433
reply.buf.reply.msg_type = DHCPV6_ADVERTISE;
1434
reply.cursor += store_options6((char *)reply.buf.data +
1438
reply.opt_state, reply.packet,
1441
} else if (no_resources_avail && (reply.ia_count == 0) &&
1442
(reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT))
1444
/* Set the NoPrefixAvail status code. */
1445
if (!set_status_code(STATUS_NoPrefixAvail,
1446
"No prefixes available for this "
1447
"interface.", reply.opt_state)) {
1448
log_error("lease_to_client: Unable to set "
1449
"NoPrefixAvail status code.");
1453
/* Rewind the cursor to the start. */
1454
reply.cursor = REPLY_OPTIONS_INDEX;
1457
* Produce an advertise that includes only:
1463
reply.buf.reply.msg_type = DHCPV6_ADVERTISE;
1464
reply.cursor += store_options6((char *)reply.buf.data +
1468
reply.opt_state, reply.packet,
1473
* Having stored the client's IA's, store any options that
1474
* will fit in the remaining space.
1476
reply.cursor += store_options6((char *)reply.buf.data +
1480
reply.opt_state, reply.packet,
1481
required_opts_solicit,
1485
/* Return our reply to the caller. */
1486
reply_ret->len = reply.cursor;
1487
reply_ret->buffer = NULL;
1488
if (!buffer_allocate(&reply_ret->buffer, reply.cursor, MDL)) {
1489
log_fatal("No memory to store Reply.");
1491
memcpy(reply_ret->buffer->data, reply.buf.data, reply.cursor);
1492
reply_ret->data = reply_ret->buffer->data;
1496
if (reply.shared != NULL)
1497
shared_network_dereference(&reply.shared, MDL);
1498
if (reply.host != NULL)
1499
host_dereference(&reply.host, MDL);
1500
if (reply.opt_state != NULL)
1501
option_state_dereference(&reply.opt_state, MDL);
1502
if (reply.packet != NULL)
1503
packet_dereference(&reply.packet, MDL);
1504
if (reply.client_id.data != NULL)
1505
data_string_forget(&reply.client_id, MDL);
1506
reply.renew = reply.rebind = reply.prefer = reply.valid = 0;
1510
/* Process a client-supplied IA_NA. This may append options to the tail of
1511
* the reply packet being built in the reply_state structure.
1514
reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) {
1515
isc_result_t status = ISC_R_SUCCESS;
1518
struct option_state *packet_ia;
1519
struct option_cache *oc;
1520
struct data_string ia_data, data;
1522
/* Initialize values that will get cleaned up on return. */
1524
memset(&ia_data, 0, sizeof(ia_data));
1525
memset(&data, 0, sizeof(data));
1527
* Note that find_client_address() may set reply->lease.
1530
/* Make sure there is at least room for the header. */
1531
if ((reply->cursor + IA_NA_OFFSET + 4) > sizeof(reply->buf)) {
1532
log_error("reply_process_ia_na: Reply too long for IA.");
1533
return ISC_R_NOSPACE;
1537
/* Fetch the IA_NA contents. */
1538
if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
1539
ia, IA_NA_OFFSET)) {
1540
log_error("reply_process_ia_na: error evaluating ia");
1541
status = ISC_R_FAILURE;
1545
/* Extract IA_NA header contents. */
1546
iaid = getULong(ia_data.data);
1547
reply->renew = getULong(ia_data.data + 4);
1548
reply->rebind = getULong(ia_data.data + 8);
1550
/* Create an IA_NA structure. */
1551
if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data,
1552
reply->client_id.len, MDL) != ISC_R_SUCCESS) {
1553
log_error("reply_process_ia_na: no memory for ia.");
1554
status = ISC_R_NOMEMORY;
1557
reply->ia->ia_type = D6O_IA_NA;
1559
/* Cache pre-existing IA, if any. */
1560
ia_hash_lookup(&reply->old_ia, ia_na_active,
1561
(unsigned char *)reply->ia->iaid_duid.data,
1562
reply->ia->iaid_duid.len, MDL);
1565
* Create an option cache to carry the IA_NA option contents, and
1566
* execute any user-supplied values into it.
1568
if (!option_state_allocate(&reply->reply_ia, MDL)) {
1569
status = ISC_R_NOMEMORY;
1573
/* Check & cache the fixed host record. */
1574
if ((reply->host != NULL) && (reply->host->fixed_addr != NULL)) {
1575
if (!evaluate_option_cache(&reply->fixed, NULL, NULL, NULL,
1576
NULL, NULL, &global_scope,
1577
reply->host->fixed_addr, MDL)) {
1578
log_error("reply_process_ia_na: unable to evaluate "
1580
status = ISC_R_FAILURE;
1584
if (reply->fixed.len < 16) {
1585
log_error("reply_process_ia_na: invalid fixed address.");
1586
status = ISC_R_INVALIDARG;
1590
reply->static_lease = ISC_TRUE;
1592
reply->static_lease = ISC_FALSE;
1595
* Save the cursor position at the start of the IA, so we can
1596
* set length and adjust t1/t2 values later. We write a temporary
1597
* header out now just in case we decide to adjust the packet
1598
* within sub-process functions.
1600
ia_cursor = reply->cursor;
1602
/* Initialize the IA_NA header. First the code. */
1603
putUShort(reply->buf.data + reply->cursor, (unsigned)D6O_IA_NA);
1606
/* Then option length. */
1607
putUShort(reply->buf.data + reply->cursor, 0x0Cu);
1610
/* Then IA_NA header contents; IAID. */
1611
putULong(reply->buf.data + reply->cursor, iaid);
1614
/* We store the client's t1 for now, and may over-ride it later. */
1615
putULong(reply->buf.data + reply->cursor, reply->renew);
1618
/* We store the client's t2 for now, and may over-ride it later. */
1619
putULong(reply->buf.data + reply->cursor, reply->rebind);
1623
* For each address in this IA_NA, decide what to do about it.
1627
* The client leaves unchanged any infomation about addresses
1628
* it has recorded but are not included ("cancel/break" below).
1629
* A not included IA ("cleanup" below) could give a Renew/Rebind.
1631
oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAADDR);
1632
reply->valid = reply->prefer = 0xffffffff;
1633
reply->client_valid = reply->client_prefer = 0;
1634
for (; oc != NULL ; oc = oc->next) {
1635
status = reply_process_addr(reply, oc);
1638
* Canceled means we did not allocate addresses to the
1639
* client, but we're "done" with this IA - we set a status
1640
* code. So transmit this reply, e.g., move on to the next
1643
if (status == ISC_R_CANCELED)
1646
if ((status != ISC_R_SUCCESS) && (status != ISC_R_ADDRINUSE))
1653
* If we fell through the above and never gave the client
1654
* an address, give it one now.
1656
if ((status != ISC_R_CANCELED) && (reply->client_resources == 0)) {
1657
status = find_client_address(reply);
1659
if (status == ISC_R_NORESOURCES) {
1660
switch (reply->packet->dhcpv6_msg_type) {
1661
case DHCPV6_SOLICIT:
1663
* No address for any IA is handled
1668
case DHCPV6_REQUEST:
1669
/* Section 18.2.1 (Request):
1671
* If the server cannot assign any addresses to
1672
* an IA in the message from the client, the
1673
* server MUST include the IA in the Reply
1674
* message with no addresses in the IA and a
1675
* Status Code option in the IA containing
1676
* status code NoAddrsAvail.
1678
option_state_dereference(&reply->reply_ia, MDL);
1679
if (!option_state_allocate(&reply->reply_ia,
1682
log_error("reply_process_ia_na: No "
1683
"memory for option state "
1685
status = ISC_R_NOMEMORY;
1689
if (!set_status_code(STATUS_NoAddrsAvail,
1690
"No addresses available "
1691
"for this interface.",
1693
log_error("reply_process_ia_na: Unable "
1694
"to set NoAddrsAvail status "
1696
status = ISC_R_FAILURE;
1700
status = ISC_R_SUCCESS;
1705
* RFC 3315 does not tell us to emit a status
1706
* code in this condition, or anything else.
1708
* If we included non-allocated addresses
1709
* (zeroed lifetimes) in an IA, then the client
1710
* will deconfigure them.
1712
* So we want to include the IA even if we
1713
* can't give it a new address if it includes
1714
* zeroed lifetime addresses.
1716
* We don't want to include the IA if we
1717
* provide zero addresses including zeroed
1720
if (reply->resources_included)
1721
status = ISC_R_SUCCESS;
1728
if (status != ISC_R_SUCCESS)
1732
reply->cursor += store_options6((char *)reply->buf.data + reply->cursor,
1733
sizeof(reply->buf) - reply->cursor,
1734
reply->reply_ia, reply->packet,
1735
required_opts_IA, NULL);
1737
/* Reset the length of this IA to match what was just written. */
1738
putUShort(reply->buf.data + ia_cursor + 2,
1739
reply->cursor - (ia_cursor + 4));
1742
* T1/T2 time selection is kind of weird. We actually use DHCP
1743
* (v4) scoped options as handy existing places where these might
1744
* be configured by an administrator. A value of zero tells the
1745
* client it may choose its own renewal time.
1748
oc = lookup_option(&dhcp_universe, reply->opt_state,
1749
DHO_DHCP_RENEWAL_TIME);
1751
if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
1752
reply->packet->options,
1753
reply->opt_state, &global_scope,
1756
log_error("Invalid renewal time.");
1758
reply->renew = getULong(data.data);
1761
if (data.data != NULL)
1762
data_string_forget(&data, MDL);
1764
putULong(reply->buf.data + ia_cursor + 8, reply->renew);
1768
oc = lookup_option(&dhcp_universe, reply->opt_state,
1769
DHO_DHCP_REBINDING_TIME);
1771
if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
1772
reply->packet->options,
1773
reply->opt_state, &global_scope,
1776
log_error("Invalid rebinding time.");
1778
reply->rebind = getULong(data.data);
1781
if (data.data != NULL)
1782
data_string_forget(&data, MDL);
1784
putULong(reply->buf.data + ia_cursor + 12, reply->rebind);
1787
* If this is not a 'soft' binding, consume the new changes into
1788
* the database (if any have been attached to the ia_na).
1790
* Loop through the assigned dynamic addresses, referencing the
1791
* leases onto this IA_NA rather than any old ones, and updating
1792
* pool timers for each (if any).
1794
if ((status != ISC_R_CANCELED) && !reply->static_lease &&
1795
(reply->buf.reply.msg_type == DHCPV6_REPLY) &&
1796
(reply->ia->num_iasubopt != 0)) {
1797
struct iasubopt *tmp;
1798
struct data_string *ia_id;
1801
for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
1802
tmp = reply->ia->iasubopt[i];
1804
if (tmp->ia != NULL)
1805
ia_dereference(&tmp->ia, MDL);
1806
ia_reference(&tmp->ia, reply->ia, MDL);
1808
/* Commit 'hard' bindings. */
1809
tmp->hard_lifetime_end_time =
1810
tmp->soft_lifetime_end_time;
1811
tmp->soft_lifetime_end_time = 0;
1812
renew_lease6(tmp->ipv6_pool, tmp);
1813
schedule_lease_timeout(tmp->ipv6_pool);
1816
* Perform ddns updates.
1818
oc = lookup_option(&server_universe, reply->opt_state,
1821
evaluate_boolean_option_cache(NULL, reply->packet,
1823
reply->packet->options,
1827
ddns_updates(reply->packet, NULL, NULL,
1828
tmp, NULL, reply->opt_state);
1832
/* Remove any old ia from the hash. */
1833
if (reply->old_ia != NULL) {
1834
ia_id = &reply->old_ia->iaid_duid;
1835
ia_hash_delete(ia_na_active,
1836
(unsigned char *)ia_id->data,
1838
ia_dereference(&reply->old_ia, MDL);
1841
/* Put new ia into the hash. */
1842
reply->ia->cltt = cur_time;
1843
ia_id = &reply->ia->iaid_duid;
1844
ia_hash_add(ia_na_active, (unsigned char *)ia_id->data,
1845
ia_id->len, reply->ia, MDL);
1847
write_ia(reply->ia);
1851
if (packet_ia != NULL)
1852
option_state_dereference(&packet_ia, MDL);
1853
if (reply->reply_ia != NULL)
1854
option_state_dereference(&reply->reply_ia, MDL);
1855
if (ia_data.data != NULL)
1856
data_string_forget(&ia_data, MDL);
1857
if (data.data != NULL)
1858
data_string_forget(&data, MDL);
1859
if (reply->ia != NULL)
1860
ia_dereference(&reply->ia, MDL);
1861
if (reply->old_ia != NULL)
1862
ia_dereference(&reply->old_ia, MDL);
1863
if (reply->lease != NULL)
1864
iasubopt_dereference(&reply->lease, MDL);
1865
if (reply->fixed.data != NULL)
1866
data_string_forget(&reply->fixed, MDL);
1869
* ISC_R_CANCELED is a status code used by the addr processing to
1870
* indicate we're replying with a status code. This is still a
1871
* success at higher layers.
1873
return((status == ISC_R_CANCELED) ? ISC_R_SUCCESS : status);
1877
* Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
1878
* into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
1879
* in the event we are replying with a status code and do not wish to process
1880
* more IAADDRs within this IA.
1883
reply_process_addr(struct reply_state *reply, struct option_cache *addr) {
1884
u_int32_t pref_life, valid_life;
1885
struct binding_scope **scope;
1886
struct group *group;
1887
struct subnet *subnet;
1888
struct iaddr tmp_addr;
1889
struct option_cache *oc;
1890
struct data_string iaaddr, data;
1891
isc_result_t status = ISC_R_SUCCESS;
1893
/* Initializes values that will be cleaned up. */
1894
memset(&iaaddr, 0, sizeof(iaaddr));
1895
memset(&data, 0, sizeof(data));
1896
/* Note that reply->lease may be set by address_is_owned() */
1899
* There is no point trying to process an incoming address if there
1900
* is no room for an outgoing address.
1902
if ((reply->cursor + 28) > sizeof(reply->buf)) {
1903
log_error("reply_process_addr: Out of room for address.");
1904
return ISC_R_NOSPACE;
1907
/* Extract this IAADDR option. */
1908
if (!evaluate_option_cache(&iaaddr, reply->packet, NULL, NULL,
1909
reply->packet->options, NULL, &global_scope,
1911
(iaaddr.len < IAADDR_OFFSET)) {
1912
log_error("reply_process_addr: error evaluating IAADDR.");
1913
status = ISC_R_FAILURE;
1917
/* The first 16 bytes are the IPv6 address. */
1918
pref_life = getULong(iaaddr.data + 16);
1919
valid_life = getULong(iaaddr.data + 20);
1921
if ((reply->client_valid == 0) ||
1922
(reply->client_valid > valid_life))
1923
reply->client_valid = valid_life;
1925
if ((reply->client_prefer == 0) ||
1926
(reply->client_prefer > pref_life))
1927
reply->client_prefer = pref_life;
1930
* Clients may choose to send :: as an address, with the idea to give
1931
* hints about preferred-lifetime or valid-lifetime.
1934
memset(tmp_addr.iabuf, 0, 16);
1935
if (!memcmp(iaaddr.data, tmp_addr.iabuf, 16)) {
1936
/* Status remains success; we just ignore this one. */
1940
/* tmp_addr len remains 16 */
1941
memcpy(tmp_addr.iabuf, iaaddr.data, 16);
1944
* Verify that this address is on the client's network.
1946
for (subnet = reply->shared->subnets ; subnet != NULL ;
1947
subnet = subnet->next_sibling) {
1948
if (addr_eq(subnet_number(tmp_addr, subnet->netmask),
1953
/* Address not found on shared network. */
1954
if (subnet == NULL) {
1955
/* Ignore this address on 'soft' bindings. */
1956
if (reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) {
1957
/* disable rapid commit */
1958
reply->buf.reply.msg_type = DHCPV6_ADVERTISE;
1959
delete_option(&dhcpv6_universe,
1962
/* status remains success */
1967
* RFC3315 section 18.2.1:
1969
* If the server finds that the prefix on one or more IP
1970
* addresses in any IA in the message from the client is not
1971
* appropriate for the link to which the client is connected,
1972
* the server MUST return the IA to the client with a Status
1973
* Code option with the value NotOnLink.
1975
if (reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) {
1976
/* Rewind the IA_NA to empty. */
1977
option_state_dereference(&reply->reply_ia, MDL);
1978
if (!option_state_allocate(&reply->reply_ia, MDL)) {
1979
log_error("reply_process_addr: No memory for "
1980
"option state wipe.");
1981
status = ISC_R_NOMEMORY;
1985
/* Append a NotOnLink status code. */
1986
if (!set_status_code(STATUS_NotOnLink,
1987
"Address not for use on this "
1988
"link.", reply->reply_ia)) {
1989
log_error("reply_process_addr: Failure "
1990
"setting status code.");
1991
status = ISC_R_FAILURE;
1995
/* Fin (no more IAADDRs). */
1996
status = ISC_R_CANCELED;
2001
* RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2003
* If the server finds that any of the addresses are not
2004
* appropriate for the link to which the client is attached,
2005
* the server returns the address to the client with lifetimes
2008
if ((reply->packet->dhcpv6_msg_type != DHCPV6_RENEW) &&
2009
(reply->packet->dhcpv6_msg_type != DHCPV6_REBIND)) {
2010
log_error("It is impossible to lease a client that is "
2011
"not sending a solicit, request, renew, or "
2013
status = ISC_R_FAILURE;
2017
reply->send_prefer = reply->send_valid = 0;
2021
/* Verify the address belongs to the client. */
2022
if (!address_is_owned(reply, &tmp_addr)) {
2024
* For solicit and request, any addresses included are
2025
* 'requested' addresses. For rebind, we actually have
2026
* no direction on what to do from 3315 section 18.2.4!
2027
* So I think the best bet is to try and give it out, and if
2028
* we can't, zero lifetimes.
2030
if ((reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) ||
2031
(reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) ||
2032
(reply->packet->dhcpv6_msg_type == DHCPV6_REBIND)) {
2033
status = reply_process_try_addr(reply, &tmp_addr);
2035
/* Either error out or skip this address. */
2036
if ((status != ISC_R_SUCCESS) &&
2037
(status != ISC_R_ADDRINUSE))
2040
if (reply->lease == NULL) {
2041
if (reply->packet->dhcpv6_msg_type ==
2043
reply->send_prefer = 0;
2044
reply->send_valid = 0;
2048
/* status remains success - ignore */
2052
* RFC3315 section 18.2.3:
2054
* If the server cannot find a client entry for the IA the
2055
* server returns the IA containing no addresses with a Status
2056
* Code option set to NoBinding in the Reply message.
2058
* On mismatch we (ab)use this pretending we have not the IA
2059
* as soon as we have not an address.
2061
} else if (reply->packet->dhcpv6_msg_type == DHCPV6_RENEW) {
2062
/* Rewind the IA_NA to empty. */
2063
option_state_dereference(&reply->reply_ia, MDL);
2064
if (!option_state_allocate(&reply->reply_ia, MDL)) {
2065
log_error("reply_process_addr: No memory for "
2066
"option state wipe.");
2067
status = ISC_R_NOMEMORY;
2071
/* Append a NoBinding status code. */
2072
if (!set_status_code(STATUS_NoBinding,
2073
"Address not bound to this "
2074
"interface.", reply->reply_ia)) {
2075
log_error("reply_process_addr: Unable to "
2076
"attach status code.");
2077
status = ISC_R_FAILURE;
2081
/* Fin (no more IAADDRs). */
2082
status = ISC_R_CANCELED;
2085
log_error("It is impossible to lease a client that is "
2086
"not sending a solicit, request, renew, or "
2088
status = ISC_R_FAILURE;
2093
if (reply->static_lease) {
2094
if (reply->host == NULL)
2095
log_fatal("Impossible condition at %s:%d.", MDL);
2097
scope = &global_scope;
2098
group = reply->host->group;
2100
if (reply->lease == NULL)
2101
log_fatal("Impossible condition at %s:%d.", MDL);
2103
scope = &reply->lease->scope;
2104
group = reply->lease->ipv6_pool->subnet->group;
2108
* If client_resources is nonzero, then the reply_process_is_addressed
2109
* function has executed configuration state into the reply option
2110
* cache. We will use that valid cache to derive configuration for
2111
* whether or not to engage in additional addresses, and similar.
2113
if (reply->client_resources != 0) {
2117
* Does this client have "enough" addresses already? Default
2118
* to one. Everybody gets one, and one should be enough for
2121
oc = lookup_option(&server_universe, reply->opt_state,
2122
SV_LIMIT_ADDRS_PER_IA);
2124
if (!evaluate_option_cache(&data, reply->packet,
2126
reply->packet->options,
2130
log_error("reply_process_addr: unable to "
2131
"evaluate addrs-per-ia value.");
2132
status = ISC_R_FAILURE;
2136
limit = getULong(data.data);
2137
data_string_forget(&data, MDL);
2141
* If we wish to limit the client to a certain number of
2142
* addresses, then omit the address from the reply.
2144
if (reply->client_resources >= limit)
2148
status = reply_process_is_addressed(reply, scope, group);
2149
if (status != ISC_R_SUCCESS)
2153
status = reply_process_send_addr(reply, &tmp_addr);
2156
if (iaaddr.data != NULL)
2157
data_string_forget(&iaaddr, MDL);
2158
if (data.data != NULL)
2159
data_string_forget(&data, MDL);
2160
if (reply->lease != NULL)
2161
iasubopt_dereference(&reply->lease, MDL);
2167
* Verify the address belongs to the client. If we've got a host
2168
* record with a fixed address, it has to be the assigned address
2169
* (fault out all else). Otherwise it's a dynamic address, so lookup
2170
* that address and make sure it belongs to this DUID:IAID pair.
2172
static isc_boolean_t
2173
address_is_owned(struct reply_state *reply, struct iaddr *addr) {
2177
* This faults out addresses that don't match fixed addresses.
2179
if (reply->static_lease) {
2180
if (reply->fixed.data == NULL)
2181
log_fatal("Impossible condition at %s:%d.", MDL);
2183
if (memcmp(addr->iabuf, reply->fixed.data, 16) == 0)
2189
if ((reply->old_ia == NULL) || (reply->old_ia->num_iasubopt == 0))
2192
for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
2193
struct iasubopt *tmp;
2195
tmp = reply->old_ia->iasubopt[i];
2197
if (memcmp(addr->iabuf, &tmp->addr, 16) == 0) {
2198
iasubopt_reference(&reply->lease, tmp, MDL);
2206
/* Process a client-supplied IA_TA. This may append options to the tail of
2207
* the reply packet being built in the reply_state structure.
2210
reply_process_ia_ta(struct reply_state *reply, struct option_cache *ia) {
2211
isc_result_t status = ISC_R_SUCCESS;
2214
struct option_state *packet_ia;
2215
struct option_cache *oc;
2216
struct data_string ia_data, data;
2217
struct data_string iaaddr;
2218
u_int32_t pref_life, valid_life;
2219
struct iaddr tmp_addr;
2221
/* Initialize values that will get cleaned up on return. */
2223
memset(&ia_data, 0, sizeof(ia_data));
2224
memset(&data, 0, sizeof(data));
2225
memset(&iaaddr, 0, sizeof(iaaddr));
2227
/* Make sure there is at least room for the header. */
2228
if ((reply->cursor + IA_TA_OFFSET + 4) > sizeof(reply->buf)) {
2229
log_error("reply_process_ia_ta: Reply too long for IA.");
2230
return ISC_R_NOSPACE;
2234
/* Fetch the IA_TA contents. */
2235
if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
2236
ia, IA_TA_OFFSET)) {
2237
log_error("reply_process_ia_ta: error evaluating ia");
2238
status = ISC_R_FAILURE;
2242
/* Extract IA_TA header contents. */
2243
iaid = getULong(ia_data.data);
2245
/* Create an IA_TA structure. */
2246
if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data,
2247
reply->client_id.len, MDL) != ISC_R_SUCCESS) {
2248
log_error("reply_process_ia_ta: no memory for ia.");
2249
status = ISC_R_NOMEMORY;
2252
reply->ia->ia_type = D6O_IA_TA;
2254
/* Cache pre-existing IA, if any. */
2255
ia_hash_lookup(&reply->old_ia, ia_ta_active,
2256
(unsigned char *)reply->ia->iaid_duid.data,
2257
reply->ia->iaid_duid.len, MDL);
2260
* Create an option cache to carry the IA_TA option contents, and
2261
* execute any user-supplied values into it.
2263
if (!option_state_allocate(&reply->reply_ia, MDL)) {
2264
status = ISC_R_NOMEMORY;
2269
* Temporary leases are dynamic by definition.
2271
reply->static_lease = ISC_FALSE;
2274
* Save the cursor position at the start of the IA, so we can
2275
* set length later. We write a temporary
2276
* header out now just in case we decide to adjust the packet
2277
* within sub-process functions.
2279
ia_cursor = reply->cursor;
2281
/* Initialize the IA_TA header. First the code. */
2282
putUShort(reply->buf.data + reply->cursor, (unsigned)D6O_IA_TA);
2285
/* Then option length. */
2286
putUShort(reply->buf.data + reply->cursor, 0x04u);
2289
/* Then IA_TA header contents; IAID. */
2290
putULong(reply->buf.data + reply->cursor, iaid);
2294
* Deal with an IAADDR for lifetimes.
2295
* For all or none, process IAADDRs as hints.
2297
reply->valid = reply->prefer = 0xffffffff;
2298
reply->client_valid = reply->client_prefer = 0;
2299
oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAADDR);
2300
for (; oc != NULL; oc = oc->next) {
2301
memset(&iaaddr, 0, sizeof(iaaddr));
2302
if (!evaluate_option_cache(&iaaddr, reply->packet,
2304
reply->packet->options, NULL,
2305
&global_scope, oc, MDL) ||
2306
(iaaddr.len < IAADDR_OFFSET)) {
2307
log_error("reply_process_ia_ta: error "
2308
"evaluating IAADDR.");
2309
status = ISC_R_FAILURE;
2312
/* The first 16 bytes are the IPv6 address. */
2313
pref_life = getULong(iaaddr.data + 16);
2314
valid_life = getULong(iaaddr.data + 20);
2316
if ((reply->client_valid == 0) ||
2317
(reply->client_valid > valid_life))
2318
reply->client_valid = valid_life;
2320
if ((reply->client_prefer == 0) ||
2321
(reply->client_prefer > pref_life))
2322
reply->client_prefer = pref_life;
2324
/* Nothing more if something has failed. */
2325
if (status == ISC_R_CANCELED)
2329
memcpy(tmp_addr.iabuf, iaaddr.data, 16);
2330
if (!temporary_is_available(reply, &tmp_addr))
2332
status = reply_process_is_addressed(reply,
2333
&reply->lease->scope,
2334
reply->shared->group);
2335
if (status != ISC_R_SUCCESS)
2337
status = reply_process_send_addr(reply, &tmp_addr);
2338
if (status != ISC_R_SUCCESS)
2340
if (reply->lease != NULL)
2341
iasubopt_dereference(&reply->lease, MDL);
2345
/* Rewind the IA_TA to empty. */
2346
option_state_dereference(&reply->reply_ia, MDL);
2347
if (!option_state_allocate(&reply->reply_ia, MDL)) {
2348
status = ISC_R_NOMEMORY;
2351
status = ISC_R_CANCELED;
2352
reply->client_resources = 0;
2353
reply->resources_included = ISC_FALSE;
2354
if (reply->lease != NULL)
2355
iasubopt_dereference(&reply->lease, MDL);
2360
* Give the client temporary addresses.
2362
if (reply->client_resources != 0)
2364
status = find_client_temporaries(reply);
2365
if (status == ISC_R_NORESOURCES) {
2366
switch (reply->packet->dhcpv6_msg_type) {
2367
case DHCPV6_SOLICIT:
2369
* No address for any IA is handled
2374
case DHCPV6_REQUEST:
2375
/* Section 18.2.1 (Request):
2377
* If the server cannot assign any addresses to
2378
* an IA in the message from the client, the
2379
* server MUST include the IA in the Reply
2380
* message with no addresses in the IA and a
2381
* Status Code option in the IA containing
2382
* status code NoAddrsAvail.
2384
option_state_dereference(&reply->reply_ia, MDL);
2385
if (!option_state_allocate(&reply->reply_ia, MDL)) {
2386
log_error("reply_process_ia_ta: No "
2387
"memory for option state wipe.");
2388
status = ISC_R_NOMEMORY;
2392
if (!set_status_code(STATUS_NoAddrsAvail,
2393
"No addresses available "
2394
"for this interface.",
2396
log_error("reply_process_ia_ta: Unable "
2397
"to set NoAddrsAvail status code.");
2398
status = ISC_R_FAILURE;
2402
status = ISC_R_SUCCESS;
2407
* We don't want to include the IA if we
2408
* provide zero addresses including zeroed
2411
if (reply->resources_included)
2412
status = ISC_R_SUCCESS;
2417
} else if (status != ISC_R_SUCCESS)
2421
reply->cursor += store_options6((char *)reply->buf.data + reply->cursor,
2422
sizeof(reply->buf) - reply->cursor,
2423
reply->reply_ia, reply->packet,
2424
required_opts_IA, NULL);
2426
/* Reset the length of this IA to match what was just written. */
2427
putUShort(reply->buf.data + ia_cursor + 2,
2428
reply->cursor - (ia_cursor + 4));
2431
* Consume the new changes into the database (if any have been
2432
* attached to the ia_ta).
2434
* Loop through the assigned dynamic addresses, referencing the
2435
* leases onto this IA_TA rather than any old ones, and updating
2436
* pool timers for each (if any).
2438
if ((status != ISC_R_CANCELED) &&
2439
(reply->buf.reply.msg_type == DHCPV6_REPLY) &&
2440
(reply->ia->num_iasubopt != 0)) {
2441
struct iasubopt *tmp;
2442
struct data_string *ia_id;
2445
for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
2446
tmp = reply->ia->iasubopt[i];
2448
if (tmp->ia != NULL)
2449
ia_dereference(&tmp->ia, MDL);
2450
ia_reference(&tmp->ia, reply->ia, MDL);
2452
/* Commit 'hard' bindings. */
2453
tmp->hard_lifetime_end_time =
2454
tmp->soft_lifetime_end_time;
2455
tmp->soft_lifetime_end_time = 0;
2456
renew_lease6(tmp->ipv6_pool, tmp);
2457
schedule_lease_timeout(tmp->ipv6_pool);
2460
* Perform ddns updates.
2462
oc = lookup_option(&server_universe, reply->opt_state,
2465
evaluate_boolean_option_cache(NULL, reply->packet,
2467
reply->packet->options,
2471
ddns_updates(reply->packet, NULL, NULL,
2472
tmp, NULL, reply->opt_state);
2476
/* Remove any old ia from the hash. */
2477
if (reply->old_ia != NULL) {
2478
ia_id = &reply->old_ia->iaid_duid;
2479
ia_hash_delete(ia_ta_active,
2480
(unsigned char *)ia_id->data,
2482
ia_dereference(&reply->old_ia, MDL);
2485
/* Put new ia into the hash. */
2486
reply->ia->cltt = cur_time;
2487
ia_id = &reply->ia->iaid_duid;
2488
ia_hash_add(ia_ta_active, (unsigned char *)ia_id->data,
2489
ia_id->len, reply->ia, MDL);
2491
write_ia(reply->ia);
2495
if (packet_ia != NULL)
2496
option_state_dereference(&packet_ia, MDL);
2497
if (iaaddr.data != NULL)
2498
data_string_forget(&iaaddr, MDL);
2499
if (reply->reply_ia != NULL)
2500
option_state_dereference(&reply->reply_ia, MDL);
2501
if (ia_data.data != NULL)
2502
data_string_forget(&ia_data, MDL);
2503
if (data.data != NULL)
2504
data_string_forget(&data, MDL);
2505
if (reply->ia != NULL)
2506
ia_dereference(&reply->ia, MDL);
2507
if (reply->old_ia != NULL)
2508
ia_dereference(&reply->old_ia, MDL);
2509
if (reply->lease != NULL)
2510
iasubopt_dereference(&reply->lease, MDL);
2513
* ISC_R_CANCELED is a status code used by the addr processing to
2514
* indicate we're replying with other addresses. This is still a
2515
* success at higher layers.
2517
return((status == ISC_R_CANCELED) ? ISC_R_SUCCESS : status);
2521
* Verify the temporary address is available.
2523
static isc_boolean_t
2524
temporary_is_available(struct reply_state *reply, struct iaddr *addr) {
2525
struct in6_addr tmp_addr;
2526
struct subnet *subnet;
2527
struct ipv6_pool *pool;
2530
memcpy(&tmp_addr, addr->iabuf, sizeof(tmp_addr));
2532
* Clients may choose to send :: as an address, with the idea to give
2533
* hints about preferred-lifetime or valid-lifetime.
2534
* So this is not a request for this address.
2536
if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr))
2540
* Verify that this address is on the client's network.
2542
for (subnet = reply->shared->subnets ; subnet != NULL ;
2543
subnet = subnet->next_sibling) {
2544
if (addr_eq(subnet_number(*addr, subnet->netmask),
2549
/* Address not found on shared network. */
2554
* Check if this address is owned (must be before next step).
2556
if (address_is_owned(reply, addr))
2560
* Verify that this address is in a temporary pool and try to get it.
2562
if (reply->shared->ipv6_pools == NULL)
2564
for (i = 0 ; (pool = reply->shared->ipv6_pools[i]) != NULL ; i++) {
2565
if (pool->pool_type != D6O_IA_TA)
2567
if (ipv6_in_pool(&tmp_addr, pool))
2572
if (lease6_exists(pool, &tmp_addr))
2574
if (iasubopt_allocate(&reply->lease, MDL) != ISC_R_SUCCESS)
2576
reply->lease->addr = tmp_addr;
2577
reply->lease->plen = 0;
2578
/* Default is soft binding for 2 minutes. */
2579
if (add_lease6(pool, reply->lease, cur_time + 120) != ISC_R_SUCCESS)
2586
* Get a temporary address per prefix.
2589
find_client_temporaries(struct reply_state *reply) {
2590
struct shared_network *shared;
2592
struct ipv6_pool *p;
2593
isc_result_t status;
2594
unsigned int attempts;
2595
struct iaddr send_addr;
2598
* No pools, we're done.
2600
shared = reply->shared;
2601
if (shared->ipv6_pools == NULL) {
2602
log_debug("Unable to get client addresses: "
2603
"no IPv6 pools on this shared network");
2604
return ISC_R_NORESOURCES;
2607
status = ISC_R_NORESOURCES;
2609
p = shared->ipv6_pools[i];
2613
if (p->pool_type != D6O_IA_TA) {
2618
* Get an address in this temporary pool.
2620
status = create_lease6(p, &reply->lease, &attempts,
2621
&reply->client_id, cur_time + 120);
2622
if (status != ISC_R_SUCCESS) {
2623
log_debug("Unable to get a temporary address.");
2627
status = reply_process_is_addressed(reply,
2628
&reply->lease->scope,
2629
reply->lease->ipv6_pool->subnet->group);
2630
if (status != ISC_R_SUCCESS) {
2634
memcpy(send_addr.iabuf, &reply->lease->addr, 16);
2635
status = reply_process_send_addr(reply, &send_addr);
2636
if (status != ISC_R_SUCCESS) {
2639
if (reply->lease != NULL) {
2640
iasubopt_dereference(&reply->lease, MDL);
2645
if (reply->lease != NULL) {
2646
iasubopt_dereference(&reply->lease, MDL);
2652
* This function only returns failure on 'hard' failures. If it succeeds,
2653
* it will leave a lease structure behind.
2656
reply_process_try_addr(struct reply_state *reply, struct iaddr *addr) {
2657
isc_result_t status = ISC_R_NORESOURCES;
2658
struct ipv6_pool *pool;
2660
struct data_string data_addr;
2662
if ((reply == NULL) || (reply->shared == NULL) ||
2663
(reply->shared->ipv6_pools == NULL) || (addr == NULL) ||
2664
(reply->lease != NULL))
2665
return ISC_R_INVALIDARG;
2667
memset(&data_addr, 0, sizeof(data_addr));
2668
data_addr.len = addr->len;
2669
data_addr.data = addr->iabuf;
2671
for (i = 0 ; (pool = reply->shared->ipv6_pools[i]) != NULL ; i++) {
2672
if (pool->pool_type != D6O_IA_NA)
2674
status = try_client_v6_address(&reply->lease, pool,
2676
if (status == ISC_R_SUCCESS)
2680
/* Note that this is just pedantry. There is no allocation to free. */
2681
data_string_forget(&data_addr, MDL);
2682
/* Return just the most recent status... */
2686
/* Look around for an address to give the client. First, look through the
2687
* old IA for addresses we can extend. Second, try to allocate a new address.
2688
* Finally, actually add that address into the current reply IA.
2691
find_client_address(struct reply_state *reply) {
2692
struct iaddr send_addr;
2693
isc_result_t status = ISC_R_NORESOURCES;
2694
struct iasubopt *lease, *best_lease = NULL;
2695
struct binding_scope **scope;
2696
struct group *group;
2699
if (reply->static_lease) {
2700
if (reply->host == NULL)
2701
return ISC_R_INVALIDARG;
2704
memcpy(send_addr.iabuf, reply->fixed.data, 16);
2706
status = ISC_R_SUCCESS;
2707
scope = &global_scope;
2708
group = reply->host->group;
2712
if (reply->old_ia != NULL) {
2713
for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
2714
lease = reply->old_ia->iasubopt[i];
2716
best_lease = lease_compare(lease, best_lease);
2720
/* Try to pick a new address if we didn't find one, or if we found an
2723
if ((best_lease == NULL) || (best_lease->state == FTS_ABANDONED)) {
2724
status = pick_v6_address(&reply->lease, reply->shared,
2726
} else if (best_lease != NULL) {
2727
iasubopt_reference(&reply->lease, best_lease, MDL);
2728
status = ISC_R_SUCCESS;
2731
/* Pick the abandoned lease as a last resort. */
2732
if ((status == ISC_R_NORESOURCES) && (best_lease != NULL)) {
2733
/* I don't see how this is supposed to be done right now. */
2734
log_error("Reclaiming abandoned addresses is not yet "
2735
"supported. Treating this as an out of space "
2737
/* iasubopt_reference(&reply->lease, best_lease, MDL); */
2740
/* Give up now if we didn't find a lease. */
2741
if (status != ISC_R_SUCCESS)
2744
if (reply->lease == NULL)
2745
log_fatal("Impossible condition at %s:%d.", MDL);
2747
/* Draw binding scopes from the lease's binding scope, and config
2748
* from the lease's containing subnet and higher. Note that it may
2749
* be desirable to place the group attachment directly in the pool.
2751
scope = &reply->lease->scope;
2752
group = reply->lease->ipv6_pool->subnet->group;
2755
memcpy(send_addr.iabuf, &reply->lease->addr, 16);
2758
status = reply_process_is_addressed(reply, scope, group);
2759
if (status != ISC_R_SUCCESS)
2762
status = reply_process_send_addr(reply, &send_addr);
2766
/* Once an address is found for a client, perform several common functions;
2767
* Calculate and store valid and preferred lease times, draw client options
2768
* into the option state.
2771
reply_process_is_addressed(struct reply_state *reply,
2772
struct binding_scope **scope, struct group *group)
2774
isc_result_t status = ISC_R_SUCCESS;
2775
struct data_string data;
2776
struct option_cache *oc;
2778
/* Initialize values we will cleanup. */
2779
memset(&data, 0, sizeof(data));
2781
/* Execute relevant options into root scope. */
2782
execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
2783
reply->packet->options, reply->opt_state,
2784
scope, group, root_group);
2786
/* Determine valid lifetime. */
2787
if (reply->client_valid == 0)
2788
reply->send_valid = DEFAULT_DEFAULT_LEASE_TIME;
2790
reply->send_valid = reply->client_valid;
2792
oc = lookup_option(&server_universe, reply->opt_state,
2793
SV_DEFAULT_LEASE_TIME);
2795
if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
2796
reply->packet->options,
2800
log_error("reply_process_is_addressed: unable to "
2801
"evaluate default lease time");
2802
status = ISC_R_FAILURE;
2806
reply->send_valid = getULong(data.data);
2807
data_string_forget(&data, MDL);
2810
if (reply->client_prefer == 0)
2811
reply->send_prefer = reply->send_valid;
2813
reply->send_prefer = reply->client_prefer;
2815
if (reply->send_prefer >= reply->send_valid)
2816
reply->send_prefer = (reply->send_valid / 2) +
2817
(reply->send_valid / 8);
2819
oc = lookup_option(&server_universe, reply->opt_state,
2820
SV_PREFER_LIFETIME);
2822
if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
2823
reply->packet->options,
2827
log_error("reply_process_is_addressed: unable to "
2828
"evaluate preferred lease time");
2829
status = ISC_R_FAILURE;
2833
reply->send_prefer = getULong(data.data);
2834
data_string_forget(&data, MDL);
2837
/* Note lowest values for later calculation of renew/rebind times. */
2838
if (reply->prefer > reply->send_prefer)
2839
reply->prefer = reply->send_prefer;
2841
if (reply->valid > reply->send_valid)
2842
reply->valid = reply->send_valid;
2846
* XXX: Old 4.0.0 alpha code would change the host {} record
2847
* XXX: uid upon lease assignment. This was intended to cover the
2848
* XXX: case where a client first identifies itself using vendor
2849
* XXX: options in a solicit, or request, but later neglects to include
2850
* XXX: these options in a Renew or Rebind. It is not clear that this
2851
* XXX: is required, and has some startling ramifications (such as
2852
* XXX: how to recover this dynamic host {} state across restarts).
2854
if (reply->host != NULL)
2855
change_host_uid(host, reply->client_id->data,
2856
reply->client_id->len);
2859
/* Perform dynamic lease related update work. */
2860
if (reply->lease != NULL) {
2861
/* Cached lifetimes */
2862
reply->lease->prefer = reply->send_prefer;
2863
reply->lease->valid = reply->send_valid;
2865
/* Advance (or rewind) the valid lifetime. */
2866
if (reply->buf.reply.msg_type == DHCPV6_REPLY) {
2867
reply->lease->soft_lifetime_end_time =
2868
cur_time + reply->send_valid;
2869
/* Wait before renew! */
2872
status = ia_add_iasubopt(reply->ia, reply->lease, MDL);
2873
if (status != ISC_R_SUCCESS) {
2874
log_fatal("reply_process_is_addressed: Unable to "
2875
"attach lease to new IA: %s",
2876
isc_result_totext(status));
2880
* If this is a new lease, make sure it is attached somewhere.
2882
if (reply->lease->ia == NULL) {
2883
ia_reference(&reply->lease->ia, reply->ia, MDL);
2887
/* Bring a copy of the relevant options into the IA scope. */
2888
execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
2889
reply->packet->options, reply->reply_ia,
2890
scope, group, root_group);
2893
if (data.data != NULL)
2894
data_string_forget(&data, MDL);
2896
if (status == ISC_R_SUCCESS)
2897
reply->client_resources++;
2902
/* Simply send an IAADDR within the IA scope as described. */
2904
reply_process_send_addr(struct reply_state *reply, struct iaddr *addr) {
2905
isc_result_t status = ISC_R_SUCCESS;
2906
struct data_string data;
2908
memset(&data, 0, sizeof(data));
2910
/* Now append the lease. */
2911
data.len = IAADDR_OFFSET;
2912
if (!buffer_allocate(&data.buffer, data.len, MDL)) {
2913
log_error("reply_process_send_addr: out of memory"
2914
"allocating new IAADDR buffer.");
2915
status = ISC_R_NOMEMORY;
2918
data.data = data.buffer->data;
2920
memcpy(data.buffer->data, addr->iabuf, 16);
2921
putULong(data.buffer->data + 16, reply->send_prefer);
2922
putULong(data.buffer->data + 20, reply->send_valid);
2924
if (!append_option_buffer(&dhcpv6_universe, reply->reply_ia,
2925
data.buffer, data.buffer->data,
2926
data.len, D6O_IAADDR, 0)) {
2927
log_error("reply_process_send_addr: unable "
2928
"to save IAADDR option");
2929
status = ISC_R_FAILURE;
2933
reply->resources_included = ISC_TRUE;
2936
if (data.data != NULL)
2937
data_string_forget(&data, MDL);
2942
/* Choose the better of two leases. */
2943
static struct iasubopt *
2944
lease_compare(struct iasubopt *alpha, struct iasubopt *beta) {
2950
switch(alpha->state) {
2952
switch(beta->state) {
2954
/* Choose the lease with the longest lifetime (most
2955
* likely the most recently allocated).
2957
if (alpha->hard_lifetime_end_time <
2958
beta->hard_lifetime_end_time)
2968
log_fatal("Impossible condition at %s:%d.", MDL);
2973
switch (beta->state) {
2978
/* Choose the most recently expired lease. */
2979
if (alpha->hard_lifetime_end_time <
2980
beta->hard_lifetime_end_time)
2982
else if ((alpha->hard_lifetime_end_time ==
2983
beta->hard_lifetime_end_time) &&
2984
(alpha->soft_lifetime_end_time <
2985
beta->soft_lifetime_end_time))
2994
log_fatal("Impossible condition at %s:%d.", MDL);
2999
switch (beta->state) {
3005
/* Choose the lease that was abandoned longest ago. */
3006
if (alpha->hard_lifetime_end_time <
3007
beta->hard_lifetime_end_time)
3011
log_fatal("Impossible condition at %s:%d.", MDL);
3016
log_fatal("Impossible condition at %s:%d.", MDL);
3019
log_fatal("Triple impossible condition at %s:%d.", MDL);
3023
/* Process a client-supplied IA_PD. This may append options to the tail of
3024
* the reply packet being built in the reply_state structure.
3027
reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia) {
3028
isc_result_t status = ISC_R_SUCCESS;
3031
struct option_state *packet_ia;
3032
struct option_cache *oc;
3033
struct data_string ia_data, data;
3035
/* Initialize values that will get cleaned up on return. */
3037
memset(&ia_data, 0, sizeof(ia_data));
3038
memset(&data, 0, sizeof(data));
3040
* Note that find_client_prefix() may set reply->lease.
3043
/* Make sure there is at least room for the header. */
3044
if ((reply->cursor + IA_PD_OFFSET + 4) > sizeof(reply->buf)) {
3045
log_error("reply_process_ia_pd: Reply too long for IA.");
3046
return ISC_R_NOSPACE;
3050
/* Fetch the IA_PD contents. */
3051
if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
3052
ia, IA_PD_OFFSET)) {
3053
log_error("reply_process_ia_pd: error evaluating ia");
3054
status = ISC_R_FAILURE;
3058
/* Extract IA_PD header contents. */
3059
iaid = getULong(ia_data.data);
3060
reply->renew = getULong(ia_data.data + 4);
3061
reply->rebind = getULong(ia_data.data + 8);
3063
/* Create an IA_PD structure. */
3064
if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data,
3065
reply->client_id.len, MDL) != ISC_R_SUCCESS) {
3066
log_error("reply_process_ia_pd: no memory for ia.");
3067
status = ISC_R_NOMEMORY;
3070
reply->ia->ia_type = D6O_IA_PD;
3072
/* Cache pre-existing IA_PD, if any. */
3073
ia_hash_lookup(&reply->old_ia, ia_pd_active,
3074
(unsigned char *)reply->ia->iaid_duid.data,
3075
reply->ia->iaid_duid.len, MDL);
3078
* Create an option cache to carry the IA_PD option contents, and
3079
* execute any user-supplied values into it.
3081
if (!option_state_allocate(&reply->reply_ia, MDL)) {
3082
status = ISC_R_NOMEMORY;
3086
/* Check & count the fixed prefix host records. */
3087
reply->static_prefixes = 0;
3088
if ((reply->host != NULL) && (reply->host->fixed_prefix != NULL)) {
3089
struct iaddrcidrnetlist *fp;
3091
for (fp = reply->host->fixed_prefix; fp != NULL;
3093
reply->static_prefixes += 1;
3098
* Save the cursor position at the start of the IA_PD, so we can
3099
* set length and adjust t1/t2 values later. We write a temporary
3100
* header out now just in case we decide to adjust the packet
3101
* within sub-process functions.
3103
ia_cursor = reply->cursor;
3105
/* Initialize the IA_PD header. First the code. */
3106
putUShort(reply->buf.data + reply->cursor, (unsigned)D6O_IA_PD);
3109
/* Then option length. */
3110
putUShort(reply->buf.data + reply->cursor, 0x0Cu);
3113
/* Then IA_PD header contents; IAID. */
3114
putULong(reply->buf.data + reply->cursor, iaid);
3117
/* We store the client's t1 for now, and may over-ride it later. */
3118
putULong(reply->buf.data + reply->cursor, reply->renew);
3121
/* We store the client's t2 for now, and may over-ride it later. */
3122
putULong(reply->buf.data + reply->cursor, reply->rebind);
3126
* For each prefix in this IA_PD, decide what to do about it.
3128
oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAPREFIX);
3129
reply->valid = reply->prefer = 0xffffffff;
3130
reply->client_valid = reply->client_prefer = 0;
3131
reply->preflen = -1;
3132
for (; oc != NULL ; oc = oc->next) {
3133
status = reply_process_prefix(reply, oc);
3136
* Canceled means we did not allocate prefixes to the
3137
* client, but we're "done" with this IA - we set a status
3138
* code. So transmit this reply, e.g., move on to the next
3141
if (status == ISC_R_CANCELED)
3144
if ((status != ISC_R_SUCCESS) && (status != ISC_R_ADDRINUSE))
3151
* If we fell through the above and never gave the client
3152
* a prefix, give it one now.
3154
if ((status != ISC_R_CANCELED) && (reply->client_resources == 0)) {
3155
status = find_client_prefix(reply);
3157
if (status == ISC_R_NORESOURCES) {
3158
switch (reply->packet->dhcpv6_msg_type) {
3159
case DHCPV6_SOLICIT:
3161
* No prefix for any IA is handled
3166
case DHCPV6_REQUEST:
3167
/* Same than for addresses. */
3168
option_state_dereference(&reply->reply_ia, MDL);
3169
if (!option_state_allocate(&reply->reply_ia,
3172
log_error("reply_process_ia_pd: No "
3173
"memory for option state "
3175
status = ISC_R_NOMEMORY;
3179
if (!set_status_code(STATUS_NoPrefixAvail,
3180
"No prefixes available "
3181
"for this interface.",
3183
log_error("reply_process_ia_pd: "
3185
"NoPrefixAvail status "
3187
status = ISC_R_FAILURE;
3191
status = ISC_R_SUCCESS;
3195
if (reply->resources_included)
3196
status = ISC_R_SUCCESS;
3203
if (status != ISC_R_SUCCESS)
3207
reply->cursor += store_options6((char *)reply->buf.data + reply->cursor,
3208
sizeof(reply->buf) - reply->cursor,
3209
reply->reply_ia, reply->packet,
3210
required_opts_IA_PD, NULL);
3212
/* Reset the length of this IA_PD to match what was just written. */
3213
putUShort(reply->buf.data + ia_cursor + 2,
3214
reply->cursor - (ia_cursor + 4));
3217
* T1/T2 time selection is kind of weird. We actually use DHCP
3218
* (v4) scoped options as handy existing places where these might
3219
* be configured by an administrator. A value of zero tells the
3220
* client it may choose its own renewal time.
3223
oc = lookup_option(&dhcp_universe, reply->opt_state,
3224
DHO_DHCP_RENEWAL_TIME);
3226
if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
3227
reply->packet->options,
3228
reply->opt_state, &global_scope,
3231
log_error("Invalid renewal time.");
3233
reply->renew = getULong(data.data);
3236
if (data.data != NULL)
3237
data_string_forget(&data, MDL);
3239
putULong(reply->buf.data + ia_cursor + 8, reply->renew);
3243
oc = lookup_option(&dhcp_universe, reply->opt_state,
3244
DHO_DHCP_REBINDING_TIME);
3246
if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
3247
reply->packet->options,
3248
reply->opt_state, &global_scope,
3251
log_error("Invalid rebinding time.");
3253
reply->rebind = getULong(data.data);
3256
if (data.data != NULL)
3257
data_string_forget(&data, MDL);
3259
putULong(reply->buf.data + ia_cursor + 12, reply->rebind);
3262
* If this is not a 'soft' binding, consume the new changes into
3263
* the database (if any have been attached to the ia_pd).
3265
* Loop through the assigned dynamic prefixes, referencing the
3266
* prefixes onto this IA_PD rather than any old ones, and updating
3267
* prefix pool timers for each (if any).
3269
if ((status != ISC_R_CANCELED) && (reply->static_prefixes == 0) &&
3270
(reply->buf.reply.msg_type == DHCPV6_REPLY) &&
3271
(reply->ia->num_iasubopt != 0)) {
3272
struct iasubopt *tmp;
3273
struct data_string *ia_id;
3276
for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
3277
tmp = reply->ia->iasubopt[i];
3279
if (tmp->ia != NULL)
3280
ia_dereference(&tmp->ia, MDL);
3281
ia_reference(&tmp->ia, reply->ia, MDL);
3283
/* Commit 'hard' bindings. */
3284
tmp->hard_lifetime_end_time =
3285
tmp->soft_lifetime_end_time;
3286
tmp->soft_lifetime_end_time = 0;
3287
renew_lease6(tmp->ipv6_pool, tmp);
3288
schedule_lease_timeout(tmp->ipv6_pool);
3291
/* Remove any old ia from the hash. */
3292
if (reply->old_ia != NULL) {
3293
ia_id = &reply->old_ia->iaid_duid;
3294
ia_hash_delete(ia_pd_active,
3295
(unsigned char *)ia_id->data,
3297
ia_dereference(&reply->old_ia, MDL);
3300
/* Put new ia into the hash. */
3301
reply->ia->cltt = cur_time;
3302
ia_id = &reply->ia->iaid_duid;
3303
ia_hash_add(ia_pd_active, (unsigned char *)ia_id->data,
3304
ia_id->len, reply->ia, MDL);
3306
write_ia(reply->ia);
3310
if (packet_ia != NULL)
3311
option_state_dereference(&packet_ia, MDL);
3312
if (reply->reply_ia != NULL)
3313
option_state_dereference(&reply->reply_ia, MDL);
3314
if (ia_data.data != NULL)
3315
data_string_forget(&ia_data, MDL);
3316
if (data.data != NULL)
3317
data_string_forget(&data, MDL);
3318
if (reply->ia != NULL)
3319
ia_dereference(&reply->ia, MDL);
3320
if (reply->old_ia != NULL)
3321
ia_dereference(&reply->old_ia, MDL);
3322
if (reply->lease != NULL)
3323
iasubopt_dereference(&reply->lease, MDL);
3326
* ISC_R_CANCELED is a status code used by the prefix processing to
3327
* indicate we're replying with a status code. This is still a
3328
* success at higher layers.
3330
return((status == ISC_R_CANCELED) ? ISC_R_SUCCESS : status);
3334
* Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
3335
* contents into the reply's current ia_pd-scoped option cache. Returns
3336
* ISC_R_CANCELED in the event we are replying with a status code and do
3337
* not wish to process more IAPREFIXes within this IA_PD.
3340
reply_process_prefix(struct reply_state *reply, struct option_cache *pref) {
3341
u_int32_t pref_life, valid_life;
3342
struct binding_scope **scope;
3343
struct group *group;
3344
struct iaddrcidrnet tmp_pref;
3345
struct option_cache *oc;
3346
struct data_string iapref, data;
3347
isc_result_t status = ISC_R_SUCCESS;
3349
/* Initializes values that will be cleaned up. */
3350
memset(&iapref, 0, sizeof(iapref));
3351
memset(&data, 0, sizeof(data));
3352
/* Note that reply->lease may be set by prefix_is_owned() */
3355
* There is no point trying to process an incoming prefix if there
3356
* is no room for an outgoing prefix.
3358
if ((reply->cursor + 29) > sizeof(reply->buf)) {
3359
log_error("reply_process_prefix: Out of room for prefix.");
3360
return ISC_R_NOSPACE;
3363
/* Extract this IAPREFIX option. */
3364
if (!evaluate_option_cache(&iapref, reply->packet, NULL, NULL,
3365
reply->packet->options, NULL, &global_scope,
3367
(iapref.len < IAPREFIX_OFFSET)) {
3368
log_error("reply_process_prefix: error evaluating IAPREFIX.");
3369
status = ISC_R_FAILURE;
3374
* Layout: preferred and valid lifetimes followed by the prefix
3375
* length and the IPv6 address.
3377
pref_life = getULong(iapref.data);
3378
valid_life = getULong(iapref.data + 4);
3380
if ((reply->client_valid == 0) ||
3381
(reply->client_valid > valid_life))
3382
reply->client_valid = valid_life;
3384
if ((reply->client_prefer == 0) ||
3385
(reply->client_prefer > pref_life))
3386
reply->client_prefer = pref_life;
3389
* Clients may choose to send ::/0 as a prefix, with the idea to give
3390
* hints about preferred-lifetime or valid-lifetime.
3392
tmp_pref.lo_addr.len = 16;
3393
memset(tmp_pref.lo_addr.iabuf, 0, 16);
3394
if ((iapref.data[8] == 0) &&
3395
(memcmp(iapref.data + 9, tmp_pref.lo_addr.iabuf, 16) == 0)) {
3396
/* Status remains success; we just ignore this one. */
3401
* Clients may choose to send ::/X as a prefix to specify a
3402
* preferred/requested prefix length. Note X is never zero here.
3404
tmp_pref.bits = (int) iapref.data[8];
3405
if (reply->preflen < 0) {
3406
/* Cache the first preferred prefix length. */
3407
reply->preflen = tmp_pref.bits;
3409
if (memcmp(iapref.data + 9, tmp_pref.lo_addr.iabuf, 16) == 0) {
3413
memcpy(tmp_pref.lo_addr.iabuf, iapref.data + 9, 16);
3415
/* Verify the prefix belongs to the client. */
3416
if (!prefix_is_owned(reply, &tmp_pref)) {
3417
/* Same than for addresses. */
3418
if ((reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) ||
3419
(reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) ||
3420
(reply->packet->dhcpv6_msg_type == DHCPV6_REBIND)) {
3421
status = reply_process_try_prefix(reply, &tmp_pref);
3423
/* Either error out or skip this prefix. */
3424
if ((status != ISC_R_SUCCESS) &&
3425
(status != ISC_R_ADDRINUSE))
3428
if (reply->lease == NULL) {
3429
if (reply->packet->dhcpv6_msg_type ==
3431
reply->send_prefer = 0;
3432
reply->send_valid = 0;
3436
/* status remains success - ignore */
3440
* RFC3633 section 18.2.3:
3442
* If the delegating router cannot find a binding
3443
* for the requesting router's IA_PD the delegating
3444
* router returns the IA_PD containing no prefixes
3445
* with a Status Code option set to NoBinding in the
3448
* On mismatch we (ab)use this pretending we have not the IA
3449
* as soon as we have not a prefix.
3451
} else if (reply->packet->dhcpv6_msg_type == DHCPV6_RENEW) {
3452
/* Rewind the IA_PD to empty. */
3453
option_state_dereference(&reply->reply_ia, MDL);
3454
if (!option_state_allocate(&reply->reply_ia, MDL)) {
3455
log_error("reply_process_prefix: No memory "
3456
"for option state wipe.");
3457
status = ISC_R_NOMEMORY;
3461
/* Append a NoBinding status code. */
3462
if (!set_status_code(STATUS_NoBinding,
3463
"Prefix not bound to this "
3464
"interface.", reply->reply_ia)) {
3465
log_error("reply_process_prefix: Unable to "
3466
"attach status code.");
3467
status = ISC_R_FAILURE;
3471
/* Fin (no more IAPREFIXes). */
3472
status = ISC_R_CANCELED;
3475
log_error("It is impossible to lease a client that is "
3476
"not sending a solicit, request, renew, or "
3478
status = ISC_R_FAILURE;
3483
if (reply->static_prefixes > 0) {
3484
if (reply->host == NULL)
3485
log_fatal("Impossible condition at %s:%d.", MDL);
3487
scope = &global_scope;
3488
group = reply->host->group;
3490
if (reply->lease == NULL)
3491
log_fatal("Impossible condition at %s:%d.", MDL);
3493
scope = &reply->lease->scope;
3494
group = reply->shared->group;
3498
* If client_resources is nonzero, then the reply_process_is_prefixed
3499
* function has executed configuration state into the reply option
3500
* cache. We will use that valid cache to derive configuration for
3501
* whether or not to engage in additional prefixes, and similar.
3503
if (reply->client_resources != 0) {
3507
* Does this client have "enough" prefixes already? Default
3508
* to one. Everybody gets one, and one should be enough for
3511
oc = lookup_option(&server_universe, reply->opt_state,
3512
SV_LIMIT_PREFS_PER_IA);
3514
if (!evaluate_option_cache(&data, reply->packet,
3516
reply->packet->options,
3520
log_error("reply_process_prefix: unable to "
3521
"evaluate prefs-per-ia value.");
3522
status = ISC_R_FAILURE;
3526
limit = getULong(data.data);
3527
data_string_forget(&data, MDL);
3531
* If we wish to limit the client to a certain number of
3532
* prefixes, then omit the prefix from the reply.
3534
if (reply->client_resources >= limit)
3538
status = reply_process_is_prefixed(reply, scope, group);
3539
if (status != ISC_R_SUCCESS)
3543
status = reply_process_send_prefix(reply, &tmp_pref);
3546
if (iapref.data != NULL)
3547
data_string_forget(&iapref, MDL);
3548
if (data.data != NULL)
3549
data_string_forget(&data, MDL);
3550
if (reply->lease != NULL)
3551
iasubopt_dereference(&reply->lease, MDL);
3557
* Verify the prefix belongs to the client. If we've got a host
3558
* record with fixed prefixes, it has to be an assigned prefix
3559
* (fault out all else). Otherwise it's a dynamic prefix, so lookup
3560
* that prefix and make sure it belongs to this DUID:IAID pair.
3562
static isc_boolean_t
3563
prefix_is_owned(struct reply_state *reply, struct iaddrcidrnet *pref) {
3564
struct iaddrcidrnetlist *l;
3568
* This faults out prefixes that don't match fixed prefixes.
3570
if (reply->static_prefixes > 0) {
3571
for (l = reply->host->fixed_prefix; l != NULL; l = l->next) {
3572
if ((pref->bits == l->cidrnet.bits) &&
3573
(memcmp(pref->lo_addr.iabuf,
3574
l->cidrnet.lo_addr.iabuf, 16) == 0))
3580
if ((reply->old_ia == NULL) ||
3581
(reply->old_ia->num_iasubopt == 0))
3584
for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
3585
struct iasubopt *tmp;
3587
tmp = reply->old_ia->iasubopt[i];
3589
if ((pref->bits == (int) tmp->plen) &&
3590
memcmp(pref->lo_addr.iabuf, &tmp->addr, 16) == 0) {
3591
iasubopt_reference(&reply->lease, tmp, MDL);
3600
* This function only returns failure on 'hard' failures. If it succeeds,
3601
* it will leave a prefix structure behind.
3604
reply_process_try_prefix(struct reply_state *reply,
3605
struct iaddrcidrnet *pref) {
3606
isc_result_t status = ISC_R_NORESOURCES;
3607
struct ipv6_pool *pool;
3609
struct data_string data_pref;
3611
if ((reply == NULL) || (reply->shared == NULL) ||
3612
(reply->shared->ipv6_pools == NULL) || (pref == NULL) ||
3613
(reply->lease != NULL))
3614
return ISC_R_INVALIDARG;
3616
memset(&data_pref, 0, sizeof(data_pref));
3618
if (!buffer_allocate(&data_pref.buffer, data_pref.len, MDL)) {
3619
log_error("reply_process_try_prefix: out of memory.");
3620
return ISC_R_NOMEMORY;
3622
data_pref.data = data_pref.buffer->data;
3623
data_pref.buffer->data[0] = (u_int8_t) pref->bits;
3624
memcpy(data_pref.buffer->data + 1, pref->lo_addr.iabuf, 16);
3626
for (i = 0 ; (pool = reply->shared->ipv6_pools[i]) != NULL ; i++) {
3627
if (pool->pool_type != D6O_IA_PD)
3629
status = try_client_v6_prefix(&reply->lease, pool,
3631
if (status == ISC_R_SUCCESS)
3635
data_string_forget(&data_pref, MDL);
3636
/* Return just the most recent status... */
3640
/* Look around for a prefix to give the client. First, look through the old
3641
* IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
3642
* Finally, actually add that prefix into the current reply IA_PD.
3645
find_client_prefix(struct reply_state *reply) {
3646
struct iaddrcidrnet send_pref;
3647
isc_result_t status = ISC_R_NORESOURCES;
3648
struct iasubopt *prefix, *best_prefix = NULL;
3649
struct binding_scope **scope;
3650
struct group *group;
3653
if (reply->host != NULL)
3654
group = reply->host->group;
3656
group = reply->shared->group;
3658
if (reply->static_prefixes > 0) {
3659
struct iaddrcidrnetlist *l;
3661
if (reply->host == NULL)
3662
return ISC_R_INVALIDARG;
3664
for (l = reply->host->fixed_prefix; l != NULL; l = l->next) {
3665
if (l->cidrnet.bits == reply->preflen)
3670
* If no fixed prefix has the preferred length,
3671
* get the first one.
3673
l = reply->host->fixed_prefix;
3675
memcpy(&send_pref, &l->cidrnet, sizeof(send_pref));
3677
status = ISC_R_SUCCESS;
3678
scope = &global_scope;
3682
if (reply->old_ia != NULL) {
3683
for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
3684
prefix = reply->old_ia->iasubopt[i];
3686
best_prefix = prefix_compare(reply, prefix,
3691
/* Try to pick a new prefix if we didn't find one, or if we found an
3694
if ((best_prefix == NULL) || (best_prefix->state == FTS_ABANDONED)) {
3695
status = pick_v6_prefix(&reply->lease, reply->preflen,
3696
reply->shared, &reply->client_id);
3697
} else if (best_prefix != NULL) {
3698
iasubopt_reference(&reply->lease, best_prefix, MDL);
3699
status = ISC_R_SUCCESS;
3702
/* Pick the abandoned prefix as a last resort. */
3703
if ((status == ISC_R_NORESOURCES) && (best_prefix != NULL)) {
3704
/* I don't see how this is supposed to be done right now. */
3705
log_error("Reclaiming abandoned prefixes is not yet "
3706
"supported. Treating this as an out of space "
3708
/* iasubopt_reference(&reply->lease, best_prefix, MDL); */
3711
/* Give up now if we didn't find a prefix. */
3712
if (status != ISC_R_SUCCESS)
3715
if (reply->lease == NULL)
3716
log_fatal("Impossible condition at %s:%d.", MDL);
3718
scope = &reply->lease->scope;
3719
group = reply->shared->group;
3721
send_pref.lo_addr.len = 16;
3722
memcpy(send_pref.lo_addr.iabuf, &reply->lease->addr, 16);
3723
send_pref.bits = (int) reply->lease->plen;
3726
status = reply_process_is_prefixed(reply, scope, group);
3727
if (status != ISC_R_SUCCESS)
3730
status = reply_process_send_prefix(reply, &send_pref);
3734
/* Once a prefix is found for a client, perform several common functions;
3735
* Calculate and store valid and preferred prefix times, draw client options
3736
* into the option state.
3739
reply_process_is_prefixed(struct reply_state *reply,
3740
struct binding_scope **scope, struct group *group)
3742
isc_result_t status = ISC_R_SUCCESS;
3743
struct data_string data;
3744
struct option_cache *oc;
3746
/* Initialize values we will cleanup. */
3747
memset(&data, 0, sizeof(data));
3749
/* Execute relevant options into root scope. */
3750
execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3751
reply->packet->options, reply->opt_state,
3752
scope, group, root_group);
3754
/* Determine valid lifetime. */
3755
if (reply->client_valid == 0)
3756
reply->send_valid = DEFAULT_DEFAULT_LEASE_TIME;
3758
reply->send_valid = reply->client_valid;
3760
oc = lookup_option(&server_universe, reply->opt_state,
3761
SV_DEFAULT_LEASE_TIME);
3763
if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
3764
reply->packet->options,
3768
log_error("reply_process_is_prefixed: unable to "
3769
"evaluate default prefix time");
3770
status = ISC_R_FAILURE;
3774
reply->send_valid = getULong(data.data);
3775
data_string_forget(&data, MDL);
3778
if (reply->client_prefer == 0)
3779
reply->send_prefer = reply->send_valid;
3781
reply->send_prefer = reply->client_prefer;
3783
if (reply->send_prefer >= reply->send_valid)
3784
reply->send_prefer = (reply->send_valid / 2) +
3785
(reply->send_valid / 8);
3787
oc = lookup_option(&server_universe, reply->opt_state,
3788
SV_PREFER_LIFETIME);
3790
if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
3791
reply->packet->options,
3795
log_error("reply_process_is_prefixed: unable to "
3796
"evaluate preferred prefix time");
3797
status = ISC_R_FAILURE;
3801
reply->send_prefer = getULong(data.data);
3802
data_string_forget(&data, MDL);
3805
/* Note lowest values for later calculation of renew/rebind times. */
3806
if (reply->prefer > reply->send_prefer)
3807
reply->prefer = reply->send_prefer;
3809
if (reply->valid > reply->send_valid)
3810
reply->valid = reply->send_valid;
3812
/* Perform dynamic prefix related update work. */
3813
if (reply->lease != NULL) {
3814
/* Cached lifetimes */
3815
reply->lease->prefer = reply->send_prefer;
3816
reply->lease->valid = reply->send_valid;
3818
/* Advance (or rewind) the valid lifetime. */
3819
if (reply->buf.reply.msg_type == DHCPV6_REPLY) {
3820
reply->lease->soft_lifetime_end_time =
3821
cur_time + reply->send_valid;
3822
/* Wait before renew! */
3825
status = ia_add_iasubopt(reply->ia, reply->lease, MDL);
3826
if (status != ISC_R_SUCCESS) {
3827
log_fatal("reply_process_is_prefixed: Unable to "
3828
"attach prefix to new IA_PD: %s",
3829
isc_result_totext(status));
3833
* If this is a new prefix, make sure it is attached somewhere.
3835
if (reply->lease->ia == NULL) {
3836
ia_reference(&reply->lease->ia, reply->ia, MDL);
3840
/* Bring a copy of the relevant options into the IA_PD scope. */
3841
execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3842
reply->packet->options, reply->reply_ia,
3843
scope, group, root_group);
3846
if (data.data != NULL)
3847
data_string_forget(&data, MDL);
3849
if (status == ISC_R_SUCCESS)
3850
reply->client_resources++;
3855
/* Simply send an IAPREFIX within the IA_PD scope as described. */
3857
reply_process_send_prefix(struct reply_state *reply,
3858
struct iaddrcidrnet *pref) {
3859
isc_result_t status = ISC_R_SUCCESS;
3860
struct data_string data;
3862
memset(&data, 0, sizeof(data));
3864
/* Now append the prefix. */
3865
data.len = IAPREFIX_OFFSET;
3866
if (!buffer_allocate(&data.buffer, data.len, MDL)) {
3867
log_error("reply_process_send_prefix: out of memory"
3868
"allocating new IAPREFIX buffer.");
3869
status = ISC_R_NOMEMORY;
3872
data.data = data.buffer->data;
3874
putULong(data.buffer->data, reply->send_prefer);
3875
putULong(data.buffer->data + 4, reply->send_valid);
3876
data.buffer->data[8] = pref->bits;
3877
memcpy(data.buffer->data + 9, pref->lo_addr.iabuf, 16);
3879
if (!append_option_buffer(&dhcpv6_universe, reply->reply_ia,
3880
data.buffer, data.buffer->data,
3881
data.len, D6O_IAPREFIX, 0)) {
3882
log_error("reply_process_send_prefix: unable "
3883
"to save IAPREFIX option");
3884
status = ISC_R_FAILURE;
3888
reply->resources_included = ISC_TRUE;
3891
if (data.data != NULL)
3892
data_string_forget(&data, MDL);
3897
/* Choose the better of two prefixes. */
3898
static struct iasubopt *
3899
prefix_compare(struct reply_state *reply,
3900
struct iasubopt *alpha, struct iasubopt *beta) {
3906
if (reply->preflen >= 0) {
3907
if ((alpha->plen == reply->preflen) &&
3908
(beta->plen != reply->preflen))
3910
if ((beta->plen == reply->preflen) &&
3911
(alpha->plen != reply->preflen))
3915
switch(alpha->state) {
3917
switch(beta->state) {
3919
/* Choose the prefix with the longest lifetime (most
3920
* likely the most recently allocated).
3922
if (alpha->hard_lifetime_end_time <
3923
beta->hard_lifetime_end_time)
3933
log_fatal("Impossible condition at %s:%d.", MDL);
3938
switch (beta->state) {
3943
/* Choose the most recently expired prefix. */
3944
if (alpha->hard_lifetime_end_time <
3945
beta->hard_lifetime_end_time)
3947
else if ((alpha->hard_lifetime_end_time ==
3948
beta->hard_lifetime_end_time) &&
3949
(alpha->soft_lifetime_end_time <
3950
beta->soft_lifetime_end_time))
3959
log_fatal("Impossible condition at %s:%d.", MDL);
3964
switch (beta->state) {
3970
/* Choose the prefix that was abandoned longest ago. */
3971
if (alpha->hard_lifetime_end_time <
3972
beta->hard_lifetime_end_time)
3976
log_fatal("Impossible condition at %s:%d.", MDL);
3981
log_fatal("Impossible condition at %s:%d.", MDL);
3984
log_fatal("Triple impossible condition at %s:%d.", MDL);
3989
* Solicit is how a client starts requesting addresses.
3991
* If the client asks for rapid commit, and we support it, we will
3992
* allocate the addresses and reply.
3994
* Otherwise we will send an advertise message.
3998
dhcpv6_solicit(struct data_string *reply_ret, struct packet *packet) {
3999
struct data_string client_id;
4002
* Validate our input.
4004
if (!valid_client_msg(packet, &client_id)) {
4008
lease_to_client(reply_ret, packet, &client_id, NULL);
4013
data_string_forget(&client_id, MDL);
4017
* Request is how a client actually requests addresses.
4019
* Very similar to Solicit handling, except the server DUID is required.
4022
/* TODO: reject unicast messages, unless we set unicast option */
4024
dhcpv6_request(struct data_string *reply_ret, struct packet *packet) {
4025
struct data_string client_id;
4026
struct data_string server_id;
4029
* Validate our input.
4031
if (!valid_client_resp(packet, &client_id, &server_id)) {
4038
lease_to_client(reply_ret, packet, &client_id, &server_id);
4043
data_string_forget(&client_id, MDL);
4044
data_string_forget(&server_id, MDL);
4047
/* Find a DHCPv6 packet's shared network from hints in the packet.
4050
shared_network_from_packet6(struct shared_network **shared,
4051
struct packet *packet)
4053
const struct packet *chk_packet;
4054
const struct in6_addr *link_addr, *first_link_addr;
4055
struct iaddr tmp_addr;
4056
struct subnet *subnet;
4057
isc_result_t status;
4059
if ((shared == NULL) || (*shared != NULL) || (packet == NULL))
4060
return ISC_R_INVALIDARG;
4063
* First, find the link address where the packet from the client
4064
* first appeared (if this packet was relayed).
4066
first_link_addr = NULL;
4067
chk_packet = packet->dhcpv6_container_packet;
4068
while (chk_packet != NULL) {
4069
link_addr = &chk_packet->dhcpv6_link_address;
4070
if (!IN6_IS_ADDR_UNSPECIFIED(link_addr) &&
4071
!IN6_IS_ADDR_LINKLOCAL(link_addr)) {
4072
first_link_addr = link_addr;
4075
chk_packet = chk_packet->dhcpv6_container_packet;
4079
* If there is a relayed link address, find the subnet associated
4080
* with that, and use that to get the appropriate
4083
if (first_link_addr != NULL) {
4084
tmp_addr.len = sizeof(*first_link_addr);
4085
memcpy(tmp_addr.iabuf,
4086
first_link_addr, sizeof(*first_link_addr));
4088
if (!find_subnet(&subnet, tmp_addr, MDL)) {
4089
log_debug("No subnet found for link-address %s.",
4091
return ISC_R_NOTFOUND;
4093
status = shared_network_reference(shared,
4094
subnet->shared_network, MDL);
4095
subnet_dereference(&subnet, MDL);
4098
* If there is no link address, we will use the interface
4099
* that this packet came in on to pick the shared_network.
4102
status = shared_network_reference(shared,
4103
packet->interface->shared_network,
4111
* When a client thinks it might be on a new link, it sends a
4114
* From RFC3315 section 18.2.2:
4116
* When the server receives a Confirm message, the server determines
4117
* whether the addresses in the Confirm message are appropriate for the
4118
* link to which the client is attached. If all of the addresses in the
4119
* Confirm message pass this test, the server returns a status of
4120
* Success. If any of the addresses do not pass this test, the server
4121
* returns a status of NotOnLink. If the server is unable to perform
4122
* this test (for example, the server does not have information about
4123
* prefixes on the link to which the client is connected), or there were
4124
* no addresses in any of the IAs sent by the client, the server MUST
4125
* NOT send a reply to the client.
4129
dhcpv6_confirm(struct data_string *reply_ret, struct packet *packet) {
4130
struct shared_network *shared;
4131
struct subnet *subnet;
4132
struct option_cache *ia, *ta, *oc;
4133
struct data_string cli_enc_opt_data, iaaddr, client_id, packet_oro;
4134
struct option_state *cli_enc_opt_state, *opt_state;
4135
struct iaddr cli_addr;
4137
isc_boolean_t inappropriate, has_addrs;
4138
char reply_data[65536];
4139
struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data;
4140
int reply_ofs = (int)((char *)reply->options - (char *)reply);
4143
* Basic client message validation.
4145
memset(&client_id, 0, sizeof(client_id));
4146
if (!valid_client_msg(packet, &client_id)) {
4151
* Do not process Confirms that do not have IA's we do not recognize.
4153
ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
4154
ta = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_TA);
4155
if ((ia == NULL) && (ta == NULL))
4159
* IA_PD's are simply ignored.
4161
delete_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
4164
* Bit of variable initialization.
4166
opt_state = cli_enc_opt_state = NULL;
4167
memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
4168
memset(&iaaddr, 0, sizeof(iaaddr));
4169
memset(&packet_oro, 0, sizeof(packet_oro));
4171
/* Determine what shared network the client is connected to. We
4172
* must not respond if we don't have any information about the
4173
* network the client is on.
4176
if ((shared_network_from_packet6(&shared, packet) != ISC_R_SUCCESS) ||
4180
/* If there are no recorded subnets, then we have no
4181
* information about this subnet - ignore Confirms.
4183
subnet = shared->subnets;
4187
/* Are the addresses in all the IA's appropriate for that link? */
4188
has_addrs = inappropriate = ISC_FALSE;
4190
while(!inappropriate) {
4191
/* If we've reached the end of the IA_NA pass, move to the
4194
if ((pass == D6O_IA_NA) && (ia == NULL)) {
4199
/* If we've reached the end of all passes, we're done. */
4203
if (((pass == D6O_IA_NA) &&
4204
!get_encapsulated_IA_state(&cli_enc_opt_state,
4206
packet, ia, IA_NA_OFFSET)) ||
4207
((pass == D6O_IA_TA) &&
4208
!get_encapsulated_IA_state(&cli_enc_opt_state,
4210
packet, ia, IA_TA_OFFSET))) {
4214
oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
4217
for ( ; oc != NULL ; oc = oc->next) {
4218
if (!evaluate_option_cache(&iaaddr, packet, NULL, NULL,
4219
packet->options, NULL,
4220
&global_scope, oc, MDL) ||
4221
(iaaddr.len < IAADDR_OFFSET)) {
4222
log_error("dhcpv6_confirm: "
4223
"error evaluating IAADDR.");
4227
/* Copy out the IPv6 address for processing. */
4229
memcpy(cli_addr.iabuf, iaaddr.data, 16);
4231
data_string_forget(&iaaddr, MDL);
4233
/* Record that we've processed at least one address. */
4234
has_addrs = ISC_TRUE;
4236
/* Find out if any subnets cover this address. */
4237
for (subnet = shared->subnets ; subnet != NULL ;
4238
subnet = subnet->next_sibling) {
4239
if (addr_eq(subnet_number(cli_addr,
4245
/* If we reach the end of the subnet list, and no
4246
* subnet matches the client address, then it must
4247
* be inappropriate to the link (so far as our
4248
* configuration says). Once we've found one
4249
* inappropriate address, there is no reason to
4250
* continue searching.
4252
if (subnet == NULL) {
4253
inappropriate = ISC_TRUE;
4258
option_state_dereference(&cli_enc_opt_state, MDL);
4259
data_string_forget(&cli_enc_opt_data, MDL);
4261
/* Advance to the next IA_*. */
4265
/* If the client supplied no addresses, do not reply. */
4272
if (!start_reply(packet, &client_id, NULL, &opt_state, reply)) {
4279
if (inappropriate) {
4280
if (!set_status_code(STATUS_NotOnLink,
4281
"Some of the addresses are not on link.",
4286
if (!set_status_code(STATUS_Success,
4287
"All addresses still on link.",
4294
* Only one option: add it.
4296
reply_ofs += store_options6(reply_data+reply_ofs,
4297
sizeof(reply_data)-reply_ofs,
4299
required_opts, &packet_oro);
4302
* Return our reply to the caller.
4304
reply_ret->len = reply_ofs;
4305
reply_ret->buffer = NULL;
4306
if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) {
4307
log_fatal("No memory to store reply.");
4309
reply_ret->data = reply_ret->buffer->data;
4310
memcpy(reply_ret->buffer->data, reply, reply_ofs);
4313
/* Cleanup any stale data strings. */
4314
if (cli_enc_opt_data.buffer != NULL)
4315
data_string_forget(&cli_enc_opt_data, MDL);
4316
if (iaaddr.buffer != NULL)
4317
data_string_forget(&iaaddr, MDL);
4318
if (client_id.buffer != NULL)
4319
data_string_forget(&client_id, MDL);
4320
if (packet_oro.buffer != NULL)
4321
data_string_forget(&packet_oro, MDL);
4323
/* Release any stale option states. */
4324
if (cli_enc_opt_state != NULL)
4325
option_state_dereference(&cli_enc_opt_state, MDL);
4326
if (opt_state != NULL)
4327
option_state_dereference(&opt_state, MDL);
4331
* Renew is when a client wants to extend its lease/prefix, at time T1.
4333
* We handle this the same as if the client wants a new lease/prefix,
4334
* except for the error code of when addresses don't match.
4337
/* TODO: reject unicast messages, unless we set unicast option */
4339
dhcpv6_renew(struct data_string *reply, struct packet *packet) {
4340
struct data_string client_id;
4341
struct data_string server_id;
4344
* Validate the request.
4346
if (!valid_client_resp(packet, &client_id, &server_id)) {
4353
lease_to_client(reply, packet, &client_id, &server_id);
4358
data_string_forget(&server_id, MDL);
4359
data_string_forget(&client_id, MDL);
4363
* Rebind is when a client wants to extend its lease, at time T2.
4365
* We handle this the same as if the client wants a new lease, except
4366
* for the error code of when addresses don't match.
4370
dhcpv6_rebind(struct data_string *reply, struct packet *packet) {
4371
struct data_string client_id;
4373
if (!valid_client_msg(packet, &client_id)) {
4377
lease_to_client(reply, packet, &client_id, NULL);
4379
data_string_forget(&client_id, MDL);
4383
ia_na_match_decline(const struct data_string *client_id,
4384
const struct data_string *iaaddr,
4385
struct iasubopt *lease)
4387
char tmp_addr[INET6_ADDRSTRLEN];
4389
log_error("Client %s reports address %s is "
4390
"already in use by another host!",
4391
print_hex_1(client_id->len, client_id->data, 60),
4392
inet_ntop(AF_INET6, iaaddr->data,
4393
tmp_addr, sizeof(tmp_addr)));
4394
if (lease != NULL) {
4395
decline_lease6(lease->ipv6_pool, lease);
4396
lease->ia->cltt = cur_time;
4397
write_ia(lease->ia);
4402
ia_na_nomatch_decline(const struct data_string *client_id,
4403
const struct data_string *iaaddr,
4404
u_int32_t *ia_na_id,
4405
struct packet *packet,
4410
char tmp_addr[INET6_ADDRSTRLEN];
4411
struct option_state *host_opt_state;
4414
log_info("Client %s declines address %s, which is not offered to it.",
4415
print_hex_1(client_id->len, client_id->data, 60),
4416
inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
4419
* Create state for this IA_NA.
4421
host_opt_state = NULL;
4422
if (!option_state_allocate(&host_opt_state, MDL)) {
4423
log_error("ia_na_nomatch_decline: out of memory "
4424
"allocating option_state.");
4428
if (!set_status_code(STATUS_NoBinding, "Decline for unknown address.",
4434
* Insure we have enough space
4436
if (reply_len < (*reply_ofs + 16)) {
4437
log_error("ia_na_nomatch_decline: "
4438
"out of space for reply packet.");
4443
* Put our status code into the reply packet.
4445
len = store_options6(reply_data+(*reply_ofs)+16,
4446
reply_len-(*reply_ofs)-16,
4447
host_opt_state, packet,
4448
required_opts_STATUS_CODE, NULL);
4451
* Store the non-encapsulated option data for this
4452
* IA_NA into our reply packet. Defined in RFC 3315,
4456
putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_NA);
4458
putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
4459
/* IA_NA, copied from the client */
4460
memcpy(reply_data+(*reply_ofs)+4, ia_na_id, 4);
4461
/* t1 and t2, odd that we need them, but here it is */
4462
putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
4463
putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
4466
* Get ready for next IA_NA.
4468
*reply_ofs += (len + 16);
4471
option_state_dereference(&host_opt_state, MDL);
4475
iterate_over_ia_na(struct data_string *reply_ret,
4476
struct packet *packet,
4477
const struct data_string *client_id,
4478
const struct data_string *server_id,
4479
const char *packet_type,
4480
void (*ia_na_match)(),
4481
void (*ia_na_nomatch)())
4483
struct option_state *opt_state;
4484
struct host_decl *packet_host;
4485
struct option_cache *ia;
4486
struct option_cache *oc;
4487
/* cli_enc_... variables come from the IA_NA/IA_TA options */
4488
struct data_string cli_enc_opt_data;
4489
struct option_state *cli_enc_opt_state;
4490
struct host_decl *host;
4491
struct option_state *host_opt_state;
4492
struct data_string iaaddr;
4493
struct data_string fixed_addr;
4494
int iaaddr_is_found;
4495
char reply_data[65536];
4496
struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data;
4497
int reply_ofs = (int)((char *)reply->options - (char *)reply);
4498
char status_msg[32];
4499
struct iasubopt *lease;
4500
struct ia_xx *existing_ia_na;
4502
struct data_string key;
4506
* Initialize to empty values, in case we have to exit early.
4509
memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
4510
cli_enc_opt_state = NULL;
4511
memset(&iaaddr, 0, sizeof(iaaddr));
4512
memset(&fixed_addr, 0, sizeof(fixed_addr));
4513
host_opt_state = NULL;
4517
* Find the host record that matches from the packet, if any.
4520
if (!find_hosts_by_uid(&packet_host,
4521
client_id->data, client_id->len, MDL)) {
4524
* Note: In general, we don't expect a client to provide
4525
* enough information to match by option for these
4526
* types of messages, but if we don't have a UID
4527
* match we can check anyway.
4529
if (!find_hosts_by_option(&packet_host,
4530
packet, packet->options, MDL)) {
4536
* Set our reply information.
4538
reply->msg_type = DHCPV6_REPLY;
4539
memcpy(reply->transaction_id, packet->dhcpv6_transaction_id,
4540
sizeof(reply->transaction_id));
4543
* Build our option state for reply.
4546
if (!option_state_allocate(&opt_state, MDL)) {
4547
log_error("iterate_over_ia_na: no memory for option_state.");
4550
execute_statements_in_scope(NULL, packet, NULL, NULL,
4551
packet->options, opt_state,
4552
&global_scope, root_group, NULL);
4555
* RFC 3315, section 18.2.7 tells us which options to include.
4557
oc = lookup_option(&dhcpv6_universe, opt_state, D6O_SERVERID);
4559
if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
4560
(unsigned char *)server_duid.data,
4561
server_duid.len, D6O_SERVERID, 0)) {
4562
log_error("iterate_over_ia_na: "
4563
"error saving server identifier.");
4568
if (!save_option_buffer(&dhcpv6_universe, opt_state,
4570
(unsigned char *)client_id->data,
4573
log_error("iterate_over_ia_na: "
4574
"error saving client identifier.");
4578
snprintf(status_msg, sizeof(status_msg), "%s received.", packet_type);
4579
if (!set_status_code(STATUS_Success, status_msg, opt_state)) {
4584
* Add our options that are not associated with any IA_NA or IA_TA.
4586
reply_ofs += store_options6(reply_data+reply_ofs,
4587
sizeof(reply_data)-reply_ofs,
4589
required_opts, NULL);
4592
* Loop through the IA_NA reported by the client, and deal with
4593
* addresses reported as already in use.
4595
for (ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
4596
ia != NULL; ia = ia->next) {
4597
iaaddr_is_found = 0;
4599
if (!get_encapsulated_IA_state(&cli_enc_opt_state,
4601
packet, ia, IA_NA_OFFSET)) {
4605
iaid = getULong(cli_enc_opt_data.data);
4608
* XXX: It is possible that we can get multiple addresses
4609
* sent by the client. We don't send multiple
4610
* addresses, so this indicates a client error.
4611
* We should check for multiple IAADDR options, log
4612
* if found, and set as an error.
4614
oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
4617
/* no address given for this IA, ignore */
4618
option_state_dereference(&cli_enc_opt_state, MDL);
4619
data_string_forget(&cli_enc_opt_data, MDL);
4623
memset(&iaaddr, 0, sizeof(iaaddr));
4624
if (!evaluate_option_cache(&iaaddr, packet, NULL, NULL,
4625
packet->options, NULL,
4626
&global_scope, oc, MDL)) {
4627
log_error("iterate_over_ia_na: "
4628
"error evaluating IAADDR.");
4633
* Now we need to figure out which host record matches
4634
* this IA_NA and IAADDR.
4636
* XXX: We don't currently track IA_NA separately, but
4637
* we will need to do this!
4640
if (!find_hosts_by_option(&host, packet,
4641
cli_enc_opt_state, MDL)) {
4642
if (packet_host != NULL) {
4648
while (host != NULL) {
4649
if (host->fixed_addr != NULL) {
4650
if (!evaluate_option_cache(&fixed_addr, NULL,
4652
NULL, &global_scope,
4655
log_error("iterate_over_ia_na: error "
4656
"evaluating host address.");
4659
if ((iaaddr.len >= 16) &&
4660
!memcmp(fixed_addr.data, iaaddr.data, 16)) {
4661
data_string_forget(&fixed_addr, MDL);
4664
data_string_forget(&fixed_addr, MDL);
4666
host = host->n_ipaddr;
4669
if ((host == NULL) && (iaaddr.len >= IAADDR_OFFSET)) {
4671
* Find existing IA_NA.
4673
if (ia_make_key(&key, iaid,
4674
(char *)client_id->data,
4676
MDL) != ISC_R_SUCCESS) {
4677
log_fatal("iterate_over_ia_na: no memory for "
4681
existing_ia_na = NULL;
4682
if (ia_hash_lookup(&existing_ia_na, ia_na_active,
4683
(unsigned char *)key.data,
4686
* Make sure this address is in the IA_NA.
4688
for (i=0; i<existing_ia_na->num_iasubopt; i++) {
4689
struct iasubopt *tmp;
4690
struct in6_addr *in6_addr;
4692
tmp = existing_ia_na->iasubopt[i];
4693
in6_addr = &tmp->addr;
4694
if (memcmp(in6_addr,
4695
iaaddr.data, 16) == 0) {
4696
iasubopt_reference(&lease,
4703
data_string_forget(&key, MDL);
4706
if ((host != NULL) || (lease != NULL)) {
4707
ia_na_match(client_id, &iaaddr, lease);
4709
ia_na_nomatch(client_id, &iaaddr,
4710
(u_int32_t *)cli_enc_opt_data.data,
4711
packet, reply_data, &reply_ofs,
4712
sizeof(reply_data));
4715
if (lease != NULL) {
4716
iasubopt_dereference(&lease, MDL);
4719
data_string_forget(&iaaddr, MDL);
4720
option_state_dereference(&cli_enc_opt_state, MDL);
4721
data_string_forget(&cli_enc_opt_data, MDL);
4725
* Return our reply to the caller.
4727
reply_ret->len = reply_ofs;
4728
reply_ret->buffer = NULL;
4729
if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) {
4730
log_fatal("No memory to store reply.");
4732
reply_ret->data = reply_ret->buffer->data;
4733
memcpy(reply_ret->buffer->data, reply, reply_ofs);
4736
if (lease != NULL) {
4737
iasubopt_dereference(&lease, MDL);
4739
if (host_opt_state != NULL) {
4740
option_state_dereference(&host_opt_state, MDL);
4742
if (fixed_addr.buffer != NULL) {
4743
data_string_forget(&fixed_addr, MDL);
4745
if (iaaddr.buffer != NULL) {
4746
data_string_forget(&iaaddr, MDL);
4748
if (cli_enc_opt_state != NULL) {
4749
option_state_dereference(&cli_enc_opt_state, MDL);
4751
if (cli_enc_opt_data.buffer != NULL) {
4752
data_string_forget(&cli_enc_opt_data, MDL);
4754
if (opt_state != NULL) {
4755
option_state_dereference(&opt_state, MDL);
4760
* Decline means a client has detected that something else is using an
4761
* address we gave it.
4763
* Since we're only dealing with fixed leases for now, there's not
4764
* much we can do, other that log the occurrence.
4766
* When we start issuing addresses from pools, then we will have to
4767
* record our declined addresses and issue another. In general with
4768
* IPv6 there is no worry about DoS by clients exhausting space, but
4769
* we still need to be aware of this possibility.
4772
/* TODO: reject unicast messages, unless we set unicast option */
4775
dhcpv6_decline(struct data_string *reply, struct packet *packet) {
4776
struct data_string client_id;
4777
struct data_string server_id;
4780
* Validate our input.
4782
if (!valid_client_resp(packet, &client_id, &server_id)) {
4787
* Undefined for IA_PD.
4789
delete_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
4792
* And operate on each IA_NA in this packet.
4794
iterate_over_ia_na(reply, packet, &client_id, &server_id, "Decline",
4795
ia_na_match_decline, ia_na_nomatch_decline);
4797
data_string_forget(&server_id, MDL);
4798
data_string_forget(&client_id, MDL);
4802
ia_na_match_release(const struct data_string *client_id,
4803
const struct data_string *iaaddr,
4804
struct iasubopt *lease)
4806
char tmp_addr[INET6_ADDRSTRLEN];
4808
log_info("Client %s releases address %s",
4809
print_hex_1(client_id->len, client_id->data, 60),
4810
inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
4811
if (lease != NULL) {
4812
release_lease6(lease->ipv6_pool, lease);
4813
lease->ia->cltt = cur_time;
4814
write_ia(lease->ia);
4819
ia_na_nomatch_release(const struct data_string *client_id,
4820
const struct data_string *iaaddr,
4821
u_int32_t *ia_na_id,
4822
struct packet *packet,
4827
char tmp_addr[INET6_ADDRSTRLEN];
4828
struct option_state *host_opt_state;
4831
log_info("Client %s releases address %s, which is not leased to it.",
4832
print_hex_1(client_id->len, client_id->data, 60),
4833
inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
4836
* Create state for this IA_NA.
4838
host_opt_state = NULL;
4839
if (!option_state_allocate(&host_opt_state, MDL)) {
4840
log_error("ia_na_nomatch_release: out of memory "
4841
"allocating option_state.");
4845
if (!set_status_code(STATUS_NoBinding,
4846
"Release for non-leased address.",
4852
* Insure we have enough space
4854
if (reply_len < (*reply_ofs + 16)) {
4855
log_error("ia_na_nomatch_release: "
4856
"out of space for reply packet.");
4861
* Put our status code into the reply packet.
4863
len = store_options6(reply_data+(*reply_ofs)+16,
4864
reply_len-(*reply_ofs)-16,
4865
host_opt_state, packet,
4866
required_opts_STATUS_CODE, NULL);
4869
* Store the non-encapsulated option data for this
4870
* IA_NA into our reply packet. Defined in RFC 3315,
4874
putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_NA);
4876
putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
4877
/* IA_NA, copied from the client */
4878
memcpy(reply_data+(*reply_ofs)+4, ia_na_id, 4);
4879
/* t1 and t2, odd that we need them, but here it is */
4880
putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
4881
putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
4884
* Get ready for next IA_NA.
4886
*reply_ofs += (len + 16);
4889
option_state_dereference(&host_opt_state, MDL);
4893
ia_pd_match_release(const struct data_string *client_id,
4894
const struct data_string *iapref,
4895
struct iasubopt *prefix)
4897
char tmp_addr[INET6_ADDRSTRLEN];
4899
log_info("Client %s releases prefix %s/%u",
4900
print_hex_1(client_id->len, client_id->data, 60),
4901
inet_ntop(AF_INET6, iapref->data + 9,
4902
tmp_addr, sizeof(tmp_addr)),
4903
(unsigned) getUChar(iapref->data + 8));
4904
if (prefix != NULL) {
4905
release_lease6(prefix->ipv6_pool, prefix);
4906
prefix->ia->cltt = cur_time;
4907
write_ia(prefix->ia);
4912
ia_pd_nomatch_release(const struct data_string *client_id,
4913
const struct data_string *iapref,
4914
u_int32_t *ia_pd_id,
4915
struct packet *packet,
4920
char tmp_addr[INET6_ADDRSTRLEN];
4921
struct option_state *host_opt_state;
4924
log_info("Client %s releases prefix %s/%u, which is not leased to it.",
4925
print_hex_1(client_id->len, client_id->data, 60),
4926
inet_ntop(AF_INET6, iapref->data + 9,
4927
tmp_addr, sizeof(tmp_addr)),
4928
(unsigned) getUChar(iapref->data + 8));
4931
* Create state for this IA_PD.
4933
host_opt_state = NULL;
4934
if (!option_state_allocate(&host_opt_state, MDL)) {
4935
log_error("ia_pd_nomatch_release: out of memory "
4936
"allocating option_state.");
4940
if (!set_status_code(STATUS_NoBinding,
4941
"Release for non-leased prefix.",
4947
* Insure we have enough space
4949
if (reply_len < (*reply_ofs + 16)) {
4950
log_error("ia_pd_nomatch_release: "
4951
"out of space for reply packet.");
4956
* Put our status code into the reply packet.
4958
len = store_options6(reply_data+(*reply_ofs)+16,
4959
reply_len-(*reply_ofs)-16,
4960
host_opt_state, packet,
4961
required_opts_STATUS_CODE, NULL);
4964
* Store the non-encapsulated option data for this
4965
* IA_PD into our reply packet. Defined in RFC 3315,
4969
putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_PD);
4971
putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
4972
/* IA_PD, copied from the client */
4973
memcpy(reply_data+(*reply_ofs)+4, ia_pd_id, 4);
4974
/* t1 and t2, odd that we need them, but here it is */
4975
putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
4976
putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
4979
* Get ready for next IA_PD.
4981
*reply_ofs += (len + 16);
4984
option_state_dereference(&host_opt_state, MDL);
4988
iterate_over_ia_pd(struct data_string *reply_ret,
4989
struct packet *packet,
4990
const struct data_string *client_id,
4991
const struct data_string *server_id,
4992
const char *packet_type,
4993
void (*ia_pd_match)(),
4994
void (*ia_pd_nomatch)())
4996
struct data_string reply_new;
4998
struct option_state *opt_state;
4999
struct host_decl *packet_host;
5000
struct option_cache *ia;
5001
struct option_cache *oc;
5002
/* cli_enc_... variables come from the IA_PD options */
5003
struct data_string cli_enc_opt_data;
5004
struct option_state *cli_enc_opt_state;
5005
struct host_decl *host;
5006
struct option_state *host_opt_state;
5007
struct data_string iaprefix;
5008
int iaprefix_is_found;
5009
char reply_data[65536];
5011
struct iasubopt *prefix;
5012
struct ia_xx *existing_ia_pd;
5014
struct data_string key;
5018
* Initialize to empty values, in case we have to exit early.
5020
memset(&reply_new, 0, sizeof(reply_new));
5022
memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
5023
cli_enc_opt_state = NULL;
5024
memset(&iaprefix, 0, sizeof(iaprefix));
5025
host_opt_state = NULL;
5029
* Compute the available length for the reply.
5031
reply_len = sizeof(reply_data) - reply_ret->len;
5035
* Find the host record that matches from the packet, if any.
5038
if (!find_hosts_by_uid(&packet_host,
5039
client_id->data, client_id->len, MDL)) {
5042
* Note: In general, we don't expect a client to provide
5043
* enough information to match by option for these
5044
* types of messages, but if we don't have a UID
5045
* match we can check anyway.
5047
if (!find_hosts_by_option(&packet_host,
5048
packet, packet->options, MDL)) {
5054
* Build our option state for reply.
5057
if (!option_state_allocate(&opt_state, MDL)) {
5058
log_error("iterate_over_ia_pd: no memory for option_state.");
5061
execute_statements_in_scope(NULL, packet, NULL, NULL,
5062
packet->options, opt_state,
5063
&global_scope, root_group, NULL);
5066
* Loop through the IA_PD reported by the client, and deal with
5067
* prefixes reported as already in use.
5069
for (ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
5070
ia != NULL; ia = ia->next) {
5071
iaprefix_is_found = 0;
5073
if (!get_encapsulated_IA_state(&cli_enc_opt_state,
5075
packet, ia, IA_PD_OFFSET)) {
5079
iaid = getULong(cli_enc_opt_data.data);
5081
oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
5084
/* no prefix given for this IA_PD, ignore */
5085
option_state_dereference(&cli_enc_opt_state, MDL);
5086
data_string_forget(&cli_enc_opt_data, MDL);
5090
for (; oc != NULL; oc = oc->next) {
5091
memset(&iaprefix, 0, sizeof(iaprefix));
5092
if (!evaluate_option_cache(&iaprefix, packet, NULL, NULL,
5093
packet->options, NULL,
5094
&global_scope, oc, MDL)) {
5095
log_error("iterate_over_ia_pd: "
5096
"error evaluating IAPREFIX.");
5101
* Now we need to figure out which host record matches
5102
* this IA_PD and IAPREFIX.
5104
* XXX: We don't currently track IA_PD separately, but
5105
* we will need to do this!
5108
if (!find_hosts_by_option(&host, packet,
5109
cli_enc_opt_state, MDL)) {
5110
if (packet_host != NULL) {
5116
while (host != NULL) {
5117
if (host->fixed_prefix != NULL) {
5118
struct iaddrcidrnetlist *l;
5119
int plen = (int) getUChar(iaprefix.data + 8);
5121
for (l = host->fixed_prefix; l != NULL;
5123
if (plen != l->cidrnet.bits)
5125
if (memcmp(iaprefix.data + 9,
5126
l->cidrnet.lo_addr.iabuf,
5130
if ((l != NULL) && (iaprefix.len >= 17))
5133
host = host->n_ipaddr;
5136
if ((host == NULL) && (iaprefix.len >= IAPREFIX_OFFSET)) {
5138
* Find existing IA_PD.
5140
if (ia_make_key(&key, iaid,
5141
(char *)client_id->data,
5143
MDL) != ISC_R_SUCCESS) {
5144
log_fatal("iterate_over_ia_pd: no memory for "
5148
existing_ia_pd = NULL;
5149
if (ia_hash_lookup(&existing_ia_pd, ia_pd_active,
5150
(unsigned char *)key.data,
5153
* Make sure this prefix is in the IA_PD.
5156
i < existing_ia_pd->num_iasubopt;
5158
struct iasubopt *tmp;
5161
plen = getUChar(iaprefix.data + 8);
5162
tmp = existing_ia_pd->iasubopt[i];
5163
if ((tmp->plen == plen) &&
5167
iasubopt_reference(&prefix,
5174
data_string_forget(&key, MDL);
5177
if ((host != NULL) || (prefix != NULL)) {
5178
ia_pd_match(client_id, &iaprefix, prefix);
5180
ia_pd_nomatch(client_id, &iaprefix,
5181
(u_int32_t *)cli_enc_opt_data.data,
5182
packet, reply_data, &reply_ofs,
5183
reply_len - reply_ofs);
5186
if (prefix != NULL) {
5187
iasubopt_dereference(&prefix, MDL);
5190
data_string_forget(&iaprefix, MDL);
5193
option_state_dereference(&cli_enc_opt_state, MDL);
5194
data_string_forget(&cli_enc_opt_data, MDL);
5198
* Return our reply to the caller.
5199
* The IA_NA routine has already filled at least the header.
5201
reply_new.len = reply_ret->len + reply_ofs;
5202
if (!buffer_allocate(&reply_new.buffer, reply_new.len, MDL)) {
5203
log_fatal("No memory to store reply.");
5205
reply_new.data = reply_new.buffer->data;
5206
memcpy(reply_new.buffer->data,
5207
reply_ret->buffer->data, reply_ret->len);
5208
memcpy(reply_new.buffer->data + reply_ret->len,
5209
reply_data, reply_ofs);
5210
data_string_forget(reply_ret, MDL);
5211
data_string_copy(reply_ret, &reply_new, MDL);
5212
data_string_forget(&reply_new, MDL);
5215
if (prefix != NULL) {
5216
iasubopt_dereference(&prefix, MDL);
5218
if (host_opt_state != NULL) {
5219
option_state_dereference(&host_opt_state, MDL);
5221
if (iaprefix.buffer != NULL) {
5222
data_string_forget(&iaprefix, MDL);
5224
if (cli_enc_opt_state != NULL) {
5225
option_state_dereference(&cli_enc_opt_state, MDL);
5227
if (cli_enc_opt_data.buffer != NULL) {
5228
data_string_forget(&cli_enc_opt_data, MDL);
5230
if (opt_state != NULL) {
5231
option_state_dereference(&opt_state, MDL);
5236
* Release means a client is done with the leases.
5239
/* TODO: reject unicast messages, unless we set unicast option */
5241
dhcpv6_release(struct data_string *reply, struct packet *packet) {
5242
struct data_string client_id;
5243
struct data_string server_id;
5246
* Validate our input.
5248
if (!valid_client_resp(packet, &client_id, &server_id)) {
5253
* And operate on each IA_NA in this packet.
5255
iterate_over_ia_na(reply, packet, &client_id, &server_id, "Release",
5256
ia_na_match_release, ia_na_nomatch_release);
5259
* And operate on each IA_PD in this packet.
5261
iterate_over_ia_pd(reply, packet, &client_id, &server_id, "Release",
5262
ia_pd_match_release, ia_pd_nomatch_release);
5264
data_string_forget(&server_id, MDL);
5265
data_string_forget(&client_id, MDL);
5269
* Information-Request is used by clients who have obtained an address
5270
* from other means, but want configuration information from the server.
5274
dhcpv6_information_request(struct data_string *reply, struct packet *packet) {
5275
struct data_string client_id;
5276
struct data_string server_id;
5279
* Validate our input.
5281
if (!valid_client_info_req(packet, &server_id)) {
5286
* Get our client ID, if there is one.
5288
memset(&client_id, 0, sizeof(client_id));
5289
if (get_client_id(packet, &client_id) != ISC_R_SUCCESS) {
5290
data_string_forget(&client_id, MDL);
5294
* Use the lease_to_client() function. This will work fine,
5295
* because the valid_client_info_req() insures that we
5296
* don't have any IA that would cause us to allocate
5297
* resources to the client.
5299
lease_to_client(reply, packet, &client_id,
5300
server_id.data != NULL ? &server_id : NULL);
5305
if (client_id.data != NULL) {
5306
data_string_forget(&client_id, MDL);
5308
data_string_forget(&server_id, MDL);
5312
* The Relay-forw message is sent by relays. It typically contains a
5313
* single option, which encapsulates an entire packet.
5315
* We need to build an encapsulated reply.
5318
/* XXX: this is very, very similar to do_packet6(), and should probably
5319
be combined in a clever way */
5321
dhcpv6_relay_forw(struct data_string *reply_ret, struct packet *packet) {
5322
struct option_cache *oc;
5323
struct data_string enc_opt_data;
5324
struct packet *enc_packet;
5325
unsigned char msg_type;
5326
const struct dhcpv6_packet *msg;
5327
const struct dhcpv6_relay_packet *relay;
5328
struct data_string enc_reply;
5329
char link_addr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
5330
char peer_addr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
5331
struct data_string a_opt, packet_ero;
5332
struct option_state *opt_state;
5333
static char reply_data[65536];
5334
struct dhcpv6_relay_packet *reply;
5338
* Initialize variables for early exit.
5341
memset(&a_opt, 0, sizeof(a_opt));
5342
memset(&packet_ero, 0, sizeof(packet_ero));
5343
memset(&enc_reply, 0, sizeof(enc_reply));
5344
memset(&enc_opt_data, 0, sizeof(enc_opt_data));
5348
* Get our encapsulated relay message.
5350
oc = lookup_option(&dhcpv6_universe, packet->options, D6O_RELAY_MSG);
5352
inet_ntop(AF_INET6, &packet->dhcpv6_link_address,
5353
link_addr, sizeof(link_addr));
5354
inet_ntop(AF_INET6, &packet->dhcpv6_peer_address,
5355
peer_addr, sizeof(peer_addr));
5356
log_info("Relay-forward from %s with link address=%s and "
5357
"peer address=%s missing Relay Message option.",
5358
piaddr(packet->client_addr), link_addr, peer_addr);
5362
if (!evaluate_option_cache(&enc_opt_data, NULL, NULL, NULL,
5363
NULL, NULL, &global_scope, oc, MDL)) {
5364
log_error("dhcpv6_forw_relay: error evaluating "
5365
"relayed message.");
5369
if (!packet6_len_okay((char *)enc_opt_data.data, enc_opt_data.len)) {
5370
log_error("dhcpv6_forw_relay: encapsulated packet too short.");
5375
* Build a packet structure from this encapsulated packet.
5378
if (!packet_allocate(&enc_packet, MDL)) {
5379
log_error("dhcpv6_forw_relay: "
5380
"no memory for encapsulated packet.");
5384
if (!option_state_allocate(&enc_packet->options, MDL)) {
5385
log_error("dhcpv6_forw_relay: "
5386
"no memory for encapsulated packet's options.");
5390
enc_packet->client_port = packet->client_port;
5391
enc_packet->client_addr = packet->client_addr;
5392
enc_packet->dhcpv6_container_packet = packet;
5394
msg_type = enc_opt_data.data[0];
5395
if ((msg_type == DHCPV6_RELAY_FORW) ||
5396
(msg_type == DHCPV6_RELAY_REPL)) {
5397
relay = (struct dhcpv6_relay_packet *)enc_opt_data.data;
5398
enc_packet->dhcpv6_msg_type = relay->msg_type;
5400
/* relay-specific data */
5401
enc_packet->dhcpv6_hop_count = relay->hop_count;
5402
memcpy(&enc_packet->dhcpv6_link_address,
5403
relay->link_address, sizeof(relay->link_address));
5404
memcpy(&enc_packet->dhcpv6_peer_address,
5405
relay->peer_address, sizeof(relay->peer_address));
5407
if (!parse_option_buffer(enc_packet->options,
5409
enc_opt_data.len-sizeof(*relay),
5410
&dhcpv6_universe)) {
5411
/* no logging here, as parse_option_buffer() logs all
5412
cases where it fails */
5416
msg = (struct dhcpv6_packet *)enc_opt_data.data;
5417
enc_packet->dhcpv6_msg_type = msg->msg_type;
5419
/* message-specific data */
5420
memcpy(enc_packet->dhcpv6_transaction_id,
5421
msg->transaction_id,
5422
sizeof(enc_packet->dhcpv6_transaction_id));
5424
if (!parse_option_buffer(enc_packet->options,
5426
enc_opt_data.len-sizeof(*msg),
5427
&dhcpv6_universe)) {
5428
/* no logging here, as parse_option_buffer() logs all
5429
cases where it fails */
5435
* This is recursive. It is possible to exceed maximum packet size.
5436
* XXX: This will cause the packet send to fail.
5438
build_dhcpv6_reply(&enc_reply, enc_packet);
5441
* If we got no encapsulated data, then it is discarded, and
5442
* our reply-forw is also discarded.
5444
if (enc_reply.data == NULL) {
5449
* Now we can use the reply_data buffer.
5450
* Packet header stuff all comes from the forward message.
5452
reply = (struct dhcpv6_relay_packet *)reply_data;
5453
reply->msg_type = DHCPV6_RELAY_REPL;
5454
reply->hop_count = packet->dhcpv6_hop_count;
5455
memcpy(reply->link_address, &packet->dhcpv6_link_address,
5456
sizeof(reply->link_address));
5457
memcpy(reply->peer_address, &packet->dhcpv6_peer_address,
5458
sizeof(reply->peer_address));
5459
reply_ofs = (int)((char *)reply->options - (char *)reply);
5462
* Get the reply option state.
5465
if (!option_state_allocate(&opt_state, MDL)) {
5466
log_error("dhcpv6_relay_forw: no memory for option state.");
5471
* Append the interface-id if present.
5473
oc = lookup_option(&dhcpv6_universe, packet->options,
5476
if (!evaluate_option_cache(&a_opt, packet,
5478
packet->options, NULL,
5479
&global_scope, oc, MDL)) {
5480
log_error("dhcpv6_relay_forw: error evaluating "
5484
if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
5485
(unsigned char *)a_opt.data,
5487
D6O_INTERFACE_ID, 0)) {
5488
log_error("dhcpv6_relay_forw: error saving "
5492
data_string_forget(&a_opt, MDL);
5496
* Append our encapsulated stuff for caller.
5498
if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
5499
(unsigned char *)enc_reply.data,
5501
D6O_RELAY_MSG, 0)) {
5502
log_error("dhcpv6_relay_forw: error saving Relay MSG.");
5507
* Get the ERO if any.
5509
oc = lookup_option(&dhcpv6_universe, packet->options, D6O_ERO);
5514
if (!evaluate_option_cache(&packet_ero, packet,
5516
packet->options, NULL,
5517
&global_scope, oc, MDL) ||
5518
(packet_ero.len & 1)) {
5519
log_error("dhcpv6_relay_forw: error evaluating ERO.");
5523
/* Decode and apply the ERO. */
5524
for (i = 0; i < packet_ero.len; i += 2) {
5525
req = getUShort(packet_ero.data + i);
5526
/* Already in the reply? */
5527
oc = lookup_option(&dhcpv6_universe, opt_state, req);
5530
/* Get it from the packet if present. */
5531
oc = lookup_option(&dhcpv6_universe,
5536
if (!evaluate_option_cache(&a_opt, packet,
5538
packet->options, NULL,
5539
&global_scope, oc, MDL)) {
5540
log_error("dhcpv6_relay_forw: error "
5541
"evaluating option %u.", req);
5544
if (!save_option_buffer(&dhcpv6_universe,
5547
(unsigned char *)a_opt.data,
5551
log_error("dhcpv6_relay_forw: error saving "
5555
data_string_forget(&a_opt, MDL);
5559
reply_ofs += store_options6(reply_data + reply_ofs,
5560
sizeof(reply_data) - reply_ofs,
5562
required_opts_agent, &packet_ero);
5565
* Return our reply to the caller.
5567
reply_ret->len = reply_ofs;
5568
reply_ret->buffer = NULL;
5569
if (!buffer_allocate(&reply_ret->buffer, reply_ret->len, MDL)) {
5570
log_fatal("No memory to store reply.");
5572
reply_ret->data = reply_ret->buffer->data;
5573
memcpy(reply_ret->buffer->data, reply_data, reply_ofs);
5576
if (opt_state != NULL)
5577
option_state_dereference(&opt_state, MDL);
5578
if (a_opt.data != NULL) {
5579
data_string_forget(&a_opt, MDL);
5581
if (packet_ero.data != NULL) {
5582
data_string_forget(&packet_ero, MDL);
5584
if (enc_reply.data != NULL) {
5585
data_string_forget(&enc_reply, MDL);
5587
if (enc_opt_data.data != NULL) {
5588
data_string_forget(&enc_opt_data, MDL);
5590
if (enc_packet != NULL) {
5591
packet_dereference(&enc_packet, MDL);
5596
dhcpv6_discard(struct packet *packet) {
5597
/* INSIST(packet->msg_type > 0); */
5598
/* INSIST(packet->msg_type < dhcpv6_type_name_max); */
5600
log_debug("Discarding %s from %s; message type not handled by server",
5601
dhcpv6_type_names[packet->dhcpv6_msg_type],
5602
piaddr(packet->client_addr));
5606
build_dhcpv6_reply(struct data_string *reply, struct packet *packet) {
5607
memset(reply, 0, sizeof(*reply));
5608
switch (packet->dhcpv6_msg_type) {
5609
case DHCPV6_SOLICIT:
5610
dhcpv6_solicit(reply, packet);
5612
case DHCPV6_ADVERTISE:
5613
dhcpv6_discard(packet);
5615
case DHCPV6_REQUEST:
5616
dhcpv6_request(reply, packet);
5618
case DHCPV6_CONFIRM:
5619
dhcpv6_confirm(reply, packet);
5622
dhcpv6_renew(reply, packet);
5625
dhcpv6_rebind(reply, packet);
5628
dhcpv6_discard(packet);
5630
case DHCPV6_RELEASE:
5631
dhcpv6_release(reply, packet);
5633
case DHCPV6_DECLINE:
5634
dhcpv6_decline(reply, packet);
5636
case DHCPV6_RECONFIGURE:
5637
dhcpv6_discard(packet);
5639
case DHCPV6_INFORMATION_REQUEST:
5640
dhcpv6_information_request(reply, packet);
5642
case DHCPV6_RELAY_FORW:
5643
dhcpv6_relay_forw(reply, packet);
5645
case DHCPV6_RELAY_REPL:
5646
dhcpv6_discard(packet);
5648
case DHCPV6_LEASEQUERY:
5649
dhcpv6_leasequery(reply, packet);
5651
case DHCPV6_LEASEQUERY_REPLY:
5652
dhcpv6_discard(packet);
5655
/* XXX: would be nice if we had "notice" level,
5656
as syslog, for this */
5657
log_info("Discarding unknown DHCPv6 message type %d "
5658
"from %s", packet->dhcpv6_msg_type,
5659
piaddr(packet->client_addr));
5664
log_packet_in(const struct packet *packet) {
5665
struct data_string s;
5667
char tmp_addr[INET6_ADDRSTRLEN];
5670
memset(&s, 0, sizeof(s));
5672
if (packet->dhcpv6_msg_type < dhcpv6_type_name_max) {
5673
data_string_sprintfa(&s, "%s message from %s port %d",
5674
dhcpv6_type_names[packet->dhcpv6_msg_type],
5675
piaddr(packet->client_addr),
5676
ntohs(packet->client_port));
5678
data_string_sprintfa(&s,
5679
"Unknown message type %d from %s port %d",
5680
packet->dhcpv6_msg_type,
5681
piaddr(packet->client_addr),
5682
ntohs(packet->client_port));
5684
if ((packet->dhcpv6_msg_type == DHCPV6_RELAY_FORW) ||
5685
(packet->dhcpv6_msg_type == DHCPV6_RELAY_REPL)) {
5686
addr = &packet->dhcpv6_link_address;
5687
data_string_sprintfa(&s, ", link address %s",
5688
inet_ntop(AF_INET6, addr,
5689
tmp_addr, sizeof(tmp_addr)));
5690
addr = &packet->dhcpv6_peer_address;
5691
data_string_sprintfa(&s, ", peer address %s",
5692
inet_ntop(AF_INET6, addr,
5693
tmp_addr, sizeof(tmp_addr)));
5696
memcpy(((char *)&tid)+1, packet->dhcpv6_transaction_id, 3);
5697
data_string_sprintfa(&s, ", transaction ID 0x%06X", tid);
5700
oc = lookup_option(&dhcpv6_universe, packet->options,
5703
memset(&tmp_ds, 0, sizeof(tmp_ds_));
5704
if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
5705
packet->options, NULL,
5706
&global_scope, oc, MDL)) {
5707
log_error("Error evaluating Client Identifier");
5709
data_strint_sprintf(&s, ", client ID %s",
5711
data_string_forget(&tmp_ds, MDL);
5717
log_info("%s", s.data);
5719
data_string_forget(&s, MDL);
5723
dhcpv6(struct packet *packet) {
5724
struct data_string reply;
5725
struct sockaddr_in6 to_addr;
5729
* Log a message that we received this packet.
5731
log_packet_in(packet);
5734
* Build our reply packet.
5736
build_dhcpv6_reply(&reply, packet);
5738
if (reply.data != NULL) {
5740
* Send our reply, if we have one.
5742
memset(&to_addr, 0, sizeof(to_addr));
5743
to_addr.sin6_family = AF_INET6;
5744
if ((packet->dhcpv6_msg_type == DHCPV6_RELAY_FORW) ||
5745
(packet->dhcpv6_msg_type == DHCPV6_RELAY_REPL)) {
5746
to_addr.sin6_port = local_port;
5748
to_addr.sin6_port = remote_port;
5750
/* For testing, we reply to the sending port, so we don't need a root client */
5751
to_addr.sin6_port = packet->client_port;
5752
memcpy(&to_addr.sin6_addr, packet->client_addr.iabuf,
5753
sizeof(to_addr.sin6_addr));
5755
log_info("Sending %s to %s port %d",
5756
dhcpv6_type_names[reply.data[0]],
5757
piaddr(packet->client_addr),
5758
ntohs(to_addr.sin6_port));
5760
send_ret = send_packet6(packet->interface,
5761
reply.data, reply.len, &to_addr);
5762
if (send_ret != reply.len) {
5763
log_error("dhcpv6: send_packet6() sent %d of %d bytes",
5764
send_ret, reply.len);
5766
data_string_forget(&reply, MDL);
5771
seek_shared_host(struct host_decl **hp, struct shared_network *shared) {
5772
struct host_decl *nofixed = NULL;
5773
struct host_decl *seek, *hold = NULL;
5776
* Seek forward through fixed addresses for the right link.
5778
* Note: how to do this for fixed prefixes???
5780
host_reference(&hold, *hp, MDL);
5781
host_dereference(hp, MDL);
5783
while (seek != NULL) {
5784
if (seek->fixed_addr == NULL)
5786
else if (fixed_matches_shared(seek, shared))
5789
seek = seek->n_ipaddr;
5792
if ((seek == NULL) && (nofixed != NULL))
5796
host_reference(hp, seek, MDL);
5799
static isc_boolean_t
5800
fixed_matches_shared(struct host_decl *host, struct shared_network *shared) {
5801
struct subnet *subnet;
5802
struct data_string addr;
5803
isc_boolean_t matched;
5806
if (host->fixed_addr == NULL)
5809
memset(&addr, 0, sizeof(addr));
5810
if (!evaluate_option_cache(&addr, NULL, NULL, NULL, NULL, NULL,
5811
&global_scope, host->fixed_addr, MDL))
5814
if (addr.len < 16) {
5815
data_string_forget(&addr, MDL);
5820
memcpy(fixed.iabuf, addr.data, 16);
5822
matched = ISC_FALSE;
5823
for (subnet = shared->subnets ; subnet != NULL ;
5824
subnet = subnet->next_sibling) {
5825
if (addr_eq(subnet_number(fixed, subnet->netmask),
5832
data_string_forget(&addr, MDL);