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