]> git.ipfire.org Git - thirdparty/dhcp.git/blame - server/dhcpv6.c
[master] Corrects medium impact issues reported by Coverity.
[thirdparty/dhcp.git] / server / dhcpv6.c
CommitLineData
98bd7ca0 1/*
388cba45 2 * Copyright (C) 2006-2014 by Internet Systems Consortium, Inc. ("ISC")
98bd7ca0
DH
3 *
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.
7 *
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.
15 */
16
01fa619f
SR
17/*! \file server/dhcpv6.c */
18
98bd7ca0
DH
19#include "dhcpd.h"
20
fe5b0fdd
DH
21#ifdef DHCPv6
22
98bd7ca0
DH
23/*
24 * We use print_hex_1() to output DUID values. We could actually output
25 * the DUID with more information... MAC address if using type 1 or 3,
26 * and so on. However, RFC 3315 contains Grave Warnings against actually
27 * attempting to understand a DUID.
28 */
29
30/*
31 * TODO: gettext() or other method of localization for the messages
32 * for status codes (and probably for log formats eventually)
33 * TODO: refactoring (simplify, simplify, simplify)
34 * TODO: support multiple shared_networks on each interface (this
35 * will allow the server to issue multiple IPv6 addresses to
36 * a single interface)
37 */
38
5279b8f3
DH
39/*
40 * DHCPv6 Reply workflow assist. A Reply packet is built by various
41 * different functions; this gives us one location where we keep state
42 * regarding a reply.
43 */
44struct reply_state {
45 /* root level persistent state */
46 struct shared_network *shared;
47 struct host_decl *host;
2267da84 48 struct subnet *subnet; /* Used to match fixed-addrs to subnet scopes. */
5279b8f3
DH
49 struct option_state *opt_state;
50 struct packet *packet;
51 struct data_string client_id;
52
53 /* IA level persistent state */
54 unsigned ia_count;
9322442f 55 unsigned pd_count;
1d9774ab 56 unsigned client_resources;
9322442f 57 isc_boolean_t resources_included;
b024480e 58 isc_boolean_t static_lease;
80c9fdb0 59 unsigned static_prefixes;
9322442f
FD
60 struct ia_xx *ia;
61 struct ia_xx *old_ia;
5279b8f3
DH
62 struct option_state *reply_ia;
63 struct data_string fixed;
d9b5c150 64 struct iaddrcidrnet fixed_pref; /* static prefix for logging */
5279b8f3 65
9322442f 66 /* IAADDR/PREFIX level persistent state */
1d17db44 67 struct iasubopt *lease;
5279b8f3
DH
68
69 /*
70 * "t1", "t2", preferred, and valid lifetimes records for calculating
71 * t1 and t2 (min/max).
72 */
73 u_int32_t renew, rebind, prefer, valid;
74
20ae1aff 75 /* Client-requested valid and preferred lifetimes. */
5279b8f3
DH
76 u_int32_t client_valid, client_prefer;
77
78 /* Chosen values to transmit for valid and preferred lifetimes. */
79 u_int32_t send_valid, send_prefer;
80
80c9fdb0
FD
81 /* Preferred prefix length (-1 is any). */
82 int preflen;
83
20ae1aff 84 /* Index into the data field that has been consumed. */
5279b8f3
DH
85 unsigned cursor;
86
a7341359
SR
87 /* Space for the on commit statements for a fixed host */
88 struct on_star on_star;
89
5279b8f3
DH
90 union reply_buffer {
91 unsigned char data[65536];
92 struct dhcpv6_packet reply;
93 } buf;
94};
95
98bd7ca0
DH
96/*
97 * Prototypes local to this file.
98 */
8eab95f2
DH
99static int get_encapsulated_IA_state(struct option_state **enc_opt_state,
100 struct data_string *enc_opt_data,
101 struct packet *packet,
102 struct option_cache *oc,
103 int offset);
98bd7ca0 104static void build_dhcpv6_reply(struct data_string *, struct packet *);
bd72740e
FD
105static isc_result_t shared_network_from_packet6(struct shared_network **shared,
106 struct packet *packet);
5279b8f3
DH
107static void seek_shared_host(struct host_decl **hp,
108 struct shared_network *shared);
109static isc_boolean_t fixed_matches_shared(struct host_decl *host,
110 struct shared_network *shared);
1d9774ab
FD
111static isc_result_t reply_process_ia_na(struct reply_state *reply,
112 struct option_cache *ia);
80c9fdb0
FD
113static isc_result_t reply_process_ia_ta(struct reply_state *reply,
114 struct option_cache *ia);
5279b8f3
DH
115static isc_result_t reply_process_addr(struct reply_state *reply,
116 struct option_cache *addr);
117static isc_boolean_t address_is_owned(struct reply_state *reply,
118 struct iaddr *addr);
783259b1
FD
119static isc_boolean_t temporary_is_available(struct reply_state *reply,
120 struct iaddr *addr);
80c9fdb0 121static isc_result_t find_client_temporaries(struct reply_state *reply);
5279b8f3
DH
122static isc_result_t reply_process_try_addr(struct reply_state *reply,
123 struct iaddr *addr);
124static isc_result_t find_client_address(struct reply_state *reply);
125static isc_result_t reply_process_is_addressed(struct reply_state *reply,
126 struct binding_scope **scope,
127 struct group *group);
128static isc_result_t reply_process_send_addr(struct reply_state *reply,
129 struct iaddr *addr);
1d17db44
FD
130static struct iasubopt *lease_compare(struct iasubopt *alpha,
131 struct iasubopt *beta);
80c9fdb0
FD
132static isc_result_t reply_process_ia_pd(struct reply_state *reply,
133 struct option_cache *ia_pd);
134static isc_result_t reply_process_prefix(struct reply_state *reply,
135 struct option_cache *pref);
136static isc_boolean_t prefix_is_owned(struct reply_state *reply,
137 struct iaddrcidrnet *pref);
138static isc_result_t find_client_prefix(struct reply_state *reply);
139static isc_result_t reply_process_try_prefix(struct reply_state *reply,
140 struct iaddrcidrnet *pref);
141static isc_result_t reply_process_is_prefixed(struct reply_state *reply,
80c9fdb0
FD
142 struct binding_scope **scope,
143 struct group *group);
144static isc_result_t reply_process_send_prefix(struct reply_state *reply,
145 struct iaddrcidrnet *pref);
1d17db44
FD
146static struct iasubopt *prefix_compare(struct reply_state *reply,
147 struct iasubopt *alpha,
148 struct iasubopt *beta);
c900c5b2
DH
149static int find_hosts_by_duid_chaddr(struct host_decl **host,
150 const struct data_string *client_id);
ad80055f
SR
151static void schedule_lease_timeout_reply(struct reply_state *reply);
152
153/*
154 * Schedule lease timeouts for all of the iasubopts in the reply.
155 * This is currently used to schedule timeouts for soft leases.
156 */
157
158static void
159schedule_lease_timeout_reply(struct reply_state *reply) {
160 struct iasubopt *tmp;
161 int i;
162
163 /* sanity check the reply */
164 if ((reply == NULL) || (reply->ia == NULL) || (reply->ia->iasubopt == NULL))
165 return;
166
167 /* walk through the list, scheduling as we go */
168 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
169 tmp = reply->ia->iasubopt[i];
170 schedule_lease_timeout(tmp->ipv6_pool);
171 }
172}
173
98bd7ca0
DH
174/*
175 * This function returns the time since DUID time start for the
176 * given time_t value.
177 */
178static u_int32_t
179duid_time(time_t when) {
180 /*
181 * This time is modulo 2^32.
182 */
183 while ((when - DUID_TIME_EPOCH) > 4294967295u) {
184 /* use 2^31 to avoid spurious compiler warnings */
185 when -= 2147483648u;
186 when -= 2147483648u;
187 }
188
189 return when - DUID_TIME_EPOCH;
190}
191
192
193/*
194 * Server DUID.
195 *
196 * This must remain the same for the lifetime of this server, because
197 * clients return the server DUID that we sent them in Request packets.
198 *
199 * We pick the server DUID like this:
200 *
201 * 1. Check dhcpd.conf - any value the administrator has configured
202 * overrides any possible values.
203 * 2. Check the leases.txt - we want to use the previous value if
204 * possible.
205 * 3. Check if dhcpd.conf specifies a type of server DUID to use,
206 * and generate that type.
207 * 4. Generate a type 1 (time + hardware address) DUID.
208 */
209static struct data_string server_duid;
210
211/*
212 * Check if the server_duid has been set.
213 */
783259b1 214isc_boolean_t
98bd7ca0
DH
215server_duid_isset(void) {
216 return (server_duid.data != NULL);
217}
218
219/*
220 * Return the server_duid.
221 */
222void
223copy_server_duid(struct data_string *ds, const char *file, int line) {
224 data_string_copy(ds, &server_duid, file, line);
225}
226
227/*
228 * Set the server DUID to a specified value. This is used when
229 * the server DUID is stored in persistent memory (basically the
230 * leases.txt file).
231 */
232void
233set_server_duid(struct data_string *new_duid) {
234 /* INSIST(new_duid != NULL); */
235 /* INSIST(new_duid->data != NULL); */
236
237 if (server_duid_isset()) {
238 data_string_forget(&server_duid, MDL);
239 }
240 data_string_copy(&server_duid, new_duid, MDL);
241}
242
243
244/*
245 * Set the server DUID based on the D6O_SERVERID option. This handles
246 * the case where the administrator explicitly put it in the dhcpd.conf
247 * file.
248 */
249isc_result_t
250set_server_duid_from_option(void) {
251 struct option_state *opt_state;
252 struct option_cache *oc;
253 struct data_string option_duid;
254 isc_result_t ret_val;
255
256 opt_state = NULL;
257 if (!option_state_allocate(&opt_state, MDL)) {
258 log_fatal("No memory for server DUID.");
259 }
260
261 execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL,
a7341359
SR
262 opt_state, &global_scope, root_group,
263 NULL, NULL);
98bd7ca0
DH
264
265 oc = lookup_option(&dhcpv6_universe, opt_state, D6O_SERVERID);
266 if (oc == NULL) {
267 ret_val = ISC_R_NOTFOUND;
268 } else {
269 memset(&option_duid, 0, sizeof(option_duid));
783259b1
FD
270 if (!evaluate_option_cache(&option_duid, NULL, NULL, NULL,
271 opt_state, NULL, &global_scope,
98bd7ca0
DH
272 oc, MDL)) {
273 ret_val = ISC_R_UNEXPECTED;
274 } else {
275 set_server_duid(&option_duid);
276 data_string_forget(&option_duid, MDL);
277 ret_val = ISC_R_SUCCESS;
278 }
279 }
280
281 option_state_dereference(&opt_state, MDL);
282
283 return ret_val;
284}
285
286/*
287 * DUID layout, as defined in RFC 3315, section 9.
288 *
289 * We support type 1 (hardware address plus time) and type 3 (hardware
290 * address).
291 *
292 * We can support type 2 for specific vendors in the future, if they
293 * publish the specification. And of course there may be additional
294 * types later.
295 */
296static int server_duid_type = DUID_LLT;
297
298/*
299 * Set the DUID type.
300 */
301void
302set_server_duid_type(int type) {
303 server_duid_type = type;
304}
305
306/*
307 * Generate a new server DUID. This is done if there was no DUID in
308 * the leases.txt or in the dhcpd.conf file.
309 */
310isc_result_t
311generate_new_server_duid(void) {
312 struct interface_info *p;
313 u_int32_t time_val;
314 struct data_string generated_duid;
315
316 /*
317 * Verify we have a type that we support.
318 */
319 if ((server_duid_type != DUID_LL) && (server_duid_type != DUID_LLT)) {
320 log_error("Invalid DUID type %d specified, "
321 "only LL and LLT types supported", server_duid_type);
98bf1607 322 return DHCP_R_INVALIDARG;
98bd7ca0
DH
323 }
324
325 /*
326 * Find an interface with a hardware address.
327 * Any will do. :)
328 */
329 for (p = interfaces; p != NULL; p = p->next) {
330 if (p->hw_address.hlen > 0) {
331 break;
332 }
333 }
334 if (p == NULL) {
335 return ISC_R_UNEXPECTED;
336 }
337
338 /*
339 * Build our DUID.
340 */
341 memset(&generated_duid, 0, sizeof(generated_duid));
342 if (server_duid_type == DUID_LLT) {
343 time_val = duid_time(time(NULL));
344 generated_duid.len = 8 + p->hw_address.hlen - 1;
783259b1 345 if (!buffer_allocate(&generated_duid.buffer,
98bd7ca0
DH
346 generated_duid.len, MDL)) {
347 log_fatal("No memory for server DUID.");
348 }
349 generated_duid.data = generated_duid.buffer->data;
350 putUShort(generated_duid.buffer->data, DUID_LLT);
783259b1 351 putUShort(generated_duid.buffer->data + 2,
98bd7ca0
DH
352 p->hw_address.hbuf[0]);
353 putULong(generated_duid.buffer->data + 4, time_val);
783259b1 354 memcpy(generated_duid.buffer->data + 8,
98bd7ca0
DH
355 p->hw_address.hbuf+1, p->hw_address.hlen-1);
356 } else if (server_duid_type == DUID_LL) {
357 generated_duid.len = 4 + p->hw_address.hlen - 1;
783259b1 358 if (!buffer_allocate(&generated_duid.buffer,
98bd7ca0
DH
359 generated_duid.len, MDL)) {
360 log_fatal("No memory for server DUID.");
361 }
362 generated_duid.data = generated_duid.buffer->data;
363 putUShort(generated_duid.buffer->data, DUID_LL);
783259b1 364 putUShort(generated_duid.buffer->data + 2,
98bd7ca0 365 p->hw_address.hbuf[0]);
783259b1 366 memcpy(generated_duid.buffer->data + 4,
98bd7ca0
DH
367 p->hw_address.hbuf+1, p->hw_address.hlen-1);
368 } else {
369 log_fatal("Unsupported server DUID type %d.", server_duid_type);
783259b1 370 }
98bd7ca0
DH
371
372 set_server_duid(&generated_duid);
373 data_string_forget(&generated_duid, MDL);
374
375 return ISC_R_SUCCESS;
376}
377
378/*
379 * Get the client identifier from the packet.
380 */
381isc_result_t
382get_client_id(struct packet *packet, struct data_string *client_id) {
383 struct option_cache *oc;
384
385 /*
386 * Verify our client_id structure is empty.
387 */
388 if ((client_id->data != NULL) || (client_id->len != 0)) {
98bf1607 389 return DHCP_R_INVALIDARG;
98bd7ca0
DH
390 }
391
392 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_CLIENTID);
393 if (oc == NULL) {
394 return ISC_R_NOTFOUND;
395 }
396
783259b1 397 if (!evaluate_option_cache(client_id, packet, NULL, NULL,
98bd7ca0
DH
398 packet->options, NULL,
399 &global_scope, oc, MDL)) {
400 return ISC_R_FAILURE;
401 }
402
403 return ISC_R_SUCCESS;
404}
405
406/*
407 * Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
408 *
409 * Servers MUST discard any Solicit messages that do not include a
410 * Client Identifier option or that do include a Server Identifier
411 * option.
412 */
413int
414valid_client_msg(struct packet *packet, struct data_string *client_id) {
415 int ret_val;
416 struct option_cache *oc;
417 struct data_string data;
418
419 ret_val = 0;
420 memset(client_id, 0, sizeof(*client_id));
421 memset(&data, 0, sizeof(data));
422
423 switch (get_client_id(packet, client_id)) {
424 case ISC_R_SUCCESS:
425 break;
426 case ISC_R_NOTFOUND:
427 log_debug("Discarding %s from %s; "
783259b1 428 "client identifier missing",
98bd7ca0
DH
429 dhcpv6_type_names[packet->dhcpv6_msg_type],
430 piaddr(packet->client_addr));
431 goto exit;
432 default:
433 log_error("Error processing %s from %s; "
434 "unable to evaluate Client Identifier",
435 dhcpv6_type_names[packet->dhcpv6_msg_type],
436 piaddr(packet->client_addr));
437 goto exit;
438 }
439
440 /*
441 * Required by RFC 3315, section 15.
442 */
443 if (packet->unicast) {
444 log_debug("Discarding %s from %s; packet sent unicast "
783259b1 445 "(CLIENTID %s)",
98bd7ca0
DH
446 dhcpv6_type_names[packet->dhcpv6_msg_type],
447 piaddr(packet->client_addr),
c382bc98 448 print_hex_1(client_id->len, client_id->data, 60));
98bd7ca0
DH
449 goto exit;
450 }
451
452
453 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
454 if (oc != NULL) {
455 if (evaluate_option_cache(&data, packet, NULL, NULL,
783259b1 456 packet->options, NULL,
98bd7ca0 457 &global_scope, oc, MDL)) {
783259b1 458 log_debug("Discarding %s from %s; "
98bd7ca0 459 "server identifier found "
783259b1 460 "(CLIENTID %s, SERVERID %s)",
98bd7ca0
DH
461 dhcpv6_type_names[packet->dhcpv6_msg_type],
462 piaddr(packet->client_addr),
783259b1 463 print_hex_1(client_id->len,
98bd7ca0
DH
464 client_id->data, 60),
465 print_hex_2(data.len,
466 data.data, 60));
467 } else {
783259b1 468 log_debug("Discarding %s from %s; "
98bd7ca0 469 "server identifier found "
783259b1 470 "(CLIENTID %s)",
98bd7ca0 471 dhcpv6_type_names[packet->dhcpv6_msg_type],
783259b1 472 print_hex_1(client_id->len,
98bd7ca0
DH
473 client_id->data, 60),
474 piaddr(packet->client_addr));
475 }
476 goto exit;
477 }
478
479 /* looks good */
480 ret_val = 1;
481
482exit:
483 if (data.len > 0) {
484 data_string_forget(&data, MDL);
485 }
486 if (!ret_val) {
487 if (client_id->len > 0) {
488 data_string_forget(client_id, MDL);
489 }
490 }
491 return ret_val;
492}
493
494/*
495 * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
496 * 15.9 (slightly different wording, but same meaning):
497 *
498 * Servers MUST discard any received Request message that meet any of
499 * the following conditions:
500 *
501 * - the message does not include a Server Identifier option.
502 * - the contents of the Server Identifier option do not match the
503 * server's DUID.
504 * - the message does not include a Client Identifier option.
505 */
506int
507valid_client_resp(struct packet *packet,
508 struct data_string *client_id,
c382bc98
SK
509 struct data_string *server_id)
510{
98bd7ca0
DH
511 int ret_val;
512 struct option_cache *oc;
513
514 /* INSIST((duid.data != NULL) && (duid.len > 0)); */
515
516 ret_val = 0;
517 memset(client_id, 0, sizeof(*client_id));
518 memset(server_id, 0, sizeof(*server_id));
519
520 switch (get_client_id(packet, client_id)) {
521 case ISC_R_SUCCESS:
522 break;
523 case ISC_R_NOTFOUND:
524 log_debug("Discarding %s from %s; "
783259b1 525 "client identifier missing",
98bd7ca0
DH
526 dhcpv6_type_names[packet->dhcpv6_msg_type],
527 piaddr(packet->client_addr));
528 goto exit;
529 default:
530 log_error("Error processing %s from %s; "
531 "unable to evaluate Client Identifier",
532 dhcpv6_type_names[packet->dhcpv6_msg_type],
533 piaddr(packet->client_addr));
534 goto exit;
535 }
536
537 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
538 if (oc == NULL) {
539 log_debug("Discarding %s from %s: "
783259b1 540 "server identifier missing (CLIENTID %s)",
98bd7ca0
DH
541 dhcpv6_type_names[packet->dhcpv6_msg_type],
542 piaddr(packet->client_addr),
543 print_hex_1(client_id->len, client_id->data, 60));
544 goto exit;
545 }
783259b1 546 if (!evaluate_option_cache(server_id, packet, NULL, NULL,
98bd7ca0
DH
547 packet->options, NULL,
548 &global_scope, oc, MDL)) {
549 log_error("Error processing %s from %s; "
550 "unable to evaluate Server Identifier (CLIENTID %s)",
551 dhcpv6_type_names[packet->dhcpv6_msg_type],
552 piaddr(packet->client_addr),
553 print_hex_1(client_id->len, client_id->data, 60));
554 goto exit;
555 }
783259b1 556 if ((server_duid.len != server_id->len) ||
98bd7ca0 557 (memcmp(server_duid.data, server_id->data, server_duid.len) != 0)) {
783259b1 558 log_debug("Discarding %s from %s; "
98bd7ca0 559 "not our server identifier "
783259b1 560 "(CLIENTID %s, SERVERID %s, server DUID %s)",
98bd7ca0
DH
561 dhcpv6_type_names[packet->dhcpv6_msg_type],
562 piaddr(packet->client_addr),
563 print_hex_1(client_id->len, client_id->data, 60),
564 print_hex_2(server_id->len, server_id->data, 60),
565 print_hex_3(server_duid.len, server_duid.data, 60));
566 goto exit;
567 }
568
569 /* looks good */
570 ret_val = 1;
571
572exit:
573 if (!ret_val) {
574 if (server_id->len > 0) {
575 data_string_forget(server_id, MDL);
576 }
577 if (client_id->len > 0) {
578 data_string_forget(client_id, MDL);
579 }
580 }
581 return ret_val;
582}
583
584/*
585 * Information request validation, defined in RFC 3315, section 15.12:
586 *
587 * Servers MUST discard any received Information-request message that
588 * meets any of the following conditions:
589 *
590 * - The message includes a Server Identifier option and the DUID in
591 * the option does not match the server's DUID.
592 *
593 * - The message includes an IA option.
594 */
595int
596valid_client_info_req(struct packet *packet, struct data_string *server_id) {
597 int ret_val;
598 struct option_cache *oc;
c382bc98
SK
599 struct data_string client_id;
600 char client_id_str[80]; /* print_hex_1() uses maximum 60 characters,
601 plus a few more for extra information */
98bd7ca0
DH
602
603 ret_val = 0;
604 memset(server_id, 0, sizeof(*server_id));
0f750c4f 605 memset(&client_id, 0, sizeof(client_id));
98bd7ca0 606
c382bc98
SK
607 /*
608 * Make a string that we can print out to give more
609 * information about the client if we need to.
610 *
611 * By RFC 3315, Section 18.1.5 clients SHOULD have a
612 * client-id on an Information-request packet, but it
613 * is not strictly necessary.
614 */
615 if (get_client_id(packet, &client_id) == ISC_R_SUCCESS) {
616 snprintf(client_id_str, sizeof(client_id_str), " (CLIENTID %s)",
617 print_hex_1(client_id.len, client_id.data, 60));
618 data_string_forget(&client_id, MDL);
619 } else {
620 client_id_str[0] = '\0';
621 }
622
98bd7ca0
DH
623 /*
624 * Required by RFC 3315, section 15.
625 */
626 if (packet->unicast) {
c382bc98 627 log_debug("Discarding %s from %s; packet sent unicast%s",
98bd7ca0 628 dhcpv6_type_names[packet->dhcpv6_msg_type],
c382bc98 629 piaddr(packet->client_addr), client_id_str);
98bd7ca0
DH
630 goto exit;
631 }
632
633 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
634 if (oc != NULL) {
635 log_debug("Discarding %s from %s; "
783259b1 636 "IA_NA option present%s",
98bd7ca0 637 dhcpv6_type_names[packet->dhcpv6_msg_type],
c382bc98 638 piaddr(packet->client_addr), client_id_str);
98bd7ca0
DH
639 goto exit;
640 }
641 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_TA);
642 if (oc != NULL) {
643 log_debug("Discarding %s from %s; "
783259b1 644 "IA_TA option present%s",
98bd7ca0 645 dhcpv6_type_names[packet->dhcpv6_msg_type],
c382bc98 646 piaddr(packet->client_addr), client_id_str);
98bd7ca0
DH
647 goto exit;
648 }
1d9774ab
FD
649 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
650 if (oc != NULL) {
651 log_debug("Discarding %s from %s; "
783259b1 652 "IA_PD option present%s",
1d9774ab
FD
653 dhcpv6_type_names[packet->dhcpv6_msg_type],
654 piaddr(packet->client_addr), client_id_str);
655 goto exit;
656 }
98bd7ca0
DH
657
658 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
659 if (oc != NULL) {
783259b1 660 if (!evaluate_option_cache(server_id, packet, NULL, NULL,
98bd7ca0
DH
661 packet->options, NULL,
662 &global_scope, oc, MDL)) {
663 log_error("Error processing %s from %s; "
c382bc98 664 "unable to evaluate Server Identifier%s",
98bd7ca0 665 dhcpv6_type_names[packet->dhcpv6_msg_type],
c382bc98 666 piaddr(packet->client_addr), client_id_str);
98bd7ca0
DH
667 goto exit;
668 }
783259b1
FD
669 if ((server_duid.len != server_id->len) ||
670 (memcmp(server_duid.data, server_id->data,
98bd7ca0 671 server_duid.len) != 0)) {
783259b1 672 log_debug("Discarding %s from %s; "
98bd7ca0 673 "not our server identifier "
783259b1 674 "(SERVERID %s, server DUID %s)%s",
98bd7ca0
DH
675 dhcpv6_type_names[packet->dhcpv6_msg_type],
676 piaddr(packet->client_addr),
783259b1 677 print_hex_1(server_id->len,
98bd7ca0 678 server_id->data, 60),
783259b1 679 print_hex_2(server_duid.len,
c382bc98
SK
680 server_duid.data, 60),
681 client_id_str);
98bd7ca0
DH
682 goto exit;
683 }
684 }
685
686 /* looks good */
687 ret_val = 1;
688
689exit:
690 if (!ret_val) {
691 if (server_id->len > 0) {
692 data_string_forget(server_id, MDL);
693 }
694 }
695 return ret_val;
696}
697
698/*
699 * Options that we want to send, in addition to what was requested
700 * via the ORO.
701 */
702static const int required_opts[] = {
703 D6O_CLIENTID,
704 D6O_SERVERID,
705 D6O_STATUS_CODE,
76db44f9 706 D6O_PREFERENCE,
98bd7ca0
DH
707 0
708};
709static const int required_opts_solicit[] = {
710 D6O_CLIENTID,
711 D6O_SERVERID,
712 D6O_IA_NA,
713 D6O_IA_TA,
1d9774ab 714 D6O_IA_PD,
98bd7ca0
DH
715 D6O_RAPID_COMMIT,
716 D6O_STATUS_CODE,
98bd7ca0 717 D6O_RECONF_ACCEPT,
76db44f9 718 D6O_PREFERENCE,
98bd7ca0
DH
719 0
720};
2b964ac0
FD
721static const int required_opts_agent[] = {
722 D6O_INTERFACE_ID,
723 D6O_RELAY_MSG,
724 0
725};
80c9fdb0 726static const int required_opts_IA[] = {
1d9774ab
FD
727 D6O_IAADDR,
728 D6O_STATUS_CODE,
1d9774ab
FD
729 0
730};
731static const int required_opts_IA_PD[] = {
732 D6O_IAPREFIX,
733 D6O_STATUS_CODE,
1d9774ab
FD
734 0
735};
98bd7ca0
DH
736static const int required_opts_STATUS_CODE[] = {
737 D6O_STATUS_CODE,
738 0
739};
740
741/*
8eab95f2
DH
742 * Extracts from packet contents an IA_* option, storing the IA structure
743 * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
744 * in enc_opt_state for later lookup and evaluation. The 'offset' indicates
745 * where in the IA_* the DHCPv6 options commence.
98bd7ca0
DH
746 */
747static int
783259b1 748get_encapsulated_IA_state(struct option_state **enc_opt_state,
98bd7ca0
DH
749 struct data_string *enc_opt_data,
750 struct packet *packet,
8eab95f2
DH
751 struct option_cache *oc,
752 int offset)
c382bc98 753{
98bd7ca0
DH
754 /*
755 * Get the raw data for the encapsulated options.
756 */
757 memset(enc_opt_data, 0, sizeof(*enc_opt_data));
758 if (!evaluate_option_cache(enc_opt_data, packet,
759 NULL, NULL, packet->options, NULL,
760 &global_scope, oc, MDL)) {
761 log_error("get_encapsulated_IA_state: "
762 "error evaluating raw option.");
763 return 0;
764 }
8eab95f2 765 if (enc_opt_data->len < offset) {
98bd7ca0
DH
766 log_error("get_encapsulated_IA_state: raw option too small.");
767 data_string_forget(enc_opt_data, MDL);
768 return 0;
769 }
770
771 /*
772 * Now create the option state structure, and pass it to the
773 * function that parses options.
774 */
775 *enc_opt_state = NULL;
776 if (!option_state_allocate(enc_opt_state, MDL)) {
777 log_error("get_encapsulated_IA_state: no memory for options.");
778 data_string_forget(enc_opt_data, MDL);
779 return 0;
780 }
783259b1 781 if (!parse_option_buffer(*enc_opt_state,
8eab95f2
DH
782 enc_opt_data->data + offset,
783 enc_opt_data->len - offset,
98bd7ca0
DH
784 &dhcpv6_universe)) {
785 log_error("get_encapsulated_IA_state: error parsing options.");
786 option_state_dereference(enc_opt_state, MDL);
787 data_string_forget(enc_opt_data, MDL);
788 return 0;
789 }
790
791 return 1;
792}
793
794static int
795set_status_code(u_int16_t status_code, const char *status_message,
c382bc98
SK
796 struct option_state *opt_state)
797{
98bd7ca0
DH
798 struct data_string d;
799 int ret_val;
800
801 memset(&d, 0, sizeof(d));
802 d.len = sizeof(status_code) + strlen(status_message);
803 if (!buffer_allocate(&d.buffer, d.len, MDL)) {
804 log_fatal("set_status_code: no memory for status code.");
805 }
806 d.data = d.buffer->data;
807 putUShort(d.buffer->data, status_code);
808 memcpy(d.buffer->data + sizeof(status_code),
809 status_message, d.len - sizeof(status_code));
810 if (!save_option_buffer(&dhcpv6_universe, opt_state,
28868515 811 d.buffer, (unsigned char *)d.data, d.len,
98bd7ca0
DH
812 D6O_STATUS_CODE, 0)) {
813 log_error("set_status_code: error saving status code.");
814 ret_val = 0;
815 } else {
816 ret_val = 1;
817 }
818 data_string_forget(&d, MDL);
819 return ret_val;
820}
821
250f7134
SR
822void check_pool6_threshold(struct reply_state *reply,
823 struct iasubopt *lease)
824{
825 struct ipv6_pond *pond;
826 int used, count, high_threshold, poolhigh = 0, poollow = 0;
827 char *shared_name = "no name";
828 char tmp_addr[INET6_ADDRSTRLEN];
829
830 if ((lease->ipv6_pool == NULL) || (lease->ipv6_pool->ipv6_pond == NULL))
831 return;
832 pond = lease->ipv6_pool->ipv6_pond;
833
834 count = pond->num_total;
835 used = pond->num_active;
836
837 /* The logged flag indicates if we have already crossed the high
838 * threshold and emitted a log message. If it is set we check to
839 * see if we have re-crossed the low threshold and need to reset
840 * things. When we cross the high threshold we determine what
841 * the low threshold is and save it into the low_threshold value.
842 * When we cross that threshold we reset the logged flag and
843 * the low_threshold to 0 which allows the high threshold message
844 * to be emitted once again.
845 * if we haven't recrossed the boundry we don't need to do anything.
846 */
847 if (pond->logged !=0) {
848 if (used <= pond->low_threshold) {
849 pond->low_threshold = 0;
850 pond->logged = 0;
851 log_error("Pool threshold reset - shared subnet: %s; "
852 "address: %s; low threshold %d/%d.",
853 shared_name,
854 inet_ntop(AF_INET6, &lease->addr,
855 tmp_addr, sizeof(tmp_addr)),
856 used, count);
857 }
858 return;
859 }
860
861 /* find the high threshold */
862 if (get_option_int(&poolhigh, &server_universe, reply->packet, NULL,
863 NULL, reply->packet->options, reply->opt_state,
864 reply->opt_state, &lease->scope,
865 SV_LOG_THRESHOLD_HIGH, MDL) == 0) {
866 /* no threshold bail out */
867 return;
868 }
869
870 /* We do have a threshold for this pool, see if its valid */
871 if ((poolhigh <= 0) || (poolhigh > 100)) {
872 /* not valid */
873 return;
874 }
875
876 /* we have a valid value, have we exceeded it */
877 high_threshold = FIND_PERCENT(count, poolhigh);
878 if (used < high_threshold) {
879 /* nope, no more to do */
880 return;
881 }
882
883 /* we've exceeded it, output a message */
884 if ((pond->shared_network != NULL) &&
885 (pond->shared_network->name != NULL)) {
886 shared_name = pond->shared_network->name;
887 }
888 log_error("Pool threshold exceeded - shared subnet: %s; "
889 "address: %s; high threshold %d%% %d/%d.",
890 shared_name,
891 inet_ntop(AF_INET6, &lease->addr, tmp_addr, sizeof(tmp_addr)),
892 poolhigh, used, count);
893
894 /* handle the low threshold now, if we don't
895 * have one we default to 0. */
896 if ((get_option_int(&poollow, &server_universe, reply->packet, NULL,
897 NULL, reply->packet->options, reply->opt_state,
898 reply->opt_state, &lease->scope,
899 SV_LOG_THRESHOLD_LOW, MDL) == 0) ||
900 (poollow > 100)) {
901 poollow = 0;
902 }
903
904 /*
905 * If the low theshold is higher than the high threshold we continue to log
906 * If it isn't then we set the flag saying we already logged and determine
907 * what the reset threshold is.
908 */
909 if (poollow < poolhigh) {
910 pond->logged = 1;
911 pond->low_threshold = FIND_PERCENT(count, poollow);
912 }
913}
914
98bd7ca0
DH
915/*
916 * We have a set of operations we do to set up the reply packet, which
917 * is the same for many message types.
918 */
919static int
920start_reply(struct packet *packet,
921 const struct data_string *client_id,
922 const struct data_string *server_id,
923 struct option_state **opt_state,
c382bc98
SK
924 struct dhcpv6_packet *reply)
925{
98bd7ca0 926 struct option_cache *oc;
28868515 927 const unsigned char *server_id_data;
98bd7ca0
DH
928 int server_id_len;
929
98bd7ca0
DH
930 /*
931 * Build our option state for reply.
932 */
933 *opt_state = NULL;
934 if (!option_state_allocate(opt_state, MDL)) {
935 log_error("start_reply: no memory for option_state.");
936 return 0;
937 }
5279b8f3
DH
938 execute_statements_in_scope(NULL, packet, NULL, NULL,
939 packet->options, *opt_state,
a7341359 940 &global_scope, root_group, NULL, NULL);
98bd7ca0 941
5279b8f3
DH
942 /*
943 * A small bit of special handling for Solicit messages.
944 *
945 * We could move the logic into a flag, but for now just check
946 * explicitly.
947 */
948 if (packet->dhcpv6_msg_type == DHCPV6_SOLICIT) {
949 reply->msg_type = DHCPV6_ADVERTISE;
950
951 /*
952 * If:
953 * - this message type supports rapid commit (Solicit), and
954 * - the server is configured to supply a rapid commit, and
955 * - the client requests a rapid commit,
956 * Then we add a rapid commit option, and send Reply (instead
957 * of an Advertise).
958 */
959 oc = lookup_option(&dhcpv6_universe,
960 *opt_state, D6O_RAPID_COMMIT);
961 if (oc != NULL) {
962 oc = lookup_option(&dhcpv6_universe,
963 packet->options, D6O_RAPID_COMMIT);
964 if (oc != NULL) {
a8ac02a4 965 /* Rapid-commit in action. */
5279b8f3 966 reply->msg_type = DHCPV6_REPLY;
a8ac02a4
FD
967 } else {
968 /* Don't want a rapid-commit in advertise. */
969 delete_option(&dhcpv6_universe,
970 *opt_state, D6O_RAPID_COMMIT);
5279b8f3
DH
971 }
972 }
a8ac02a4 973 } else {
5279b8f3 974 reply->msg_type = DHCPV6_REPLY;
a8ac02a4
FD
975 /* Delete the rapid-commit from the sent options. */
976 oc = lookup_option(&dhcpv6_universe,
977 *opt_state, D6O_RAPID_COMMIT);
978 if (oc != NULL) {
979 delete_option(&dhcpv6_universe,
980 *opt_state, D6O_RAPID_COMMIT);
981 }
982 }
5279b8f3
DH
983
984 /*
985 * Use the client's transaction identifier for the reply.
986 */
987 memcpy(reply->transaction_id, packet->dhcpv6_transaction_id,
988 sizeof(reply->transaction_id));
989
98bd7ca0
DH
990 /*
991 * RFC 3315, section 18.2 says we need server identifier and
992 * client identifier.
993 *
994 * If the server ID is defined via the configuration file, then
995 * it will already be present in the option state at this point,
996 * so we don't need to set it.
997 *
998 * If we have a server ID passed in from the caller,
999 * use that, otherwise use the global DUID.
1000 */
1001 oc = lookup_option(&dhcpv6_universe, *opt_state, D6O_SERVERID);
1002 if (oc == NULL) {
1003 if (server_id == NULL) {
28868515 1004 server_id_data = server_duid.data;
98bd7ca0
DH
1005 server_id_len = server_duid.len;
1006 } else {
28868515 1007 server_id_data = server_id->data;
98bd7ca0
DH
1008 server_id_len = server_id->len;
1009 }
1010 if (!save_option_buffer(&dhcpv6_universe, *opt_state,
28868515
SK
1011 NULL, (unsigned char *)server_id_data,
1012 server_id_len, D6O_SERVERID, 0)) {
98bd7ca0
DH
1013 log_error("start_reply: "
1014 "error saving server identifier.");
1015 return 0;
1016 }
1017 }
1018
1019 if (client_id->buffer != NULL) {
1020 if (!save_option_buffer(&dhcpv6_universe, *opt_state,
1021 client_id->buffer,
1022 (unsigned char *)client_id->data,
1023 client_id->len,
1024 D6O_CLIENTID, 0)) {
1025 log_error("start_reply: error saving "
1026 "client identifier.");
1027 return 0;
1028 }
1029 }
1030
1031 /*
1032 * If the client accepts reconfiguration, let it know that we
1033 * will send them.
1034 *
1035 * Note: we don't actually do this yet, but DOCSIS requires we
1036 * claim to.
1037 */
1038 oc = lookup_option(&dhcpv6_universe, packet->options,
1039 D6O_RECONF_ACCEPT);
1040 if (oc != NULL) {
1041 if (!save_option_buffer(&dhcpv6_universe, *opt_state,
28868515
SK
1042 NULL, (unsigned char *)"", 0,
1043 D6O_RECONF_ACCEPT, 0)) {
98bd7ca0
DH
1044 log_error("start_reply: "
1045 "error saving RECONF_ACCEPT option.");
1046 option_state_dereference(opt_state, MDL);
1047 return 0;
1048 }
1049 }
1050
98bd7ca0
DH
1051 return 1;
1052}
1053
1054/*
5279b8f3 1055 * Try to get the IPv6 address the client asked for from the
98bd7ca0
DH
1056 * pool.
1057 *
1058 * addr is the result (should be a pointer to NULL on entry)
1059 * pool is the pool to search in
1060 * requested_addr is the address the client wants
1061 */
1062static isc_result_t
1d17db44 1063try_client_v6_address(struct iasubopt **addr,
98bd7ca0 1064 struct ipv6_pool *pool,
c382bc98
SK
1065 const struct data_string *requested_addr)
1066{
98bd7ca0
DH
1067 struct in6_addr tmp_addr;
1068 isc_result_t result;
98bd7ca0
DH
1069
1070 if (requested_addr->len < sizeof(tmp_addr)) {
98bf1607 1071 return DHCP_R_INVALIDARG;
98bd7ca0
DH
1072 }
1073 memcpy(&tmp_addr, requested_addr->data, sizeof(tmp_addr));
1074 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr)) {
1075 return ISC_R_FAILURE;
1076 }
1077
1aa0fe5e
DH
1078 /*
1079 * The address is not covered by this (or possibly any) dynamic
1080 * range.
1081 */
9322442f 1082 if (!ipv6_in_pool(&tmp_addr, pool)) {
1aa0fe5e 1083 return ISC_R_ADDRNOTAVAIL;
98bd7ca0
DH
1084 }
1085
1086 if (lease6_exists(pool, &tmp_addr)) {
1087 return ISC_R_ADDRINUSE;
1088 }
1089
1d17db44 1090 result = iasubopt_allocate(addr, MDL);
98bd7ca0
DH
1091 if (result != ISC_R_SUCCESS) {
1092 return result;
1093 }
1094 (*addr)->addr = tmp_addr;
9322442f 1095 (*addr)->plen = 0;
98bd7ca0 1096
5d89d60f
FD
1097 /* Default is soft binding for 2 minutes. */
1098 result = add_lease6(pool, *addr, cur_time + 120);
98bd7ca0 1099 if (result != ISC_R_SUCCESS) {
1d17db44 1100 iasubopt_dereference(addr, MDL);
98bd7ca0
DH
1101 }
1102 return result;
1103}
1104
01fa619f
SR
1105
1106/*!
98bd7ca0 1107 *
01fa619f
SR
1108 * \brief Get an IPv6 address for the client.
1109 *
1110 * Attempt to find a usable address for the client. We walk through
1111 * the ponds checking for permit and deny then through the pools
1112 * seeing if they have an available address.
1113 *
1114 * \param reply = the state structure for the current work on this request
1115 * if we create a lease we return it using reply->lease
1116 *
1117 * \return
1118 * ISC_R_SUCCESS = we were able to find an address and are returning a
1119 * pointer to the lease
1120 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1121 * is probabalistic. We don't exhaustively try the
1122 * address range, instead we hash the duid and if
1123 * the address derived from the hash is in use we
1124 * hash the address. After a number of failures we
1125 * conclude the pool is basically full.
98bd7ca0
DH
1126 */
1127static isc_result_t
01fa619f 1128pick_v6_address(struct reply_state *reply)
c382bc98 1129{
01fa619f
SR
1130 struct ipv6_pool *p = NULL;
1131 struct ipv6_pond *pond;
98bd7ca0
DH
1132 int i;
1133 int start_pool;
28868515 1134 unsigned int attempts;
1b5053b5 1135 char tmp_buf[INET6_ADDRSTRLEN];
01fa619f 1136 struct iasubopt **addr = &reply->lease;
98bd7ca0 1137
98bd7ca0 1138 /*
01fa619f
SR
1139 * Do a quick walk through of the ponds and pools
1140 * to see if we have any NA address pools
98bd7ca0 1141 */
01fa619f
SR
1142 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
1143 if (pond->ipv6_pools == NULL)
1144 continue;
1145
1146 for (i = 0; (p = pond->ipv6_pools[i]) != NULL; i++) {
1147 if (p->pool_type == D6O_IA_NA)
1148 break;
80c9fdb0 1149 }
01fa619f 1150 if (p != NULL)
80c9fdb0 1151 break;
80c9fdb0 1152 }
98bd7ca0 1153
01fa619f
SR
1154 /* If we get here and p is NULL we have no useful pools */
1155 if (p == NULL) {
1156 log_debug("Unable to pick client address: "
1157 "no IPv6 pools on this shared network");
1158 return ISC_R_NORESOURCES;
1159 }
1160
98bd7ca0 1161 /*
01fa619f
SR
1162 * We have at least one pool that could provide an address
1163 * Now we walk through the ponds and pools again and check
1164 * to see if the client is permitted and if an address is
1165 * available
1166 *
1167 * Within a given pond we start looking at the last pool we
1168 * allocated from, unless it had a collision trying to allocate
1169 * an address. This will tend to move us into less-filled pools.
1170 */
1171
1172 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
1173 if (((pond->prohibit_list != NULL) &&
1174 (permitted(reply->packet, pond->prohibit_list))) ||
1175 ((pond->permit_list != NULL) &&
1176 (!permitted(reply->packet, pond->permit_list))))
1177 continue;
1178
1179 start_pool = pond->last_ipv6_pool;
1180 i = start_pool;
1181 do {
1182 p = pond->ipv6_pools[i];
1183 if ((p->pool_type == D6O_IA_NA) &&
1184 (create_lease6(p, addr, &attempts,
1185 &reply->ia->iaid_duid,
1186 cur_time + 120) == ISC_R_SUCCESS)) {
1187 /*
1188 * Record the pool used (or next one if there
1189 * was a collision).
1190 */
1191 if (attempts > 1) {
1192 i++;
1193 if (pond->ipv6_pools[i] == NULL) {
1194 i = 0;
1195 }
98bd7ca0 1196 }
01fa619f 1197 pond->last_ipv6_pool = i;
98bd7ca0 1198
01fa619f
SR
1199 log_debug("Picking pool address %s",
1200 inet_ntop(AF_INET6, &((*addr)->addr),
1201 tmp_buf, sizeof(tmp_buf)));
1202 return (ISC_R_SUCCESS);
1203 }
98bd7ca0 1204
01fa619f
SR
1205 i++;
1206 if (pond->ipv6_pools[i] == NULL) {
1207 i = 0;
1208 }
1209 } while (i != start_pool);
1210 }
98bd7ca0
DH
1211
1212 /*
1213 * If we failed to pick an IPv6 address from any of the subnets.
1214 * Presumably that means we have no addresses for the client.
1215 */
1b5053b5 1216 log_debug("Unable to pick client address: no addresses available");
98bd7ca0
DH
1217 return ISC_R_NORESOURCES;
1218}
1219
80c9fdb0
FD
1220/*
1221 * Try to get the IPv6 prefix the client asked for from the
1222 * prefix pool.
1223 *
1224 * pref is the result (should be a pointer to NULL on entry)
9322442f 1225 * pool is the prefix pool to search in
80c9fdb0
FD
1226 * requested_pref is the address the client wants
1227 */
1228static isc_result_t
1d17db44 1229try_client_v6_prefix(struct iasubopt **pref,
9322442f 1230 struct ipv6_pool *pool,
80c9fdb0
FD
1231 const struct data_string *requested_pref)
1232{
1233 u_int8_t tmp_plen;
1234 struct in6_addr tmp_pref;
1235 struct iaddr ia;
1236 isc_result_t result;
1237
1238 if (requested_pref->len < sizeof(tmp_plen) + sizeof(tmp_pref)) {
98bf1607 1239 return DHCP_R_INVALIDARG;
80c9fdb0
FD
1240 }
1241 tmp_plen = (int) requested_pref->data[0];
d19fa5a1
SR
1242 if ((tmp_plen < 3) || (tmp_plen > 128) ||
1243 ((int)tmp_plen != pool->units)) {
80c9fdb0
FD
1244 return ISC_R_FAILURE;
1245 }
1246 memcpy(&tmp_pref, requested_pref->data + 1, sizeof(tmp_pref));
1247 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref)) {
1248 return ISC_R_FAILURE;
1249 }
1250 ia.len = 16;
1251 memcpy(&ia.iabuf, &tmp_pref, 16);
1252 if (!is_cidr_mask_valid(&ia, (int) tmp_plen)) {
1253 return ISC_R_FAILURE;
1254 }
1255
d19fa5a1
SR
1256 if (!ipv6_in_pool(&tmp_pref, pool)) {
1257 return ISC_R_ADDRNOTAVAIL;
80c9fdb0
FD
1258 }
1259
9322442f 1260 if (prefix6_exists(pool, &tmp_pref, tmp_plen)) {
80c9fdb0
FD
1261 return ISC_R_ADDRINUSE;
1262 }
1263
1d17db44 1264 result = iasubopt_allocate(pref, MDL);
80c9fdb0
FD
1265 if (result != ISC_R_SUCCESS) {
1266 return result;
1267 }
9322442f 1268 (*pref)->addr = tmp_pref;
80c9fdb0
FD
1269 (*pref)->plen = tmp_plen;
1270
5d89d60f 1271 /* Default is soft binding for 2 minutes. */
9322442f 1272 result = add_lease6(pool, *pref, cur_time + 120);
80c9fdb0 1273 if (result != ISC_R_SUCCESS) {
1d17db44 1274 iasubopt_dereference(pref, MDL);
80c9fdb0
FD
1275 }
1276 return result;
1277}
1278
01fa619f 1279/*!
80c9fdb0 1280 *
01fa619f
SR
1281 * \brief Get an IPv6 prefix for the client.
1282 *
1283 * Attempt to find a usable prefix for the client. We walk through
1284 * the ponds checking for permit and deny then through the pools
1285 * seeing if they have an available prefix.
1286 *
1287 * \param reply = the state structure for the current work on this request
1288 * if we create a lease we return it using reply->lease
1289 *
1290 * \return
1291 * ISC_R_SUCCESS = we were able to find an prefix and are returning a
1292 * pointer to the lease
1293 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1294 * is probabalistic. We don't exhaustively try the
1295 * address range, instead we hash the duid and if
1296 * the address derived from the hash is in use we
1297 * hash the address. After a number of failures we
1298 * conclude the pool is basically full.
80c9fdb0 1299 */
01fa619f 1300
80c9fdb0 1301static isc_result_t
01fa619f 1302pick_v6_prefix(struct reply_state *reply)
80c9fdb0 1303{
01fa619f
SR
1304 struct ipv6_pool *p = NULL;
1305 struct ipv6_pond *pond;
80c9fdb0
FD
1306 int i;
1307 unsigned int attempts;
1308 char tmp_buf[INET6_ADDRSTRLEN];
01fa619f 1309 struct iasubopt **pref = &reply->lease;
80c9fdb0
FD
1310
1311 /*
01fa619f
SR
1312 * Do a quick walk through of the ponds and pools
1313 * to see if we have any prefix pools
80c9fdb0 1314 */
01fa619f
SR
1315 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
1316 if (pond->ipv6_pools == NULL)
1317 continue;
1318
1319 for (i = 0; (p = pond->ipv6_pools[i]) != NULL; i++) {
1320 if (p->pool_type == D6O_IA_PD)
1321 break;
1322 }
1323 if (p != NULL)
1324 break;
1325 }
1326
1327 /* If we get here and p is NULL we have no useful pools */
1328 if (p == NULL) {
80c9fdb0 1329 log_debug("Unable to pick client prefix: "
9322442f 1330 "no IPv6 pools on this shared network");
80c9fdb0
FD
1331 return ISC_R_NORESOURCES;
1332 }
1333
1334 /*
01fa619f
SR
1335 * We have at least one pool that could provide a prefix
1336 * Now we walk through the ponds and pools again and check
1337 * to see if the client is permitted and if an prefix is
1338 * available
1339 *
1340 */
1341
1342 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
1343 if (((pond->prohibit_list != NULL) &&
1344 (permitted(reply->packet, pond->prohibit_list))) ||
1345 ((pond->permit_list != NULL) &&
1346 (!permitted(reply->packet, pond->permit_list))))
9322442f 1347 continue;
80c9fdb0 1348
01fa619f
SR
1349 for (i = 0; (p = pond->ipv6_pools[i]) != NULL; i++) {
1350 if (p->pool_type != D6O_IA_PD) {
1351 continue;
1352 }
80c9fdb0 1353
01fa619f
SR
1354 /*
1355 * Try only pools with the requested prefix length if any.
1356 */
1357 if ((reply->preflen >= 0) && (p->units != reply->preflen)) {
1358 continue;
1359 }
1360
1361 if (create_prefix6(p, pref, &attempts, &reply->ia->iaid_duid,
1362 cur_time + 120) == ISC_R_SUCCESS) {
1363 log_debug("Picking pool prefix %s/%u",
1364 inet_ntop(AF_INET6, &((*pref)->addr),
1365 tmp_buf, sizeof(tmp_buf)),
1366 (unsigned) (*pref)->plen);
1367
1368 return (ISC_R_SUCCESS);
1369 }
80c9fdb0
FD
1370 }
1371 }
1372
1373 /*
1374 * If we failed to pick an IPv6 prefix
1375 * Presumably that means we have no prefixes for the client.
1376 */
1377 log_debug("Unable to pick client prefix: no prefixes available");
1378 return ISC_R_NORESOURCES;
1379}
1380
5279b8f3 1381/*
cbbd2714
SR
1382 *! \file server/dhcpv6.c
1383 *
1384 * \brief construct a reply containing information about a client's lease
1385 *
5279b8f3
DH
1386 * lease_to_client() is called from several messages to construct a
1387 * reply that contains all that we know about the client's correct lease
1388 * (or projected lease).
1389 *
20ae1aff 1390 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
5279b8f3
DH
1391 * send what we "may" give them on a request.
1392 *
1393 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1394 * the client should really use).
1395 *
1396 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1397 * Rebind out any "wrong" addresses the client sends. This means we send
1398 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1399 * possibly send the address with zeroed lifetimes.
1400 *
4f963ddc
FD
1401 * Information-Request - No binding.
1402 *
5279b8f3
DH
1403 * The basic structure is to traverse the client-supplied data first, and
1404 * validate and echo back any contents that can be. If the client-supplied
1405 * data does not error out (on renew/rebind as above), but we did not send
1406 * any addresses, attempt to allocate one.
cbbd2714
SR
1407 *
1408 * At the end of the this function we call commit_leases_timed() to
1409 * fsync and rotate the file as necessary. commit_leases_timed() will
1410 * check that we have written at least one lease to the file and that
1411 * some time has passed before doing any fsync or file rewrite so we
1412 * don't bother tracking if we did a write_ia during this function.
5279b8f3 1413 */
98bd7ca0 1414/* TODO: look at client hints for lease times */
cbbd2714 1415
98bd7ca0
DH
1416static void
1417lease_to_client(struct data_string *reply_ret,
1418 struct packet *packet,
1419 const struct data_string *client_id,
c382bc98
SK
1420 const struct data_string *server_id)
1421{
5279b8f3 1422 static struct reply_state reply;
98bd7ca0
DH
1423 struct option_cache *oc;
1424 struct data_string packet_oro;
01fa619f 1425 int i;
98bd7ca0 1426
355db4b6
SR
1427 memset(&packet_oro, 0, sizeof(packet_oro));
1428
5279b8f3 1429 /* Locate the client. */
bd72740e
FD
1430 if (shared_network_from_packet6(&reply.shared,
1431 packet) != ISC_R_SUCCESS)
1432 goto exit;
06eb8bab 1433
98bd7ca0 1434 /*
5279b8f3 1435 * Initialize the reply.
98bd7ca0 1436 */
5279b8f3
DH
1437 packet_reference(&reply.packet, packet, MDL);
1438 data_string_copy(&reply.client_id, client_id, MDL);
1439
1440 if (!start_reply(packet, client_id, server_id, &reply.opt_state,
1441 &reply.buf.reply))
98bd7ca0 1442 goto exit;
5279b8f3
DH
1443
1444 /* Set the write cursor to just past the reply header. */
1445 reply.cursor = REPLY_OPTIONS_INDEX;
98bd7ca0
DH
1446
1447 /*
1448 * Get the ORO from the packet, if any.
1449 */
1450 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_ORO);
1451 if (oc != NULL) {
1452 if (!evaluate_option_cache(&packet_oro, packet,
1453 NULL, NULL,
1454 packet->options, NULL,
1455 &global_scope, oc, MDL)) {
1456 log_error("lease_to_client: error evaluating ORO.");
1457 goto exit;
1458 }
1459 }
1460
5279b8f3
DH
1461 /*
1462 * Find a host record that matches from the packet, if any, and is
1463 * valid for the shared network the client is on.
98bd7ca0 1464 */
c900c5b2 1465 if (find_hosts_by_uid(&reply.host, client_id->data, client_id->len,
01fa619f
SR
1466 MDL)) {
1467 packet->known = 1;
bd72740e 1468 seek_shared_host(&reply.host, reply.shared);
01fa619f 1469 }
98bd7ca0 1470
5279b8f3 1471 if ((reply.host == NULL) &&
01fa619f
SR
1472 find_hosts_by_option(&reply.host, packet, packet->options, MDL)) {
1473 packet->known = 1;
c900c5b2 1474 seek_shared_host(&reply.host, reply.shared);
01fa619f 1475 }
c900c5b2
DH
1476
1477 /*
1478 * Check for 'hardware' matches last, as some of the synthesis methods
1479 * are not considered to be as reliable.
1480 */
1481 if ((reply.host == NULL) &&
01fa619f
SR
1482 find_hosts_by_duid_chaddr(&reply.host, client_id)) {
1483 packet->known = 1;
bd72740e 1484 seek_shared_host(&reply.host, reply.shared);
01fa619f 1485 }
98bd7ca0 1486
80c9fdb0 1487 /* Process the client supplied IA's onto the reply buffer. */
5279b8f3
DH
1488 reply.ia_count = 0;
1489 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
d19fa5a1 1490
5279b8f3 1491 for (; oc != NULL ; oc = oc->next) {
9f1d5a2f
DH
1492 isc_result_t status;
1493
1d9774ab
FD
1494 /* Start counting resources (addresses) offered. */
1495 reply.client_resources = 0;
9322442f 1496 reply.resources_included = ISC_FALSE;
9f1d5a2f 1497
1d9774ab 1498 status = reply_process_ia_na(&reply, oc);
9f1d5a2f
DH
1499
1500 /*
1501 * We continue to try other IA's whether we can address
1502 * this one or not. Any other result is an immediate fail.
1503 */
1504 if ((status != ISC_R_SUCCESS) &&
1505 (status != ISC_R_NORESOURCES))
5279b8f3 1506 goto exit;
80c9fdb0
FD
1507 }
1508 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_TA);
1509 for (; oc != NULL ; oc = oc->next) {
1510 isc_result_t status;
1511
80c9fdb0
FD
1512 /* Start counting resources (addresses) offered. */
1513 reply.client_resources = 0;
9322442f 1514 reply.resources_included = ISC_FALSE;
80c9fdb0
FD
1515
1516 status = reply_process_ia_ta(&reply, oc);
1517
1518 /*
1519 * We continue to try other IA's whether we can address
1520 * this one or not. Any other result is an immediate fail.
1521 */
1522 if ((status != ISC_R_SUCCESS) &&
1523 (status != ISC_R_NORESOURCES))
1524 goto exit;
5279b8f3
DH
1525 }
1526
80c9fdb0 1527 /* Same for IA_PD's. */
9322442f 1528 reply.pd_count = 0;
80c9fdb0
FD
1529 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
1530 for (; oc != NULL ; oc = oc->next) {
1531 isc_result_t status;
1532
1533 /* Start counting resources (prefixes) offered. */
1534 reply.client_resources = 0;
9322442f 1535 reply.resources_included = ISC_FALSE;
80c9fdb0
FD
1536
1537 status = reply_process_ia_pd(&reply, oc);
1538
1539 /*
1540 * We continue to try other IA_PD's whether we can address
1541 * this one or not. Any other result is an immediate fail.
1542 */
1543 if ((status != ISC_R_SUCCESS) &&
1544 (status != ISC_R_NORESOURCES))
1545 goto exit;
80c9fdb0 1546 }
1d9774ab 1547
5279b8f3 1548 /*
4f963ddc
FD
1549 * Make no reply if we gave no resources and is not
1550 * for Information-Request.
5279b8f3 1551 */
7d6180be
DH
1552 if ((reply.ia_count == 0) && (reply.pd_count == 0)) {
1553 if (reply.packet->dhcpv6_msg_type !=
1554 DHCPV6_INFORMATION_REQUEST)
1555 goto exit;
1556
1557 /*
1558 * Because we only execute statements on a per-IA basis,
1559 * we need to execute statements in any non-IA reply to
1560 * source configuration.
1561 */
1562 execute_statements_in_scope(NULL, reply.packet, NULL, NULL,
1563 reply.packet->options,
1564 reply.opt_state, &global_scope,
a7341359
SR
1565 reply.shared->group, root_group,
1566 NULL);
2267da84 1567
01fa619f
SR
1568 /* Execute statements from class scopes. */
1569 for (i = reply.packet->class_count; i > 0; i--) {
1570 execute_statements_in_scope(NULL, reply.packet,
1571 NULL, NULL,
1572 reply.packet->options,
1573 reply.opt_state,
1574 &global_scope,
1575 reply.packet->classes[i - 1]->group,
1576 reply.shared->group, NULL);
1577 }
1578
2267da84
DH
1579 /* Bring in any configuration from a host record. */
1580 if (reply.host != NULL)
a7341359
SR
1581 execute_statements_in_scope(NULL, reply.packet,
1582 NULL, NULL,
1583 reply.packet->options,
2267da84
DH
1584 reply.opt_state,
1585 &global_scope,
1586 reply.host->group,
a7341359 1587 reply.shared->group, NULL);
7d6180be 1588 }
98bd7ca0 1589
5279b8f3 1590 /*
9f1d5a2f
DH
1591 * RFC3315 section 17.2.2 (Solicit):
1592 *
1593 * If the server will not assign any addresses to any IAs in a
1594 * subsequent Request from the client, the server MUST send an
1595 * Advertise message to the client that includes only a Status
1596 * Code option with code NoAddrsAvail and a status message for
1597 * the user, a Server Identifier option with the server's DUID,
1598 * and a Client Identifier option with the client's DUID.
1599 *
388cba45
SR
1600 * This has been updated by an errata such that the server
1601 * can always send an IA.
1602 *
9f1d5a2f
DH
1603 * Section 18.2.1 (Request):
1604 *
1605 * If the server cannot assign any addresses to an IA in the
1606 * message from the client, the server MUST include the IA in
1607 * the Reply message with no addresses in the IA and a Status
1608 * Code option in the IA containing status code NoAddrsAvail.
1609 *
892379ec 1610 * Section 18.1.8 (Client Behavior):
9f1d5a2f 1611 *
892379ec
FD
1612 * Leave unchanged any information about addresses the client has
1613 * recorded in the IA but that were not included in the IA from
1614 * the server.
1615 * Sends a Renew/Rebind if the IA is not in the Reply message.
5279b8f3 1616 */
9f1d5a2f 1617
d19fa5a1
SR
1618 /*
1619 * Having stored the client's IA's, store any options that
1620 * will fit in the remaining space.
1621 */
1622 reply.cursor += store_options6((char *)reply.buf.data + reply.cursor,
1623 sizeof(reply.buf) - reply.cursor,
1624 reply.opt_state, reply.packet,
1625 required_opts_solicit,
1626 &packet_oro);
5279b8f3
DH
1627
1628 /* Return our reply to the caller. */
1629 reply_ret->len = reply.cursor;
1630 reply_ret->buffer = NULL;
1631 if (!buffer_allocate(&reply_ret->buffer, reply.cursor, MDL)) {
1632 log_fatal("No memory to store Reply.");
98bd7ca0 1633 }
5279b8f3
DH
1634 memcpy(reply_ret->buffer->data, reply.buf.data, reply.cursor);
1635 reply_ret->data = reply_ret->buffer->data;
1636
cbbd2714
SR
1637 /* If appropriate commit and rotate the lease file */
1638 (void) commit_leases_timed();
1639
5279b8f3
DH
1640 exit:
1641 /* Cleanup. */
1642 if (reply.shared != NULL)
1643 shared_network_dereference(&reply.shared, MDL);
1644 if (reply.host != NULL)
1645 host_dereference(&reply.host, MDL);
1646 if (reply.opt_state != NULL)
1647 option_state_dereference(&reply.opt_state, MDL);
1648 if (reply.packet != NULL)
1649 packet_dereference(&reply.packet, MDL);
1650 if (reply.client_id.data != NULL)
1651 data_string_forget(&reply.client_id, MDL);
3bedb117
SR
1652 if (packet_oro.buffer != NULL)
1653 data_string_forget(&packet_oro, MDL);
5279b8f3
DH
1654 reply.renew = reply.rebind = reply.prefer = reply.valid = 0;
1655 reply.cursor = 0;
1656}
98bd7ca0 1657
b9137d42 1658/* Process a client-supplied IA_NA. This may append options to the tail of
5279b8f3
DH
1659 * the reply packet being built in the reply_state structure.
1660 */
1661static isc_result_t
1d9774ab 1662reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) {
5279b8f3
DH
1663 isc_result_t status = ISC_R_SUCCESS;
1664 u_int32_t iaid;
1665 unsigned ia_cursor;
1666 struct option_state *packet_ia;
1667 struct option_cache *oc;
1668 struct data_string ia_data, data;
98bd7ca0 1669
5279b8f3
DH
1670 /* Initialize values that will get cleaned up on return. */
1671 packet_ia = NULL;
1672 memset(&ia_data, 0, sizeof(ia_data));
1673 memset(&data, 0, sizeof(data));
b9137d42
SK
1674 /*
1675 * Note that find_client_address() may set reply->lease.
1676 */
98bd7ca0 1677
5279b8f3
DH
1678 /* Make sure there is at least room for the header. */
1679 if ((reply->cursor + IA_NA_OFFSET + 4) > sizeof(reply->buf)) {
1d9774ab 1680 log_error("reply_process_ia_na: Reply too long for IA.");
5279b8f3 1681 return ISC_R_NOSPACE;
98bd7ca0 1682 }
98bd7ca0 1683
98bd7ca0 1684
5279b8f3
DH
1685 /* Fetch the IA_NA contents. */
1686 if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
1687 ia, IA_NA_OFFSET)) {
9322442f 1688 log_error("reply_process_ia_na: error evaluating ia");
5279b8f3
DH
1689 status = ISC_R_FAILURE;
1690 goto cleanup;
1691 }
98bd7ca0 1692
5279b8f3
DH
1693 /* Extract IA_NA header contents. */
1694 iaid = getULong(ia_data.data);
1695 reply->renew = getULong(ia_data.data + 4);
1696 reply->rebind = getULong(ia_data.data + 8);
1697
1698 /* Create an IA_NA structure. */
9322442f
FD
1699 if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data,
1700 reply->client_id.len, MDL) != ISC_R_SUCCESS) {
1701 log_error("reply_process_ia_na: no memory for ia.");
5279b8f3
DH
1702 status = ISC_R_NOMEMORY;
1703 goto cleanup;
1704 }
9322442f 1705 reply->ia->ia_type = D6O_IA_NA;
5279b8f3
DH
1706
1707 /* Cache pre-existing IA, if any. */
9322442f
FD
1708 ia_hash_lookup(&reply->old_ia, ia_na_active,
1709 (unsigned char *)reply->ia->iaid_duid.data,
1710 reply->ia->iaid_duid.len, MDL);
5279b8f3
DH
1711
1712 /*
1713 * Create an option cache to carry the IA_NA option contents, and
1714 * execute any user-supplied values into it.
1715 */
1716 if (!option_state_allocate(&reply->reply_ia, MDL)) {
1717 status = ISC_R_NOMEMORY;
1718 goto cleanup;
1719 }
1720
1721 /* Check & cache the fixed host record. */
1722 if ((reply->host != NULL) && (reply->host->fixed_addr != NULL)) {
2267da84
DH
1723 struct iaddr tmp_addr;
1724
5279b8f3
DH
1725 if (!evaluate_option_cache(&reply->fixed, NULL, NULL, NULL,
1726 NULL, NULL, &global_scope,
1727 reply->host->fixed_addr, MDL)) {
1d9774ab 1728 log_error("reply_process_ia_na: unable to evaluate "
5279b8f3
DH
1729 "fixed address.");
1730 status = ISC_R_FAILURE;
1731 goto cleanup;
98bd7ca0
DH
1732 }
1733
5279b8f3 1734 if (reply->fixed.len < 16) {
1d9774ab 1735 log_error("reply_process_ia_na: invalid fixed address.");
98bf1607 1736 status = DHCP_R_INVALIDARG;
5279b8f3 1737 goto cleanup;
98bd7ca0
DH
1738 }
1739
2267da84
DH
1740 /* Find the static lease's subnet. */
1741 tmp_addr.len = 16;
1742 memcpy(tmp_addr.iabuf, reply->fixed.data, 16);
1743
1744 if (find_grouped_subnet(&reply->subnet, reply->shared,
1745 tmp_addr, MDL) == 0)
1746 log_fatal("Impossible condition at %s:%d.", MDL);
1747
5279b8f3
DH
1748 reply->static_lease = ISC_TRUE;
1749 } else
1750 reply->static_lease = ISC_FALSE;
1751
1752 /*
1753 * Save the cursor position at the start of the IA, so we can
1754 * set length and adjust t1/t2 values later. We write a temporary
1755 * header out now just in case we decide to adjust the packet
1756 * within sub-process functions.
1757 */
1758 ia_cursor = reply->cursor;
1759
1760 /* Initialize the IA_NA header. First the code. */
1761 putUShort(reply->buf.data + reply->cursor, (unsigned)D6O_IA_NA);
1762 reply->cursor += 2;
1763
1764 /* Then option length. */
1765 putUShort(reply->buf.data + reply->cursor, 0x0Cu);
1766 reply->cursor += 2;
1767
1768 /* Then IA_NA header contents; IAID. */
1769 putULong(reply->buf.data + reply->cursor, iaid);
1770 reply->cursor += 4;
1771
1772 /* We store the client's t1 for now, and may over-ride it later. */
1773 putULong(reply->buf.data + reply->cursor, reply->renew);
1774 reply->cursor += 4;
1775
1776 /* We store the client's t2 for now, and may over-ride it later. */
1777 putULong(reply->buf.data + reply->cursor, reply->rebind);
1778 reply->cursor += 4;
1779
1780 /*
892379ec
FD
1781 * For each address in this IA_NA, decide what to do about it.
1782 *
1783 * Guidelines:
1784 *
7c7515b9 1785 * The client leaves unchanged any information about addresses
892379ec
FD
1786 * it has recorded but are not included ("cancel/break" below).
1787 * A not included IA ("cleanup" below) could give a Renew/Rebind.
5279b8f3
DH
1788 */
1789 oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAADDR);
1790 reply->valid = reply->prefer = 0xffffffff;
1791 reply->client_valid = reply->client_prefer = 0;
5279b8f3
DH
1792 for (; oc != NULL ; oc = oc->next) {
1793 status = reply_process_addr(reply, oc);
1794
98bd7ca0 1795 /*
5279b8f3
DH
1796 * Canceled means we did not allocate addresses to the
1797 * client, but we're "done" with this IA - we set a status
1798 * code. So transmit this reply, e.g., move on to the next
1799 * IA.
98bd7ca0 1800 */
5279b8f3
DH
1801 if (status == ISC_R_CANCELED)
1802 break;
98bd7ca0 1803
1aa0fe5e
DH
1804 if ((status != ISC_R_SUCCESS) &&
1805 (status != ISC_R_ADDRINUSE) &&
1806 (status != ISC_R_ADDRNOTAVAIL))
5279b8f3
DH
1807 goto cleanup;
1808 }
1809
1810 reply->ia_count++;
1811
1812 /*
1813 * If we fell through the above and never gave the client
1814 * an address, give it one now.
1815 */
1d9774ab 1816 if ((status != ISC_R_CANCELED) && (reply->client_resources == 0)) {
5279b8f3
DH
1817 status = find_client_address(reply);
1818
9f1d5a2f
DH
1819 if (status == ISC_R_NORESOURCES) {
1820 switch (reply->packet->dhcpv6_msg_type) {
1821 case DHCPV6_SOLICIT:
1822 /*
80c9fdb0 1823 * No address for any IA is handled
892379ec 1824 * by the caller.
9f1d5a2f 1825 */
80c9fdb0 1826 /* FALL THROUGH */
9f1d5a2f
DH
1827
1828 case DHCPV6_REQUEST:
1829 /* Section 18.2.1 (Request):
1830 *
1831 * If the server cannot assign any addresses to
1832 * an IA in the message from the client, the
1833 * server MUST include the IA in the Reply
1834 * message with no addresses in the IA and a
1835 * Status Code option in the IA containing
1836 * status code NoAddrsAvail.
1837 */
5279b8f3
DH
1838 option_state_dereference(&reply->reply_ia, MDL);
1839 if (!option_state_allocate(&reply->reply_ia,
9f1d5a2f
DH
1840 MDL))
1841 {
1d9774ab 1842 log_error("reply_process_ia_na: No "
9f1d5a2f
DH
1843 "memory for option state "
1844 "wipe.");
5279b8f3
DH
1845 status = ISC_R_NOMEMORY;
1846 goto cleanup;
1847 }
5279b8f3 1848
9f1d5a2f
DH
1849 if (!set_status_code(STATUS_NoAddrsAvail,
1850 "No addresses available "
1851 "for this interface.",
1852 reply->reply_ia)) {
1d9774ab 1853 log_error("reply_process_ia_na: Unable "
9f1d5a2f
DH
1854 "to set NoAddrsAvail status "
1855 "code.");
1856 status = ISC_R_FAILURE;
1857 goto cleanup;
1858 }
5279b8f3 1859
9f1d5a2f
DH
1860 status = ISC_R_SUCCESS;
1861 break;
1862
1863 default:
1864 /*
1865 * RFC 3315 does not tell us to emit a status
1866 * code in this condition, or anything else.
1867 *
1868 * If we included non-allocated addresses
1869 * (zeroed lifetimes) in an IA, then the client
1870 * will deconfigure them.
1871 *
1872 * So we want to include the IA even if we
1873 * can't give it a new address if it includes
1874 * zeroed lifetime addresses.
1875 *
1876 * We don't want to include the IA if we
1877 * provide zero addresses including zeroed
892379ec 1878 * lifetimes.
9f1d5a2f 1879 */
9322442f 1880 if (reply->resources_included)
9f1d5a2f
DH
1881 status = ISC_R_SUCCESS;
1882 else
1883 goto cleanup;
1884 break;
1885 }
98bd7ca0
DH
1886 }
1887
5279b8f3
DH
1888 if (status != ISC_R_SUCCESS)
1889 goto cleanup;
1890 }
1891
1892 reply->cursor += store_options6((char *)reply->buf.data + reply->cursor,
1893 sizeof(reply->buf) - reply->cursor,
1894 reply->reply_ia, reply->packet,
80c9fdb0 1895 required_opts_IA, NULL);
5279b8f3
DH
1896
1897 /* Reset the length of this IA to match what was just written. */
1898 putUShort(reply->buf.data + ia_cursor + 2,
1899 reply->cursor - (ia_cursor + 4));
1900
1901 /*
1902 * T1/T2 time selection is kind of weird. We actually use DHCP
1903 * (v4) scoped options as handy existing places where these might
1904 * be configured by an administrator. A value of zero tells the
1905 * client it may choose its own renewal time.
1906 */
1907 reply->renew = 0;
1908 oc = lookup_option(&dhcp_universe, reply->opt_state,
1909 DHO_DHCP_RENEWAL_TIME);
1910 if (oc != NULL) {
1911 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
1912 reply->packet->options,
1913 reply->opt_state, &global_scope,
1914 oc, MDL) ||
1915 (data.len != 4)) {
1916 log_error("Invalid renewal time.");
1917 } else {
1918 reply->renew = getULong(data.data);
98bd7ca0
DH
1919 }
1920
5279b8f3
DH
1921 if (data.data != NULL)
1922 data_string_forget(&data, MDL);
1923 }
1924 putULong(reply->buf.data + ia_cursor + 8, reply->renew);
1925
1926 /* Now T2. */
1927 reply->rebind = 0;
1928 oc = lookup_option(&dhcp_universe, reply->opt_state,
1929 DHO_DHCP_REBINDING_TIME);
1930 if (oc != NULL) {
1931 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
1932 reply->packet->options,
1933 reply->opt_state, &global_scope,
1934 oc, MDL) ||
1935 (data.len != 4)) {
1936 log_error("Invalid rebinding time.");
98bd7ca0 1937 } else {
5279b8f3 1938 reply->rebind = getULong(data.data);
98bd7ca0
DH
1939 }
1940
5279b8f3
DH
1941 if (data.data != NULL)
1942 data_string_forget(&data, MDL);
1943 }
1944 putULong(reply->buf.data + ia_cursor + 12, reply->rebind);
98bd7ca0 1945
d9b5c150
SR
1946 /*
1947 * yes, goto's aren't the best but we also want to avoid extra
1948 * indents
1949 */
1950 if (status == ISC_R_CANCELED)
1951 goto cleanup;
1952
1953 /*
1954 * Handle static leases, we always log stuff and if it's
1955 * a hard binding we run any commit statements that we have
1956 */
1957 if (reply->static_lease) {
1958 char tmp_addr[INET6_ADDRSTRLEN];
1959 log_info("%s NA: address %s to client with duid %s iaid = %d "
1960 "static",
1961 dhcpv6_type_names[reply->buf.reply.msg_type],
1962 inet_ntop(AF_INET6, reply->fixed.data, tmp_addr,
1963 sizeof(tmp_addr)),
1964 print_hex_1(reply->client_id.len,
1965 reply->client_id.data, 60),
1966 iaid);
1967
1968 if ((reply->buf.reply.msg_type == DHCPV6_REPLY) &&
1969 (reply->on_star.on_commit != NULL)) {
1970 execute_statements(NULL, reply->packet, NULL, NULL,
1971 reply->packet->options,
1972 reply->opt_state, NULL,
1973 reply->on_star.on_commit, NULL);
1974 executable_statement_dereference
1975 (&reply->on_star.on_commit, MDL);
1976 }
1977 goto cleanup;
1978 }
1979
1980 /*
1981 * If we have any addresses log what we are doing.
1982 */
1983 if (reply->ia->num_iasubopt != 0) {
1984 struct iasubopt *tmp;
1985 int i;
1986 char tmp_addr[INET6_ADDRSTRLEN];
1987
1988 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
1989 tmp = reply->ia->iasubopt[i];
1990
1991 log_info("%s NA: address %s to client with duid %s "
1992 "iaid = %d valid for %d seconds",
1993 dhcpv6_type_names[reply->buf.reply.msg_type],
1994 inet_ntop(AF_INET6, &tmp->addr,
1995 tmp_addr, sizeof(tmp_addr)),
1996 print_hex_1(reply->client_id.len,
1997 reply->client_id.data, 60),
1998 iaid, tmp->valid);
1999 }
2000 }
2001
5279b8f3
DH
2002 /*
2003 * If this is not a 'soft' binding, consume the new changes into
2004 * the database (if any have been attached to the ia_na).
2005 *
2006 * Loop through the assigned dynamic addresses, referencing the
2007 * leases onto this IA_NA rather than any old ones, and updating
2008 * pool timers for each (if any).
2009 */
d9b5c150
SR
2010
2011 if ((reply->ia->num_iasubopt != 0) &&
2012 (reply->buf.reply.msg_type == DHCPV6_REPLY)) {
1d17db44 2013 struct iasubopt *tmp;
5279b8f3
DH
2014 struct data_string *ia_id;
2015 int i;
98bd7ca0 2016
1d17db44
FD
2017 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
2018 tmp = reply->ia->iasubopt[i];
98bd7ca0 2019
9322442f
FD
2020 if (tmp->ia != NULL)
2021 ia_dereference(&tmp->ia, MDL);
2022 ia_reference(&tmp->ia, reply->ia, MDL);
98bd7ca0 2023
5d89d60f 2024 /* Commit 'hard' bindings. */
5d89d60f 2025 renew_lease6(tmp->ipv6_pool, tmp);
5279b8f3 2026 schedule_lease_timeout(tmp->ipv6_pool);
98bd7ca0 2027
a7341359
SR
2028 /* If we have anything to do on commit do it now */
2029 if (tmp->on_star.on_commit != NULL) {
2030 execute_statements(NULL, reply->packet,
2031 NULL, NULL,
2032 reply->packet->options,
2033 reply->opt_state,
58cb5d86 2034 &tmp->scope,
a7341359
SR
2035 tmp->on_star.on_commit,
2036 &tmp->on_star);
2037 executable_statement_dereference
2038 (&tmp->on_star.on_commit, MDL);
2039 }
2040
98bf1607 2041#if defined (NSUPDATE)
98bd7ca0 2042 /*
5d89d60f 2043 * Perform ddns updates.
98bd7ca0 2044 */
5279b8f3
DH
2045 oc = lookup_option(&server_universe, reply->opt_state,
2046 SV_DDNS_UPDATES);
2047 if ((oc == NULL) ||
2048 evaluate_boolean_option_cache(NULL, reply->packet,
2049 NULL, NULL,
2050 reply->packet->options,
2051 reply->opt_state,
bead14ea 2052 &tmp->scope,
5279b8f3
DH
2053 oc, MDL)) {
2054 ddns_updates(reply->packet, NULL, NULL,
bead14ea 2055 tmp, NULL, reply->opt_state);
98bd7ca0 2056 }
98bf1607 2057#endif
250f7134
SR
2058 /* Do our threshold check. */
2059 check_pool6_threshold(reply, tmp);
5279b8f3 2060 }
98bd7ca0 2061
9322442f 2062 /* Remove any old ia from the hash. */
80c9fdb0
FD
2063 if (reply->old_ia != NULL) {
2064 ia_id = &reply->old_ia->iaid_duid;
9322442f
FD
2065 ia_hash_delete(ia_na_active,
2066 (unsigned char *)ia_id->data,
2067 ia_id->len, MDL);
2068 ia_dereference(&reply->old_ia, MDL);
98bd7ca0
DH
2069 }
2070
9322442f 2071 /* Put new ia into the hash. */
1acab09f 2072 reply->ia->cltt = cur_time;
9322442f
FD
2073 ia_id = &reply->ia->iaid_duid;
2074 ia_hash_add(ia_na_active, (unsigned char *)ia_id->data,
2075 ia_id->len, reply->ia, MDL);
98bd7ca0 2076
9322442f 2077 write_ia(reply->ia);
ad80055f
SR
2078 } else {
2079 schedule_lease_timeout_reply(reply);
5279b8f3 2080 }
98bd7ca0 2081
5279b8f3
DH
2082 cleanup:
2083 if (packet_ia != NULL)
2084 option_state_dereference(&packet_ia, MDL);
2085 if (reply->reply_ia != NULL)
2086 option_state_dereference(&reply->reply_ia, MDL);
2087 if (ia_data.data != NULL)
2088 data_string_forget(&ia_data, MDL);
2089 if (data.data != NULL)
2090 data_string_forget(&data, MDL);
9322442f
FD
2091 if (reply->ia != NULL)
2092 ia_dereference(&reply->ia, MDL);
80c9fdb0 2093 if (reply->old_ia != NULL)
9322442f 2094 ia_dereference(&reply->old_ia, MDL);
5d89d60f 2095 if (reply->lease != NULL)
1d17db44 2096 iasubopt_dereference(&reply->lease, MDL);
5279b8f3
DH
2097 if (reply->fixed.data != NULL)
2098 data_string_forget(&reply->fixed, MDL);
2267da84
DH
2099 if (reply->subnet != NULL)
2100 subnet_dereference(&reply->subnet, MDL);
a7341359
SR
2101 if (reply->on_star.on_expiry != NULL)
2102 executable_statement_dereference
2103 (&reply->on_star.on_expiry, MDL);
2104 if (reply->on_star.on_release != NULL)
2105 executable_statement_dereference
2106 (&reply->on_star.on_release, MDL);
5279b8f3
DH
2107
2108 /*
2109 * ISC_R_CANCELED is a status code used by the addr processing to
2110 * indicate we're replying with a status code. This is still a
2111 * success at higher layers.
2112 */
2113 return((status == ISC_R_CANCELED) ? ISC_R_SUCCESS : status);
2114}
2115
2116/*
9322442f 2117 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
5279b8f3
DH
2118 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
2119 * in the event we are replying with a status code and do not wish to process
2120 * more IAADDRs within this IA.
2121 */
2122static isc_result_t
2123reply_process_addr(struct reply_state *reply, struct option_cache *addr) {
2124 u_int32_t pref_life, valid_life;
2125 struct binding_scope **scope;
2126 struct group *group;
2127 struct subnet *subnet;
2128 struct iaddr tmp_addr;
b024480e 2129 struct option_cache *oc;
5279b8f3
DH
2130 struct data_string iaaddr, data;
2131 isc_result_t status = ISC_R_SUCCESS;
2132
2133 /* Initializes values that will be cleaned up. */
2134 memset(&iaaddr, 0, sizeof(iaaddr));
2135 memset(&data, 0, sizeof(data));
2136 /* Note that reply->lease may be set by address_is_owned() */
2137
2138 /*
2139 * There is no point trying to process an incoming address if there
2140 * is no room for an outgoing address.
2141 */
2142 if ((reply->cursor + 28) > sizeof(reply->buf)) {
2143 log_error("reply_process_addr: Out of room for address.");
2144 return ISC_R_NOSPACE;
2145 }
2146
2147 /* Extract this IAADDR option. */
2148 if (!evaluate_option_cache(&iaaddr, reply->packet, NULL, NULL,
2149 reply->packet->options, NULL, &global_scope,
2150 addr, MDL) ||
2151 (iaaddr.len < IAADDR_OFFSET)) {
2152 log_error("reply_process_addr: error evaluating IAADDR.");
2153 status = ISC_R_FAILURE;
2154 goto cleanup;
2155 }
2156
bead14ea 2157 /* The first 16 bytes are the IPv6 address. */
5279b8f3
DH
2158 pref_life = getULong(iaaddr.data + 16);
2159 valid_life = getULong(iaaddr.data + 20);
2160
2161 if ((reply->client_valid == 0) ||
2162 (reply->client_valid > valid_life))
2163 reply->client_valid = valid_life;
2164
2165 if ((reply->client_prefer == 0) ||
2166 (reply->client_prefer > pref_life))
2167 reply->client_prefer = pref_life;
2168
2169 /*
2170 * Clients may choose to send :: as an address, with the idea to give
2171 * hints about preferred-lifetime or valid-lifetime.
2172 */
bead14ea
DH
2173 tmp_addr.len = 16;
2174 memset(tmp_addr.iabuf, 0, 16);
5279b8f3
DH
2175 if (!memcmp(iaaddr.data, tmp_addr.iabuf, 16)) {
2176 /* Status remains success; we just ignore this one. */
2177 goto cleanup;
2178 }
2179
bead14ea
DH
2180 /* tmp_addr len remains 16 */
2181 memcpy(tmp_addr.iabuf, iaaddr.data, 16);
2182
5279b8f3
DH
2183 /*
2184 * Verify that this address is on the client's network.
2185 */
2186 for (subnet = reply->shared->subnets ; subnet != NULL ;
2187 subnet = subnet->next_sibling) {
2188 if (addr_eq(subnet_number(tmp_addr, subnet->netmask),
2189 subnet->net))
2190 break;
2191 }
98bd7ca0 2192
5279b8f3
DH
2193 /* Address not found on shared network. */
2194 if (subnet == NULL) {
2195 /* Ignore this address on 'soft' bindings. */
9322442f
FD
2196 if (reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) {
2197 /* disable rapid commit */
2198 reply->buf.reply.msg_type = DHCPV6_ADVERTISE;
2199 delete_option(&dhcpv6_universe,
2200 reply->opt_state,
2201 D6O_RAPID_COMMIT);
5279b8f3
DH
2202 /* status remains success */
2203 goto cleanup;
9322442f 2204 }
98bd7ca0 2205
5279b8f3
DH
2206 /*
2207 * RFC3315 section 18.2.1:
2208 *
2209 * If the server finds that the prefix on one or more IP
2210 * addresses in any IA in the message from the client is not
2211 * appropriate for the link to which the client is connected,
2212 * the server MUST return the IA to the client with a Status
2213 * Code option with the value NotOnLink.
2214 */
2215 if (reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) {
2216 /* Rewind the IA_NA to empty. */
2217 option_state_dereference(&reply->reply_ia, MDL);
2218 if (!option_state_allocate(&reply->reply_ia, MDL)) {
2219 log_error("reply_process_addr: No memory for "
2220 "option state wipe.");
2221 status = ISC_R_NOMEMORY;
2222 goto cleanup;
2223 }
98bd7ca0 2224
5279b8f3
DH
2225 /* Append a NotOnLink status code. */
2226 if (!set_status_code(STATUS_NotOnLink,
2227 "Address not for use on this "
2228 "link.", reply->reply_ia)) {
2229 log_error("reply_process_addr: Failure "
2230 "setting status code.");
2231 status = ISC_R_FAILURE;
2232 goto cleanup;
98bd7ca0 2233 }
5279b8f3
DH
2234
2235 /* Fin (no more IAADDRs). */
2236 status = ISC_R_CANCELED;
2237 goto cleanup;
98bd7ca0
DH
2238 }
2239
2240 /*
5279b8f3
DH
2241 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2242 *
2243 * If the server finds that any of the addresses are not
2244 * appropriate for the link to which the client is attached,
2245 * the server returns the address to the client with lifetimes
2246 * of 0.
98bd7ca0 2247 */
5279b8f3
DH
2248 if ((reply->packet->dhcpv6_msg_type != DHCPV6_RENEW) &&
2249 (reply->packet->dhcpv6_msg_type != DHCPV6_REBIND)) {
2250 log_error("It is impossible to lease a client that is "
f415516e 2251 "not sending a solicit, request, renew, or "
5279b8f3
DH
2252 "rebind.");
2253 status = ISC_R_FAILURE;
2254 goto cleanup;
98bd7ca0
DH
2255 }
2256
5279b8f3
DH
2257 reply->send_prefer = reply->send_valid = 0;
2258 goto send_addr;
2259 }
2260
2261 /* Verify the address belongs to the client. */
2262 if (!address_is_owned(reply, &tmp_addr)) {
98bd7ca0 2263 /*
5279b8f3
DH
2264 * For solicit and request, any addresses included are
2265 * 'requested' addresses. For rebind, we actually have
2266 * no direction on what to do from 3315 section 18.2.4!
2267 * So I think the best bet is to try and give it out, and if
2268 * we can't, zero lifetimes.
98bd7ca0 2269 */
5279b8f3
DH
2270 if ((reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) ||
2271 (reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) ||
2272 (reply->packet->dhcpv6_msg_type == DHCPV6_REBIND)) {
2273 status = reply_process_try_addr(reply, &tmp_addr);
2274
1aa0fe5e
DH
2275 /*
2276 * If the address is in use, or isn't in any dynamic
2277 * range, continue as normal. If any other error was
2278 * found, error out.
2279 */
6f76de58 2280 if ((status != ISC_R_SUCCESS) &&
1aa0fe5e
DH
2281 (status != ISC_R_ADDRINUSE) &&
2282 (status != ISC_R_ADDRNOTAVAIL))
5279b8f3
DH
2283 goto cleanup;
2284
1aa0fe5e
DH
2285 /*
2286 * If we didn't honor this lease, for solicit and
2287 * request we simply omit it from our answer. For
2288 * rebind, we send it with zeroed lifetimes.
2289 */
5279b8f3
DH
2290 if (reply->lease == NULL) {
2291 if (reply->packet->dhcpv6_msg_type ==
2292 DHCPV6_REBIND) {
2293 reply->send_prefer = 0;
2294 reply->send_valid = 0;
2295 goto send_addr;
2296 }
2297
2298 /* status remains success - ignore */
2299 goto cleanup;
98bd7ca0 2300 }
5279b8f3
DH
2301 /*
2302 * RFC3315 section 18.2.3:
2303 *
2304 * If the server cannot find a client entry for the IA the
2305 * server returns the IA containing no addresses with a Status
2306 * Code option set to NoBinding in the Reply message.
892379ec
FD
2307 *
2308 * On mismatch we (ab)use this pretending we have not the IA
2309 * as soon as we have not an address.
5279b8f3
DH
2310 */
2311 } else if (reply->packet->dhcpv6_msg_type == DHCPV6_RENEW) {
2312 /* Rewind the IA_NA to empty. */
2313 option_state_dereference(&reply->reply_ia, MDL);
2314 if (!option_state_allocate(&reply->reply_ia, MDL)) {
2315 log_error("reply_process_addr: No memory for "
2316 "option state wipe.");
2317 status = ISC_R_NOMEMORY;
2318 goto cleanup;
98bd7ca0 2319 }
98bd7ca0 2320
5279b8f3
DH
2321 /* Append a NoBinding status code. */
2322 if (!set_status_code(STATUS_NoBinding,
2323 "Address not bound to this "
2324 "interface.", reply->reply_ia)) {
2325 log_error("reply_process_addr: Unable to "
2326 "attach status code.");
2327 status = ISC_R_FAILURE;
2328 goto cleanup;
98bd7ca0 2329 }
5279b8f3
DH
2330
2331 /* Fin (no more IAADDRs). */
2332 status = ISC_R_CANCELED;
2333 goto cleanup;
2334 } else {
2335 log_error("It is impossible to lease a client that is "
2336 "not sending a solicit, request, renew, or "
2337 "rebind message.");
2338 status = ISC_R_FAILURE;
2339 goto cleanup;
98bd7ca0 2340 }
5279b8f3 2341 }
98bd7ca0 2342
5279b8f3
DH
2343 if (reply->static_lease) {
2344 if (reply->host == NULL)
2345 log_fatal("Impossible condition at %s:%d.", MDL);
d9b43370 2346
5279b8f3 2347 scope = &global_scope;
2267da84 2348 group = reply->subnet->group;
5279b8f3
DH
2349 } else {
2350 if (reply->lease == NULL)
2351 log_fatal("Impossible condition at %s:%d.", MDL);
7285af30 2352
5279b8f3 2353 scope = &reply->lease->scope;
01fa619f 2354 group = reply->lease->ipv6_pool->ipv6_pond->group;
5279b8f3 2355 }
98bd7ca0 2356
b024480e 2357 /*
1d9774ab 2358 * If client_resources is nonzero, then the reply_process_is_addressed
b024480e
DH
2359 * function has executed configuration state into the reply option
2360 * cache. We will use that valid cache to derive configuration for
2361 * whether or not to engage in additional addresses, and similar.
2362 */
1d9774ab 2363 if (reply->client_resources != 0) {
b024480e
DH
2364 unsigned limit = 1;
2365
2366 /*
2367 * Does this client have "enough" addresses already? Default
2368 * to one. Everybody gets one, and one should be enough for
2369 * anybody.
2370 */
2371 oc = lookup_option(&server_universe, reply->opt_state,
2372 SV_LIMIT_ADDRS_PER_IA);
2373 if (oc != NULL) {
2374 if (!evaluate_option_cache(&data, reply->packet,
2375 NULL, NULL,
2376 reply->packet->options,
2377 reply->opt_state,
2378 scope, oc, MDL) ||
2379 (data.len != 4)) {
1d9774ab 2380 log_error("reply_process_addr: unable to "
b024480e
DH
2381 "evaluate addrs-per-ia value.");
2382 status = ISC_R_FAILURE;
2383 goto cleanup;
2384 }
2385
2386 limit = getULong(data.data);
2387 data_string_forget(&data, MDL);
2388 }
2389
2390 /*
2391 * If we wish to limit the client to a certain number of
2392 * addresses, then omit the address from the reply.
2393 */
1d9774ab 2394 if (reply->client_resources >= limit)
b024480e
DH
2395 goto cleanup;
2396 }
2397
9322442f 2398 status = reply_process_is_addressed(reply, scope, group);
5279b8f3
DH
2399 if (status != ISC_R_SUCCESS)
2400 goto cleanup;
98bd7ca0 2401
5279b8f3
DH
2402 send_addr:
2403 status = reply_process_send_addr(reply, &tmp_addr);
98bd7ca0 2404
5279b8f3
DH
2405 cleanup:
2406 if (iaaddr.data != NULL)
2407 data_string_forget(&iaaddr, MDL);
2408 if (data.data != NULL)
2409 data_string_forget(&data, MDL);
2410 if (reply->lease != NULL)
1d17db44 2411 iasubopt_dereference(&reply->lease, MDL);
98bd7ca0 2412
5279b8f3
DH
2413 return status;
2414}
98bd7ca0 2415
5279b8f3
DH
2416/*
2417 * Verify the address belongs to the client. If we've got a host
2418 * record with a fixed address, it has to be the assigned address
2419 * (fault out all else). Otherwise it's a dynamic address, so lookup
2420 * that address and make sure it belongs to this DUID:IAID pair.
2421 */
2422static isc_boolean_t
2423address_is_owned(struct reply_state *reply, struct iaddr *addr) {
2424 int i;
01fa619f 2425 struct ipv6_pond *pond;
98bd7ca0 2426
5279b8f3
DH
2427 /*
2428 * This faults out addresses that don't match fixed addresses.
2429 */
2430 if (reply->static_lease) {
2431 if (reply->fixed.data == NULL)
2432 log_fatal("Impossible condition at %s:%d.", MDL);
98bd7ca0 2433
5279b8f3 2434 if (memcmp(addr->iabuf, reply->fixed.data, 16) == 0)
bc7f8b8e 2435 return (ISC_TRUE);
98bd7ca0 2436
bc7f8b8e 2437 return (ISC_FALSE);
5279b8f3
DH
2438 }
2439
1d17db44 2440 if ((reply->old_ia == NULL) || (reply->old_ia->num_iasubopt == 0))
bc7f8b8e 2441 return (ISC_FALSE);
5279b8f3 2442
1d17db44
FD
2443 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
2444 struct iasubopt *tmp;
5279b8f3 2445
1d17db44 2446 tmp = reply->old_ia->iasubopt[i];
5279b8f3
DH
2447
2448 if (memcmp(addr->iabuf, &tmp->addr, 16) == 0) {
bc7f8b8e
SR
2449 if (lease6_usable(tmp) == ISC_FALSE) {
2450 return (ISC_FALSE);
2451 }
01fa619f
SR
2452
2453 pond = tmp->ipv6_pool->ipv6_pond;
2454 if (((pond->prohibit_list != NULL) &&
2455 (permitted(reply->packet, pond->prohibit_list))) ||
2456 ((pond->permit_list != NULL) &&
2457 (!permitted(reply->packet, pond->permit_list))))
2458 return (ISC_FALSE);
2459
1d17db44 2460 iasubopt_reference(&reply->lease, tmp, MDL);
01fa619f 2461
bc7f8b8e 2462 return (ISC_TRUE);
98bd7ca0 2463 }
98bd7ca0
DH
2464 }
2465
bc7f8b8e 2466 return (ISC_FALSE);
5279b8f3
DH
2467}
2468
80c9fdb0
FD
2469/* Process a client-supplied IA_TA. This may append options to the tail of
2470 * the reply packet being built in the reply_state structure.
5279b8f3
DH
2471 */
2472static isc_result_t
80c9fdb0
FD
2473reply_process_ia_ta(struct reply_state *reply, struct option_cache *ia) {
2474 isc_result_t status = ISC_R_SUCCESS;
2475 u_int32_t iaid;
2476 unsigned ia_cursor;
2477 struct option_state *packet_ia;
2478 struct option_cache *oc;
2479 struct data_string ia_data, data;
2480 struct data_string iaaddr;
2481 u_int32_t pref_life, valid_life;
783259b1 2482 struct iaddr tmp_addr;
5279b8f3 2483
80c9fdb0
FD
2484 /* Initialize values that will get cleaned up on return. */
2485 packet_ia = NULL;
2486 memset(&ia_data, 0, sizeof(ia_data));
2487 memset(&data, 0, sizeof(data));
2488 memset(&iaaddr, 0, sizeof(iaaddr));
5279b8f3 2489
80c9fdb0
FD
2490 /* Make sure there is at least room for the header. */
2491 if ((reply->cursor + IA_TA_OFFSET + 4) > sizeof(reply->buf)) {
2492 log_error("reply_process_ia_ta: Reply too long for IA.");
2493 return ISC_R_NOSPACE;
98bd7ca0 2494 }
98bd7ca0 2495
5279b8f3 2496
80c9fdb0
FD
2497 /* Fetch the IA_TA contents. */
2498 if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
2499 ia, IA_TA_OFFSET)) {
9322442f 2500 log_error("reply_process_ia_ta: error evaluating ia");
80c9fdb0
FD
2501 status = ISC_R_FAILURE;
2502 goto cleanup;
98bd7ca0 2503 }
5279b8f3 2504
80c9fdb0
FD
2505 /* Extract IA_TA header contents. */
2506 iaid = getULong(ia_data.data);
5279b8f3 2507
80c9fdb0 2508 /* Create an IA_TA structure. */
783259b1 2509 if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data,
9322442f
FD
2510 reply->client_id.len, MDL) != ISC_R_SUCCESS) {
2511 log_error("reply_process_ia_ta: no memory for ia.");
80c9fdb0
FD
2512 status = ISC_R_NOMEMORY;
2513 goto cleanup;
98bd7ca0 2514 }
9322442f 2515 reply->ia->ia_type = D6O_IA_TA;
5279b8f3 2516
80c9fdb0 2517 /* Cache pre-existing IA, if any. */
9322442f
FD
2518 ia_hash_lookup(&reply->old_ia, ia_ta_active,
2519 (unsigned char *)reply->ia->iaid_duid.data,
2520 reply->ia->iaid_duid.len, MDL);
80c9fdb0
FD
2521
2522 /*
2523 * Create an option cache to carry the IA_TA option contents, and
2524 * execute any user-supplied values into it.
5279b8f3 2525 */
80c9fdb0
FD
2526 if (!option_state_allocate(&reply->reply_ia, MDL)) {
2527 status = ISC_R_NOMEMORY;
2528 goto cleanup;
98bd7ca0 2529 }
5279b8f3 2530
80c9fdb0
FD
2531 /*
2532 * Temporary leases are dynamic by definition.
2533 */
2534 reply->static_lease = ISC_FALSE;
5279b8f3 2535
80c9fdb0
FD
2536 /*
2537 * Save the cursor position at the start of the IA, so we can
2538 * set length later. We write a temporary
2539 * header out now just in case we decide to adjust the packet
2540 * within sub-process functions.
2541 */
2542 ia_cursor = reply->cursor;
2543
2544 /* Initialize the IA_TA header. First the code. */
2545 putUShort(reply->buf.data + reply->cursor, (unsigned)D6O_IA_TA);
2546 reply->cursor += 2;
2547
2548 /* Then option length. */
2549 putUShort(reply->buf.data + reply->cursor, 0x04u);
2550 reply->cursor += 2;
2551
2552 /* Then IA_TA header contents; IAID. */
2553 putULong(reply->buf.data + reply->cursor, iaid);
2554 reply->cursor += 4;
2555
2556 /*
2557 * Deal with an IAADDR for lifetimes.
783259b1 2558 * For all or none, process IAADDRs as hints.
80c9fdb0
FD
2559 */
2560 reply->valid = reply->prefer = 0xffffffff;
2561 reply->client_valid = reply->client_prefer = 0;
2562 oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAADDR);
783259b1
FD
2563 for (; oc != NULL; oc = oc->next) {
2564 memset(&iaaddr, 0, sizeof(iaaddr));
80c9fdb0
FD
2565 if (!evaluate_option_cache(&iaaddr, reply->packet,
2566 NULL, NULL,
2567 reply->packet->options, NULL,
2568 &global_scope, oc, MDL) ||
2569 (iaaddr.len < IAADDR_OFFSET)) {
2570 log_error("reply_process_ia_ta: error "
2571 "evaluating IAADDR.");
2572 status = ISC_R_FAILURE;
2573 goto cleanup;
2574 }
2575 /* The first 16 bytes are the IPv6 address. */
2576 pref_life = getULong(iaaddr.data + 16);
2577 valid_life = getULong(iaaddr.data + 20);
2578
2579 if ((reply->client_valid == 0) ||
2580 (reply->client_valid > valid_life))
2581 reply->client_valid = valid_life;
2582
2583 if ((reply->client_prefer == 0) ||
2584 (reply->client_prefer > pref_life))
2585 reply->client_prefer = pref_life;
80c9fdb0 2586
783259b1
FD
2587 /* Nothing more if something has failed. */
2588 if (status == ISC_R_CANCELED)
2589 continue;
2590
2591 tmp_addr.len = 16;
2592 memcpy(tmp_addr.iabuf, iaaddr.data, 16);
2593 if (!temporary_is_available(reply, &tmp_addr))
2594 goto bad_temp;
2595 status = reply_process_is_addressed(reply,
2596 &reply->lease->scope,
01fa619f 2597 reply->lease->ipv6_pool->ipv6_pond->group);
783259b1
FD
2598 if (status != ISC_R_SUCCESS)
2599 goto bad_temp;
2600 status = reply_process_send_addr(reply, &tmp_addr);
2601 if (status != ISC_R_SUCCESS)
2602 goto bad_temp;
2603 if (reply->lease != NULL)
2604 iasubopt_dereference(&reply->lease, MDL);
2605 continue;
2606
2607 bad_temp:
2608 /* Rewind the IA_TA to empty. */
2609 option_state_dereference(&reply->reply_ia, MDL);
2610 if (!option_state_allocate(&reply->reply_ia, MDL)) {
2611 status = ISC_R_NOMEMORY;
80c9fdb0
FD
2612 goto cleanup;
2613 }
2614 status = ISC_R_CANCELED;
783259b1
FD
2615 reply->client_resources = 0;
2616 reply->resources_included = ISC_FALSE;
2617 if (reply->lease != NULL)
2618 iasubopt_dereference(&reply->lease, MDL);
80c9fdb0 2619 }
783259b1 2620 reply->ia_count++;
80c9fdb0
FD
2621
2622 /*
2623 * Give the client temporary addresses.
2624 */
783259b1
FD
2625 if (reply->client_resources != 0)
2626 goto store;
80c9fdb0
FD
2627 status = find_client_temporaries(reply);
2628 if (status == ISC_R_NORESOURCES) {
2629 switch (reply->packet->dhcpv6_msg_type) {
2630 case DHCPV6_SOLICIT:
2631 /*
2632 * No address for any IA is handled
2633 * by the caller.
2634 */
2635 /* FALL THROUGH */
2636
2637 case DHCPV6_REQUEST:
2638 /* Section 18.2.1 (Request):
2639 *
2640 * If the server cannot assign any addresses to
2641 * an IA in the message from the client, the
2642 * server MUST include the IA in the Reply
2643 * message with no addresses in the IA and a
2644 * Status Code option in the IA containing
2645 * status code NoAddrsAvail.
2646 */
2647 option_state_dereference(&reply->reply_ia, MDL);
2648 if (!option_state_allocate(&reply->reply_ia, MDL)) {
2649 log_error("reply_process_ia_ta: No "
2650 "memory for option state wipe.");
2651 status = ISC_R_NOMEMORY;
2652 goto cleanup;
2653 }
2654
2655 if (!set_status_code(STATUS_NoAddrsAvail,
2656 "No addresses available "
2657 "for this interface.",
2658 reply->reply_ia)) {
2659 log_error("reply_process_ia_ta: Unable "
2660 "to set NoAddrsAvail status code.");
2661 status = ISC_R_FAILURE;
2662 goto cleanup;
2663 }
2664
2665 status = ISC_R_SUCCESS;
2666 break;
2667
2668 default:
783259b1
FD
2669 /*
2670 * We don't want to include the IA if we
2671 * provide zero addresses including zeroed
2672 * lifetimes.
2673 */
2674 if (reply->resources_included)
2675 status = ISC_R_SUCCESS;
2676 else
2677 goto cleanup;
2678 break;
80c9fdb0
FD
2679 }
2680 } else if (status != ISC_R_SUCCESS)
2681 goto cleanup;
2682
2683 store:
2684 reply->cursor += store_options6((char *)reply->buf.data + reply->cursor,
2685 sizeof(reply->buf) - reply->cursor,
2686 reply->reply_ia, reply->packet,
2687 required_opts_IA, NULL);
2688
2689 /* Reset the length of this IA to match what was just written. */
2690 putUShort(reply->buf.data + ia_cursor + 2,
2691 reply->cursor - (ia_cursor + 4));
2692
2693 /*
d9b5c150
SR
2694 * yes, goto's aren't the best but we also want to avoid extra
2695 * indents
2696 */
2697 if (status == ISC_R_CANCELED)
2698 goto cleanup;
2699
2700 /*
2701 * If we have any addresses log what we are doing.
2702 */
2703 if (reply->ia->num_iasubopt != 0) {
2704 struct iasubopt *tmp;
2705 int i;
2706 char tmp_addr[INET6_ADDRSTRLEN];
2707
2708 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
2709 tmp = reply->ia->iasubopt[i];
2710
2711 log_info("%s TA: address %s to client with duid %s "
2712 "iaid = %d valid for %d seconds",
2713 dhcpv6_type_names[reply->buf.reply.msg_type],
2714 inet_ntop(AF_INET6, &tmp->addr,
2715 tmp_addr, sizeof(tmp_addr)),
2716 print_hex_1(reply->client_id.len,
2717 reply->client_id.data, 60),
2718 iaid,
2719 tmp->valid);
2720 }
2721 }
2722
2723 /*
2724 * For hard bindings we consume the new changes into
2725 * the database (if any have been attached to the ia_ta).
80c9fdb0
FD
2726 *
2727 * Loop through the assigned dynamic addresses, referencing the
2728 * leases onto this IA_TA rather than any old ones, and updating
2729 * pool timers for each (if any).
2730 */
d9b5c150
SR
2731 if ((reply->ia->num_iasubopt != 0) &&
2732 (reply->buf.reply.msg_type == DHCPV6_REPLY)) {
1d17db44 2733 struct iasubopt *tmp;
80c9fdb0
FD
2734 struct data_string *ia_id;
2735 int i;
2736
1d17db44
FD
2737 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
2738 tmp = reply->ia->iasubopt[i];
80c9fdb0 2739
9322442f
FD
2740 if (tmp->ia != NULL)
2741 ia_dereference(&tmp->ia, MDL);
2742 ia_reference(&tmp->ia, reply->ia, MDL);
80c9fdb0 2743
5d89d60f 2744 /* Commit 'hard' bindings. */
5d89d60f 2745 renew_lease6(tmp->ipv6_pool, tmp);
80c9fdb0
FD
2746 schedule_lease_timeout(tmp->ipv6_pool);
2747
a7341359
SR
2748 /* If we have anything to do on commit do it now */
2749 if (tmp->on_star.on_commit != NULL) {
2750 execute_statements(NULL, reply->packet,
2751 NULL, NULL,
2752 reply->packet->options,
2753 reply->opt_state,
58cb5d86 2754 &tmp->scope,
a7341359
SR
2755 tmp->on_star.on_commit,
2756 &tmp->on_star);
2757 executable_statement_dereference
2758 (&tmp->on_star.on_commit, MDL);
2759 }
2760
98bf1607 2761#if defined (NSUPDATE)
80c9fdb0
FD
2762 /*
2763 * Perform ddns updates.
2764 */
2765 oc = lookup_option(&server_universe, reply->opt_state,
2766 SV_DDNS_UPDATES);
2767 if ((oc == NULL) ||
2768 evaluate_boolean_option_cache(NULL, reply->packet,
2769 NULL, NULL,
2770 reply->packet->options,
2771 reply->opt_state,
2772 &tmp->scope,
2773 oc, MDL)) {
2774 ddns_updates(reply->packet, NULL, NULL,
2775 tmp, NULL, reply->opt_state);
2776 }
98bf1607 2777#endif
250f7134
SR
2778 /* Do our threshold check. */
2779 check_pool6_threshold(reply, tmp);
80c9fdb0
FD
2780 }
2781
9322442f 2782 /* Remove any old ia from the hash. */
80c9fdb0
FD
2783 if (reply->old_ia != NULL) {
2784 ia_id = &reply->old_ia->iaid_duid;
9322442f
FD
2785 ia_hash_delete(ia_ta_active,
2786 (unsigned char *)ia_id->data,
2787 ia_id->len, MDL);
2788 ia_dereference(&reply->old_ia, MDL);
80c9fdb0
FD
2789 }
2790
9322442f 2791 /* Put new ia into the hash. */
1acab09f 2792 reply->ia->cltt = cur_time;
9322442f
FD
2793 ia_id = &reply->ia->iaid_duid;
2794 ia_hash_add(ia_ta_active, (unsigned char *)ia_id->data,
2795 ia_id->len, reply->ia, MDL);
80c9fdb0 2796
9322442f 2797 write_ia(reply->ia);
ad80055f
SR
2798 } else {
2799 schedule_lease_timeout_reply(reply);
80c9fdb0
FD
2800 }
2801
2802 cleanup:
2803 if (packet_ia != NULL)
2804 option_state_dereference(&packet_ia, MDL);
2805 if (iaaddr.data != NULL)
2806 data_string_forget(&iaaddr, MDL);
2807 if (reply->reply_ia != NULL)
2808 option_state_dereference(&reply->reply_ia, MDL);
2809 if (ia_data.data != NULL)
2810 data_string_forget(&ia_data, MDL);
2811 if (data.data != NULL)
2812 data_string_forget(&data, MDL);
9322442f
FD
2813 if (reply->ia != NULL)
2814 ia_dereference(&reply->ia, MDL);
80c9fdb0 2815 if (reply->old_ia != NULL)
9322442f 2816 ia_dereference(&reply->old_ia, MDL);
5d89d60f 2817 if (reply->lease != NULL)
1d17db44 2818 iasubopt_dereference(&reply->lease, MDL);
80c9fdb0
FD
2819
2820 /*
2821 * ISC_R_CANCELED is a status code used by the addr processing to
783259b1 2822 * indicate we're replying with other addresses. This is still a
80c9fdb0
FD
2823 * success at higher layers.
2824 */
2825 return((status == ISC_R_CANCELED) ? ISC_R_SUCCESS : status);
2826}
2827
783259b1
FD
2828/*
2829 * Verify the temporary address is available.
2830 */
2831static isc_boolean_t
2832temporary_is_available(struct reply_state *reply, struct iaddr *addr) {
2833 struct in6_addr tmp_addr;
2834 struct subnet *subnet;
01fa619f
SR
2835 struct ipv6_pool *pool = NULL;
2836 struct ipv6_pond *pond = NULL;
783259b1
FD
2837 int i;
2838
2839 memcpy(&tmp_addr, addr->iabuf, sizeof(tmp_addr));
2840 /*
2841 * Clients may choose to send :: as an address, with the idea to give
2842 * hints about preferred-lifetime or valid-lifetime.
2843 * So this is not a request for this address.
2844 */
2845 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr))
2846 return ISC_FALSE;
2847
2848 /*
2849 * Verify that this address is on the client's network.
2850 */
2851 for (subnet = reply->shared->subnets ; subnet != NULL ;
2852 subnet = subnet->next_sibling) {
2853 if (addr_eq(subnet_number(*addr, subnet->netmask),
2854 subnet->net))
2855 break;
2856 }
2857
2858 /* Address not found on shared network. */
2859 if (subnet == NULL)
2860 return ISC_FALSE;
2861
2862 /*
2863 * Check if this address is owned (must be before next step).
2864 */
2865 if (address_is_owned(reply, addr))
2866 return ISC_TRUE;
2867
2868 /*
2869 * Verify that this address is in a temporary pool and try to get it.
2870 */
01fa619f
SR
2871 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
2872 if (((pond->prohibit_list != NULL) &&
2873 (permitted(reply->packet, pond->prohibit_list))) ||
2874 ((pond->permit_list != NULL) &&
2875 (!permitted(reply->packet, pond->permit_list))))
783259b1 2876 continue;
01fa619f
SR
2877
2878 for (i = 0 ; (pool = pond->ipv6_pools[i]) != NULL ; i++) {
2879 if (pool->pool_type != D6O_IA_TA)
2880 continue;
2881
2882 if (ipv6_in_pool(&tmp_addr, pool))
2883 break;
2884 }
2885
2886 if (pool != NULL)
783259b1
FD
2887 break;
2888 }
01fa619f 2889
783259b1
FD
2890 if (pool == NULL)
2891 return ISC_FALSE;
2892 if (lease6_exists(pool, &tmp_addr))
2893 return ISC_FALSE;
2894 if (iasubopt_allocate(&reply->lease, MDL) != ISC_R_SUCCESS)
2895 return ISC_FALSE;
2896 reply->lease->addr = tmp_addr;
2897 reply->lease->plen = 0;
2898 /* Default is soft binding for 2 minutes. */
2899 if (add_lease6(pool, reply->lease, cur_time + 120) != ISC_R_SUCCESS)
2900 return ISC_FALSE;
2901
2902 return ISC_TRUE;
2903}
2904
80c9fdb0
FD
2905/*
2906 * Get a temporary address per prefix.
2907 */
2908static isc_result_t
2909find_client_temporaries(struct reply_state *reply) {
80c9fdb0 2910 int i;
f1ef85cf 2911 struct ipv6_pool *p = NULL;
01fa619f
SR
2912 struct ipv6_pond *pond;
2913 isc_result_t status = ISC_R_NORESOURCES;;
80c9fdb0
FD
2914 unsigned int attempts;
2915 struct iaddr send_addr;
2916
2917 /*
01fa619f
SR
2918 * Do a quick walk through of the ponds and pools
2919 * to see if we have any prefix pools
80c9fdb0 2920 */
01fa619f
SR
2921 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
2922 if (pond->ipv6_pools == NULL)
2923 continue;
2924
2925 for (i = 0; (p = pond->ipv6_pools[i]) != NULL; i++) {
2926 if (p->pool_type == D6O_IA_TA)
2927 break;
2928 }
2929 if (p != NULL)
2930 break;
2931 }
2932
2933 /* If we get here and p is NULL we have no useful pools */
2934 if (p == NULL) {
80c9fdb0
FD
2935 log_debug("Unable to get client addresses: "
2936 "no IPv6 pools on this shared network");
2937 return ISC_R_NORESOURCES;
2938 }
2939
01fa619f
SR
2940 /*
2941 * We have at least one pool that could provide an address
2942 * Now we walk through the ponds and pools again and check
2943 * to see if the client is permitted and if an address is
2944 * available
2945 */
2946
2947 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
2948 if (((pond->prohibit_list != NULL) &&
2949 (permitted(reply->packet, pond->prohibit_list))) ||
2950 ((pond->permit_list != NULL) &&
2951 (!permitted(reply->packet, pond->permit_list))))
80c9fdb0 2952 continue;
80c9fdb0 2953
01fa619f
SR
2954 for (i = 0; (p = pond->ipv6_pools[i]) != NULL; i++) {
2955 if (p->pool_type != D6O_IA_TA) {
2956 continue;
2957 }
80c9fdb0 2958
01fa619f
SR
2959 /*
2960 * Get an address in this temporary pool.
2961 */
2962 status = create_lease6(p, &reply->lease, &attempts,
2963 &reply->client_id, cur_time + 120);
2964 if (status != ISC_R_SUCCESS) {
2965 log_debug("Unable to get a temporary address.");
2966 goto cleanup;
2967 }
2968
2969 status = reply_process_is_addressed(reply,
2970 &reply->lease->scope,
2971 pond->group);
2972 if (status != ISC_R_SUCCESS) {
2973 goto cleanup;
2974 }
2975 send_addr.len = 16;
2976 memcpy(send_addr.iabuf, &reply->lease->addr, 16);
2977 status = reply_process_send_addr(reply, &send_addr);
2978 if (status != ISC_R_SUCCESS) {
2979 goto cleanup;
2980 }
2981 /*
2982 * reply->lease can't be null as we use it above
2983 * add check if that changes
2984 */
2985 iasubopt_dereference(&reply->lease, MDL);
80c9fdb0 2986 }
80c9fdb0
FD
2987 }
2988
2989 cleanup:
2990 if (reply->lease != NULL) {
1d17db44 2991 iasubopt_dereference(&reply->lease, MDL);
80c9fdb0
FD
2992 }
2993 return status;
2994}
2995
2996/*
2997 * This function only returns failure on 'hard' failures. If it succeeds,
2998 * it will leave a lease structure behind.
2999 */
3000static isc_result_t
3001reply_process_try_addr(struct reply_state *reply, struct iaddr *addr) {
d19fa5a1 3002 isc_result_t status = ISC_R_ADDRNOTAVAIL;
01fa619f
SR
3003 struct ipv6_pool *pool = NULL;
3004 struct ipv6_pond *pond = NULL;
80c9fdb0
FD
3005 int i;
3006 struct data_string data_addr;
3007
3008 if ((reply == NULL) || (reply->shared == NULL) ||
d19fa5a1
SR
3009 (addr == NULL) || (reply->lease != NULL))
3010 return (DHCP_R_INVALIDARG);
3011
01fa619f
SR
3012 /*
3013 * Do a quick walk through of the ponds and pools
3014 * to see if we have any NA address pools
3015 */
3016 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
3017 if (pond->ipv6_pools == NULL)
3018 continue;
3019
3020 for (i = 0; ; i++) {
3021 pool = pond->ipv6_pools[i];
3022 if ((pool == NULL) ||
3023 (pool->pool_type == D6O_IA_NA))
3024 break;
3025 }
3026 if (pool != NULL)
3027 break;
3028 }
3029
3030 /* If we get here and p is NULL we have no useful pools */
3031 if (pool == NULL) {
d19fa5a1 3032 return (ISC_R_ADDRNOTAVAIL);
01fa619f 3033 }
80c9fdb0
FD
3034
3035 memset(&data_addr, 0, sizeof(data_addr));
3036 data_addr.len = addr->len;
3037 data_addr.data = addr->iabuf;
3038
01fa619f
SR
3039 /*
3040 * We have at least one pool that could provide an address
3041 * Now we walk through the ponds and pools again and check
3042 * to see if the client is permitted and if an address is
3043 * available
3044 *
3045 * Within a given pond we start looking at the last pool we
3046 * allocated from, unless it had a collision trying to allocate
3047 * an address. This will tend to move us into less-filled pools.
3048 */
3049
3050 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
3051 if (((pond->prohibit_list != NULL) &&
3052 (permitted(reply->packet, pond->prohibit_list))) ||
3053 ((pond->permit_list != NULL) &&
3054 (!permitted(reply->packet, pond->permit_list))))
9322442f 3055 continue;
01fa619f
SR
3056
3057 for (i = 0 ; (pool = pond->ipv6_pools[i]) != NULL ; i++) {
3058 if (pool->pool_type != D6O_IA_NA)
3059 continue;
3060
3061 status = try_client_v6_address(&reply->lease, pool,
3062 &data_addr);
3063 if (status == ISC_R_SUCCESS)
3064 break;
3065 }
3066
80c9fdb0
FD
3067 if (status == ISC_R_SUCCESS)
3068 break;
3069 }
3070
3071 /* Note that this is just pedantry. There is no allocation to free. */
3072 data_string_forget(&data_addr, MDL);
3073 /* Return just the most recent status... */
d19fa5a1 3074 return (status);
80c9fdb0
FD
3075}
3076
3077/* Look around for an address to give the client. First, look through the
3078 * old IA for addresses we can extend. Second, try to allocate a new address.
3079 * Finally, actually add that address into the current reply IA.
3080 */
3081static isc_result_t
3082find_client_address(struct reply_state *reply) {
3083 struct iaddr send_addr;
3084 isc_result_t status = ISC_R_NORESOURCES;
1d17db44 3085 struct iasubopt *lease, *best_lease = NULL;
80c9fdb0
FD
3086 struct binding_scope **scope;
3087 struct group *group;
3088 int i;
3089
80c9fdb0
FD
3090 if (reply->static_lease) {
3091 if (reply->host == NULL)
98bf1607 3092 return DHCP_R_INVALIDARG;
80c9fdb0
FD
3093
3094 send_addr.len = 16;
3095 memcpy(send_addr.iabuf, reply->fixed.data, 16);
3096
80c9fdb0 3097 scope = &global_scope;
2267da84 3098 group = reply->subnet->group;
80c9fdb0
FD
3099 goto send_addr;
3100 }
3101
3102 if (reply->old_ia != NULL) {
1d17db44 3103 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
0d8c3d6e 3104 struct shared_network *candidate_shared;
01fa619f 3105 struct ipv6_pond *pond;
0d8c3d6e 3106
1d17db44 3107 lease = reply->old_ia->iasubopt[i];
0d8c3d6e 3108 candidate_shared = lease->ipv6_pool->shared_network;
01fa619f 3109 pond = lease->ipv6_pool->ipv6_pond;
80c9fdb0 3110
0d8c3d6e
DH
3111 /*
3112 * Look for the best lease on the client's shared
01fa619f 3113 * network, that is still permitted
0d8c3d6e 3114 */
01fa619f
SR
3115
3116 if ((candidate_shared != reply->shared) ||
3117 (lease6_usable(lease) != ISC_TRUE))
3118 continue;
3119
3120 if (((pond->prohibit_list != NULL) &&
3121 (permitted(reply->packet, pond->prohibit_list))) ||
3122 ((pond->permit_list != NULL) &&
3123 (!permitted(reply->packet, pond->permit_list))))
3124 continue;
3125
3126 best_lease = lease_compare(lease, best_lease);
80c9fdb0
FD
3127 }
3128 }
3129
3130 /* Try to pick a new address if we didn't find one, or if we found an
3131 * abandoned lease.
3132 */
3133 if ((best_lease == NULL) || (best_lease->state == FTS_ABANDONED)) {
01fa619f 3134 status = pick_v6_address(reply);
80c9fdb0 3135 } else if (best_lease != NULL) {
1d17db44 3136 iasubopt_reference(&reply->lease, best_lease, MDL);
80c9fdb0
FD
3137 status = ISC_R_SUCCESS;
3138 }
3139
3140 /* Pick the abandoned lease as a last resort. */
3141 if ((status == ISC_R_NORESOURCES) && (best_lease != NULL)) {
3142 /* I don't see how this is supposed to be done right now. */
3143 log_error("Reclaiming abandoned addresses is not yet "
3144 "supported. Treating this as an out of space "
3145 "condition.");
1d17db44 3146 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
80c9fdb0
FD
3147 }
3148
3149 /* Give up now if we didn't find a lease. */
3150 if (status != ISC_R_SUCCESS)
3151 return status;
3152
3153 if (reply->lease == NULL)
3154 log_fatal("Impossible condition at %s:%d.", MDL);
3155
7d6180be
DH
3156 /* Draw binding scopes from the lease's binding scope, and config
3157 * from the lease's containing subnet and higher. Note that it may
3158 * be desirable to place the group attachment directly in the pool.
3159 */
80c9fdb0 3160 scope = &reply->lease->scope;
01fa619f 3161 group = reply->lease->ipv6_pool->ipv6_pond->group;
80c9fdb0
FD
3162
3163 send_addr.len = 16;
3164 memcpy(send_addr.iabuf, &reply->lease->addr, 16);
3165
3166 send_addr:
9322442f 3167 status = reply_process_is_addressed(reply, scope, group);
80c9fdb0
FD
3168 if (status != ISC_R_SUCCESS)
3169 return status;
3170
3171 status = reply_process_send_addr(reply, &send_addr);
3172 return status;
3173}
3174
3175/* Once an address is found for a client, perform several common functions;
3176 * Calculate and store valid and preferred lease times, draw client options
3177 * into the option state.
3178 */
3179static isc_result_t
9322442f 3180reply_process_is_addressed(struct reply_state *reply,
80c9fdb0
FD
3181 struct binding_scope **scope, struct group *group)
3182{
3183 isc_result_t status = ISC_R_SUCCESS;
3184 struct data_string data;
3185 struct option_cache *oc;
a7341359
SR
3186 struct option_state *tmp_options = NULL;
3187 struct on_star *on_star;
01fa619f 3188 int i;
80c9fdb0
FD
3189
3190 /* Initialize values we will cleanup. */
3191 memset(&data, 0, sizeof(data));
3192
a7341359
SR
3193 /*
3194 * Find the proper on_star block to use. We use the
3195 * one in the lease if we have a lease or the one in
3196 * the reply if we don't have a lease because this is
3197 * a static instance
3198 */
3199 if (reply->lease) {
3200 on_star = &reply->lease->on_star;
3201 } else {
3202 on_star = &reply->on_star;
3203 }
3204
3205 /*
3206 * Bring in the root configuration. We only do this to bring
3207 * in the on * statements, as we didn't have the lease available
3208 * we did it the first time.
3209 */
3210 option_state_allocate(&tmp_options, MDL);
3211 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3212 reply->packet->options, tmp_options,
3213 &global_scope, root_group, NULL,
3214 on_star);
3215 if (tmp_options != NULL) {
3216 option_state_dereference(&tmp_options, MDL);
3217 }
3218
2267da84
DH
3219 /*
3220 * Bring configured options into the root packet level cache - start
3221 * with the lease's closest enclosing group (passed in by the caller
3222 * as 'group').
3223 */
80c9fdb0
FD
3224 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3225 reply->packet->options, reply->opt_state,
a7341359 3226 scope, group, root_group, on_star);
80c9fdb0 3227
01fa619f
SR
3228 /* Execute statements from class scopes. */
3229 for (i = reply->packet->class_count; i > 0; i--) {
3230 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3231 reply->packet->options,
3232 reply->opt_state, scope,
3233 reply->packet->classes[i - 1]->group,
3234 group, on_star);
3235 }
3236
2267da84
DH
3237 /*
3238 * If there is a host record, over-ride with values configured there,
3239 * without re-evaluating configuration from the previously executed
3240 * group or its common enclosers.
3241 */
3242 if (reply->host != NULL)
3243 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3244 reply->packet->options,
3245 reply->opt_state, scope,
a7341359
SR
3246 reply->host->group, group,
3247 on_star);
2267da84 3248
80c9fdb0
FD
3249 /* Determine valid lifetime. */
3250 if (reply->client_valid == 0)
3251 reply->send_valid = DEFAULT_DEFAULT_LEASE_TIME;
3252 else
3253 reply->send_valid = reply->client_valid;
3254
3255 oc = lookup_option(&server_universe, reply->opt_state,
3256 SV_DEFAULT_LEASE_TIME);
3257 if (oc != NULL) {
3258 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
3259 reply->packet->options,
3260 reply->opt_state,
3261 scope, oc, MDL) ||
3262 (data.len != 4)) {
3263 log_error("reply_process_is_addressed: unable to "
3264 "evaluate default lease time");
3265 status = ISC_R_FAILURE;
3266 goto cleanup;
3267 }
3268
3269 reply->send_valid = getULong(data.data);
3270 data_string_forget(&data, MDL);
3271 }
3272
3273 if (reply->client_prefer == 0)
3274 reply->send_prefer = reply->send_valid;
3275 else
3276 reply->send_prefer = reply->client_prefer;
3277
3278 if (reply->send_prefer >= reply->send_valid)
3279 reply->send_prefer = (reply->send_valid / 2) +
3280 (reply->send_valid / 8);
3281
3282 oc = lookup_option(&server_universe, reply->opt_state,
3283 SV_PREFER_LIFETIME);
3284 if (oc != NULL) {
3285 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
3286 reply->packet->options,
3287 reply->opt_state,
3288 scope, oc, MDL) ||
3289 (data.len != 4)) {
3290 log_error("reply_process_is_addressed: unable to "
3291 "evaluate preferred lease time");
3292 status = ISC_R_FAILURE;
3293 goto cleanup;
3294 }
3295
3296 reply->send_prefer = getULong(data.data);
3297 data_string_forget(&data, MDL);
3298 }
3299
3300 /* Note lowest values for later calculation of renew/rebind times. */
3301 if (reply->prefer > reply->send_prefer)
3302 reply->prefer = reply->send_prefer;
3303
3304 if (reply->valid > reply->send_valid)
3305 reply->valid = reply->send_valid;
3306
3307#if 0
3308 /*
3309 * XXX: Old 4.0.0 alpha code would change the host {} record
3310 * XXX: uid upon lease assignment. This was intended to cover the
3311 * XXX: case where a client first identifies itself using vendor
3312 * XXX: options in a solicit, or request, but later neglects to include
3313 * XXX: these options in a Renew or Rebind. It is not clear that this
3314 * XXX: is required, and has some startling ramifications (such as
3315 * XXX: how to recover this dynamic host {} state across restarts).
3316 */
3317 if (reply->host != NULL)
3318 change_host_uid(host, reply->client_id->data,
3319 reply->client_id->len);
3320#endif /* 0 */
3321
3322 /* Perform dynamic lease related update work. */
3323 if (reply->lease != NULL) {
1acab09f
FD
3324 /* Cached lifetimes */
3325 reply->lease->prefer = reply->send_prefer;
3326 reply->lease->valid = reply->send_valid;
3327
80c9fdb0 3328 /* Advance (or rewind) the valid lifetime. */
5d89d60f
FD
3329 if (reply->buf.reply.msg_type == DHCPV6_REPLY) {
3330 reply->lease->soft_lifetime_end_time =
3331 cur_time + reply->send_valid;
3332 /* Wait before renew! */
3333 }
80c9fdb0 3334
1d17db44 3335 status = ia_add_iasubopt(reply->ia, reply->lease, MDL);
80c9fdb0
FD
3336 if (status != ISC_R_SUCCESS) {
3337 log_fatal("reply_process_is_addressed: Unable to "
3338 "attach lease to new IA: %s",
3339 isc_result_totext(status));
3340 }
3341
3342 /*
3343 * If this is a new lease, make sure it is attached somewhere.
3344 */
9322442f
FD
3345 if (reply->lease->ia == NULL) {
3346 ia_reference(&reply->lease->ia, reply->ia, MDL);
80c9fdb0
FD
3347 }
3348 }
3349
3350 /* Bring a copy of the relevant options into the IA scope. */
3351 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3352 reply->packet->options, reply->reply_ia,
a7341359 3353 scope, group, root_group, NULL);
80c9fdb0 3354
01fa619f
SR
3355 /* Execute statements from class scopes. */
3356 for (i = reply->packet->class_count; i > 0; i--) {
3357 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3358 reply->packet->options,
3359 reply->reply_ia, scope,
3360 reply->packet->classes[i - 1]->group,
3361 group, NULL);
3362 }
3363
2267da84
DH
3364 /*
3365 * And bring in host record configuration, if any, but not to overlap
3366 * the previous group or its common enclosers.
3367 */
3368 if (reply->host != NULL)
3369 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3370 reply->packet->options,
3371 reply->reply_ia, scope,
a7341359 3372 reply->host->group, group, NULL);
2267da84 3373
80c9fdb0
FD
3374 cleanup:
3375 if (data.data != NULL)
3376 data_string_forget(&data, MDL);
3377
3378 if (status == ISC_R_SUCCESS)
3379 reply->client_resources++;
3380
3381 return status;
3382}
3383
3384/* Simply send an IAADDR within the IA scope as described. */
3385static isc_result_t
3386reply_process_send_addr(struct reply_state *reply, struct iaddr *addr) {
3387 isc_result_t status = ISC_R_SUCCESS;
3388 struct data_string data;
3389
3390 memset(&data, 0, sizeof(data));
3391
3392 /* Now append the lease. */
3393 data.len = IAADDR_OFFSET;
3394 if (!buffer_allocate(&data.buffer, data.len, MDL)) {
3395 log_error("reply_process_send_addr: out of memory"
3396 "allocating new IAADDR buffer.");
3397 status = ISC_R_NOMEMORY;
3398 goto cleanup;
3399 }
3400 data.data = data.buffer->data;
3401
3402 memcpy(data.buffer->data, addr->iabuf, 16);
3403 putULong(data.buffer->data + 16, reply->send_prefer);
3404 putULong(data.buffer->data + 20, reply->send_valid);
3405
3406 if (!append_option_buffer(&dhcpv6_universe, reply->reply_ia,
3407 data.buffer, data.buffer->data,
3408 data.len, D6O_IAADDR, 0)) {
3409 log_error("reply_process_send_addr: unable "
3410 "to save IAADDR option");
3411 status = ISC_R_FAILURE;
3412 goto cleanup;
3413 }
3414
9322442f 3415 reply->resources_included = ISC_TRUE;
80c9fdb0
FD
3416
3417 cleanup:
3418 if (data.data != NULL)
3419 data_string_forget(&data, MDL);
3420
3421 return status;
3422}
3423
3424/* Choose the better of two leases. */
1d17db44
FD
3425static struct iasubopt *
3426lease_compare(struct iasubopt *alpha, struct iasubopt *beta) {
80c9fdb0
FD
3427 if (alpha == NULL)
3428 return beta;
3429 if (beta == NULL)
3430 return alpha;
3431
3432 switch(alpha->state) {
3433 case FTS_ACTIVE:
3434 switch(beta->state) {
3435 case FTS_ACTIVE:
3436 /* Choose the lease with the longest lifetime (most
3437 * likely the most recently allocated).
3438 */
5d89d60f
FD
3439 if (alpha->hard_lifetime_end_time <
3440 beta->hard_lifetime_end_time)
80c9fdb0
FD
3441 return beta;
3442 else
3443 return alpha;
3444
3445 case FTS_EXPIRED:
3446 case FTS_ABANDONED:
3447 return alpha;
3448
3449 default:
3450 log_fatal("Impossible condition at %s:%d.", MDL);
3451 }
3452 break;
3453
3454 case FTS_EXPIRED:
3455 switch (beta->state) {
3456 case FTS_ACTIVE:
3457 return beta;
3458
3459 case FTS_EXPIRED:
3460 /* Choose the most recently expired lease. */
5d89d60f
FD
3461 if (alpha->hard_lifetime_end_time <
3462 beta->hard_lifetime_end_time)
3463 return beta;
3464 else if ((alpha->hard_lifetime_end_time ==
3465 beta->hard_lifetime_end_time) &&
3466 (alpha->soft_lifetime_end_time <
3467 beta->soft_lifetime_end_time))
80c9fdb0
FD
3468 return beta;
3469 else
3470 return alpha;
3471
3472 case FTS_ABANDONED:
3473 return alpha;
3474
3475 default:
3476 log_fatal("Impossible condition at %s:%d.", MDL);
3477 }
3478 break;
3479
3480 case FTS_ABANDONED:
3481 switch (beta->state) {
3482 case FTS_ACTIVE:
3483 case FTS_EXPIRED:
3484 return alpha;
3485
3486 case FTS_ABANDONED:
3487 /* Choose the lease that was abandoned longest ago. */
5d89d60f
FD
3488 if (alpha->hard_lifetime_end_time <
3489 beta->hard_lifetime_end_time)
80c9fdb0 3490 return alpha;
a07d99bb
TM
3491 else
3492 return beta;
80c9fdb0
FD
3493
3494 default:
3495 log_fatal("Impossible condition at %s:%d.", MDL);
3496 }
3497 break;
3498
3499 default:
3500 log_fatal("Impossible condition at %s:%d.", MDL);
3501 }
3502
3503 log_fatal("Triple impossible condition at %s:%d.", MDL);
3504 return NULL;
3505}
3506
3507/* Process a client-supplied IA_PD. This may append options to the tail of
3508 * the reply packet being built in the reply_state structure.
3509 */
3510static isc_result_t
9322442f 3511reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia) {
80c9fdb0
FD
3512 isc_result_t status = ISC_R_SUCCESS;
3513 u_int32_t iaid;
3514 unsigned ia_cursor;
3515 struct option_state *packet_ia;
3516 struct option_cache *oc;
9322442f 3517 struct data_string ia_data, data;
80c9fdb0
FD
3518
3519 /* Initialize values that will get cleaned up on return. */
3520 packet_ia = NULL;
9322442f 3521 memset(&ia_data, 0, sizeof(ia_data));
80c9fdb0 3522 memset(&data, 0, sizeof(data));
80c9fdb0 3523 /*
9322442f 3524 * Note that find_client_prefix() may set reply->lease.
80c9fdb0
FD
3525 */
3526
3527 /* Make sure there is at least room for the header. */
3528 if ((reply->cursor + IA_PD_OFFSET + 4) > sizeof(reply->buf)) {
3529 log_error("reply_process_ia_pd: Reply too long for IA.");
3530 return ISC_R_NOSPACE;
3531 }
3532
3533
3534 /* Fetch the IA_PD contents. */
9322442f
FD
3535 if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
3536 ia, IA_PD_OFFSET)) {
3537 log_error("reply_process_ia_pd: error evaluating ia");
80c9fdb0
FD
3538 status = ISC_R_FAILURE;
3539 goto cleanup;
3540 }
3541
3542 /* Extract IA_PD header contents. */
9322442f
FD
3543 iaid = getULong(ia_data.data);
3544 reply->renew = getULong(ia_data.data + 4);
3545 reply->rebind = getULong(ia_data.data + 8);
80c9fdb0
FD
3546
3547 /* Create an IA_PD structure. */
9322442f
FD
3548 if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data,
3549 reply->client_id.len, MDL) != ISC_R_SUCCESS) {
3550 log_error("reply_process_ia_pd: no memory for ia.");
80c9fdb0
FD
3551 status = ISC_R_NOMEMORY;
3552 goto cleanup;
3553 }
9322442f 3554 reply->ia->ia_type = D6O_IA_PD;
80c9fdb0
FD
3555
3556 /* Cache pre-existing IA_PD, if any. */
9322442f
FD
3557 ia_hash_lookup(&reply->old_ia, ia_pd_active,
3558 (unsigned char *)reply->ia->iaid_duid.data,
3559 reply->ia->iaid_duid.len, MDL);
80c9fdb0
FD
3560
3561 /*
3562 * Create an option cache to carry the IA_PD option contents, and
3563 * execute any user-supplied values into it.
3564 */
3565 if (!option_state_allocate(&reply->reply_ia, MDL)) {
3566 status = ISC_R_NOMEMORY;
3567 goto cleanup;
3568 }
3569
3570 /* Check & count the fixed prefix host records. */
3571 reply->static_prefixes = 0;
3572 if ((reply->host != NULL) && (reply->host->fixed_prefix != NULL)) {
3573 struct iaddrcidrnetlist *fp;
3574
3575 for (fp = reply->host->fixed_prefix; fp != NULL;
3576 fp = fp->next) {
3577 reply->static_prefixes += 1;
3578 }
3579 }
3580
3581 /*
3582 * Save the cursor position at the start of the IA_PD, so we can
3583 * set length and adjust t1/t2 values later. We write a temporary
3584 * header out now just in case we decide to adjust the packet
3585 * within sub-process functions.
3586 */
3587 ia_cursor = reply->cursor;
3588
3589 /* Initialize the IA_PD header. First the code. */
3590 putUShort(reply->buf.data + reply->cursor, (unsigned)D6O_IA_PD);
3591 reply->cursor += 2;
3592
3593 /* Then option length. */
3594 putUShort(reply->buf.data + reply->cursor, 0x0Cu);
3595 reply->cursor += 2;
3596
3597 /* Then IA_PD header contents; IAID. */
3598 putULong(reply->buf.data + reply->cursor, iaid);
3599 reply->cursor += 4;
3600
3601 /* We store the client's t1 for now, and may over-ride it later. */
3602 putULong(reply->buf.data + reply->cursor, reply->renew);
3603 reply->cursor += 4;
3604
3605 /* We store the client's t2 for now, and may over-ride it later. */
3606 putULong(reply->buf.data + reply->cursor, reply->rebind);
3607 reply->cursor += 4;
3608
3609 /*
3610 * For each prefix in this IA_PD, decide what to do about it.
3611 */
3612 oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAPREFIX);
3613 reply->valid = reply->prefer = 0xffffffff;
3614 reply->client_valid = reply->client_prefer = 0;
3615 reply->preflen = -1;
3616 for (; oc != NULL ; oc = oc->next) {
3617 status = reply_process_prefix(reply, oc);
3618
3619 /*
3620 * Canceled means we did not allocate prefixes to the
3621 * client, but we're "done" with this IA - we set a status
3622 * code. So transmit this reply, e.g., move on to the next
3623 * IA.
3624 */
3625 if (status == ISC_R_CANCELED)
3626 break;
3627
d19fa5a1
SR
3628 if ((status != ISC_R_SUCCESS) &&
3629 (status != ISC_R_ADDRINUSE) &&
3630 (status != ISC_R_ADDRNOTAVAIL))
80c9fdb0
FD
3631 goto cleanup;
3632 }
3633
9322442f 3634 reply->pd_count++;
80c9fdb0
FD
3635
3636 /*
3637 * If we fell through the above and never gave the client
3638 * a prefix, give it one now.
3639 */
3640 if ((status != ISC_R_CANCELED) && (reply->client_resources == 0)) {
3641 status = find_client_prefix(reply);
3642
3643 if (status == ISC_R_NORESOURCES) {
3644 switch (reply->packet->dhcpv6_msg_type) {
3645 case DHCPV6_SOLICIT:
3646 /*
3647 * No prefix for any IA is handled
3648 * by the caller.
3649 */
3650 /* FALL THROUGH */
3651
3652 case DHCPV6_REQUEST:
3653 /* Same than for addresses. */
3654 option_state_dereference(&reply->reply_ia, MDL);
3655 if (!option_state_allocate(&reply->reply_ia,
3656 MDL))
3657 {
3658 log_error("reply_process_ia_pd: No "
3659 "memory for option state "
3660 "wipe.");
3661 status = ISC_R_NOMEMORY;
3662 goto cleanup;
3663 }
3664
3665 if (!set_status_code(STATUS_NoPrefixAvail,
3666 "No prefixes available "
3667 "for this interface.",
3668 reply->reply_ia)) {
3669 log_error("reply_process_ia_pd: "
3670 "Unable to set "
3671 "NoPrefixAvail status "
3672 "code.");
3673 status = ISC_R_FAILURE;
3674 goto cleanup;
3675 }
3676
3677 status = ISC_R_SUCCESS;
3678 break;
3679
3680 default:
9322442f 3681 if (reply->resources_included)
80c9fdb0
FD
3682 status = ISC_R_SUCCESS;
3683 else
3684 goto cleanup;
3685 break;
3686 }
3687 }
3688
3689 if (status != ISC_R_SUCCESS)
3690 goto cleanup;
3691 }
3692
3693 reply->cursor += store_options6((char *)reply->buf.data + reply->cursor,
3694 sizeof(reply->buf) - reply->cursor,
3695 reply->reply_ia, reply->packet,
3696 required_opts_IA_PD, NULL);
3697
3698 /* Reset the length of this IA_PD to match what was just written. */
3699 putUShort(reply->buf.data + ia_cursor + 2,
3700 reply->cursor - (ia_cursor + 4));
3701
3702 /*
3703 * T1/T2 time selection is kind of weird. We actually use DHCP
3704 * (v4) scoped options as handy existing places where these might
3705 * be configured by an administrator. A value of zero tells the
3706 * client it may choose its own renewal time.
3707 */
3708 reply->renew = 0;
3709 oc = lookup_option(&dhcp_universe, reply->opt_state,
3710 DHO_DHCP_RENEWAL_TIME);
3711 if (oc != NULL) {
3712 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
3713 reply->packet->options,
3714 reply->opt_state, &global_scope,
3715 oc, MDL) ||
3716 (data.len != 4)) {
3717 log_error("Invalid renewal time.");
3718 } else {
3719 reply->renew = getULong(data.data);
3720 }
3721
3722 if (data.data != NULL)
3723 data_string_forget(&data, MDL);
3724 }
3725 putULong(reply->buf.data + ia_cursor + 8, reply->renew);
3726
3727 /* Now T2. */
3728 reply->rebind = 0;
3729 oc = lookup_option(&dhcp_universe, reply->opt_state,
3730 DHO_DHCP_REBINDING_TIME);
3731 if (oc != NULL) {
3732 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
3733 reply->packet->options,
3734 reply->opt_state, &global_scope,
3735 oc, MDL) ||
3736 (data.len != 4)) {
3737 log_error("Invalid rebinding time.");
3738 } else {
3739 reply->rebind = getULong(data.data);
3740 }
3741
3742 if (data.data != NULL)
3743 data_string_forget(&data, MDL);
3744 }
3745 putULong(reply->buf.data + ia_cursor + 12, reply->rebind);
3746
d9b5c150
SR
3747 /*
3748 * yes, goto's aren't the best but we also want to avoid extra
3749 * indents
3750 */
3751 if (status == ISC_R_CANCELED)
3752 goto cleanup;
3753
3754 /*
3755 * Handle static prefixes, we always log stuff and if it's
3756 * a hard binding we run any commit statements that we have
3757 */
3758 if (reply->static_prefixes != 0) {
3759 char tmp_addr[INET6_ADDRSTRLEN];
3760 log_info("%s PD: address %s/%d to client with duid %s "
3761 "iaid = %d static",
3762 dhcpv6_type_names[reply->buf.reply.msg_type],
3763 inet_ntop(AF_INET6, reply->fixed_pref.lo_addr.iabuf,
3764 tmp_addr, sizeof(tmp_addr)),
3765 reply->fixed_pref.bits,
3766 print_hex_1(reply->client_id.len,
3767 reply->client_id.data, 60),
3768 iaid);
3769 if ((reply->buf.reply.msg_type == DHCPV6_REPLY) &&
3770 (reply->on_star.on_commit != NULL)) {
3771 execute_statements(NULL, reply->packet, NULL, NULL,
3772 reply->packet->options,
3773 reply->opt_state,
3774 NULL, reply->on_star.on_commit,
3775 NULL);
3776 executable_statement_dereference
3777 (&reply->on_star.on_commit, MDL);
3778 }
3779 goto cleanup;
3780 }
3781
3782 /*
3783 * If we have any addresses log what we are doing.
3784 */
3785 if (reply->ia->num_iasubopt != 0) {
3786 struct iasubopt *tmp;
3787 int i;
3788 char tmp_addr[INET6_ADDRSTRLEN];
3789
3790 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
3791 tmp = reply->ia->iasubopt[i];
3792
3793 log_info("%s PD: address %s/%d to client with duid %s"
3794 " iaid = %d valid for %d seconds",
3795 dhcpv6_type_names[reply->buf.reply.msg_type],
3796 inet_ntop(AF_INET6, &tmp->addr,
3797 tmp_addr, sizeof(tmp_addr)),
3798 (int)tmp->plen,
3799 print_hex_1(reply->client_id.len,
3800 reply->client_id.data, 60),
3801 iaid, tmp->valid);
3802 }
3803 }
3804
80c9fdb0
FD
3805 /*
3806 * If this is not a 'soft' binding, consume the new changes into
3807 * the database (if any have been attached to the ia_pd).
3808 *
3809 * Loop through the assigned dynamic prefixes, referencing the
3810 * prefixes onto this IA_PD rather than any old ones, and updating
3811 * prefix pool timers for each (if any).
3812 */
d9b5c150 3813 if ((reply->buf.reply.msg_type == DHCPV6_REPLY) &&
1d17db44
FD
3814 (reply->ia->num_iasubopt != 0)) {
3815 struct iasubopt *tmp;
80c9fdb0
FD
3816 struct data_string *ia_id;
3817 int i;
3818
1d17db44
FD
3819 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
3820 tmp = reply->ia->iasubopt[i];
80c9fdb0 3821
9322442f
FD
3822 if (tmp->ia != NULL)
3823 ia_dereference(&tmp->ia, MDL);
3824 ia_reference(&tmp->ia, reply->ia, MDL);
80c9fdb0 3825
5d89d60f 3826 /* Commit 'hard' bindings. */
9322442f
FD
3827 renew_lease6(tmp->ipv6_pool, tmp);
3828 schedule_lease_timeout(tmp->ipv6_pool);
a7341359
SR
3829
3830 /* If we have anything to do on commit do it now */
3831 if (tmp->on_star.on_commit != NULL) {
3832 execute_statements(NULL, reply->packet,
3833 NULL, NULL,
3834 reply->packet->options,
3835 reply->opt_state,
58cb5d86 3836 &tmp->scope,
a7341359
SR
3837 tmp->on_star.on_commit,
3838 &tmp->on_star);
3839 executable_statement_dereference
3840 (&tmp->on_star.on_commit, MDL);
3841 }
250f7134
SR
3842
3843 /* Do our threshold check. */
3844 check_pool6_threshold(reply, tmp);
80c9fdb0
FD
3845 }
3846
9322442f
FD
3847 /* Remove any old ia from the hash. */
3848 if (reply->old_ia != NULL) {
3849 ia_id = &reply->old_ia->iaid_duid;
3850 ia_hash_delete(ia_pd_active,
3851 (unsigned char *)ia_id->data,
3852 ia_id->len, MDL);
3853 ia_dereference(&reply->old_ia, MDL);
80c9fdb0
FD
3854 }
3855
9322442f 3856 /* Put new ia into the hash. */
1acab09f 3857 reply->ia->cltt = cur_time;
9322442f
FD
3858 ia_id = &reply->ia->iaid_duid;
3859 ia_hash_add(ia_pd_active, (unsigned char *)ia_id->data,
3860 ia_id->len, reply->ia, MDL);
80c9fdb0 3861
9322442f 3862 write_ia(reply->ia);
ad80055f
SR
3863 } else {
3864 schedule_lease_timeout_reply(reply);
80c9fdb0
FD
3865 }
3866
3867 cleanup:
3868 if (packet_ia != NULL)
3869 option_state_dereference(&packet_ia, MDL);
3870 if (reply->reply_ia != NULL)
3871 option_state_dereference(&reply->reply_ia, MDL);
9322442f
FD
3872 if (ia_data.data != NULL)
3873 data_string_forget(&ia_data, MDL);
80c9fdb0
FD
3874 if (data.data != NULL)
3875 data_string_forget(&data, MDL);
9322442f
FD
3876 if (reply->ia != NULL)
3877 ia_dereference(&reply->ia, MDL);
3878 if (reply->old_ia != NULL)
3879 ia_dereference(&reply->old_ia, MDL);
3880 if (reply->lease != NULL)
1d17db44 3881 iasubopt_dereference(&reply->lease, MDL);
a7341359
SR
3882 if (reply->on_star.on_expiry != NULL)
3883 executable_statement_dereference
3884 (&reply->on_star.on_expiry, MDL);
3885 if (reply->on_star.on_release != NULL)
3886 executable_statement_dereference
3887 (&reply->on_star.on_release, MDL);
80c9fdb0
FD
3888
3889 /*
3890 * ISC_R_CANCELED is a status code used by the prefix processing to
3891 * indicate we're replying with a status code. This is still a
3892 * success at higher layers.
3893 */
3894 return((status == ISC_R_CANCELED) ? ISC_R_SUCCESS : status);
3895}
3896
3897/*
3898 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
3899 * contents into the reply's current ia_pd-scoped option cache. Returns
3900 * ISC_R_CANCELED in the event we are replying with a status code and do
3901 * not wish to process more IAPREFIXes within this IA_PD.
3902 */
3903static isc_result_t
3904reply_process_prefix(struct reply_state *reply, struct option_cache *pref) {
3905 u_int32_t pref_life, valid_life;
3906 struct binding_scope **scope;
80c9fdb0
FD
3907 struct iaddrcidrnet tmp_pref;
3908 struct option_cache *oc;
3909 struct data_string iapref, data;
80c9fdb0 3910 isc_result_t status = ISC_R_SUCCESS;
01fa619f 3911 struct group *group;
80c9fdb0
FD
3912
3913 /* Initializes values that will be cleaned up. */
80c9fdb0
FD
3914 memset(&iapref, 0, sizeof(iapref));
3915 memset(&data, 0, sizeof(data));
9322442f 3916 /* Note that reply->lease may be set by prefix_is_owned() */
80c9fdb0
FD
3917
3918 /*
3919 * There is no point trying to process an incoming prefix if there
3920 * is no room for an outgoing prefix.
3921 */
3922 if ((reply->cursor + 29) > sizeof(reply->buf)) {
3923 log_error("reply_process_prefix: Out of room for prefix.");
3924 return ISC_R_NOSPACE;
3925 }
3926
3927 /* Extract this IAPREFIX option. */
3928 if (!evaluate_option_cache(&iapref, reply->packet, NULL, NULL,
3929 reply->packet->options, NULL, &global_scope,
3930 pref, MDL) ||
3931 (iapref.len < IAPREFIX_OFFSET)) {
3932 log_error("reply_process_prefix: error evaluating IAPREFIX.");
3933 status = ISC_R_FAILURE;
3934 goto cleanup;
3935 }
3936
3937 /*
3938 * Layout: preferred and valid lifetimes followed by the prefix
3939 * length and the IPv6 address.
3940 */
3941 pref_life = getULong(iapref.data);
3942 valid_life = getULong(iapref.data + 4);
3943
3944 if ((reply->client_valid == 0) ||
3945 (reply->client_valid > valid_life))
3946 reply->client_valid = valid_life;
3947
3948 if ((reply->client_prefer == 0) ||
3949 (reply->client_prefer > pref_life))
3950 reply->client_prefer = pref_life;
3951
3952 /*
3953 * Clients may choose to send ::/0 as a prefix, with the idea to give
3954 * hints about preferred-lifetime or valid-lifetime.
3955 */
3956 tmp_pref.lo_addr.len = 16;
3957 memset(tmp_pref.lo_addr.iabuf, 0, 16);
3958 if ((iapref.data[8] == 0) &&
3959 (memcmp(iapref.data + 9, tmp_pref.lo_addr.iabuf, 16) == 0)) {
3960 /* Status remains success; we just ignore this one. */
3961 goto cleanup;
3962 }
3963
3964 /*
3965 * Clients may choose to send ::/X as a prefix to specify a
3966 * preferred/requested prefix length. Note X is never zero here.
3967 */
3968 tmp_pref.bits = (int) iapref.data[8];
3969 if (reply->preflen < 0) {
3970 /* Cache the first preferred prefix length. */
3971 reply->preflen = tmp_pref.bits;
3972 }
3973 if (memcmp(iapref.data + 9, tmp_pref.lo_addr.iabuf, 16) == 0) {
3974 goto cleanup;
3975 }
3976
3977 memcpy(tmp_pref.lo_addr.iabuf, iapref.data + 9, 16);
3978
3979 /* Verify the prefix belongs to the client. */
3980 if (!prefix_is_owned(reply, &tmp_pref)) {
3981 /* Same than for addresses. */
3982 if ((reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) ||
3983 (reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) ||
3984 (reply->packet->dhcpv6_msg_type == DHCPV6_REBIND)) {
3985 status = reply_process_try_prefix(reply, &tmp_pref);
3986
3987 /* Either error out or skip this prefix. */
d19fa5a1
SR
3988 if ((status != ISC_R_SUCCESS) &&
3989 (status != ISC_R_ADDRINUSE) &&
3990 (status != ISC_R_ADDRNOTAVAIL))
80c9fdb0
FD
3991 goto cleanup;
3992
9322442f 3993 if (reply->lease == NULL) {
80c9fdb0
FD
3994 if (reply->packet->dhcpv6_msg_type ==
3995 DHCPV6_REBIND) {
3996 reply->send_prefer = 0;
3997 reply->send_valid = 0;
3998 goto send_pref;
3999 }
4000
4001 /* status remains success - ignore */
4002 goto cleanup;
4003 }
80c9fdb0
FD
4004 /*
4005 * RFC3633 section 18.2.3:
4006 *
4007 * If the delegating router cannot find a binding
4008 * for the requesting router's IA_PD the delegating
4009 * router returns the IA_PD containing no prefixes
4010 * with a Status Code option set to NoBinding in the
4011 * Reply message.
4012 *
4013 * On mismatch we (ab)use this pretending we have not the IA
4014 * as soon as we have not a prefix.
4015 */
4016 } else if (reply->packet->dhcpv6_msg_type == DHCPV6_RENEW) {
4017 /* Rewind the IA_PD to empty. */
4018 option_state_dereference(&reply->reply_ia, MDL);
4019 if (!option_state_allocate(&reply->reply_ia, MDL)) {
4020 log_error("reply_process_prefix: No memory "
4021 "for option state wipe.");
4022 status = ISC_R_NOMEMORY;
4023 goto cleanup;
4024 }
4025
4026 /* Append a NoBinding status code. */
4027 if (!set_status_code(STATUS_NoBinding,
4028 "Prefix not bound to this "
4029 "interface.", reply->reply_ia)) {
4030 log_error("reply_process_prefix: Unable to "
4031 "attach status code.");
4032 status = ISC_R_FAILURE;
4033 goto cleanup;
4034 }
4035
4036 /* Fin (no more IAPREFIXes). */
4037 status = ISC_R_CANCELED;
4038 goto cleanup;
4039 } else {
4040 log_error("It is impossible to lease a client that is "
4041 "not sending a solicit, request, renew, or "
4042 "rebind message.");
4043 status = ISC_R_FAILURE;
4044 goto cleanup;
4045 }
4046 }
4047
4048 if (reply->static_prefixes > 0) {
4049 if (reply->host == NULL)
4050 log_fatal("Impossible condition at %s:%d.", MDL);
4051
4052 scope = &global_scope;
01fa619f
SR
4053
4054 /* Find the static prefixe's subnet. */
4055 if (find_grouped_subnet(&reply->subnet, reply->shared,
4056 tmp_pref.lo_addr, MDL) == 0)
4057 log_fatal("Impossible condition at %s:%d.", MDL);
4058 group = reply->subnet->group;
4059 subnet_dereference(&reply->subnet, MDL);
d9b5c150
SR
4060
4061 /* Copy the static prefix for logging purposes */
4062 memcpy(&reply->fixed_pref, &tmp_pref, sizeof(tmp_pref));
80c9fdb0 4063 } else {
9322442f 4064 if (reply->lease == NULL)
80c9fdb0
FD
4065 log_fatal("Impossible condition at %s:%d.", MDL);
4066
9322442f 4067 scope = &reply->lease->scope;
01fa619f 4068 group = reply->lease->ipv6_pool->ipv6_pond->group;
80c9fdb0
FD
4069 }
4070
4071 /*
4072 * If client_resources is nonzero, then the reply_process_is_prefixed
4073 * function has executed configuration state into the reply option
4074 * cache. We will use that valid cache to derive configuration for
4075 * whether or not to engage in additional prefixes, and similar.
4076 */
4077 if (reply->client_resources != 0) {
4078 unsigned limit = 1;
4079
4080 /*
4081 * Does this client have "enough" prefixes already? Default
4082 * to one. Everybody gets one, and one should be enough for
4083 * anybody.
4084 */
4085 oc = lookup_option(&server_universe, reply->opt_state,
4086 SV_LIMIT_PREFS_PER_IA);
4087 if (oc != NULL) {
4088 if (!evaluate_option_cache(&data, reply->packet,
4089 NULL, NULL,
4090 reply->packet->options,
4091 reply->opt_state,
4092 scope, oc, MDL) ||
4093 (data.len != 4)) {
4094 log_error("reply_process_prefix: unable to "
4095 "evaluate prefs-per-ia value.");
4096 status = ISC_R_FAILURE;
4097 goto cleanup;
4098 }
4099
4100 limit = getULong(data.data);
4101 data_string_forget(&data, MDL);
4102 }
4103
4104 /*
4105 * If we wish to limit the client to a certain number of
4106 * prefixes, then omit the prefix from the reply.
4107 */
4108 if (reply->client_resources >= limit)
4109 goto cleanup;
4110 }
4111
01fa619f 4112 status = reply_process_is_prefixed(reply, scope, group);
80c9fdb0
FD
4113 if (status != ISC_R_SUCCESS)
4114 goto cleanup;
4115
4116 send_pref:
4117 status = reply_process_send_prefix(reply, &tmp_pref);
4118
4119 cleanup:
4120 if (iapref.data != NULL)
4121 data_string_forget(&iapref, MDL);
4122 if (data.data != NULL)
4123 data_string_forget(&data, MDL);
9322442f 4124 if (reply->lease != NULL)
1d17db44 4125 iasubopt_dereference(&reply->lease, MDL);
80c9fdb0
FD
4126
4127 return status;
4128}
4129
4130/*
4131 * Verify the prefix belongs to the client. If we've got a host
4132 * record with fixed prefixes, it has to be an assigned prefix
4133 * (fault out all else). Otherwise it's a dynamic prefix, so lookup
4134 * that prefix and make sure it belongs to this DUID:IAID pair.
4135 */
4136static isc_boolean_t
4137prefix_is_owned(struct reply_state *reply, struct iaddrcidrnet *pref) {
4138 struct iaddrcidrnetlist *l;
4139 int i;
01fa619f 4140 struct ipv6_pond *pond;
80c9fdb0
FD
4141
4142 /*
4143 * This faults out prefixes that don't match fixed prefixes.
4144 */
4145 if (reply->static_prefixes > 0) {
4146 for (l = reply->host->fixed_prefix; l != NULL; l = l->next) {
4147 if ((pref->bits == l->cidrnet.bits) &&
4148 (memcmp(pref->lo_addr.iabuf,
4149 l->cidrnet.lo_addr.iabuf, 16) == 0))
bc7f8b8e 4150 return (ISC_TRUE);
80c9fdb0 4151 }
bc7f8b8e 4152 return (ISC_FALSE);
80c9fdb0
FD
4153 }
4154
9322442f 4155 if ((reply->old_ia == NULL) ||
1d17db44 4156 (reply->old_ia->num_iasubopt == 0))
bc7f8b8e 4157 return (ISC_FALSE);
80c9fdb0 4158
1d17db44
FD
4159 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
4160 struct iasubopt *tmp;
80c9fdb0 4161
1d17db44 4162 tmp = reply->old_ia->iasubopt[i];
80c9fdb0
FD
4163
4164 if ((pref->bits == (int) tmp->plen) &&
bc7f8b8e
SR
4165 (memcmp(pref->lo_addr.iabuf, &tmp->addr, 16) == 0)) {
4166 if (lease6_usable(tmp) == ISC_FALSE) {
4167 return (ISC_FALSE);
4168 }
01fa619f
SR
4169
4170 pond = tmp->ipv6_pool->ipv6_pond;
4171 if (((pond->prohibit_list != NULL) &&
4172 (permitted(reply->packet, pond->prohibit_list))) ||
4173 ((pond->permit_list != NULL) &&
4174 (!permitted(reply->packet, pond->permit_list))))
4175 return (ISC_FALSE);
4176
1d17db44 4177 iasubopt_reference(&reply->lease, tmp, MDL);
bc7f8b8e 4178 return (ISC_TRUE);
80c9fdb0
FD
4179 }
4180 }
4181
bc7f8b8e 4182 return (ISC_FALSE);
80c9fdb0
FD
4183}
4184
4185/*
4186 * This function only returns failure on 'hard' failures. If it succeeds,
4187 * it will leave a prefix structure behind.
4188 */
4189static isc_result_t
4190reply_process_try_prefix(struct reply_state *reply,
4191 struct iaddrcidrnet *pref) {
d19fa5a1 4192 isc_result_t status = ISC_R_ADDRNOTAVAIL;
01fa619f
SR
4193 struct ipv6_pool *pool = NULL;
4194 struct ipv6_pond *pond = NULL;
80c9fdb0
FD
4195 int i;
4196 struct data_string data_pref;
4197
bd72740e 4198 if ((reply == NULL) || (reply->shared == NULL) ||
d19fa5a1
SR
4199 (pref == NULL) || (reply->lease != NULL))
4200 return (DHCP_R_INVALIDARG);
4201
01fa619f
SR
4202 /*
4203 * Do a quick walk through of the ponds and pools
4204 * to see if we have any prefix pools
4205 */
4206 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
4207 if (pond->ipv6_pools == NULL)
4208 continue;
4209
4210 for (i = 0; (pool = pond->ipv6_pools[i]) != NULL; i++) {
4211 if (pool->pool_type == D6O_IA_PD)
4212 break;
4213 }
4214 if (pool != NULL)
4215 break;
4216 }
4217
4218 /* If we get here and p is NULL we have no useful pools */
4219 if (pool == NULL) {
d19fa5a1 4220 return (ISC_R_ADDRNOTAVAIL);
01fa619f 4221 }
80c9fdb0
FD
4222
4223 memset(&data_pref, 0, sizeof(data_pref));
4224 data_pref.len = 17;
4225 if (!buffer_allocate(&data_pref.buffer, data_pref.len, MDL)) {
4226 log_error("reply_process_try_prefix: out of memory.");
d19fa5a1 4227 return (ISC_R_NOMEMORY);
80c9fdb0
FD
4228 }
4229 data_pref.data = data_pref.buffer->data;
4230 data_pref.buffer->data[0] = (u_int8_t) pref->bits;
4231 memcpy(data_pref.buffer->data + 1, pref->lo_addr.iabuf, 16);
4232
01fa619f
SR
4233 /*
4234 * We have at least one pool that could provide a prefix
4235 * Now we walk through the ponds and pools again and check
4236 * to see if the client is permitted and if an prefix is
4237 * available
4238 *
4239 */
4240
4241 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
4242 if (((pond->prohibit_list != NULL) &&
4243 (permitted(reply->packet, pond->prohibit_list))) ||
4244 ((pond->permit_list != NULL) &&
4245 (!permitted(reply->packet, pond->permit_list))))
9322442f 4246 continue;
01fa619f
SR
4247
4248 for (i = 0; (pool = pond->ipv6_pools[i]) != NULL; i++) {
4249 if (pool->pool_type != D6O_IA_PD) {
4250 continue;
4251 }
4252
4253 status = try_client_v6_prefix(&reply->lease, pool,
4254 &data_pref);
4255 /* If we found it in this pool (either in use or available),
4256 there is no need to look further. */
4257 if ( (status == ISC_R_SUCCESS) || (status == ISC_R_ADDRINUSE) )
4258 break;
4259 }
c7aa4dd4 4260 if ( (status == ISC_R_SUCCESS) || (status == ISC_R_ADDRINUSE) )
80c9fdb0
FD
4261 break;
4262 }
4263
4264 data_string_forget(&data_pref, MDL);
4265 /* Return just the most recent status... */
d19fa5a1 4266 return (status);
80c9fdb0
FD
4267}
4268
4269/* Look around for a prefix to give the client. First, look through the old
4270 * IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
4271 * Finally, actually add that prefix into the current reply IA_PD.
4272 */
4273static isc_result_t
4274find_client_prefix(struct reply_state *reply) {
4275 struct iaddrcidrnet send_pref;
4276 isc_result_t status = ISC_R_NORESOURCES;
1d17db44 4277 struct iasubopt *prefix, *best_prefix = NULL;
80c9fdb0 4278 struct binding_scope **scope;
80c9fdb0 4279 int i;
01fa619f 4280 struct group *group;
80c9fdb0 4281
80c9fdb0
FD
4282 if (reply->static_prefixes > 0) {
4283 struct iaddrcidrnetlist *l;
4284
4285 if (reply->host == NULL)
98bf1607 4286 return DHCP_R_INVALIDARG;
80c9fdb0
FD
4287
4288 for (l = reply->host->fixed_prefix; l != NULL; l = l->next) {
4289 if (l->cidrnet.bits == reply->preflen)
4290 break;
4291 }
4292 if (l == NULL) {
4293 /*
4294 * If no fixed prefix has the preferred length,
4295 * get the first one.
4296 */
4297 l = reply->host->fixed_prefix;
4298 }
4299 memcpy(&send_pref, &l->cidrnet, sizeof(send_pref));
4300
80c9fdb0 4301 scope = &global_scope;
01fa619f
SR
4302
4303 /* Find the static prefixe's subnet. */
4304 if (find_grouped_subnet(&reply->subnet, reply->shared,
4305 send_pref.lo_addr, MDL) == 0)
4306 log_fatal("Impossible condition at %s:%d.", MDL);
4307 group = reply->subnet->group;
4308 subnet_dereference(&reply->subnet, MDL);
4309
d9b5c150
SR
4310 /* Copy the prefix for logging purposes */
4311 memcpy(&reply->fixed_pref, &l->cidrnet, sizeof(send_pref));
4312
80c9fdb0
FD
4313 goto send_pref;
4314 }
4315
9322442f 4316 if (reply->old_ia != NULL) {
1d17db44 4317 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
0d8c3d6e 4318 struct shared_network *candidate_shared;
01fa619f 4319 struct ipv6_pond *pond;
0d8c3d6e 4320
1d17db44 4321 prefix = reply->old_ia->iasubopt[i];
0d8c3d6e 4322 candidate_shared = prefix->ipv6_pool->shared_network;
01fa619f 4323 pond = prefix->ipv6_pool->ipv6_pond;
80c9fdb0 4324
0d8c3d6e
DH
4325 /*
4326 * Consider this prefix if it is in a global pool or
4327 * if it is scoped in a pool under the client's shared
4328 * network.
4329 */
01fa619f
SR
4330 if (((candidate_shared != NULL) &&
4331 (candidate_shared != reply->shared)) ||
4332 (lease6_usable(prefix) != ISC_TRUE))
4333 continue;
4334
4335 /*
4336 * And check if the prefix is still permitted
4337 */
4338
4339 if (((pond->prohibit_list != NULL) &&
4340 (permitted(reply->packet, pond->prohibit_list))) ||
4341 ((pond->permit_list != NULL) &&
4342 (!permitted(reply->packet, pond->permit_list))))
4343 continue;
4344
4345 best_prefix = prefix_compare(reply, prefix,
4346 best_prefix);
80c9fdb0
FD
4347 }
4348 }
4349
4350 /* Try to pick a new prefix if we didn't find one, or if we found an
4351 * abandoned prefix.
4352 */
4353 if ((best_prefix == NULL) || (best_prefix->state == FTS_ABANDONED)) {
01fa619f 4354 status = pick_v6_prefix(reply);
80c9fdb0 4355 } else if (best_prefix != NULL) {
1d17db44 4356 iasubopt_reference(&reply->lease, best_prefix, MDL);
80c9fdb0
FD
4357 status = ISC_R_SUCCESS;
4358 }
4359
4360 /* Pick the abandoned prefix as a last resort. */
4361 if ((status == ISC_R_NORESOURCES) && (best_prefix != NULL)) {
4362 /* I don't see how this is supposed to be done right now. */
4363 log_error("Reclaiming abandoned prefixes is not yet "
4364 "supported. Treating this as an out of space "
4365 "condition.");
1d17db44 4366 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
80c9fdb0
FD
4367 }
4368
4369 /* Give up now if we didn't find a prefix. */
4370 if (status != ISC_R_SUCCESS)
5279b8f3
DH
4371 return status;
4372
9322442f 4373 if (reply->lease == NULL)
5279b8f3
DH
4374 log_fatal("Impossible condition at %s:%d.", MDL);
4375
9322442f 4376 scope = &reply->lease->scope;
01fa619f 4377 group = reply->lease->ipv6_pool->ipv6_pond->group;
5279b8f3 4378
80c9fdb0 4379 send_pref.lo_addr.len = 16;
9322442f
FD
4380 memcpy(send_pref.lo_addr.iabuf, &reply->lease->addr, 16);
4381 send_pref.bits = (int) reply->lease->plen;
5279b8f3 4382
80c9fdb0 4383 send_pref:
01fa619f 4384 status = reply_process_is_prefixed(reply, scope, group);
5279b8f3
DH
4385 if (status != ISC_R_SUCCESS)
4386 return status;
4387
80c9fdb0 4388 status = reply_process_send_prefix(reply, &send_pref);
5279b8f3
DH
4389 return status;
4390}
4391
80c9fdb0
FD
4392/* Once a prefix is found for a client, perform several common functions;
4393 * Calculate and store valid and preferred prefix times, draw client options
5279b8f3
DH
4394 * into the option state.
4395 */
4396static isc_result_t
9322442f 4397reply_process_is_prefixed(struct reply_state *reply,
80c9fdb0 4398 struct binding_scope **scope, struct group *group)
5279b8f3
DH
4399{
4400 isc_result_t status = ISC_R_SUCCESS;
4401 struct data_string data;
4402 struct option_cache *oc;
a7341359
SR
4403 struct option_state *tmp_options = NULL;
4404 struct on_star *on_star;
01fa619f 4405 int i;
5279b8f3
DH
4406
4407 /* Initialize values we will cleanup. */
4408 memset(&data, 0, sizeof(data));
4409
a7341359
SR
4410 /*
4411 * Find the proper on_star block to use. We use the
4412 * one in the lease if we have a lease or the one in
4413 * the reply if we don't have a lease because this is
4414 * a static instance
4415 */
4416 if (reply->lease) {
4417 on_star = &reply->lease->on_star;
4418 } else {
4419 on_star = &reply->on_star;
4420 }
4421
4422 /*
4423 * Bring in the root configuration. We only do this to bring
4424 * in the on * statements, as we didn't have the lease available
4425 * we we did it the first time.
4426 */
4427 option_state_allocate(&tmp_options, MDL);
4428 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4429 reply->packet->options, tmp_options,
4430 &global_scope, root_group, NULL,
4431 on_star);
4432 if (tmp_options != NULL) {
4433 option_state_dereference(&tmp_options, MDL);
4434 }
4435
2267da84
DH
4436 /*
4437 * Bring configured options into the root packet level cache - start
4438 * with the lease's closest enclosing group (passed in by the caller
4439 * as 'group').
4440 */
5279b8f3
DH
4441 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4442 reply->packet->options, reply->opt_state,
a7341359 4443 scope, group, root_group, on_star);
5279b8f3 4444
01fa619f
SR
4445 /* Execute statements from class scopes. */
4446 for (i = reply->packet->class_count; i > 0; i--) {
4447 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4448 reply->packet->options,
4449 reply->opt_state, scope,
4450 reply->packet->classes[i - 1]->group,
4451 group, on_star);
4452 }
4453
2267da84
DH
4454 /*
4455 * If there is a host record, over-ride with values configured there,
4456 * without re-evaluating configuration from the previously executed
4457 * group or its common enclosers.
4458 */
4459 if (reply->host != NULL)
4460 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4461 reply->packet->options,
4462 reply->opt_state, scope,
a7341359
SR
4463 reply->host->group, group,
4464 on_star);
2267da84 4465
5279b8f3
DH
4466 /* Determine valid lifetime. */
4467 if (reply->client_valid == 0)
4468 reply->send_valid = DEFAULT_DEFAULT_LEASE_TIME;
4469 else
4470 reply->send_valid = reply->client_valid;
4471
4472 oc = lookup_option(&server_universe, reply->opt_state,
4473 SV_DEFAULT_LEASE_TIME);
4474 if (oc != NULL) {
b024480e 4475 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
5279b8f3
DH
4476 reply->packet->options,
4477 reply->opt_state,
b024480e 4478 scope, oc, MDL) ||
5279b8f3 4479 (data.len != 4)) {
80c9fdb0
FD
4480 log_error("reply_process_is_prefixed: unable to "
4481 "evaluate default prefix time");
5279b8f3
DH
4482 status = ISC_R_FAILURE;
4483 goto cleanup;
4484 }
4485
4486 reply->send_valid = getULong(data.data);
4487 data_string_forget(&data, MDL);
98bd7ca0 4488 }
5279b8f3
DH
4489
4490 if (reply->client_prefer == 0)
4491 reply->send_prefer = reply->send_valid;
4492 else
4493 reply->send_prefer = reply->client_prefer;
4494
4495 if (reply->send_prefer >= reply->send_valid)
4496 reply->send_prefer = (reply->send_valid / 2) +
4497 (reply->send_valid / 8);
4498
4499 oc = lookup_option(&server_universe, reply->opt_state,
4500 SV_PREFER_LIFETIME);
4501 if (oc != NULL) {
b024480e 4502 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
5279b8f3
DH
4503 reply->packet->options,
4504 reply->opt_state,
b024480e 4505 scope, oc, MDL) ||
5279b8f3 4506 (data.len != 4)) {
80c9fdb0
FD
4507 log_error("reply_process_is_prefixed: unable to "
4508 "evaluate preferred prefix time");
5279b8f3
DH
4509 status = ISC_R_FAILURE;
4510 goto cleanup;
4511 }
4512
4513 reply->send_prefer = getULong(data.data);
4514 data_string_forget(&data, MDL);
98bd7ca0 4515 }
5279b8f3
DH
4516
4517 /* Note lowest values for later calculation of renew/rebind times. */
4518 if (reply->prefer > reply->send_prefer)
4519 reply->prefer = reply->send_prefer;
4520
4521 if (reply->valid > reply->send_valid)
4522 reply->valid = reply->send_valid;
4523
80c9fdb0 4524 /* Perform dynamic prefix related update work. */
9322442f 4525 if (reply->lease != NULL) {
1acab09f
FD
4526 /* Cached lifetimes */
4527 reply->lease->prefer = reply->send_prefer;
4528 reply->lease->valid = reply->send_valid;
4529
5279b8f3 4530 /* Advance (or rewind) the valid lifetime. */
5d89d60f 4531 if (reply->buf.reply.msg_type == DHCPV6_REPLY) {
9322442f 4532 reply->lease->soft_lifetime_end_time =
5d89d60f
FD
4533 cur_time + reply->send_valid;
4534 /* Wait before renew! */
4535 }
5279b8f3 4536
1d17db44 4537 status = ia_add_iasubopt(reply->ia, reply->lease, MDL);
5279b8f3 4538 if (status != ISC_R_SUCCESS) {
80c9fdb0
FD
4539 log_fatal("reply_process_is_prefixed: Unable to "
4540 "attach prefix to new IA_PD: %s",
4541 isc_result_totext(status));
5279b8f3
DH
4542 }
4543
4544 /*
80c9fdb0 4545 * If this is a new prefix, make sure it is attached somewhere.
5279b8f3 4546 */
9322442f
FD
4547 if (reply->lease->ia == NULL) {
4548 ia_reference(&reply->lease->ia, reply->ia, MDL);
5279b8f3 4549 }
98bd7ca0 4550 }
5279b8f3 4551
80c9fdb0 4552 /* Bring a copy of the relevant options into the IA_PD scope. */
5279b8f3
DH
4553 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4554 reply->packet->options, reply->reply_ia,
a7341359 4555 scope, group, root_group, NULL);
5279b8f3 4556
01fa619f
SR
4557 /* Execute statements from class scopes. */
4558 for (i = reply->packet->class_count; i > 0; i--) {
4559 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4560 reply->packet->options,
4561 reply->reply_ia, scope,
4562 reply->packet->classes[i - 1]->group,
4563 group, NULL);
4564 }
4565
2267da84
DH
4566 /*
4567 * And bring in host record configuration, if any, but not to overlap
4568 * the previous group or its common enclosers.
4569 */
4570 if (reply->host != NULL)
4571 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4572 reply->packet->options,
4573 reply->reply_ia, scope,
a7341359 4574 reply->host->group, group, NULL);
2267da84 4575
5279b8f3
DH
4576 cleanup:
4577 if (data.data != NULL)
4578 data_string_forget(&data, MDL);
4579
4580 if (status == ISC_R_SUCCESS)
1d9774ab 4581 reply->client_resources++;
5279b8f3
DH
4582
4583 return status;
4584}
4585
80c9fdb0 4586/* Simply send an IAPREFIX within the IA_PD scope as described. */
5279b8f3 4587static isc_result_t
80c9fdb0
FD
4588reply_process_send_prefix(struct reply_state *reply,
4589 struct iaddrcidrnet *pref) {
5279b8f3
DH
4590 isc_result_t status = ISC_R_SUCCESS;
4591 struct data_string data;
4592
4593 memset(&data, 0, sizeof(data));
4594
80c9fdb0
FD
4595 /* Now append the prefix. */
4596 data.len = IAPREFIX_OFFSET;
5279b8f3 4597 if (!buffer_allocate(&data.buffer, data.len, MDL)) {
80c9fdb0
FD
4598 log_error("reply_process_send_prefix: out of memory"
4599 "allocating new IAPREFIX buffer.");
5279b8f3
DH
4600 status = ISC_R_NOMEMORY;
4601 goto cleanup;
98bd7ca0 4602 }
5279b8f3
DH
4603 data.data = data.buffer->data;
4604
80c9fdb0
FD
4605 putULong(data.buffer->data, reply->send_prefer);
4606 putULong(data.buffer->data + 4, reply->send_valid);
4607 data.buffer->data[8] = pref->bits;
4608 memcpy(data.buffer->data + 9, pref->lo_addr.iabuf, 16);
5279b8f3 4609
bead14ea
DH
4610 if (!append_option_buffer(&dhcpv6_universe, reply->reply_ia,
4611 data.buffer, data.buffer->data,
80c9fdb0
FD
4612 data.len, D6O_IAPREFIX, 0)) {
4613 log_error("reply_process_send_prefix: unable "
4614 "to save IAPREFIX option");
5279b8f3
DH
4615 status = ISC_R_FAILURE;
4616 goto cleanup;
4617 }
4618
9322442f 4619 reply->resources_included = ISC_TRUE;
9f1d5a2f 4620
5279b8f3
DH
4621 cleanup:
4622 if (data.data != NULL)
4623 data_string_forget(&data, MDL);
4624
4625 return status;
4626}
4627
80c9fdb0 4628/* Choose the better of two prefixes. */
1d17db44 4629static struct iasubopt *
80c9fdb0 4630prefix_compare(struct reply_state *reply,
1d17db44 4631 struct iasubopt *alpha, struct iasubopt *beta) {
5279b8f3
DH
4632 if (alpha == NULL)
4633 return beta;
4634 if (beta == NULL)
4635 return alpha;
4636
80c9fdb0
FD
4637 if (reply->preflen >= 0) {
4638 if ((alpha->plen == reply->preflen) &&
4639 (beta->plen != reply->preflen))
4640 return alpha;
4641 if ((beta->plen == reply->preflen) &&
4642 (alpha->plen != reply->preflen))
4643 return beta;
4644 }
4645
5279b8f3
DH
4646 switch(alpha->state) {
4647 case FTS_ACTIVE:
4648 switch(beta->state) {
4649 case FTS_ACTIVE:
80c9fdb0 4650 /* Choose the prefix with the longest lifetime (most
5279b8f3
DH
4651 * likely the most recently allocated).
4652 */
5d89d60f
FD
4653 if (alpha->hard_lifetime_end_time <
4654 beta->hard_lifetime_end_time)
5279b8f3
DH
4655 return beta;
4656 else
4657 return alpha;
4658
4659 case FTS_EXPIRED:
4660 case FTS_ABANDONED:
4661 return alpha;
4662
4663 default:
4664 log_fatal("Impossible condition at %s:%d.", MDL);
4665 }
4666 break;
4667
4668 case FTS_EXPIRED:
4669 switch (beta->state) {
4670 case FTS_ACTIVE:
4671 return beta;
4672
4673 case FTS_EXPIRED:
80c9fdb0 4674 /* Choose the most recently expired prefix. */
5d89d60f
FD
4675 if (alpha->hard_lifetime_end_time <
4676 beta->hard_lifetime_end_time)
4677 return beta;
4678 else if ((alpha->hard_lifetime_end_time ==
4679 beta->hard_lifetime_end_time) &&
4680 (alpha->soft_lifetime_end_time <
4681 beta->soft_lifetime_end_time))
5279b8f3
DH
4682 return beta;
4683 else
4684 return alpha;
4685
4686 case FTS_ABANDONED:
4687 return alpha;
4688
4689 default:
4690 log_fatal("Impossible condition at %s:%d.", MDL);
4691 }
4692 break;
4693
4694 case FTS_ABANDONED:
4695 switch (beta->state) {
4696 case FTS_ACTIVE:
4697 case FTS_EXPIRED:
4698 return alpha;
4699
4700 case FTS_ABANDONED:
80c9fdb0 4701 /* Choose the prefix that was abandoned longest ago. */
5d89d60f
FD
4702 if (alpha->hard_lifetime_end_time <
4703 beta->hard_lifetime_end_time)
5279b8f3 4704 return alpha;
a07d99bb
TM
4705 else
4706 return beta;
5279b8f3
DH
4707
4708 default:
4709 log_fatal("Impossible condition at %s:%d.", MDL);
4710 }
4711 break;
4712
4713 default:
4714 log_fatal("Impossible condition at %s:%d.", MDL);
98bd7ca0 4715 }
5279b8f3
DH
4716
4717 log_fatal("Triple impossible condition at %s:%d.", MDL);
4718 return NULL;
98bd7ca0
DH
4719}
4720
4721/*
4722 * Solicit is how a client starts requesting addresses.
4723 *
4724 * If the client asks for rapid commit, and we support it, we will
4725 * allocate the addresses and reply.
4726 *
4727 * Otherwise we will send an advertise message.
4728 */
4729
98bd7ca0
DH
4730static void
4731dhcpv6_solicit(struct data_string *reply_ret, struct packet *packet) {
4732 struct data_string client_id;
98bd7ca0
DH
4733
4734 /*
4735 * Validate our input.
4736 */
4737 if (!valid_client_msg(packet, &client_id)) {
4738 return;
4739 }
4740
4741 lease_to_client(reply_ret, packet, &client_id, NULL);
4742
4743 /*
4744 * Clean up.
4745 */
4746 data_string_forget(&client_id, MDL);
4747}
4748
4749/*
4750 * Request is how a client actually requests addresses.
4751 *
4752 * Very similar to Solicit handling, except the server DUID is required.
4753 */
4754
72073970 4755/* TODO: reject unicast messages, unless we set unicast option */
98bd7ca0
DH
4756static void
4757dhcpv6_request(struct data_string *reply_ret, struct packet *packet) {
4758 struct data_string client_id;
4759 struct data_string server_id;
4760
4761 /*
4762 * Validate our input.
4763 */
4764 if (!valid_client_resp(packet, &client_id, &server_id)) {
4765 return;
4766 }
4767
4768 /*
4769 * Issue our lease.
4770 */
4771 lease_to_client(reply_ret, packet, &client_id, &server_id);
4772
4773 /*
4774 * Cleanup.
4775 */
4776 data_string_forget(&client_id, MDL);
4777 data_string_forget(&server_id, MDL);
4778}
4779
8eab95f2
DH
4780/* Find a DHCPv6 packet's shared network from hints in the packet.
4781 */
bd72740e 4782static isc_result_t
8eab95f2
DH
4783shared_network_from_packet6(struct shared_network **shared,
4784 struct packet *packet)
4785{
4786 const struct packet *chk_packet;
4787 const struct in6_addr *link_addr, *first_link_addr;
4788 struct iaddr tmp_addr;
4789 struct subnet *subnet;
bd72740e 4790 isc_result_t status;
8eab95f2 4791
bd72740e 4792 if ((shared == NULL) || (*shared != NULL) || (packet == NULL))
98bf1607 4793 return DHCP_R_INVALIDARG;
8eab95f2
DH
4794
4795 /*
4796 * First, find the link address where the packet from the client
4797 * first appeared (if this packet was relayed).
4798 */
4799 first_link_addr = NULL;
4800 chk_packet = packet->dhcpv6_container_packet;
4801 while (chk_packet != NULL) {
4802 link_addr = &chk_packet->dhcpv6_link_address;
4803 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr) &&
4804 !IN6_IS_ADDR_LINKLOCAL(link_addr)) {
4805 first_link_addr = link_addr;
b445a411 4806 break;
8eab95f2
DH
4807 }
4808 chk_packet = chk_packet->dhcpv6_container_packet;
4809 }
4810
4811 /*
4812 * If there is a relayed link address, find the subnet associated
4813 * with that, and use that to get the appropriate
4814 * shared_network.
4815 */
4816 if (first_link_addr != NULL) {
4817 tmp_addr.len = sizeof(*first_link_addr);
4818 memcpy(tmp_addr.iabuf,
4819 first_link_addr, sizeof(*first_link_addr));
4820 subnet = NULL;
4821 if (!find_subnet(&subnet, tmp_addr, MDL)) {
4822 log_debug("No subnet found for link-address %s.",
4823 piaddr(tmp_addr));
bd72740e 4824 return ISC_R_NOTFOUND;
8eab95f2 4825 }
bd72740e
FD
4826 status = shared_network_reference(shared,
4827 subnet->shared_network, MDL);
8eab95f2
DH
4828 subnet_dereference(&subnet, MDL);
4829
4830 /*
4831 * If there is no link address, we will use the interface
4832 * that this packet came in on to pick the shared_network.
4833 */
4dc5a6b1 4834 } else if (packet->interface != NULL) {
bd72740e 4835 status = shared_network_reference(shared,
8eab95f2
DH
4836 packet->interface->shared_network,
4837 MDL);
4dc5a6b1
SR
4838 if (packet->dhcpv6_container_packet != NULL) {
4839 log_info("[L2 Relay] No link address in relay packet "
4840 "assuming L2 relay and using receiving "
4841 "interface");
4842 }
4843
4844 } else {
4845 /*
4846 * We shouldn't be able to get here but if there is no link
4847 * address and no interface we don't know where to get the
4848 * pool from log an error and return an error.
4849 */
4850 log_error("No interface and no link address "
4851 "can't determine pool");
4852 status = DHCP_R_INVALIDARG;
8eab95f2 4853 }
bd72740e
FD
4854
4855 return status;
8eab95f2
DH
4856}
4857
98bd7ca0
DH
4858/*
4859 * When a client thinks it might be on a new link, it sends a
4860 * Confirm message.
8eab95f2
DH
4861 *
4862 * From RFC3315 section 18.2.2:
4863 *
4864 * When the server receives a Confirm message, the server determines
4865 * whether the addresses in the Confirm message are appropriate for the
4866 * link to which the client is attached. If all of the addresses in the
4867 * Confirm message pass this test, the server returns a status of
4868 * Success. If any of the addresses do not pass this test, the server
4869 * returns a status of NotOnLink. If the server is unable to perform
4870 * this test (for example, the server does not have information about
4871 * prefixes on the link to which the client is connected), or there were
4872 * no addresses in any of the IAs sent by the client, the server MUST
4873 * NOT send a reply to the client.
98bd7ca0
DH
4874 */
4875
98bd7ca0
DH
4876static void
4877dhcpv6_confirm(struct data_string *reply_ret, struct packet *packet) {
8eab95f2
DH
4878 struct shared_network *shared;
4879 struct subnet *subnet;
4880 struct option_cache *ia, *ta, *oc;
4881 struct data_string cli_enc_opt_data, iaaddr, client_id, packet_oro;
4882 struct option_state *cli_enc_opt_state, *opt_state;
4883 struct iaddr cli_addr;
4884 int pass;
4885 isc_boolean_t inappropriate, has_addrs;
98bd7ca0
DH
4886 char reply_data[65536];
4887 struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data;
a3528574 4888 int reply_ofs = (int)(offsetof(struct dhcpv6_packet, options));
98bd7ca0
DH
4889
4890 /*
8eab95f2 4891 * Basic client message validation.
98bd7ca0 4892 */
8eab95f2 4893 memset(&client_id, 0, sizeof(client_id));
98bd7ca0
DH
4894 if (!valid_client_msg(packet, &client_id)) {
4895 return;
4896 }
4897
80c9fdb0
FD
4898 /*
4899 * Do not process Confirms that do not have IA's we do not recognize.
8eab95f2
DH
4900 */
4901 ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
4902 ta = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_TA);
4903 if ((ia == NULL) && (ta == NULL))
4904 return;
4905
80c9fdb0
FD
4906 /*
4907 * IA_PD's are simply ignored.
4908 */
4909 delete_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
4910
98bd7ca0
DH
4911 /*
4912 * Bit of variable initialization.
4913 */
8eab95f2
DH
4914 opt_state = cli_enc_opt_state = NULL;
4915 memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
98bd7ca0 4916 memset(&iaaddr, 0, sizeof(iaaddr));
98bd7ca0
DH
4917 memset(&packet_oro, 0, sizeof(packet_oro));
4918
8eab95f2
DH
4919 /* Determine what shared network the client is connected to. We
4920 * must not respond if we don't have any information about the
4921 * network the client is on.
98bd7ca0 4922 */
8eab95f2 4923 shared = NULL;
bd72740e
FD
4924 if ((shared_network_from_packet6(&shared, packet) != ISC_R_SUCCESS) ||
4925 (shared == NULL))
98bd7ca0 4926 goto exit;
98bd7ca0 4927
8eab95f2
DH
4928 /* If there are no recorded subnets, then we have no
4929 * information about this subnet - ignore Confirms.
98bd7ca0 4930 */
8eab95f2
DH
4931 subnet = shared->subnets;
4932 if (subnet == NULL)
4933 goto exit;
98bd7ca0 4934
8eab95f2
DH
4935 /* Are the addresses in all the IA's appropriate for that link? */
4936 has_addrs = inappropriate = ISC_FALSE;
4937 pass = D6O_IA_NA;
4938 while(!inappropriate) {
4939 /* If we've reached the end of the IA_NA pass, move to the
4940 * IA_TA pass.
4941 */
4942 if ((pass == D6O_IA_NA) && (ia == NULL)) {
4943 pass = D6O_IA_TA;
4944 ia = ta;
98bd7ca0
DH
4945 }
4946
8eab95f2
DH
4947 /* If we've reached the end of all passes, we're done. */
4948 if (ia == NULL)
4949 break;
98bd7ca0 4950
8eab95f2
DH
4951 if (((pass == D6O_IA_NA) &&
4952 !get_encapsulated_IA_state(&cli_enc_opt_state,
4953 &cli_enc_opt_data,
4954 packet, ia, IA_NA_OFFSET)) ||
4955 ((pass == D6O_IA_TA) &&
4956 !get_encapsulated_IA_state(&cli_enc_opt_state,
4957 &cli_enc_opt_data,
4958 packet, ia, IA_TA_OFFSET))) {
98bd7ca0
DH
4959 goto exit;
4960 }
4961
8eab95f2
DH
4962 oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
4963 D6O_IAADDR);
98bd7ca0 4964
8eab95f2
DH
4965 for ( ; oc != NULL ; oc = oc->next) {
4966 if (!evaluate_option_cache(&iaaddr, packet, NULL, NULL,
4967 packet->options, NULL,
4968 &global_scope, oc, MDL) ||
5279b8f3 4969 (iaaddr.len < IAADDR_OFFSET)) {
8eab95f2
DH
4970 log_error("dhcpv6_confirm: "
4971 "error evaluating IAADDR.");
98bd7ca0
DH
4972 goto exit;
4973 }
8eab95f2
DH
4974
4975 /* Copy out the IPv6 address for processing. */
4976 cli_addr.len = 16;
4977 memcpy(cli_addr.iabuf, iaaddr.data, 16);
4978
5279b8f3
DH
4979 data_string_forget(&iaaddr, MDL);
4980
8eab95f2
DH
4981 /* Record that we've processed at least one address. */
4982 has_addrs = ISC_TRUE;
4983
4984 /* Find out if any subnets cover this address. */
4985 for (subnet = shared->subnets ; subnet != NULL ;
4986 subnet = subnet->next_sibling) {
4987 if (addr_eq(subnet_number(cli_addr,
4988 subnet->netmask),
4989 subnet->net))
4990 break;
4991 }
4992
8eab95f2
DH
4993 /* If we reach the end of the subnet list, and no
4994 * subnet matches the client address, then it must
4995 * be inappropriate to the link (so far as our
4996 * configuration says). Once we've found one
4997 * inappropriate address, there is no reason to
4998 * continue searching.
4999 */
5000 if (subnet == NULL) {
5001 inappropriate = ISC_TRUE;
98bd7ca0
DH
5002 break;
5003 }
5279b8f3 5004 }
98bd7ca0 5005
8eab95f2
DH
5006 option_state_dereference(&cli_enc_opt_state, MDL);
5007 data_string_forget(&cli_enc_opt_data, MDL);
98bd7ca0 5008
8eab95f2
DH
5009 /* Advance to the next IA_*. */
5010 ia = ia->next;
98bd7ca0
DH
5011 }
5012
8eab95f2
DH
5013 /* If the client supplied no addresses, do not reply. */
5014 if (!has_addrs)
5015 goto exit;
5016
98bd7ca0 5017 /*
8eab95f2 5018 * Set up reply.
98bd7ca0 5019 */
8eab95f2 5020 if (!start_reply(packet, &client_id, NULL, &opt_state, reply)) {
98bd7ca0
DH
5021 goto exit;
5022 }
5023
5024 /*
5025 * Set our status.
5026 */
8eab95f2 5027 if (inappropriate) {
98bd7ca0
DH
5028 if (!set_status_code(STATUS_NotOnLink,
5029 "Some of the addresses are not on link.",
5030 opt_state)) {
5031 goto exit;
5032 }
5033 } else {
5034 if (!set_status_code(STATUS_Success,
5035 "All addresses still on link.",
5036 opt_state)) {
5037 goto exit;
5038 }
5039 }
5040
5041 /*
5042 * Only one option: add it.
5043 */
5044 reply_ofs += store_options6(reply_data+reply_ofs,
5045 sizeof(reply_data)-reply_ofs,
5046 opt_state, packet,
5047 required_opts, &packet_oro);
5048
5049 /*
5050 * Return our reply to the caller.
5051 */
5052 reply_ret->len = reply_ofs;
5053 reply_ret->buffer = NULL;
5054 if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) {
5055 log_fatal("No memory to store reply.");
5056 }
5057 reply_ret->data = reply_ret->buffer->data;
5058 memcpy(reply_ret->buffer->data, reply, reply_ofs);
5059
5060exit:
8eab95f2
DH
5061 /* Cleanup any stale data strings. */
5062 if (cli_enc_opt_data.buffer != NULL)
5063 data_string_forget(&cli_enc_opt_data, MDL);
5064 if (iaaddr.buffer != NULL)
98bd7ca0 5065 data_string_forget(&iaaddr, MDL);
8eab95f2
DH
5066 if (client_id.buffer != NULL)
5067 data_string_forget(&client_id, MDL);
5068 if (packet_oro.buffer != NULL)
5069 data_string_forget(&packet_oro, MDL);
5070
5071 /* Release any stale option states. */
5072 if (cli_enc_opt_state != NULL)
5073 option_state_dereference(&cli_enc_opt_state, MDL);
5074 if (opt_state != NULL)
5075 option_state_dereference(&opt_state, MDL);
98bd7ca0
DH
5076}
5077
5078/*
80c9fdb0 5079 * Renew is when a client wants to extend its lease/prefix, at time T1.
98bd7ca0 5080 *
80c9fdb0
FD
5081 * We handle this the same as if the client wants a new lease/prefix,
5082 * except for the error code of when addresses don't match.
98bd7ca0
DH
5083 */
5084
72073970 5085/* TODO: reject unicast messages, unless we set unicast option */
98bd7ca0
DH
5086static void
5087dhcpv6_renew(struct data_string *reply, struct packet *packet) {
5088 struct data_string client_id;
5089 struct data_string server_id;
5090
5091 /*
5092 * Validate the request.
5093 */
5094 if (!valid_client_resp(packet, &client_id, &server_id)) {
5095 return;
5096 }
5097
5098 /*
5099 * Renew our lease.
5100 */
5101 lease_to_client(reply, packet, &client_id, &server_id);
5102
5103 /*
5104 * Cleanup.
5105 */
5106 data_string_forget(&server_id, MDL);
5107 data_string_forget(&client_id, MDL);
5108}
5109
5110/*
5111 * Rebind is when a client wants to extend its lease, at time T2.
5112 *
5113 * We handle this the same as if the client wants a new lease, except
5114 * for the error code of when addresses don't match.
5115 */
5116
98bd7ca0
DH
5117static void
5118dhcpv6_rebind(struct data_string *reply, struct packet *packet) {
5119 struct data_string client_id;
5120
5121 if (!valid_client_msg(packet, &client_id)) {
5122 return;
5123 }
5124
5279b8f3 5125 lease_to_client(reply, packet, &client_id, NULL);
98bd7ca0
DH
5126
5127 data_string_forget(&client_id, MDL);
5128}
5129
5130static void
5131ia_na_match_decline(const struct data_string *client_id,
5132 const struct data_string *iaaddr,
1d17db44 5133 struct iasubopt *lease)
c382bc98 5134{
98bd7ca0
DH
5135 char tmp_addr[INET6_ADDRSTRLEN];
5136
5137 log_error("Client %s reports address %s is "
5138 "already in use by another host!",
5139 print_hex_1(client_id->len, client_id->data, 60),
5140 inet_ntop(AF_INET6, iaaddr->data,
5141 tmp_addr, sizeof(tmp_addr)));
5142 if (lease != NULL) {
5143 decline_lease6(lease->ipv6_pool, lease);
1acab09f 5144 lease->ia->cltt = cur_time;
9322442f 5145 write_ia(lease->ia);
98bd7ca0
DH
5146 }
5147}
5148
5149static void
5150ia_na_nomatch_decline(const struct data_string *client_id,
5151 const struct data_string *iaaddr,
5152 u_int32_t *ia_na_id,
5153 struct packet *packet,
5154 char *reply_data,
5155 int *reply_ofs,
c382bc98
SK
5156 int reply_len)
5157{
98bd7ca0
DH
5158 char tmp_addr[INET6_ADDRSTRLEN];
5159 struct option_state *host_opt_state;
5160 int len;
5161
5162 log_info("Client %s declines address %s, which is not offered to it.",
5163 print_hex_1(client_id->len, client_id->data, 60),
5164 inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
5165
5166 /*
5167 * Create state for this IA_NA.
5168 */
5169 host_opt_state = NULL;
5170 if (!option_state_allocate(&host_opt_state, MDL)) {
5171 log_error("ia_na_nomatch_decline: out of memory "
5172 "allocating option_state.");
5173 goto exit;
5174 }
5175
5176 if (!set_status_code(STATUS_NoBinding, "Decline for unknown address.",
5177 host_opt_state)) {
5178 goto exit;
5179 }
5180
5181 /*
5182 * Insure we have enough space
5183 */
5184 if (reply_len < (*reply_ofs + 16)) {
5185 log_error("ia_na_nomatch_decline: "
5186 "out of space for reply packet.");
5187 goto exit;
5188 }
5189
5190 /*
5191 * Put our status code into the reply packet.
5192 */
5193 len = store_options6(reply_data+(*reply_ofs)+16,
5194 reply_len-(*reply_ofs)-16,
5195 host_opt_state, packet,
5196 required_opts_STATUS_CODE, NULL);
5197
5198 /*
5199 * Store the non-encapsulated option data for this
5200 * IA_NA into our reply packet. Defined in RFC 3315,
5201 * section 22.4.
5202 */
5203 /* option number */
28868515 5204 putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_NA);
98bd7ca0 5205 /* option length */
28868515 5206 putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
98bd7ca0
DH
5207 /* IA_NA, copied from the client */
5208 memcpy(reply_data+(*reply_ofs)+4, ia_na_id, 4);
5209 /* t1 and t2, odd that we need them, but here it is */
28868515
SK
5210 putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
5211 putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
98bd7ca0
DH
5212
5213 /*
5214 * Get ready for next IA_NA.
5215 */
5216 *reply_ofs += (len + 16);
5217
5218exit:
5219 option_state_dereference(&host_opt_state, MDL);
5220}
5221
5222static void
5223iterate_over_ia_na(struct data_string *reply_ret,
5224 struct packet *packet,
5225 const struct data_string *client_id,
5226 const struct data_string *server_id,
06eb8bab 5227 const char *packet_type,
98bd7ca0 5228 void (*ia_na_match)(),
c382bc98
SK
5229 void (*ia_na_nomatch)())
5230{
98bd7ca0
DH
5231 struct option_state *opt_state;
5232 struct host_decl *packet_host;
5233 struct option_cache *ia;
5234 struct option_cache *oc;
5235 /* cli_enc_... variables come from the IA_NA/IA_TA options */
5236 struct data_string cli_enc_opt_data;
5237 struct option_state *cli_enc_opt_state;
5238 struct host_decl *host;
5239 struct option_state *host_opt_state;
98bd7ca0
DH
5240 struct data_string iaaddr;
5241 struct data_string fixed_addr;
98bd7ca0
DH
5242 char reply_data[65536];
5243 struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data;
a3528574 5244 int reply_ofs = (int)(offsetof(struct dhcpv6_packet, options));
98bd7ca0 5245 char status_msg[32];
1d17db44 5246 struct iasubopt *lease;
9322442f 5247 struct ia_xx *existing_ia_na;
98bd7ca0
DH
5248 int i;
5249 struct data_string key;
5250 u_int32_t iaid;
5251
5252 /*
5253 * Initialize to empty values, in case we have to exit early.
5254 */
5255 opt_state = NULL;
5256 memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
5257 cli_enc_opt_state = NULL;
5258 memset(&iaaddr, 0, sizeof(iaaddr));
5259 memset(&fixed_addr, 0, sizeof(fixed_addr));
5260 host_opt_state = NULL;
5261 lease = NULL;
5262
5263 /*
5264 * Find the host record that matches from the packet, if any.
5265 */
5266 packet_host = NULL;
5267 if (!find_hosts_by_uid(&packet_host,
5268 client_id->data, client_id->len, MDL)) {
5269 packet_host = NULL;
5270 /*
5271 * Note: In general, we don't expect a client to provide
5272 * enough information to match by option for these
5273 * types of messages, but if we don't have a UID
5274 * match we can check anyway.
5275 */
5276 if (!find_hosts_by_option(&packet_host,
5277 packet, packet->options, MDL)) {
5278 packet_host = NULL;
c900c5b2
DH
5279
5280 if (!find_hosts_by_duid_chaddr(&packet_host,
5281 client_id))
5282 packet_host = NULL;
98bd7ca0
DH
5283 }
5284 }
5285
5286 /*
5287 * Set our reply information.
5288 */
5289 reply->msg_type = DHCPV6_REPLY;
5290 memcpy(reply->transaction_id, packet->dhcpv6_transaction_id,
5291 sizeof(reply->transaction_id));
5292
5293 /*
5294 * Build our option state for reply.
5295 */
5296 opt_state = NULL;
5297 if (!option_state_allocate(&opt_state, MDL)) {
5298 log_error("iterate_over_ia_na: no memory for option_state.");
5299 goto exit;
5300 }
5301 execute_statements_in_scope(NULL, packet, NULL, NULL,
5302 packet->options, opt_state,
a7341359 5303 &global_scope, root_group, NULL, NULL);
98bd7ca0
DH
5304
5305 /*
5306 * RFC 3315, section 18.2.7 tells us which options to include.
5307 */
5308 oc = lookup_option(&dhcpv6_universe, opt_state, D6O_SERVERID);
5309 if (oc == NULL) {
28868515
SK
5310 if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
5311 (unsigned char *)server_duid.data,
98bd7ca0
DH
5312 server_duid.len, D6O_SERVERID, 0)) {
5313 log_error("iterate_over_ia_na: "
5314 "error saving server identifier.");
5315 goto exit;
5316 }
5317 }
5318
5319 if (!save_option_buffer(&dhcpv6_universe, opt_state,
5320 client_id->buffer,
5321 (unsigned char *)client_id->data,
5322 client_id->len,
5323 D6O_CLIENTID, 0)) {
5324 log_error("iterate_over_ia_na: "
5325 "error saving client identifier.");
5326 goto exit;
5327 }
5328
5329 snprintf(status_msg, sizeof(status_msg), "%s received.", packet_type);
5330 if (!set_status_code(STATUS_Success, status_msg, opt_state)) {
5331 goto exit;
5332 }
5333
5334 /*
5335 * Add our options that are not associated with any IA_NA or IA_TA.
5336 */
5337 reply_ofs += store_options6(reply_data+reply_ofs,
5338 sizeof(reply_data)-reply_ofs,
5339 opt_state, packet,
5340 required_opts, NULL);
5341
5342 /*
5343 * Loop through the IA_NA reported by the client, and deal with
5344 * addresses reported as already in use.
5345 */
5346 for (ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
5347 ia != NULL; ia = ia->next) {
98bd7ca0
DH
5348
5349 if (!get_encapsulated_IA_state(&cli_enc_opt_state,
5350 &cli_enc_opt_data,
8eab95f2 5351 packet, ia, IA_NA_OFFSET)) {
98bd7ca0
DH
5352 goto exit;
5353 }
5354
5355 iaid = getULong(cli_enc_opt_data.data);
5356
5357 /*
5358 * XXX: It is possible that we can get multiple addresses
5359 * sent by the client. We don't send multiple
5360 * addresses, so this indicates a client error.
5361 * We should check for multiple IAADDR options, log
5362 * if found, and set as an error.
5363 */
5364 oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
5365 D6O_IAADDR);
5366 if (oc == NULL) {
5367 /* no address given for this IA, ignore */
5368 option_state_dereference(&cli_enc_opt_state, MDL);
5369 data_string_forget(&cli_enc_opt_data, MDL);
5370 continue;
5371 }
5372
5373 memset(&iaaddr, 0, sizeof(iaaddr));
5374 if (!evaluate_option_cache(&iaaddr, packet, NULL, NULL,
5375 packet->options, NULL,
5376 &global_scope, oc, MDL)) {
5377 log_error("iterate_over_ia_na: "
5378 "error evaluating IAADDR.");
5379 goto exit;
5380 }
5381
5382 /*
5383 * Now we need to figure out which host record matches
c900c5b2
DH
5384 * this IA_NA and IAADDR (encapsulated option contents
5385 * matching a host record by option).
98bd7ca0
DH
5386 *
5387 * XXX: We don't currently track IA_NA separately, but
5388 * we will need to do this!
5389 */
5390 host = NULL;
5391 if (!find_hosts_by_option(&host, packet,
5392 cli_enc_opt_state, MDL)) {
5393 if (packet_host != NULL) {
5394 host = packet_host;
5395 } else {
5396 host = NULL;
5397 }
5398 }
5399 while (host != NULL) {
5400 if (host->fixed_addr != NULL) {
5401 if (!evaluate_option_cache(&fixed_addr, NULL,
5402 NULL, NULL, NULL,
5403 NULL, &global_scope,
5404 host->fixed_addr,
5405 MDL)) {
5406 log_error("iterate_over_ia_na: error "
5407 "evaluating host address.");
5408 goto exit;
5409 }
5410 if ((iaaddr.len >= 16) &&
5411 !memcmp(fixed_addr.data, iaaddr.data, 16)) {
5412 data_string_forget(&fixed_addr, MDL);
5413 break;
5414 }
5415 data_string_forget(&fixed_addr, MDL);
5416 }
5417 host = host->n_ipaddr;
5418 }
5419
5279b8f3 5420 if ((host == NULL) && (iaaddr.len >= IAADDR_OFFSET)) {
98bd7ca0
DH
5421 /*
5422 * Find existing IA_NA.
5423 */
1d9774ab
FD
5424 if (ia_make_key(&key, iaid,
5425 (char *)client_id->data,
5426 client_id->len,
5427 MDL) != ISC_R_SUCCESS) {
98bd7ca0
DH
5428 log_fatal("iterate_over_ia_na: no memory for "
5429 "key.");
5430 }
5431
5432 existing_ia_na = NULL;
9322442f
FD
5433 if (ia_hash_lookup(&existing_ia_na, ia_na_active,
5434 (unsigned char *)key.data,
5435 key.len, MDL)) {
98bd7ca0
DH
5436 /*
5437 * Make sure this address is in the IA_NA.
5438 */
1d17db44
FD
5439 for (i=0; i<existing_ia_na->num_iasubopt; i++) {
5440 struct iasubopt *tmp;
98bd7ca0
DH
5441 struct in6_addr *in6_addr;
5442
1d17db44 5443 tmp = existing_ia_na->iasubopt[i];
98bd7ca0
DH
5444 in6_addr = &tmp->addr;
5445 if (memcmp(in6_addr,
5446 iaaddr.data, 16) == 0) {
1d17db44
FD
5447 iasubopt_reference(&lease,
5448 tmp, MDL);
98bd7ca0 5449 break;
5279b8f3 5450 }
98bd7ca0
DH
5451 }
5452 }
5453
5454 data_string_forget(&key, MDL);
5455 }
5456
5457 if ((host != NULL) || (lease != NULL)) {
5458 ia_na_match(client_id, &iaaddr, lease);
5459 } else {
5460 ia_na_nomatch(client_id, &iaaddr,
5461 (u_int32_t *)cli_enc_opt_data.data,
5462 packet, reply_data, &reply_ofs,
5463 sizeof(reply_data));
5464 }
5465
5466 if (lease != NULL) {
1d17db44 5467 iasubopt_dereference(&lease, MDL);
98bd7ca0
DH
5468 }
5469
5470 data_string_forget(&iaaddr, MDL);
5471 option_state_dereference(&cli_enc_opt_state, MDL);
5472 data_string_forget(&cli_enc_opt_data, MDL);
5473 }
5474
5475 /*
5476 * Return our reply to the caller.
5477 */
5478 reply_ret->len = reply_ofs;
5479 reply_ret->buffer = NULL;
5480 if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) {
5481 log_fatal("No memory to store reply.");
5482 }
5483 reply_ret->data = reply_ret->buffer->data;
5484 memcpy(reply_ret->buffer->data, reply, reply_ofs);
5485
5486exit:
5487 if (lease != NULL) {
1d17db44 5488 iasubopt_dereference(&lease, MDL);
98bd7ca0
DH
5489 }
5490 if (host_opt_state != NULL) {
5491 option_state_dereference(&host_opt_state, MDL);
5492 }
5493 if (fixed_addr.buffer != NULL) {
5494 data_string_forget(&fixed_addr, MDL);
5495 }
5496 if (iaaddr.buffer != NULL) {
5497 data_string_forget(&iaaddr, MDL);
5498 }
5499 if (cli_enc_opt_state != NULL) {
5500 option_state_dereference(&cli_enc_opt_state, MDL);
5501 }
5502 if (cli_enc_opt_data.buffer != NULL) {
5503 data_string_forget(&cli_enc_opt_data, MDL);
5504 }
5505 if (opt_state != NULL) {
5506 option_state_dereference(&opt_state, MDL);
5507 }
5508}
5509
5510/*
5511 * Decline means a client has detected that something else is using an
5512 * address we gave it.
5513 *
5514 * Since we're only dealing with fixed leases for now, there's not
20ae1aff 5515 * much we can do, other that log the occurrence.
98bd7ca0
DH
5516 *
5517 * When we start issuing addresses from pools, then we will have to
5518 * record our declined addresses and issue another. In general with
5519 * IPv6 there is no worry about DoS by clients exhausting space, but
5520 * we still need to be aware of this possibility.
5521 */
5522
72073970 5523/* TODO: reject unicast messages, unless we set unicast option */
98bd7ca0
DH
5524/* TODO: IA_TA */
5525static void
5526dhcpv6_decline(struct data_string *reply, struct packet *packet) {
5527 struct data_string client_id;
5528 struct data_string server_id;
5529
5530 /*
5531 * Validate our input.
5532 */
5533 if (!valid_client_resp(packet, &client_id, &server_id)) {
5534 return;
5535 }
5536
80c9fdb0
FD
5537 /*
5538 * Undefined for IA_PD.
5539 */
5540 delete_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
5541
98bd7ca0
DH
5542 /*
5543 * And operate on each IA_NA in this packet.
5544 */
5545 iterate_over_ia_na(reply, packet, &client_id, &server_id, "Decline",
5546 ia_na_match_decline, ia_na_nomatch_decline);
80c9fdb0
FD
5547
5548 data_string_forget(&server_id, MDL);
5549 data_string_forget(&client_id, MDL);
98bd7ca0
DH
5550}
5551
5552static void
5553ia_na_match_release(const struct data_string *client_id,
5554 const struct data_string *iaaddr,
1d17db44 5555 struct iasubopt *lease)
c382bc98 5556{
98bd7ca0
DH
5557 char tmp_addr[INET6_ADDRSTRLEN];
5558
5559 log_info("Client %s releases address %s",
5560 print_hex_1(client_id->len, client_id->data, 60),
5561 inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
5562 if (lease != NULL) {
5563 release_lease6(lease->ipv6_pool, lease);
1acab09f 5564 lease->ia->cltt = cur_time;
9322442f 5565 write_ia(lease->ia);
98bd7ca0
DH
5566 }
5567}
5568
5569static void
5570ia_na_nomatch_release(const struct data_string *client_id,
5571 const struct data_string *iaaddr,
5572 u_int32_t *ia_na_id,
5573 struct packet *packet,
5574 char *reply_data,
5575 int *reply_ofs,
c382bc98
SK
5576 int reply_len)
5577{
98bd7ca0
DH
5578 char tmp_addr[INET6_ADDRSTRLEN];
5579 struct option_state *host_opt_state;
5580 int len;
5581
5582 log_info("Client %s releases address %s, which is not leased to it.",
5583 print_hex_1(client_id->len, client_id->data, 60),
5584 inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
5585
5586 /*
5587 * Create state for this IA_NA.
5588 */
5589 host_opt_state = NULL;
5590 if (!option_state_allocate(&host_opt_state, MDL)) {
c382bc98 5591 log_error("ia_na_nomatch_release: out of memory "
98bd7ca0
DH
5592 "allocating option_state.");
5593 goto exit;
5594 }
5595
5596 if (!set_status_code(STATUS_NoBinding,
5597 "Release for non-leased address.",
5598 host_opt_state)) {
5599 goto exit;
5600 }
5601
5602 /*
5603 * Insure we have enough space
5604 */
5605 if (reply_len < (*reply_ofs + 16)) {
c382bc98 5606 log_error("ia_na_nomatch_release: "
98bd7ca0
DH
5607 "out of space for reply packet.");
5608 goto exit;
5609 }
5610
5611 /*
5612 * Put our status code into the reply packet.
5613 */
5614 len = store_options6(reply_data+(*reply_ofs)+16,
5615 reply_len-(*reply_ofs)-16,
5616 host_opt_state, packet,
5617 required_opts_STATUS_CODE, NULL);
5618
5619 /*
5620 * Store the non-encapsulated option data for this
5621 * IA_NA into our reply packet. Defined in RFC 3315,
5622 * section 22.4.
5623 */
5624 /* option number */
28868515 5625 putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_NA);
98bd7ca0 5626 /* option length */
28868515 5627 putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
98bd7ca0
DH
5628 /* IA_NA, copied from the client */
5629 memcpy(reply_data+(*reply_ofs)+4, ia_na_id, 4);
5630 /* t1 and t2, odd that we need them, but here it is */
28868515
SK
5631 putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
5632 putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
98bd7ca0
DH
5633
5634 /*
5635 * Get ready for next IA_NA.
5636 */
5637 *reply_ofs += (len + 16);
5638
5639exit:
5640 option_state_dereference(&host_opt_state, MDL);
5641}
5642
80c9fdb0
FD
5643static void
5644ia_pd_match_release(const struct data_string *client_id,
5645 const struct data_string *iapref,
1d17db44 5646 struct iasubopt *prefix)
80c9fdb0
FD
5647{
5648 char tmp_addr[INET6_ADDRSTRLEN];
5649
5650 log_info("Client %s releases prefix %s/%u",
5651 print_hex_1(client_id->len, client_id->data, 60),
5652 inet_ntop(AF_INET6, iapref->data + 9,
5653 tmp_addr, sizeof(tmp_addr)),
5654 (unsigned) getUChar(iapref->data + 8));
5655 if (prefix != NULL) {
9322442f 5656 release_lease6(prefix->ipv6_pool, prefix);
1acab09f 5657 prefix->ia->cltt = cur_time;
9322442f 5658 write_ia(prefix->ia);
80c9fdb0
FD
5659 }
5660}
5661
5662static void
5663ia_pd_nomatch_release(const struct data_string *client_id,
5664 const struct data_string *iapref,
5665 u_int32_t *ia_pd_id,
5666 struct packet *packet,
5667 char *reply_data,
5668 int *reply_ofs,
5669 int reply_len)
5670{
5671 char tmp_addr[INET6_ADDRSTRLEN];
5672 struct option_state *host_opt_state;
5673 int len;
5674
5675 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
5676 print_hex_1(client_id->len, client_id->data, 60),
5677 inet_ntop(AF_INET6, iapref->data + 9,
5678 tmp_addr, sizeof(tmp_addr)),
5679 (unsigned) getUChar(iapref->data + 8));
5680
5681 /*
5682 * Create state for this IA_PD.
5683 */
5684 host_opt_state = NULL;
5685 if (!option_state_allocate(&host_opt_state, MDL)) {
5686 log_error("ia_pd_nomatch_release: out of memory "
5687 "allocating option_state.");
5688 goto exit;
5689 }
5690
5691 if (!set_status_code(STATUS_NoBinding,
5692 "Release for non-leased prefix.",
5693 host_opt_state)) {
5694 goto exit;
5695 }
5696
5697 /*
5698 * Insure we have enough space
5699 */
5700 if (reply_len < (*reply_ofs + 16)) {
5701 log_error("ia_pd_nomatch_release: "
5702 "out of space for reply packet.");
5703 goto exit;
5704 }
5705
5706 /*
5707 * Put our status code into the reply packet.
5708 */
5709 len = store_options6(reply_data+(*reply_ofs)+16,
5710 reply_len-(*reply_ofs)-16,
5711 host_opt_state, packet,
5712 required_opts_STATUS_CODE, NULL);
5713
5714 /*
5715 * Store the non-encapsulated option data for this
5716 * IA_PD into our reply packet. Defined in RFC 3315,
5717 * section 22.4.
5718 */
5719 /* option number */
5720 putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_PD);
5721 /* option length */
5722 putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
5723 /* IA_PD, copied from the client */
5724 memcpy(reply_data+(*reply_ofs)+4, ia_pd_id, 4);
5725 /* t1 and t2, odd that we need them, but here it is */
5726 putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
5727 putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
5728
5729 /*
5730 * Get ready for next IA_PD.
5731 */
5732 *reply_ofs += (len + 16);
5733
5734exit:
5735 option_state_dereference(&host_opt_state, MDL);
5736}
5737
5738static void
5739iterate_over_ia_pd(struct data_string *reply_ret,
5740 struct packet *packet,
5741 const struct data_string *client_id,
5742 const struct data_string *server_id,
5743 const char *packet_type,
5744 void (*ia_pd_match)(),
5745 void (*ia_pd_nomatch)())
5746{
5747 struct data_string reply_new;
5748 int reply_len;
5749 struct option_state *opt_state;
5750 struct host_decl *packet_host;
5751 struct option_cache *ia;
5752 struct option_cache *oc;
5753 /* cli_enc_... variables come from the IA_PD options */
5754 struct data_string cli_enc_opt_data;
5755 struct option_state *cli_enc_opt_state;
5756 struct host_decl *host;
5757 struct option_state *host_opt_state;
5758 struct data_string iaprefix;
80c9fdb0
FD
5759 char reply_data[65536];
5760 int reply_ofs;
1d17db44 5761 struct iasubopt *prefix;
9322442f 5762 struct ia_xx *existing_ia_pd;
80c9fdb0
FD
5763 int i;
5764 struct data_string key;
5765 u_int32_t iaid;
5766
5767 /*
5768 * Initialize to empty values, in case we have to exit early.
5769 */
5770 memset(&reply_new, 0, sizeof(reply_new));
5771 opt_state = NULL;
5772 memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
5773 cli_enc_opt_state = NULL;
5774 memset(&iaprefix, 0, sizeof(iaprefix));
5775 host_opt_state = NULL;
5776 prefix = NULL;
5777
5778 /*
5779 * Compute the available length for the reply.
5780 */
5781 reply_len = sizeof(reply_data) - reply_ret->len;
5782 reply_ofs = 0;
5783
5784 /*
5785 * Find the host record that matches from the packet, if any.
5786 */
5787 packet_host = NULL;
5788 if (!find_hosts_by_uid(&packet_host,
5789 client_id->data, client_id->len, MDL)) {
5790 packet_host = NULL;
5791 /*
5792 * Note: In general, we don't expect a client to provide
5793 * enough information to match by option for these
5794 * types of messages, but if we don't have a UID
5795 * match we can check anyway.
5796 */
5797 if (!find_hosts_by_option(&packet_host,
5798 packet, packet->options, MDL)) {
5799 packet_host = NULL;
c900c5b2
DH
5800
5801 if (!find_hosts_by_duid_chaddr(&packet_host,
5802 client_id))
5803 packet_host = NULL;
80c9fdb0
FD
5804 }
5805 }
5806
5807 /*
5808 * Build our option state for reply.
5809 */
5810 opt_state = NULL;
5811 if (!option_state_allocate(&opt_state, MDL)) {
5812 log_error("iterate_over_ia_pd: no memory for option_state.");
5813 goto exit;
5814 }
5815 execute_statements_in_scope(NULL, packet, NULL, NULL,
5816 packet->options, opt_state,
a7341359 5817 &global_scope, root_group, NULL, NULL);
80c9fdb0
FD
5818
5819 /*
5820 * Loop through the IA_PD reported by the client, and deal with
5821 * prefixes reported as already in use.
5822 */
5823 for (ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
5824 ia != NULL; ia = ia->next) {
80c9fdb0
FD
5825
5826 if (!get_encapsulated_IA_state(&cli_enc_opt_state,
5827 &cli_enc_opt_data,
5828 packet, ia, IA_PD_OFFSET)) {
5829 goto exit;
5830 }
5831
5832 iaid = getULong(cli_enc_opt_data.data);
5833
5834 oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
5835 D6O_IAPREFIX);
5836 if (oc == NULL) {
5837 /* no prefix given for this IA_PD, ignore */
5838 option_state_dereference(&cli_enc_opt_state, MDL);
5839 data_string_forget(&cli_enc_opt_data, MDL);
5840 continue;
5841 }
5842
5843 for (; oc != NULL; oc = oc->next) {
5844 memset(&iaprefix, 0, sizeof(iaprefix));
5845 if (!evaluate_option_cache(&iaprefix, packet, NULL, NULL,
5846 packet->options, NULL,
5847 &global_scope, oc, MDL)) {
5848 log_error("iterate_over_ia_pd: "
5849 "error evaluating IAPREFIX.");
5850 goto exit;
5851 }
5852
5853 /*
5854 * Now we need to figure out which host record matches
c900c5b2
DH
5855 * this IA_PD and IAPREFIX (encapsulated option contents
5856 * matching a host record by option).
80c9fdb0
FD
5857 *
5858 * XXX: We don't currently track IA_PD separately, but
5859 * we will need to do this!
5860 */
5861 host = NULL;
5862 if (!find_hosts_by_option(&host, packet,
5863 cli_enc_opt_state, MDL)) {
5864 if (packet_host != NULL) {
5865 host = packet_host;
5866 } else {
5867 host = NULL;
5868 }
5869 }
5870 while (host != NULL) {
5871 if (host->fixed_prefix != NULL) {
5872 struct iaddrcidrnetlist *l;
5873 int plen = (int) getUChar(iaprefix.data + 8);
5874
5875 for (l = host->fixed_prefix; l != NULL;
5876 l = l->next) {
5877 if (plen != l->cidrnet.bits)
5878 continue;
5879 if (memcmp(iaprefix.data + 9,
5880 l->cidrnet.lo_addr.iabuf,
5881 16) == 0)
5882 break;
5883 }
5884 if ((l != NULL) && (iaprefix.len >= 17))
5885 break;
5886 }
5887 host = host->n_ipaddr;
5888 }
5889
5890 if ((host == NULL) && (iaprefix.len >= IAPREFIX_OFFSET)) {
5891 /*
5892 * Find existing IA_PD.
5893 */
5894 if (ia_make_key(&key, iaid,
5895 (char *)client_id->data,
5896 client_id->len,
5897 MDL) != ISC_R_SUCCESS) {
5898 log_fatal("iterate_over_ia_pd: no memory for "
5899 "key.");
5900 }
5901
5902 existing_ia_pd = NULL;
9322442f
FD
5903 if (ia_hash_lookup(&existing_ia_pd, ia_pd_active,
5904 (unsigned char *)key.data,
5905 key.len, MDL)) {
80c9fdb0
FD
5906 /*
5907 * Make sure this prefix is in the IA_PD.
5908 */
5909 for (i = 0;
1d17db44 5910 i < existing_ia_pd->num_iasubopt;
80c9fdb0 5911 i++) {
1d17db44 5912 struct iasubopt *tmp;
80c9fdb0
FD
5913 u_int8_t plen;
5914
5915 plen = getUChar(iaprefix.data + 8);
1d17db44 5916 tmp = existing_ia_pd->iasubopt[i];
80c9fdb0 5917 if ((tmp->plen == plen) &&
9322442f 5918 (memcmp(&tmp->addr,
80c9fdb0
FD
5919 iaprefix.data + 9,
5920 16) == 0)) {
1d17db44
FD
5921 iasubopt_reference(&prefix,
5922 tmp, MDL);
80c9fdb0
FD
5923 break;
5924 }
5925 }
5926 }
5927
5928 data_string_forget(&key, MDL);
5929 }
5930
5931 if ((host != NULL) || (prefix != NULL)) {
5932 ia_pd_match(client_id, &iaprefix, prefix);
5933 } else {
5934 ia_pd_nomatch(client_id, &iaprefix,
5935 (u_int32_t *)cli_enc_opt_data.data,
5936 packet, reply_data, &reply_ofs,
5937 reply_len - reply_ofs);
5938 }
5939
5940 if (prefix != NULL) {
1d17db44 5941 iasubopt_dereference(&prefix, MDL);
80c9fdb0
FD
5942 }
5943
5944 data_string_forget(&iaprefix, MDL);
5945 }
5946
5947 option_state_dereference(&cli_enc_opt_state, MDL);
5948 data_string_forget(&cli_enc_opt_data, MDL);
5949 }
5950
5951 /*
5952 * Return our reply to the caller.
5953 * The IA_NA routine has already filled at least the header.
5954 */
5955 reply_new.len = reply_ret->len + reply_ofs;
5956 if (!buffer_allocate(&reply_new.buffer, reply_new.len, MDL)) {
5957 log_fatal("No memory to store reply.");
5958 }
5959 reply_new.data = reply_new.buffer->data;
5960 memcpy(reply_new.buffer->data,
5961 reply_ret->buffer->data, reply_ret->len);
5962 memcpy(reply_new.buffer->data + reply_ret->len,
5963 reply_data, reply_ofs);
5964 data_string_forget(reply_ret, MDL);
5965 data_string_copy(reply_ret, &reply_new, MDL);
5966 data_string_forget(&reply_new, MDL);
5967
5968exit:
5969 if (prefix != NULL) {
1d17db44 5970 iasubopt_dereference(&prefix, MDL);
80c9fdb0
FD
5971 }
5972 if (host_opt_state != NULL) {
5973 option_state_dereference(&host_opt_state, MDL);
5974 }
5975 if (iaprefix.buffer != NULL) {
5976 data_string_forget(&iaprefix, MDL);
5977 }
5978 if (cli_enc_opt_state != NULL) {
5979 option_state_dereference(&cli_enc_opt_state, MDL);
5980 }
5981 if (cli_enc_opt_data.buffer != NULL) {
5982 data_string_forget(&cli_enc_opt_data, MDL);
5983 }
5984 if (opt_state != NULL) {
5985 option_state_dereference(&opt_state, MDL);
5986 }
5987}
5988
98bd7ca0 5989/*
9322442f 5990 * Release means a client is done with the leases.
98bd7ca0
DH
5991 */
5992
72073970 5993/* TODO: reject unicast messages, unless we set unicast option */
98bd7ca0
DH
5994static void
5995dhcpv6_release(struct data_string *reply, struct packet *packet) {
5996 struct data_string client_id;
5997 struct data_string server_id;
5998
5999 /*
6000 * Validate our input.
6001 */
6002 if (!valid_client_resp(packet, &client_id, &server_id)) {
6003 return;
6004 }
6005
6006 /*
6007 * And operate on each IA_NA in this packet.
6008 */
6009 iterate_over_ia_na(reply, packet, &client_id, &server_id, "Release",
6010 ia_na_match_release, ia_na_nomatch_release);
6011
80c9fdb0
FD
6012 /*
6013 * And operate on each IA_PD in this packet.
6014 */
6015 iterate_over_ia_pd(reply, packet, &client_id, &server_id, "Release",
6016 ia_pd_match_release, ia_pd_nomatch_release);
6017
98bd7ca0
DH
6018 data_string_forget(&server_id, MDL);
6019 data_string_forget(&client_id, MDL);
6020}
6021
6022/*
6023 * Information-Request is used by clients who have obtained an address
6024 * from other means, but want configuration information from the server.
6025 */
6026
98bd7ca0
DH
6027static void
6028dhcpv6_information_request(struct data_string *reply, struct packet *packet) {
6029 struct data_string client_id;
6030 struct data_string server_id;
6031
6032 /*
6033 * Validate our input.
6034 */
6035 if (!valid_client_info_req(packet, &server_id)) {
6036 return;
6037 }
6038
6039 /*
6040 * Get our client ID, if there is one.
6041 */
6042 memset(&client_id, 0, sizeof(client_id));
6043 if (get_client_id(packet, &client_id) != ISC_R_SUCCESS) {
6044 data_string_forget(&client_id, MDL);
6045 }
6046
6047 /*
6048 * Use the lease_to_client() function. This will work fine,
6049 * because the valid_client_info_req() insures that we
80c9fdb0
FD
6050 * don't have any IA that would cause us to allocate
6051 * resources to the client.
98bd7ca0 6052 */
4f963ddc
FD
6053 lease_to_client(reply, packet, &client_id,
6054 server_id.data != NULL ? &server_id : NULL);
98bd7ca0
DH
6055
6056 /*
6057 * Cleanup.
6058 */
6059 if (client_id.data != NULL) {
6060 data_string_forget(&client_id, MDL);
6061 }
6062 data_string_forget(&server_id, MDL);
6063}
6064
6065/*
6066 * The Relay-forw message is sent by relays. It typically contains a
6067 * single option, which encapsulates an entire packet.
6068 *
6069 * We need to build an encapsulated reply.
6070 */
6071
6072/* XXX: this is very, very similar to do_packet6(), and should probably
6073 be combined in a clever way */
6074static void
6075dhcpv6_relay_forw(struct data_string *reply_ret, struct packet *packet) {
98bd7ca0
DH
6076 struct option_cache *oc;
6077 struct data_string enc_opt_data;
6078 struct packet *enc_packet;
6079 unsigned char msg_type;
5279b8f3
DH
6080 const struct dhcpv6_packet *msg;
6081 const struct dhcpv6_relay_packet *relay;
98bd7ca0
DH
6082 struct data_string enc_reply;
6083 char link_addr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6084 char peer_addr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
2b964ac0
FD
6085 struct data_string a_opt, packet_ero;
6086 struct option_state *opt_state;
6087 static char reply_data[65536];
6088 struct dhcpv6_relay_packet *reply;
6089 int reply_ofs;
98bd7ca0
DH
6090
6091 /*
20ae1aff 6092 * Initialize variables for early exit.
98bd7ca0 6093 */
93c769ce 6094 opt_state = NULL;
2b964ac0
FD
6095 memset(&a_opt, 0, sizeof(a_opt));
6096 memset(&packet_ero, 0, sizeof(packet_ero));
93c769ce
FD
6097 memset(&enc_reply, 0, sizeof(enc_reply));
6098 memset(&enc_opt_data, 0, sizeof(enc_opt_data));
6099 enc_packet = NULL;
98bd7ca0
DH
6100
6101 /*
6102 * Get our encapsulated relay message.
6103 */
6104 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_RELAY_MSG);
6105 if (oc == NULL) {
6106 inet_ntop(AF_INET6, &packet->dhcpv6_link_address,
6107 link_addr, sizeof(link_addr));
6108 inet_ntop(AF_INET6, &packet->dhcpv6_peer_address,
6109 peer_addr, sizeof(peer_addr));
6110 log_info("Relay-forward from %s with link address=%s and "
6111 "peer address=%s missing Relay Message option.",
6112 piaddr(packet->client_addr), link_addr, peer_addr);
6113 goto exit;
6114 }
6115
98bd7ca0
DH
6116 if (!evaluate_option_cache(&enc_opt_data, NULL, NULL, NULL,
6117 NULL, NULL, &global_scope, oc, MDL)) {
6118 log_error("dhcpv6_forw_relay: error evaluating "
6119 "relayed message.");
6120 goto exit;
6121 }
6122
28868515 6123 if (!packet6_len_okay((char *)enc_opt_data.data, enc_opt_data.len)) {
98bd7ca0
DH
6124 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
6125 goto exit;
6126 }
6127
6128 /*
6129 * Build a packet structure from this encapsulated packet.
6130 */
6131 enc_packet = NULL;
6132 if (!packet_allocate(&enc_packet, MDL)) {
6133 log_error("dhcpv6_forw_relay: "
6134 "no memory for encapsulated packet.");
6135 goto exit;
6136 }
6137
6138 if (!option_state_allocate(&enc_packet->options, MDL)) {
6139 log_error("dhcpv6_forw_relay: "
6140 "no memory for encapsulated packet's options.");
6141 goto exit;
6142 }
6143
6144 enc_packet->client_port = packet->client_port;
6145 enc_packet->client_addr = packet->client_addr;
4dc5a6b1 6146 interface_reference(&enc_packet->interface, packet->interface, MDL);
98bd7ca0
DH
6147 enc_packet->dhcpv6_container_packet = packet;
6148
6149 msg_type = enc_opt_data.data[0];
5279b8f3
DH
6150 if ((msg_type == DHCPV6_RELAY_FORW) ||
6151 (msg_type == DHCPV6_RELAY_REPL)) {
b342f2e7 6152 int relaylen = (int)(offsetof(struct dhcpv6_relay_packet, options));
5279b8f3
DH
6153 relay = (struct dhcpv6_relay_packet *)enc_opt_data.data;
6154 enc_packet->dhcpv6_msg_type = relay->msg_type;
98bd7ca0 6155
5279b8f3
DH
6156 /* relay-specific data */
6157 enc_packet->dhcpv6_hop_count = relay->hop_count;
98bd7ca0
DH
6158 memcpy(&enc_packet->dhcpv6_link_address,
6159 relay->link_address, sizeof(relay->link_address));
6160 memcpy(&enc_packet->dhcpv6_peer_address,
6161 relay->peer_address, sizeof(relay->peer_address));
6162
5279b8f3
DH
6163 if (!parse_option_buffer(enc_packet->options,
6164 relay->options,
b342f2e7 6165 enc_opt_data.len - relaylen,
5279b8f3
DH
6166 &dhcpv6_universe)) {
6167 /* no logging here, as parse_option_buffer() logs all
6168 cases where it fails */
6169 goto exit;
6170 }
6171 } else {
b342f2e7 6172 int msglen = (int)(offsetof(struct dhcpv6_packet, options));
5279b8f3
DH
6173 msg = (struct dhcpv6_packet *)enc_opt_data.data;
6174 enc_packet->dhcpv6_msg_type = msg->msg_type;
6175
6176 /* message-specific data */
6177 memcpy(enc_packet->dhcpv6_transaction_id,
6178 msg->transaction_id,
6179 sizeof(enc_packet->dhcpv6_transaction_id));
6180
6181 if (!parse_option_buffer(enc_packet->options,
6182 msg->options,
b342f2e7 6183 enc_opt_data.len - msglen,
5279b8f3
DH
6184 &dhcpv6_universe)) {
6185 /* no logging here, as parse_option_buffer() logs all
6186 cases where it fails */
6187 goto exit;
6188 }
6189 }
98bd7ca0
DH
6190
6191 /*
6192 * This is recursive. It is possible to exceed maximum packet size.
6193 * XXX: This will cause the packet send to fail.
6194 */
6195 build_dhcpv6_reply(&enc_reply, enc_packet);
6196
6197 /*
6198 * If we got no encapsulated data, then it is discarded, and
6199 * our reply-forw is also discarded.
6200 */
6201 if (enc_reply.data == NULL) {
6202 goto exit;
6203 }
6204
6205 /*
2b964ac0
FD
6206 * Now we can use the reply_data buffer.
6207 * Packet header stuff all comes from the forward message.
6208 */
6209 reply = (struct dhcpv6_relay_packet *)reply_data;
6210 reply->msg_type = DHCPV6_RELAY_REPL;
6211 reply->hop_count = packet->dhcpv6_hop_count;
6212 memcpy(reply->link_address, &packet->dhcpv6_link_address,
6213 sizeof(reply->link_address));
6214 memcpy(reply->peer_address, &packet->dhcpv6_peer_address,
6215 sizeof(reply->peer_address));
a3528574 6216 reply_ofs = (int)(offsetof(struct dhcpv6_relay_packet, options));
2b964ac0
FD
6217
6218 /*
6219 * Get the reply option state.
6220 */
6221 opt_state = NULL;
6222 if (!option_state_allocate(&opt_state, MDL)) {
6223 log_error("dhcpv6_relay_forw: no memory for option state.");
6224 goto exit;
6225 }
6226
6227 /*
6228 * Append the interface-id if present.
98bd7ca0 6229 */
2b964ac0
FD
6230 oc = lookup_option(&dhcpv6_universe, packet->options,
6231 D6O_INTERFACE_ID);
98bd7ca0 6232 if (oc != NULL) {
2b964ac0
FD
6233 if (!evaluate_option_cache(&a_opt, packet,
6234 NULL, NULL,
6235 packet->options, NULL,
6236 &global_scope, oc, MDL)) {
6237 log_error("dhcpv6_relay_forw: error evaluating "
6238 "Interface ID.");
6239 goto exit;
6240 }
6241 if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
6242 (unsigned char *)a_opt.data,
6243 a_opt.len,
6244 D6O_INTERFACE_ID, 0)) {
6245 log_error("dhcpv6_relay_forw: error saving "
98bd7ca0
DH
6246 "Interface ID.");
6247 goto exit;
6248 }
2b964ac0 6249 data_string_forget(&a_opt, MDL);
98bd7ca0
DH
6250 }
6251
98bd7ca0 6252 /*
2b964ac0 6253 * Append our encapsulated stuff for caller.
98bd7ca0 6254 */
2b964ac0
FD
6255 if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
6256 (unsigned char *)enc_reply.data,
6257 enc_reply.len,
6258 D6O_RELAY_MSG, 0)) {
6259 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
6260 goto exit;
98bd7ca0 6261 }
2b964ac0
FD
6262
6263 /*
6264 * Get the ERO if any.
98bd7ca0 6265 */
2b964ac0
FD
6266 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_ERO);
6267 if (oc != NULL) {
6268 unsigned req;
6269 int i;
6270
6271 if (!evaluate_option_cache(&packet_ero, packet,
6272 NULL, NULL,
6273 packet->options, NULL,
6274 &global_scope, oc, MDL) ||
6275 (packet_ero.len & 1)) {
6276 log_error("dhcpv6_relay_forw: error evaluating ERO.");
6277 goto exit;
6278 }
6279
6280 /* Decode and apply the ERO. */
6281 for (i = 0; i < packet_ero.len; i += 2) {
6282 req = getUShort(packet_ero.data + i);
6283 /* Already in the reply? */
6284 oc = lookup_option(&dhcpv6_universe, opt_state, req);
6285 if (oc != NULL)
6286 continue;
6287 /* Get it from the packet if present. */
6288 oc = lookup_option(&dhcpv6_universe,
6289 packet->options,
6290 req);
6291 if (oc == NULL)
6292 continue;
6293 if (!evaluate_option_cache(&a_opt, packet,
6294 NULL, NULL,
6295 packet->options, NULL,
6296 &global_scope, oc, MDL)) {
6297 log_error("dhcpv6_relay_forw: error "
6298 "evaluating option %u.", req);
6299 goto exit;
6300 }
6301 if (!save_option_buffer(&dhcpv6_universe,
6302 opt_state,
6303 NULL,
6304 (unsigned char *)a_opt.data,
6305 a_opt.len,
6306 req,
6307 0)) {
6308 log_error("dhcpv6_relay_forw: error saving "
6309 "option %u.", req);
6310 goto exit;
6311 }
6312 data_string_forget(&a_opt, MDL);
6313 }
98bd7ca0 6314 }
2b964ac0
FD
6315
6316 reply_ofs += store_options6(reply_data + reply_ofs,
6317 sizeof(reply_data) - reply_ofs,
6318 opt_state, packet,
6319 required_opts_agent, &packet_ero);
6320
6321 /*
6322 * Return our reply to the caller.
6323 */
6324 reply_ret->len = reply_ofs;
98bd7ca0
DH
6325 reply_ret->buffer = NULL;
6326 if (!buffer_allocate(&reply_ret->buffer, reply_ret->len, MDL)) {
6327 log_fatal("No memory to store reply.");
6328 }
6329 reply_ret->data = reply_ret->buffer->data;
2b964ac0 6330 memcpy(reply_ret->buffer->data, reply_data, reply_ofs);
98bd7ca0
DH
6331
6332exit:
2b964ac0
FD
6333 if (opt_state != NULL)
6334 option_state_dereference(&opt_state, MDL);
6335 if (a_opt.data != NULL) {
6336 data_string_forget(&a_opt, MDL);
6337 }
6338 if (packet_ero.data != NULL) {
6339 data_string_forget(&packet_ero, MDL);
98bd7ca0
DH
6340 }
6341 if (enc_reply.data != NULL) {
6342 data_string_forget(&enc_reply, MDL);
6343 }
6344 if (enc_opt_data.data != NULL) {
6345 data_string_forget(&enc_opt_data, MDL);
6346 }
6347 if (enc_packet != NULL) {
6348 packet_dereference(&enc_packet, MDL);
6349 }
6350}
6351
6352static void
6353dhcpv6_discard(struct packet *packet) {
6354 /* INSIST(packet->msg_type > 0); */
6355 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
6356
6357 log_debug("Discarding %s from %s; message type not handled by server",
6358 dhcpv6_type_names[packet->dhcpv6_msg_type],
6359 piaddr(packet->client_addr));
6360}
6361
6362static void
6363build_dhcpv6_reply(struct data_string *reply, struct packet *packet) {
6364 memset(reply, 0, sizeof(*reply));
01fa619f 6365
619304cd
SR
6366 /* I would like to classify the client once here, but
6367 * as I don't want to classify all of the incoming packets
6368 * I need to do it before handling specific types.
6369 * We don't need to classify if we are tossing the packet
6370 * or if it is a relay - the classification step will get
6371 * done when we process the inner client packet.
6372 */
01fa619f 6373
98bd7ca0
DH
6374 switch (packet->dhcpv6_msg_type) {
6375 case DHCPV6_SOLICIT:
619304cd 6376 classify_client(packet);
98bd7ca0
DH
6377 dhcpv6_solicit(reply, packet);
6378 break;
6379 case DHCPV6_ADVERTISE:
6380 dhcpv6_discard(packet);
6381 break;
6382 case DHCPV6_REQUEST:
619304cd 6383 classify_client(packet);
98bd7ca0
DH
6384 dhcpv6_request(reply, packet);
6385 break;
6386 case DHCPV6_CONFIRM:
619304cd 6387 classify_client(packet);
98bd7ca0
DH
6388 dhcpv6_confirm(reply, packet);
6389 break;
6390 case DHCPV6_RENEW:
619304cd 6391 classify_client(packet);
98bd7ca0
DH
6392 dhcpv6_renew(reply, packet);
6393 break;
6394 case DHCPV6_REBIND:
619304cd 6395 classify_client(packet);
98bd7ca0
DH
6396 dhcpv6_rebind(reply, packet);
6397 break;
6398 case DHCPV6_REPLY:
6399 dhcpv6_discard(packet);
6400 break;
6401 case DHCPV6_RELEASE:
619304cd 6402 classify_client(packet);
98bd7ca0
DH
6403 dhcpv6_release(reply, packet);
6404 break;
6405 case DHCPV6_DECLINE:
619304cd 6406 classify_client(packet);
98bd7ca0
DH
6407 dhcpv6_decline(reply, packet);
6408 break;
6409 case DHCPV6_RECONFIGURE:
6410 dhcpv6_discard(packet);
6411 break;
6412 case DHCPV6_INFORMATION_REQUEST:
619304cd 6413 classify_client(packet);
98bd7ca0
DH
6414 dhcpv6_information_request(reply, packet);
6415 break;
6416 case DHCPV6_RELAY_FORW:
6417 dhcpv6_relay_forw(reply, packet);
6418 break;
6419 case DHCPV6_RELAY_REPL:
6420 dhcpv6_discard(packet);
6421 break;
37ec5845 6422 case DHCPV6_LEASEQUERY:
619304cd 6423 classify_client(packet);
37ec5845
FD
6424 dhcpv6_leasequery(reply, packet);
6425 break;
6426 case DHCPV6_LEASEQUERY_REPLY:
6427 dhcpv6_discard(packet);
6428 break;
98bd7ca0
DH
6429 default:
6430 /* XXX: would be nice if we had "notice" level,
6431 as syslog, for this */
6432 log_info("Discarding unknown DHCPv6 message type %d "
6433 "from %s", packet->dhcpv6_msg_type,
6434 piaddr(packet->client_addr));
6435 }
6436}
6437
6438static void
6439log_packet_in(const struct packet *packet) {
6440 struct data_string s;
6441 u_int32_t tid;
6442 char tmp_addr[INET6_ADDRSTRLEN];
6443 const void *addr;
98bd7ca0
DH
6444
6445 memset(&s, 0, sizeof(s));
6446
6447 if (packet->dhcpv6_msg_type < dhcpv6_type_name_max) {
6448 data_string_sprintfa(&s, "%s message from %s port %d",
6449 dhcpv6_type_names[packet->dhcpv6_msg_type],
6450 piaddr(packet->client_addr),
6451 ntohs(packet->client_port));
6452 } else {
6453 data_string_sprintfa(&s,
6454 "Unknown message type %d from %s port %d",
6455 packet->dhcpv6_msg_type,
6456 piaddr(packet->client_addr),
6457 ntohs(packet->client_port));
6458 }
6459 if ((packet->dhcpv6_msg_type == DHCPV6_RELAY_FORW) ||
6460 (packet->dhcpv6_msg_type == DHCPV6_RELAY_REPL)) {
6461 addr = &packet->dhcpv6_link_address;
6462 data_string_sprintfa(&s, ", link address %s",
6463 inet_ntop(AF_INET6, addr,
6464 tmp_addr, sizeof(tmp_addr)));
6465 addr = &packet->dhcpv6_peer_address;
6466 data_string_sprintfa(&s, ", peer address %s",
6467 inet_ntop(AF_INET6, addr,
6468 tmp_addr, sizeof(tmp_addr)));
6469 } else {
6470 tid = 0;
6471 memcpy(((char *)&tid)+1, packet->dhcpv6_transaction_id, 3);
6472 data_string_sprintfa(&s, ", transaction ID 0x%06X", tid);
6473
6474/*
6475 oc = lookup_option(&dhcpv6_universe, packet->options,
6476 D6O_CLIENTID);
6477 if (oc != NULL) {
6478 memset(&tmp_ds, 0, sizeof(tmp_ds_));
6479 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
6480 packet->options, NULL,
6481 &global_scope, oc, MDL)) {
6482 log_error("Error evaluating Client Identifier");
6483 } else {
6484 data_strint_sprintf(&s, ", client ID %s",
6485
6486 data_string_forget(&tmp_ds, MDL);
6487 }
6488 }
6489*/
6490
6491 }
6492 log_info("%s", s.data);
6493
6494 data_string_forget(&s, MDL);
6495}
6496
6497void
6498dhcpv6(struct packet *packet) {
6499 struct data_string reply;
6500 struct sockaddr_in6 to_addr;
6501 int send_ret;
6502
6503 /*
6504 * Log a message that we received this packet.
6505 */
6506 log_packet_in(packet);
6507
6508 /*
6509 * Build our reply packet.
6510 */
6511 build_dhcpv6_reply(&reply, packet);
6512
6513 if (reply.data != NULL) {
6514 /*
6515 * Send our reply, if we have one.
6516 */
6517 memset(&to_addr, 0, sizeof(to_addr));
6518 to_addr.sin6_family = AF_INET6;
6519 if ((packet->dhcpv6_msg_type == DHCPV6_RELAY_FORW) ||
6520 (packet->dhcpv6_msg_type == DHCPV6_RELAY_REPL)) {
6521 to_addr.sin6_port = local_port;
6522 } else {
6523 to_addr.sin6_port = remote_port;
6524 }
fb30f3fc
SR
6525
6526#if defined (REPLY_TO_SOURCE_PORT)
6527 /*
6528 * This appears to have been included for testing so we would
6529 * not need a root client, but was accidently left in the
6530 * final code. We continue to include it in case
6531 * some users have come to rely upon it, but leave
6532 * it off by default as it's a bad idea.
6533 */
98bd7ca0 6534 to_addr.sin6_port = packet->client_port;
fb30f3fc
SR
6535#endif
6536
98bd7ca0
DH
6537 memcpy(&to_addr.sin6_addr, packet->client_addr.iabuf,
6538 sizeof(to_addr.sin6_addr));
6539
6540 log_info("Sending %s to %s port %d",
6541 dhcpv6_type_names[reply.data[0]],
6542 piaddr(packet->client_addr),
6543 ntohs(to_addr.sin6_port));
6544
6545 send_ret = send_packet6(packet->interface,
6546 reply.data, reply.len, &to_addr);
6547 if (send_ret != reply.len) {
6548 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
6549 send_ret, reply.len);
6550 }
6551 data_string_forget(&reply, MDL);
6552 }
6553}
6554
5279b8f3
DH
6555static void
6556seek_shared_host(struct host_decl **hp, struct shared_network *shared) {
6557 struct host_decl *nofixed = NULL;
6558 struct host_decl *seek, *hold = NULL;
6559
6560 /*
bd72740e
FD
6561 * Seek forward through fixed addresses for the right link.
6562 *
6563 * Note: how to do this for fixed prefixes???
5279b8f3
DH
6564 */
6565 host_reference(&hold, *hp, MDL);
6566 host_dereference(hp, MDL);
6567 seek = hold;
6568 while (seek != NULL) {
6569 if (seek->fixed_addr == NULL)
6570 nofixed = seek;
6571 else if (fixed_matches_shared(seek, shared))
6572 break;
6573
6574 seek = seek->n_ipaddr;
6575 }
6576
6577 if ((seek == NULL) && (nofixed != NULL))
6578 seek = nofixed;
6579
6580 if (seek != NULL)
6581 host_reference(hp, seek, MDL);
6582}
6583
6584static isc_boolean_t
6585fixed_matches_shared(struct host_decl *host, struct shared_network *shared) {
6586 struct subnet *subnet;
6587 struct data_string addr;
6588 isc_boolean_t matched;
6589 struct iaddr fixed;
6590
6591 if (host->fixed_addr == NULL)
6592 return ISC_FALSE;
6593
6594 memset(&addr, 0, sizeof(addr));
6595 if (!evaluate_option_cache(&addr, NULL, NULL, NULL, NULL, NULL,
6596 &global_scope, host->fixed_addr, MDL))
6597 return ISC_FALSE;
6598
6599 if (addr.len < 16) {
6600 data_string_forget(&addr, MDL);
6601 return ISC_FALSE;
6602 }
6603
6604 fixed.len = 16;
6605 memcpy(fixed.iabuf, addr.data, 16);
6606
6607 matched = ISC_FALSE;
6608 for (subnet = shared->subnets ; subnet != NULL ;
6609 subnet = subnet->next_sibling) {
6610 if (addr_eq(subnet_number(fixed, subnet->netmask),
6611 subnet->net)) {
6612 matched = ISC_TRUE;
6613 break;
6614 }
6615 }
6616
6617 data_string_forget(&addr, MDL);
6618 return matched;
6619}
6620
c900c5b2
DH
6621/*
6622 * find_host_by_duid_chaddr() synthesizes a DHCPv4-like 'hardware'
6623 * parameter from a DHCPv6 supplied DUID (client-identifier option),
6624 * and may seek to use client or relay supplied hardware addresses.
6625 */
6626static int
6627find_hosts_by_duid_chaddr(struct host_decl **host,
6628 const struct data_string *client_id) {
6629 static int once_htype;
6630 int htype, hlen;
6631 const unsigned char *chaddr;
6632
6633 /*
6634 * The DUID-LL and DUID-LLT must have a 2-byte DUID type and 2-byte
6635 * htype.
6636 */
6637 if (client_id->len < 4)
6638 return 0;
6639
6640 /*
6641 * The third and fourth octets of the DUID-LL and DUID-LLT
6642 * is the hardware type, but in 16 bits.
6643 */
6644 htype = getUShort(client_id->data + 2);
6645 hlen = 0;
fed0952f 6646 chaddr = NULL;
c900c5b2
DH
6647
6648 /* The first two octets of the DUID identify the type. */
6649 switch(getUShort(client_id->data)) {
6650 case DUID_LLT:
6651 if (client_id->len > 8) {
6652 hlen = client_id->len - 8;
6653 chaddr = client_id->data + 8;
6654 }
6655 break;
6656
6657 case DUID_LL:
6658 /*
6659 * Note that client_id->len must be greater than or equal
6660 * to four to get to this point in the function.
6661 */
6662 hlen = client_id->len - 4;
6663 chaddr = client_id->data + 4;
6664 break;
6665
6666 default:
c900c5b2
DH
6667 break;
6668 }
6669
e563ec2e 6670 if ((hlen == 0) || (hlen > HARDWARE_ADDR_LEN))
c900c5b2
DH
6671 return 0;
6672
6673 /*
6674 * XXX: DHCPv6 gives a 16-bit field for the htype. DHCPv4 gives an
6675 * 8-bit field. To change the semantics of the generic 'hardware'
6676 * structure, we would have to adjust many DHCPv4 sources (from
6677 * interface to DHCPv4 lease code), and we would have to update the
6678 * 'hardware' config directive (probably being reverse compatible and
6679 * providing a new upgrade/replacement primitive). This is a little
6680 * too much to change for now. Hopefully we will revisit this before
6681 * hardware types exceeding 8 bits are assigned.
6682 */
6683 if ((htype & 0xFF00) && !once_htype) {
6684 once_htype = 1;
6685 log_error("Attention: At least one client advertises a "
6686 "hardware type of %d, which exceeds the software "
6687 "limitation of 255.", htype);
6688 }
6689
6690 return find_hosts_by_haddr(host, htype, chaddr, hlen, MDL);
6691}
6692
fe5b0fdd
DH
6693#endif /* DHCPv6 */
6694