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