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