]> git.ipfire.org Git - thirdparty/dhcp.git/blob - server/dhcpv6.c
Improve NoAddrsAvail & co
[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 client_resources;
53 isc_boolean_t ia_addrs_included;
54 isc_boolean_t static_lease;
55 struct ia_na *ia_na;
56 struct ia_na *old_ia_na;
57 struct option_state *reply_ia;
58 struct data_string fixed;
59
60 /* IAADDR level persistent state */
61 struct iaaddr *lease;
62
63 /*
64 * "t1", "t2", preferred, and valid lifetimes records for calculating
65 * t1 and t2 (min/max).
66 */
67 u_int32_t renew, rebind, prefer, valid;
68
69 /* Client-requested valid and preferred lifetimes. */
70 u_int32_t client_valid, client_prefer;
71
72 /* Chosen values to transmit for valid and preferred lifetimes. */
73 u_int32_t send_valid, send_prefer;
74
75 /* Index into the data field that has been consumed. */
76 unsigned cursor;
77
78 union reply_buffer {
79 unsigned char data[65536];
80 struct dhcpv6_packet reply;
81 } buf;
82 };
83
84 /*
85 * Prototypes local to this file.
86 */
87 static int get_encapsulated_IA_state(struct option_state **enc_opt_state,
88 struct data_string *enc_opt_data,
89 struct packet *packet,
90 struct option_cache *oc,
91 int offset);
92 static void build_dhcpv6_reply(struct data_string *, struct packet *);
93 static isc_result_t shared_network_from_packet6(struct shared_network **shared,
94 struct packet *packet);
95 static void seek_shared_host(struct host_decl **hp,
96 struct shared_network *shared);
97 static isc_boolean_t fixed_matches_shared(struct host_decl *host,
98 struct shared_network *shared);
99 static isc_result_t reply_process_ia_na(struct reply_state *reply,
100 struct option_cache *ia);
101 static isc_result_t reply_process_addr(struct reply_state *reply,
102 struct option_cache *addr);
103 static isc_boolean_t address_is_owned(struct reply_state *reply,
104 struct iaddr *addr);
105 static isc_result_t reply_process_try_addr(struct reply_state *reply,
106 struct iaddr *addr);
107 static isc_result_t find_client_address(struct reply_state *reply);
108 static isc_result_t reply_process_is_addressed(struct reply_state *reply,
109 struct binding_scope **scope,
110 struct group *group);
111 static isc_result_t reply_process_send_addr(struct reply_state *reply,
112 struct iaddr *addr);
113 static struct iaaddr *lease_compare(struct iaaddr *alpha, struct iaaddr *beta);
114
115 /*
116 * This function returns the time since DUID time start for the
117 * given time_t value.
118 */
119 static u_int32_t
120 duid_time(time_t when) {
121 /*
122 * This time is modulo 2^32.
123 */
124 while ((when - DUID_TIME_EPOCH) > 4294967295u) {
125 /* use 2^31 to avoid spurious compiler warnings */
126 when -= 2147483648u;
127 when -= 2147483648u;
128 }
129
130 return when - DUID_TIME_EPOCH;
131 }
132
133
134 /*
135 * Server DUID.
136 *
137 * This must remain the same for the lifetime of this server, because
138 * clients return the server DUID that we sent them in Request packets.
139 *
140 * We pick the server DUID like this:
141 *
142 * 1. Check dhcpd.conf - any value the administrator has configured
143 * overrides any possible values.
144 * 2. Check the leases.txt - we want to use the previous value if
145 * possible.
146 * 3. Check if dhcpd.conf specifies a type of server DUID to use,
147 * and generate that type.
148 * 4. Generate a type 1 (time + hardware address) DUID.
149 */
150 static struct data_string server_duid;
151
152 /*
153 * Check if the server_duid has been set.
154 */
155 isc_boolean_t
156 server_duid_isset(void) {
157 return (server_duid.data != NULL);
158 }
159
160 /*
161 * Return the server_duid.
162 */
163 void
164 copy_server_duid(struct data_string *ds, const char *file, int line) {
165 data_string_copy(ds, &server_duid, file, line);
166 }
167
168 /*
169 * Set the server DUID to a specified value. This is used when
170 * the server DUID is stored in persistent memory (basically the
171 * leases.txt file).
172 */
173 void
174 set_server_duid(struct data_string *new_duid) {
175 /* INSIST(new_duid != NULL); */
176 /* INSIST(new_duid->data != NULL); */
177
178 if (server_duid_isset()) {
179 data_string_forget(&server_duid, MDL);
180 }
181 data_string_copy(&server_duid, new_duid, MDL);
182 }
183
184
185 /*
186 * Set the server DUID based on the D6O_SERVERID option. This handles
187 * the case where the administrator explicitly put it in the dhcpd.conf
188 * file.
189 */
190 isc_result_t
191 set_server_duid_from_option(void) {
192 struct option_state *opt_state;
193 struct option_cache *oc;
194 struct data_string option_duid;
195 isc_result_t ret_val;
196
197 opt_state = NULL;
198 if (!option_state_allocate(&opt_state, MDL)) {
199 log_fatal("No memory for server DUID.");
200 }
201
202 execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL,
203 opt_state, &global_scope, root_group, NULL);
204
205 oc = lookup_option(&dhcpv6_universe, opt_state, D6O_SERVERID);
206 if (oc == NULL) {
207 ret_val = ISC_R_NOTFOUND;
208 } else {
209 memset(&option_duid, 0, sizeof(option_duid));
210 if (!evaluate_option_cache(&option_duid, NULL, NULL, NULL,
211 opt_state, NULL, &global_scope,
212 oc, MDL)) {
213 ret_val = ISC_R_UNEXPECTED;
214 } else {
215 set_server_duid(&option_duid);
216 data_string_forget(&option_duid, MDL);
217 ret_val = ISC_R_SUCCESS;
218 }
219 }
220
221 option_state_dereference(&opt_state, MDL);
222
223 return ret_val;
224 }
225
226 /*
227 * DUID layout, as defined in RFC 3315, section 9.
228 *
229 * We support type 1 (hardware address plus time) and type 3 (hardware
230 * address).
231 *
232 * We can support type 2 for specific vendors in the future, if they
233 * publish the specification. And of course there may be additional
234 * types later.
235 */
236 static int server_duid_type = DUID_LLT;
237
238 /*
239 * Set the DUID type.
240 */
241 void
242 set_server_duid_type(int type) {
243 server_duid_type = type;
244 }
245
246 /*
247 * Generate a new server DUID. This is done if there was no DUID in
248 * the leases.txt or in the dhcpd.conf file.
249 */
250 isc_result_t
251 generate_new_server_duid(void) {
252 struct interface_info *p;
253 u_int32_t time_val;
254 struct data_string generated_duid;
255
256 /*
257 * Verify we have a type that we support.
258 */
259 if ((server_duid_type != DUID_LL) && (server_duid_type != DUID_LLT)) {
260 log_error("Invalid DUID type %d specified, "
261 "only LL and LLT types supported", server_duid_type);
262 return ISC_R_INVALIDARG;
263 }
264
265 /*
266 * Find an interface with a hardware address.
267 * Any will do. :)
268 */
269 for (p = interfaces; p != NULL; p = p->next) {
270 if (p->hw_address.hlen > 0) {
271 break;
272 }
273 }
274 if (p == NULL) {
275 return ISC_R_UNEXPECTED;
276 }
277
278 /*
279 * Build our DUID.
280 */
281 memset(&generated_duid, 0, sizeof(generated_duid));
282 if (server_duid_type == DUID_LLT) {
283 time_val = duid_time(time(NULL));
284 generated_duid.len = 8 + p->hw_address.hlen - 1;
285 if (!buffer_allocate(&generated_duid.buffer,
286 generated_duid.len, MDL)) {
287 log_fatal("No memory for server DUID.");
288 }
289 generated_duid.data = generated_duid.buffer->data;
290 putUShort(generated_duid.buffer->data, DUID_LLT);
291 putUShort(generated_duid.buffer->data + 2,
292 p->hw_address.hbuf[0]);
293 putULong(generated_duid.buffer->data + 4, time_val);
294 memcpy(generated_duid.buffer->data + 8,
295 p->hw_address.hbuf+1, p->hw_address.hlen-1);
296 } else if (server_duid_type == DUID_LL) {
297 generated_duid.len = 4 + p->hw_address.hlen - 1;
298 if (!buffer_allocate(&generated_duid.buffer,
299 generated_duid.len, MDL)) {
300 log_fatal("No memory for server DUID.");
301 }
302 generated_duid.data = generated_duid.buffer->data;
303 putUShort(generated_duid.buffer->data, DUID_LL);
304 putUShort(generated_duid.buffer->data + 2,
305 p->hw_address.hbuf[0]);
306 memcpy(generated_duid.buffer->data +4,
307 p->hw_address.hbuf+1, p->hw_address.hlen-1);
308 } else {
309 log_fatal("Unsupported server DUID type %d.", server_duid_type);
310 }
311
312 set_server_duid(&generated_duid);
313 data_string_forget(&generated_duid, MDL);
314
315 return ISC_R_SUCCESS;
316 }
317
318 /*
319 * Get the client identifier from the packet.
320 */
321 isc_result_t
322 get_client_id(struct packet *packet, struct data_string *client_id) {
323 struct option_cache *oc;
324
325 /*
326 * Verify our client_id structure is empty.
327 */
328 if ((client_id->data != NULL) || (client_id->len != 0)) {
329 return ISC_R_INVALIDARG;
330 }
331
332 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_CLIENTID);
333 if (oc == NULL) {
334 return ISC_R_NOTFOUND;
335 }
336
337 if (!evaluate_option_cache(client_id, packet, NULL, NULL,
338 packet->options, NULL,
339 &global_scope, oc, MDL)) {
340 return ISC_R_FAILURE;
341 }
342
343 return ISC_R_SUCCESS;
344 }
345
346 /*
347 * Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
348 *
349 * Servers MUST discard any Solicit messages that do not include a
350 * Client Identifier option or that do include a Server Identifier
351 * option.
352 */
353 int
354 valid_client_msg(struct packet *packet, struct data_string *client_id) {
355 int ret_val;
356 struct option_cache *oc;
357 struct data_string data;
358
359 ret_val = 0;
360 memset(client_id, 0, sizeof(*client_id));
361 memset(&data, 0, sizeof(data));
362
363 switch (get_client_id(packet, client_id)) {
364 case ISC_R_SUCCESS:
365 break;
366 case ISC_R_NOTFOUND:
367 log_debug("Discarding %s from %s; "
368 "client identifier missing",
369 dhcpv6_type_names[packet->dhcpv6_msg_type],
370 piaddr(packet->client_addr));
371 goto exit;
372 default:
373 log_error("Error processing %s from %s; "
374 "unable to evaluate Client Identifier",
375 dhcpv6_type_names[packet->dhcpv6_msg_type],
376 piaddr(packet->client_addr));
377 goto exit;
378 }
379
380 /*
381 * Required by RFC 3315, section 15.
382 */
383 if (packet->unicast) {
384 log_debug("Discarding %s from %s; packet sent unicast "
385 "(CLIENTID %s)",
386 dhcpv6_type_names[packet->dhcpv6_msg_type],
387 piaddr(packet->client_addr),
388 print_hex_1(client_id->len, client_id->data, 60));
389 goto exit;
390 }
391
392
393 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
394 if (oc != NULL) {
395 if (evaluate_option_cache(&data, packet, NULL, NULL,
396 packet->options, NULL,
397 &global_scope, oc, MDL)) {
398 log_debug("Discarding %s from %s; "
399 "server identifier found "
400 "(CLIENTID %s, SERVERID %s)",
401 dhcpv6_type_names[packet->dhcpv6_msg_type],
402 piaddr(packet->client_addr),
403 print_hex_1(client_id->len,
404 client_id->data, 60),
405 print_hex_2(data.len,
406 data.data, 60));
407 } else {
408 log_debug("Discarding %s from %s; "
409 "server identifier found "
410 "(CLIENTID %s)",
411 dhcpv6_type_names[packet->dhcpv6_msg_type],
412 print_hex_1(client_id->len,
413 client_id->data, 60),
414 piaddr(packet->client_addr));
415 }
416 goto exit;
417 }
418
419 /* looks good */
420 ret_val = 1;
421
422 exit:
423 if (data.len > 0) {
424 data_string_forget(&data, MDL);
425 }
426 if (!ret_val) {
427 if (client_id->len > 0) {
428 data_string_forget(client_id, MDL);
429 }
430 }
431 return ret_val;
432 }
433
434 /*
435 * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
436 * 15.9 (slightly different wording, but same meaning):
437 *
438 * Servers MUST discard any received Request message that meet any of
439 * the following conditions:
440 *
441 * - the message does not include a Server Identifier option.
442 * - the contents of the Server Identifier option do not match the
443 * server's DUID.
444 * - the message does not include a Client Identifier option.
445 */
446 int
447 valid_client_resp(struct packet *packet,
448 struct data_string *client_id,
449 struct data_string *server_id)
450 {
451 int ret_val;
452 struct option_cache *oc;
453
454 /* INSIST((duid.data != NULL) && (duid.len > 0)); */
455
456 ret_val = 0;
457 memset(client_id, 0, sizeof(*client_id));
458 memset(server_id, 0, sizeof(*server_id));
459
460 switch (get_client_id(packet, client_id)) {
461 case ISC_R_SUCCESS:
462 break;
463 case ISC_R_NOTFOUND:
464 log_debug("Discarding %s from %s; "
465 "client identifier missing",
466 dhcpv6_type_names[packet->dhcpv6_msg_type],
467 piaddr(packet->client_addr));
468 goto exit;
469 default:
470 log_error("Error processing %s from %s; "
471 "unable to evaluate Client Identifier",
472 dhcpv6_type_names[packet->dhcpv6_msg_type],
473 piaddr(packet->client_addr));
474 goto exit;
475 }
476
477 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
478 if (oc == NULL) {
479 log_debug("Discarding %s from %s: "
480 "server identifier missing (CLIENTID %s)",
481 dhcpv6_type_names[packet->dhcpv6_msg_type],
482 piaddr(packet->client_addr),
483 print_hex_1(client_id->len, client_id->data, 60));
484 goto exit;
485 }
486 if (!evaluate_option_cache(server_id, packet, NULL, NULL,
487 packet->options, NULL,
488 &global_scope, oc, MDL)) {
489 log_error("Error processing %s from %s; "
490 "unable to evaluate Server Identifier (CLIENTID %s)",
491 dhcpv6_type_names[packet->dhcpv6_msg_type],
492 piaddr(packet->client_addr),
493 print_hex_1(client_id->len, client_id->data, 60));
494 goto exit;
495 }
496 if ((server_duid.len != server_id->len) ||
497 (memcmp(server_duid.data, server_id->data, server_duid.len) != 0)) {
498 log_debug("Discarding %s from %s; "
499 "not our server identifier "
500 "(CLIENTID %s, SERVERID %s, server DUID %s)",
501 dhcpv6_type_names[packet->dhcpv6_msg_type],
502 piaddr(packet->client_addr),
503 print_hex_1(client_id->len, client_id->data, 60),
504 print_hex_2(server_id->len, server_id->data, 60),
505 print_hex_3(server_duid.len, server_duid.data, 60));
506 goto exit;
507 }
508
509 /* looks good */
510 ret_val = 1;
511
512 exit:
513 if (!ret_val) {
514 if (server_id->len > 0) {
515 data_string_forget(server_id, MDL);
516 }
517 if (client_id->len > 0) {
518 data_string_forget(client_id, MDL);
519 }
520 }
521 return ret_val;
522 }
523
524 /*
525 * Information request validation, defined in RFC 3315, section 15.12:
526 *
527 * Servers MUST discard any received Information-request message that
528 * meets any of the following conditions:
529 *
530 * - The message includes a Server Identifier option and the DUID in
531 * the option does not match the server's DUID.
532 *
533 * - The message includes an IA option.
534 */
535 int
536 valid_client_info_req(struct packet *packet, struct data_string *server_id) {
537 int ret_val;
538 struct option_cache *oc;
539 struct data_string client_id;
540 char client_id_str[80]; /* print_hex_1() uses maximum 60 characters,
541 plus a few more for extra information */
542
543 ret_val = 0;
544 memset(server_id, 0, sizeof(*server_id));
545
546 /*
547 * Make a string that we can print out to give more
548 * information about the client if we need to.
549 *
550 * By RFC 3315, Section 18.1.5 clients SHOULD have a
551 * client-id on an Information-request packet, but it
552 * is not strictly necessary.
553 */
554 if (get_client_id(packet, &client_id) == ISC_R_SUCCESS) {
555 snprintf(client_id_str, sizeof(client_id_str), " (CLIENTID %s)",
556 print_hex_1(client_id.len, client_id.data, 60));
557 data_string_forget(&client_id, MDL);
558 } else {
559 client_id_str[0] = '\0';
560 }
561
562 /*
563 * Required by RFC 3315, section 15.
564 */
565 if (packet->unicast) {
566 log_debug("Discarding %s from %s; packet sent unicast%s",
567 dhcpv6_type_names[packet->dhcpv6_msg_type],
568 piaddr(packet->client_addr), client_id_str);
569 goto exit;
570 }
571
572 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
573 if (oc != NULL) {
574 log_debug("Discarding %s from %s; "
575 "IA_NA option present%s",
576 dhcpv6_type_names[packet->dhcpv6_msg_type],
577 piaddr(packet->client_addr), client_id_str);
578 goto exit;
579 }
580 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_TA);
581 if (oc != NULL) {
582 log_debug("Discarding %s from %s; "
583 "IA_TA option present%s",
584 dhcpv6_type_names[packet->dhcpv6_msg_type],
585 piaddr(packet->client_addr), client_id_str);
586 goto exit;
587 }
588 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
589 if (oc != NULL) {
590 log_debug("Discarding %s from %s; "
591 "IA_PD option present%s",
592 dhcpv6_type_names[packet->dhcpv6_msg_type],
593 piaddr(packet->client_addr), client_id_str);
594 goto exit;
595 }
596
597 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
598 if (oc != NULL) {
599 if (!evaluate_option_cache(server_id, packet, NULL, NULL,
600 packet->options, NULL,
601 &global_scope, oc, MDL)) {
602 log_error("Error processing %s from %s; "
603 "unable to evaluate Server Identifier%s",
604 dhcpv6_type_names[packet->dhcpv6_msg_type],
605 piaddr(packet->client_addr), client_id_str);
606 goto exit;
607 }
608 if ((server_duid.len != server_id->len) ||
609 (memcmp(server_duid.data, server_id->data,
610 server_duid.len) != 0)) {
611 log_debug("Discarding %s from %s; "
612 "not our server identifier "
613 "(SERVERID %s, server DUID %s)%s",
614 dhcpv6_type_names[packet->dhcpv6_msg_type],
615 piaddr(packet->client_addr),
616 print_hex_1(server_id->len,
617 server_id->data, 60),
618 print_hex_2(server_duid.len,
619 server_duid.data, 60),
620 client_id_str);
621 goto exit;
622 }
623 }
624
625 /* looks good */
626 ret_val = 1;
627
628 exit:
629 if (!ret_val) {
630 if (server_id->len > 0) {
631 data_string_forget(server_id, MDL);
632 }
633 }
634 return ret_val;
635 }
636
637 /*
638 * Options that we want to send, in addition to what was requested
639 * via the ORO.
640 */
641 static const int required_opts[] = {
642 D6O_CLIENTID,
643 D6O_SERVERID,
644 D6O_STATUS_CODE,
645 D6O_PREFERENCE,
646 0
647 };
648 static const int required_opts_NAA[] = {
649 D6O_CLIENTID,
650 D6O_SERVERID,
651 D6O_STATUS_CODE,
652 0
653 };
654 static const int required_opts_solicit[] = {
655 D6O_CLIENTID,
656 D6O_SERVERID,
657 D6O_IA_NA,
658 D6O_IA_TA,
659 D6O_IA_PD,
660 D6O_RAPID_COMMIT,
661 D6O_STATUS_CODE,
662 D6O_VENDOR_OPTS,
663 D6O_RECONF_ACCEPT,
664 D6O_PREFERENCE,
665 0
666 };
667 static const int required_opts_IA_NA[] = {
668 D6O_IAADDR,
669 D6O_STATUS_CODE,
670 D6O_VENDOR_OPTS,
671 0
672 };
673 /*
674 static const int required_opts_IA_TA[] = {
675 D6O_IAADDR,
676 D6O_STATUS_CODE,
677 D6O_VENDOR_OPTS,
678 0
679 };
680 static const int required_opts_IA_PD[] = {
681 D6O_IAPREFIX,
682 D6O_STATUS_CODE,
683 D6O_VENDOR_OPTS,
684 0
685 };
686 */
687 static const int required_opts_STATUS_CODE[] = {
688 D6O_STATUS_CODE,
689 0
690 };
691
692 /*
693 * Extracts from packet contents an IA_* option, storing the IA structure
694 * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
695 * in enc_opt_state for later lookup and evaluation. The 'offset' indicates
696 * where in the IA_* the DHCPv6 options commence.
697 */
698 static int
699 get_encapsulated_IA_state(struct option_state **enc_opt_state,
700 struct data_string *enc_opt_data,
701 struct packet *packet,
702 struct option_cache *oc,
703 int offset)
704 {
705 /*
706 * Get the raw data for the encapsulated options.
707 */
708 memset(enc_opt_data, 0, sizeof(*enc_opt_data));
709 if (!evaluate_option_cache(enc_opt_data, packet,
710 NULL, NULL, packet->options, NULL,
711 &global_scope, oc, MDL)) {
712 log_error("get_encapsulated_IA_state: "
713 "error evaluating raw option.");
714 return 0;
715 }
716 if (enc_opt_data->len < offset) {
717 log_error("get_encapsulated_IA_state: raw option too small.");
718 data_string_forget(enc_opt_data, MDL);
719 return 0;
720 }
721
722 /*
723 * Now create the option state structure, and pass it to the
724 * function that parses options.
725 */
726 *enc_opt_state = NULL;
727 if (!option_state_allocate(enc_opt_state, MDL)) {
728 log_error("get_encapsulated_IA_state: no memory for options.");
729 data_string_forget(enc_opt_data, MDL);
730 return 0;
731 }
732 if (!parse_option_buffer(*enc_opt_state,
733 enc_opt_data->data + offset,
734 enc_opt_data->len - offset,
735 &dhcpv6_universe)) {
736 log_error("get_encapsulated_IA_state: error parsing options.");
737 option_state_dereference(enc_opt_state, MDL);
738 data_string_forget(enc_opt_data, MDL);
739 return 0;
740 }
741
742 return 1;
743 }
744
745 static int
746 set_status_code(u_int16_t status_code, const char *status_message,
747 struct option_state *opt_state)
748 {
749 struct data_string d;
750 int ret_val;
751
752 memset(&d, 0, sizeof(d));
753 d.len = sizeof(status_code) + strlen(status_message);
754 if (!buffer_allocate(&d.buffer, d.len, MDL)) {
755 log_fatal("set_status_code: no memory for status code.");
756 }
757 d.data = d.buffer->data;
758 putUShort(d.buffer->data, status_code);
759 memcpy(d.buffer->data + sizeof(status_code),
760 status_message, d.len - sizeof(status_code));
761 if (!save_option_buffer(&dhcpv6_universe, opt_state,
762 d.buffer, (unsigned char *)d.data, d.len,
763 D6O_STATUS_CODE, 0)) {
764 log_error("set_status_code: error saving status code.");
765 ret_val = 0;
766 } else {
767 ret_val = 1;
768 }
769 data_string_forget(&d, MDL);
770 return ret_val;
771 }
772
773 /*
774 * We have a set of operations we do to set up the reply packet, which
775 * is the same for many message types.
776 */
777 static int
778 start_reply(struct packet *packet,
779 const struct data_string *client_id,
780 const struct data_string *server_id,
781 struct option_state **opt_state,
782 struct dhcpv6_packet *reply)
783 {
784 struct option_cache *oc;
785 const unsigned char *server_id_data;
786 int server_id_len;
787
788 /*
789 * Build our option state for reply.
790 */
791 *opt_state = NULL;
792 if (!option_state_allocate(opt_state, MDL)) {
793 log_error("start_reply: no memory for option_state.");
794 return 0;
795 }
796 execute_statements_in_scope(NULL, packet, NULL, NULL,
797 packet->options, *opt_state,
798 &global_scope, root_group, NULL);
799
800 /*
801 * A small bit of special handling for Solicit messages.
802 *
803 * We could move the logic into a flag, but for now just check
804 * explicitly.
805 */
806 if (packet->dhcpv6_msg_type == DHCPV6_SOLICIT) {
807 reply->msg_type = DHCPV6_ADVERTISE;
808
809 /*
810 * If:
811 * - this message type supports rapid commit (Solicit), and
812 * - the server is configured to supply a rapid commit, and
813 * - the client requests a rapid commit,
814 * Then we add a rapid commit option, and send Reply (instead
815 * of an Advertise).
816 */
817 oc = lookup_option(&dhcpv6_universe,
818 *opt_state, D6O_RAPID_COMMIT);
819 if (oc != NULL) {
820 oc = lookup_option(&dhcpv6_universe,
821 packet->options, D6O_RAPID_COMMIT);
822 if (oc != NULL) {
823 /* Rapid-commit in action. */
824 reply->msg_type = DHCPV6_REPLY;
825 } else {
826 /* Don't want a rapid-commit in advertise. */
827 delete_option(&dhcpv6_universe,
828 *opt_state, D6O_RAPID_COMMIT);
829 }
830 }
831 } else {
832 reply->msg_type = DHCPV6_REPLY;
833 /* Delete the rapid-commit from the sent options. */
834 oc = lookup_option(&dhcpv6_universe,
835 *opt_state, D6O_RAPID_COMMIT);
836 if (oc != NULL) {
837 delete_option(&dhcpv6_universe,
838 *opt_state, D6O_RAPID_COMMIT);
839 }
840 }
841
842 /*
843 * Use the client's transaction identifier for the reply.
844 */
845 memcpy(reply->transaction_id, packet->dhcpv6_transaction_id,
846 sizeof(reply->transaction_id));
847
848 /*
849 * RFC 3315, section 18.2 says we need server identifier and
850 * client identifier.
851 *
852 * If the server ID is defined via the configuration file, then
853 * it will already be present in the option state at this point,
854 * so we don't need to set it.
855 *
856 * If we have a server ID passed in from the caller,
857 * use that, otherwise use the global DUID.
858 */
859 oc = lookup_option(&dhcpv6_universe, *opt_state, D6O_SERVERID);
860 if (oc == NULL) {
861 if (server_id == NULL) {
862 server_id_data = server_duid.data;
863 server_id_len = server_duid.len;
864 } else {
865 server_id_data = server_id->data;
866 server_id_len = server_id->len;
867 }
868 if (!save_option_buffer(&dhcpv6_universe, *opt_state,
869 NULL, (unsigned char *)server_id_data,
870 server_id_len, D6O_SERVERID, 0)) {
871 log_error("start_reply: "
872 "error saving server identifier.");
873 return 0;
874 }
875 }
876
877 if (client_id->buffer != NULL) {
878 if (!save_option_buffer(&dhcpv6_universe, *opt_state,
879 client_id->buffer,
880 (unsigned char *)client_id->data,
881 client_id->len,
882 D6O_CLIENTID, 0)) {
883 log_error("start_reply: error saving "
884 "client identifier.");
885 return 0;
886 }
887 }
888
889 /*
890 * If the client accepts reconfiguration, let it know that we
891 * will send them.
892 *
893 * Note: we don't actually do this yet, but DOCSIS requires we
894 * claim to.
895 */
896 oc = lookup_option(&dhcpv6_universe, packet->options,
897 D6O_RECONF_ACCEPT);
898 if (oc != NULL) {
899 if (!save_option_buffer(&dhcpv6_universe, *opt_state,
900 NULL, (unsigned char *)"", 0,
901 D6O_RECONF_ACCEPT, 0)) {
902 log_error("start_reply: "
903 "error saving RECONF_ACCEPT option.");
904 option_state_dereference(opt_state, MDL);
905 return 0;
906 }
907 }
908
909 return 1;
910 }
911
912 /*
913 * Try to get the IPv6 address the client asked for from the
914 * pool.
915 *
916 * addr is the result (should be a pointer to NULL on entry)
917 * pool is the pool to search in
918 * requested_addr is the address the client wants
919 */
920 static isc_result_t
921 try_client_v6_address(struct iaaddr **addr,
922 struct ipv6_pool *pool,
923 const struct data_string *requested_addr)
924 {
925 struct in6_addr tmp_addr;
926 isc_result_t result;
927
928 if (requested_addr->len < sizeof(tmp_addr)) {
929 return ISC_R_INVALIDARG;
930 }
931 memcpy(&tmp_addr, requested_addr->data, sizeof(tmp_addr));
932 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr)) {
933 return ISC_R_FAILURE;
934 }
935
936 if (!ipv6_addr_in_pool(&tmp_addr, pool)) {
937 return ISC_R_FAILURE;
938 }
939
940 if (lease6_exists(pool, &tmp_addr)) {
941 return ISC_R_ADDRINUSE;
942 }
943
944 result = iaaddr_allocate(addr, MDL);
945 if (result != ISC_R_SUCCESS) {
946 return result;
947 }
948 (*addr)->addr = tmp_addr;
949
950 result = add_lease6(pool, *addr, 0);
951 if (result != ISC_R_SUCCESS) {
952 iaaddr_dereference(addr, MDL);
953 }
954 return result;
955 }
956
957 /*
958 * Get an IPv6 address for the client.
959 *
960 * addr is the result (should be a pointer to NULL on entry)
961 * packet is the information about the packet from the client
962 * requested_iaaddr is a hint from the client
963 * client_id is the DUID for the client
964 */
965 static isc_result_t
966 pick_v6_address(struct iaaddr **addr, struct shared_network *shared_network,
967 const struct data_string *client_id)
968 {
969 struct ipv6_pool *p;
970 int i;
971 int start_pool;
972 unsigned int attempts;
973 char tmp_buf[INET6_ADDRSTRLEN];
974
975 /*
976 * No pools, we're done.
977 */
978 if (shared_network->ipv6_pools == NULL) {
979 log_debug("Unable to pick client address: "
980 "no IPv6 pools on this shared network");
981 return ISC_R_NORESOURCES;
982 }
983
984 /*
985 * Otherwise try to get a lease from the first subnet possible.
986 *
987 * We start looking at the last pool we allocated from, unless
988 * it had a collision trying to allocate an address. This will
989 * tend to move us into less-filled pools.
990 */
991 start_pool = shared_network->last_ipv6_pool;
992 i = start_pool;
993 do {
994
995 p = shared_network->ipv6_pools[i];
996 if (activate_lease6(p, addr, &attempts,
997 client_id, 0) == ISC_R_SUCCESS) {
998 /*
999 * Record the pool used (or next one if there
1000 * was a collision).
1001 */
1002 if (attempts > 1) {
1003 i++;
1004 if (shared_network->ipv6_pools[i] == NULL) {
1005 i = 0;
1006 }
1007 }
1008 shared_network->last_ipv6_pool = i;
1009
1010 log_debug("Picking pool address %s",
1011 inet_ntop(AF_INET6, &((*addr)->addr),
1012 tmp_buf, sizeof(tmp_buf)));
1013 return ISC_R_SUCCESS;
1014 }
1015
1016 i++;
1017 if (shared_network->ipv6_pools[i] == NULL) {
1018 i = 0;
1019 }
1020 } while (i != start_pool);
1021
1022 /*
1023 * If we failed to pick an IPv6 address from any of the subnets.
1024 * Presumably that means we have no addresses for the client.
1025 */
1026 log_debug("Unable to pick client address: no addresses available");
1027 return ISC_R_NORESOURCES;
1028 }
1029
1030 /*
1031 * lease_to_client() is called from several messages to construct a
1032 * reply that contains all that we know about the client's correct lease
1033 * (or projected lease).
1034 *
1035 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1036 * send what we "may" give them on a request.
1037 *
1038 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1039 * the client should really use).
1040 *
1041 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1042 * Rebind out any "wrong" addresses the client sends. This means we send
1043 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1044 * possibly send the address with zeroed lifetimes.
1045 *
1046 * Information-Request - No binding.
1047 *
1048 * The basic structure is to traverse the client-supplied data first, and
1049 * validate and echo back any contents that can be. If the client-supplied
1050 * data does not error out (on renew/rebind as above), but we did not send
1051 * any addresses, attempt to allocate one.
1052 */
1053 /* TODO: look at client hints for lease times */
1054 static void
1055 lease_to_client(struct data_string *reply_ret,
1056 struct packet *packet,
1057 const struct data_string *client_id,
1058 const struct data_string *server_id)
1059 {
1060 static struct reply_state reply;
1061 struct option_cache *oc;
1062 struct data_string packet_oro;
1063 isc_boolean_t no_addrs_avail;
1064
1065 /* Locate the client. */
1066 if (shared_network_from_packet6(&reply.shared,
1067 packet) != ISC_R_SUCCESS)
1068 goto exit;
1069
1070 /*
1071 * Initialize the reply.
1072 */
1073 packet_reference(&reply.packet, packet, MDL);
1074 data_string_copy(&reply.client_id, client_id, MDL);
1075
1076 if (!start_reply(packet, client_id, server_id, &reply.opt_state,
1077 &reply.buf.reply))
1078 goto exit;
1079
1080 /* Set the write cursor to just past the reply header. */
1081 reply.cursor = REPLY_OPTIONS_INDEX;
1082
1083 /*
1084 * Get the ORO from the packet, if any.
1085 */
1086 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_ORO);
1087 memset(&packet_oro, 0, sizeof(packet_oro));
1088 if (oc != NULL) {
1089 if (!evaluate_option_cache(&packet_oro, packet,
1090 NULL, NULL,
1091 packet->options, NULL,
1092 &global_scope, oc, MDL)) {
1093 log_error("lease_to_client: error evaluating ORO.");
1094 goto exit;
1095 }
1096 }
1097
1098 /*
1099 * Find a host record that matches from the packet, if any, and is
1100 * valid for the shared network the client is on.
1101 */
1102 if (find_hosts_by_option(&reply.host, packet, packet->options, MDL)) {
1103 seek_shared_host(&reply.host, reply.shared);
1104 }
1105
1106 if ((reply.host == NULL) &&
1107 find_hosts_by_uid(&reply.host, client_id->data, client_id->len,
1108 MDL)) {
1109 seek_shared_host(&reply.host, reply.shared);
1110 }
1111
1112 /* Process the client supplied IA_NA's onto the reply buffer. */
1113 reply.ia_count = 0;
1114 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
1115 no_addrs_avail = ISC_FALSE;
1116 for (; oc != NULL ; oc = oc->next) {
1117 isc_result_t status;
1118
1119 /* Start counting resources (addresses) offered. */
1120 reply.client_resources = 0;
1121 reply.ia_addrs_included = ISC_FALSE;
1122
1123 status = reply_process_ia_na(&reply, oc);
1124
1125 /*
1126 * We continue to try other IA's whether we can address
1127 * this one or not. Any other result is an immediate fail.
1128 */
1129 if ((status != ISC_R_SUCCESS) &&
1130 (status != ISC_R_NORESOURCES))
1131 goto exit;
1132
1133 /*
1134 * If any address can be given to any IA, then do not set the
1135 * NoAddrsAvail status code.
1136 */
1137 if (reply.client_resources == 0)
1138 no_addrs_avail = ISC_TRUE;
1139 }
1140
1141 /* Do IA_TA and IA_PD */
1142
1143 /*
1144 * Make no reply if we gave no resources and is not
1145 * for Information-Request.
1146 */
1147 if ((reply.ia_count == 0) &&
1148 (packet->dhcpv6_msg_type != DHCPV6_INFORMATION_REQUEST))
1149 goto exit;
1150
1151 /*
1152 * RFC3315 section 17.2.2 (Solicit):
1153 *
1154 * If the server will not assign any addresses to any IAs in a
1155 * subsequent Request from the client, the server MUST send an
1156 * Advertise message to the client that includes only a Status
1157 * Code option with code NoAddrsAvail and a status message for
1158 * the user, a Server Identifier option with the server's DUID,
1159 * and a Client Identifier option with the client's DUID.
1160 *
1161 * Section 18.2.1 (Request):
1162 *
1163 * If the server cannot assign any addresses to an IA in the
1164 * message from the client, the server MUST include the IA in
1165 * the Reply message with no addresses in the IA and a Status
1166 * Code option in the IA containing status code NoAddrsAvail.
1167 *
1168 * Section 18.1.8 (Client Behavior):
1169 *
1170 * Leave unchanged any information about addresses the client has
1171 * recorded in the IA but that were not included in the IA from
1172 * the server.
1173 * Sends a Renew/Rebind if the IA is not in the Reply message.
1174 */
1175 if (no_addrs_avail &&
1176 (reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT))
1177 {
1178 /* Set the NoAddrsAvail status code. */
1179 if (!set_status_code(STATUS_NoAddrsAvail,
1180 "No addresses available for this "
1181 "interface.", reply.opt_state)) {
1182 log_error("lease_to_client: Unable to set "
1183 "NoAddrsAvail status code.");
1184 goto exit;
1185 }
1186
1187 /* Rewind the cursor to the start. */
1188 reply.cursor = REPLY_OPTIONS_INDEX;
1189
1190 /*
1191 * Produce an advertise that includes only:
1192 *
1193 * Status code.
1194 * Server DUID.
1195 * Client DUID.
1196 */
1197 reply.buf.reply.msg_type = DHCPV6_ADVERTISE;
1198 reply.cursor += store_options6((char *)reply.buf.data +
1199 reply.cursor,
1200 sizeof(reply.buf) -
1201 reply.cursor,
1202 reply.opt_state, reply.packet,
1203 required_opts_NAA,
1204 NULL);
1205 } else {
1206 /*
1207 * Having stored the client's IA_NA's, store any options that
1208 * will fit in the remaining space.
1209 */
1210 reply.cursor += store_options6((char *)reply.buf.data +
1211 reply.cursor,
1212 sizeof(reply.buf) -
1213 reply.cursor,
1214 reply.opt_state, reply.packet,
1215 required_opts_solicit,
1216 &packet_oro);
1217 }
1218
1219 /* Return our reply to the caller. */
1220 reply_ret->len = reply.cursor;
1221 reply_ret->buffer = NULL;
1222 if (!buffer_allocate(&reply_ret->buffer, reply.cursor, MDL)) {
1223 log_fatal("No memory to store Reply.");
1224 }
1225 memcpy(reply_ret->buffer->data, reply.buf.data, reply.cursor);
1226 reply_ret->data = reply_ret->buffer->data;
1227
1228 exit:
1229 /* Cleanup. */
1230 if (reply.shared != NULL)
1231 shared_network_dereference(&reply.shared, MDL);
1232 if (reply.host != NULL)
1233 host_dereference(&reply.host, MDL);
1234 if (reply.opt_state != NULL)
1235 option_state_dereference(&reply.opt_state, MDL);
1236 if (reply.packet != NULL)
1237 packet_dereference(&reply.packet, MDL);
1238 if (reply.client_id.data != NULL)
1239 data_string_forget(&reply.client_id, MDL);
1240 reply.renew = reply.rebind = reply.prefer = reply.valid = 0;
1241 reply.cursor = 0;
1242 }
1243
1244 /* Process a client-supplied IA_NA. This may append options to the tail of
1245 * the reply packet being built in the reply_state structure.
1246 */
1247 static isc_result_t
1248 reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) {
1249 isc_result_t status = ISC_R_SUCCESS;
1250 u_int32_t iaid;
1251 unsigned ia_cursor;
1252 struct option_state *packet_ia;
1253 struct option_cache *oc;
1254 struct data_string ia_data, data;
1255 isc_boolean_t lease_in_database;
1256
1257 /* Initialize values that will get cleaned up on return. */
1258 packet_ia = NULL;
1259 memset(&ia_data, 0, sizeof(ia_data));
1260 memset(&data, 0, sizeof(data));
1261 lease_in_database = ISC_FALSE;
1262 /*
1263 * Note that find_client_address() may set reply->lease.
1264 */
1265
1266 /* Make sure there is at least room for the header. */
1267 if ((reply->cursor + IA_NA_OFFSET + 4) > sizeof(reply->buf)) {
1268 log_error("reply_process_ia_na: Reply too long for IA.");
1269 return ISC_R_NOSPACE;
1270 }
1271
1272
1273 /* Fetch the IA_NA contents. */
1274 if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
1275 ia, IA_NA_OFFSET)) {
1276 log_error("reply_process_ia_na: error evaluating ia_na");
1277 status = ISC_R_FAILURE;
1278 goto cleanup;
1279 }
1280
1281 /* Extract IA_NA header contents. */
1282 iaid = getULong(ia_data.data);
1283 reply->renew = getULong(ia_data.data + 4);
1284 reply->rebind = getULong(ia_data.data + 8);
1285
1286 /* Create an IA_NA structure. */
1287 if (ia_na_allocate(&reply->ia_na, iaid, (char *)reply->client_id.data,
1288 reply->client_id.len, MDL) != ISC_R_SUCCESS) {
1289 log_error("lease_to_client: no memory for ia_na.");
1290 status = ISC_R_NOMEMORY;
1291 goto cleanup;
1292 }
1293 reply->ia_na->ia_type = D6O_IA_NA;
1294
1295 /* Cache pre-existing IA, if any. */
1296 ia_na_hash_lookup(&reply->old_ia_na, ia_na_active,
1297 (unsigned char *)reply->ia_na->iaid_duid.data,
1298 reply->ia_na->iaid_duid.len, MDL);
1299
1300 /*
1301 * Create an option cache to carry the IA_NA option contents, and
1302 * execute any user-supplied values into it.
1303 */
1304 if (!option_state_allocate(&reply->reply_ia, MDL)) {
1305 status = ISC_R_NOMEMORY;
1306 goto cleanup;
1307 }
1308
1309 /* Check & cache the fixed host record. */
1310 if ((reply->host != NULL) && (reply->host->fixed_addr != NULL)) {
1311 if (!evaluate_option_cache(&reply->fixed, NULL, NULL, NULL,
1312 NULL, NULL, &global_scope,
1313 reply->host->fixed_addr, MDL)) {
1314 log_error("reply_process_ia_na: unable to evaluate "
1315 "fixed address.");
1316 status = ISC_R_FAILURE;
1317 goto cleanup;
1318 }
1319
1320 if (reply->fixed.len < 16) {
1321 log_error("reply_process_ia_na: invalid fixed address.");
1322 status = ISC_R_INVALIDARG;
1323 goto cleanup;
1324 }
1325
1326 reply->static_lease = ISC_TRUE;
1327 } else
1328 reply->static_lease = ISC_FALSE;
1329
1330 /*
1331 * Save the cursor position at the start of the IA, so we can
1332 * set length and adjust t1/t2 values later. We write a temporary
1333 * header out now just in case we decide to adjust the packet
1334 * within sub-process functions.
1335 */
1336 ia_cursor = reply->cursor;
1337
1338 /* Initialize the IA_NA header. First the code. */
1339 putUShort(reply->buf.data + reply->cursor, (unsigned)D6O_IA_NA);
1340 reply->cursor += 2;
1341
1342 /* Then option length. */
1343 putUShort(reply->buf.data + reply->cursor, 0x0Cu);
1344 reply->cursor += 2;
1345
1346 /* Then IA_NA header contents; IAID. */
1347 putULong(reply->buf.data + reply->cursor, iaid);
1348 reply->cursor += 4;
1349
1350 /* We store the client's t1 for now, and may over-ride it later. */
1351 putULong(reply->buf.data + reply->cursor, reply->renew);
1352 reply->cursor += 4;
1353
1354 /* We store the client's t2 for now, and may over-ride it later. */
1355 putULong(reply->buf.data + reply->cursor, reply->rebind);
1356 reply->cursor += 4;
1357
1358 /*
1359 * For each address in this IA_NA, decide what to do about it.
1360 *
1361 * Guidelines:
1362 *
1363 * The client leaves unchanged any infomation about addresses
1364 * it has recorded but are not included ("cancel/break" below).
1365 * A not included IA ("cleanup" below) could give a Renew/Rebind.
1366 */
1367 oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAADDR);
1368 reply->valid = reply->prefer = 0xffffffff;
1369 reply->client_valid = reply->client_prefer = 0;
1370 for (; oc != NULL ; oc = oc->next) {
1371 status = reply_process_addr(reply, oc);
1372
1373 /*
1374 * Canceled means we did not allocate addresses to the
1375 * client, but we're "done" with this IA - we set a status
1376 * code. So transmit this reply, e.g., move on to the next
1377 * IA.
1378 */
1379 if (status == ISC_R_CANCELED)
1380 break;
1381
1382 if ((status != ISC_R_SUCCESS) && (status != ISC_R_ADDRINUSE))
1383 goto cleanup;
1384 }
1385
1386 reply->ia_count++;
1387
1388 /*
1389 * If we fell through the above and never gave the client
1390 * an address, give it one now.
1391 */
1392 if ((status != ISC_R_CANCELED) && (reply->client_resources == 0)) {
1393 status = find_client_address(reply);
1394
1395 if (status == ISC_R_NORESOURCES) {
1396 switch (reply->packet->dhcpv6_msg_type) {
1397 case DHCPV6_SOLICIT:
1398 /*
1399 * No address for all the IA's is handled
1400 * by the caller.
1401 */
1402
1403 case DHCPV6_REQUEST:
1404 /* Section 18.2.1 (Request):
1405 *
1406 * If the server cannot assign any addresses to
1407 * an IA in the message from the client, the
1408 * server MUST include the IA in the Reply
1409 * message with no addresses in the IA and a
1410 * Status Code option in the IA containing
1411 * status code NoAddrsAvail.
1412 */
1413 option_state_dereference(&reply->reply_ia, MDL);
1414 if (!option_state_allocate(&reply->reply_ia,
1415 MDL))
1416 {
1417 log_error("reply_process_ia_na: No "
1418 "memory for option state "
1419 "wipe.");
1420 status = ISC_R_NOMEMORY;
1421 goto cleanup;
1422 }
1423
1424 if (!set_status_code(STATUS_NoAddrsAvail,
1425 "No addresses available "
1426 "for this interface.",
1427 reply->reply_ia)) {
1428 log_error("reply_process_ia_na: Unable "
1429 "to set NoAddrsAvail status "
1430 "code.");
1431 status = ISC_R_FAILURE;
1432 goto cleanup;
1433 }
1434
1435 status = ISC_R_SUCCESS;
1436 break;
1437
1438 default:
1439 /*
1440 * RFC 3315 does not tell us to emit a status
1441 * code in this condition, or anything else.
1442 *
1443 * If we included non-allocated addresses
1444 * (zeroed lifetimes) in an IA, then the client
1445 * will deconfigure them.
1446 *
1447 * So we want to include the IA even if we
1448 * can't give it a new address if it includes
1449 * zeroed lifetime addresses.
1450 *
1451 * We don't want to include the IA if we
1452 * provide zero addresses including zeroed
1453 * lifetimes.
1454 */
1455 if (reply->ia_addrs_included)
1456 status = ISC_R_SUCCESS;
1457 else
1458 goto cleanup;
1459 break;
1460 }
1461 }
1462
1463 if (status != ISC_R_SUCCESS)
1464 goto cleanup;
1465 }
1466
1467 reply->cursor += store_options6((char *)reply->buf.data + reply->cursor,
1468 sizeof(reply->buf) - reply->cursor,
1469 reply->reply_ia, reply->packet,
1470 required_opts_IA_NA, NULL);
1471
1472 /* Reset the length of this IA to match what was just written. */
1473 putUShort(reply->buf.data + ia_cursor + 2,
1474 reply->cursor - (ia_cursor + 4));
1475
1476 /*
1477 * T1/T2 time selection is kind of weird. We actually use DHCP
1478 * (v4) scoped options as handy existing places where these might
1479 * be configured by an administrator. A value of zero tells the
1480 * client it may choose its own renewal time.
1481 */
1482 reply->renew = 0;
1483 oc = lookup_option(&dhcp_universe, reply->opt_state,
1484 DHO_DHCP_RENEWAL_TIME);
1485 if (oc != NULL) {
1486 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
1487 reply->packet->options,
1488 reply->opt_state, &global_scope,
1489 oc, MDL) ||
1490 (data.len != 4)) {
1491 log_error("Invalid renewal time.");
1492 } else {
1493 reply->renew = getULong(data.data);
1494 }
1495
1496 if (data.data != NULL)
1497 data_string_forget(&data, MDL);
1498 }
1499 putULong(reply->buf.data + ia_cursor + 8, reply->renew);
1500
1501 /* Now T2. */
1502 reply->rebind = 0;
1503 oc = lookup_option(&dhcp_universe, reply->opt_state,
1504 DHO_DHCP_REBINDING_TIME);
1505 if (oc != NULL) {
1506 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
1507 reply->packet->options,
1508 reply->opt_state, &global_scope,
1509 oc, MDL) ||
1510 (data.len != 4)) {
1511 log_error("Invalid rebinding time.");
1512 } else {
1513 reply->rebind = getULong(data.data);
1514 }
1515
1516 if (data.data != NULL)
1517 data_string_forget(&data, MDL);
1518 }
1519 putULong(reply->buf.data + ia_cursor + 12, reply->rebind);
1520
1521 /*
1522 * If this is not a 'soft' binding, consume the new changes into
1523 * the database (if any have been attached to the ia_na).
1524 *
1525 * Loop through the assigned dynamic addresses, referencing the
1526 * leases onto this IA_NA rather than any old ones, and updating
1527 * pool timers for each (if any).
1528 */
1529 if ((status != ISC_R_CANCELED) && !reply->static_lease &&
1530 (reply->buf.reply.msg_type == DHCPV6_REPLY) &&
1531 (reply->ia_na->num_iaaddr != 0)) {
1532 struct iaaddr *tmp;
1533 struct data_string *ia_id;
1534 int i;
1535
1536 for (i = 0 ; i < reply->ia_na->num_iaaddr ; i++) {
1537 tmp = reply->ia_na->iaaddr[i];
1538
1539 if (tmp->ia_na != NULL)
1540 ia_na_dereference(&tmp->ia_na, MDL);
1541 ia_na_reference(&tmp->ia_na, reply->ia_na, MDL);
1542
1543 schedule_lease_timeout(tmp->ipv6_pool);
1544
1545 /*
1546 * If this constitutes a 'hard' binding, perform ddns
1547 * updates.
1548 */
1549 oc = lookup_option(&server_universe, reply->opt_state,
1550 SV_DDNS_UPDATES);
1551 if ((oc == NULL) ||
1552 evaluate_boolean_option_cache(NULL, reply->packet,
1553 NULL, NULL,
1554 reply->packet->options,
1555 reply->opt_state,
1556 &tmp->scope,
1557 oc, MDL)) {
1558 ddns_updates(reply->packet, NULL, NULL,
1559 tmp, NULL, reply->opt_state);
1560 }
1561 }
1562
1563 /* Remove any old ia_na from the hash. */
1564 if (reply->old_ia_na != NULL) {
1565 ia_id = &reply->old_ia_na->iaid_duid;
1566 ia_na_hash_delete(ia_na_active,
1567 (unsigned char *)ia_id->data,
1568 ia_id->len, MDL);
1569 ia_na_dereference(&reply->old_ia_na, MDL);
1570 }
1571
1572 /* Put new ia_na into the hash. */
1573 ia_id = &reply->ia_na->iaid_duid;
1574 ia_na_hash_add(ia_na_active, (unsigned char *)ia_id->data,
1575 ia_id->len, reply->ia_na, MDL);
1576
1577 write_ia(reply->ia_na);
1578
1579 /*
1580 * Note that we wrote the lease into the database,
1581 * so that we know not to release it when we're done
1582 * with this function.
1583 */
1584 lease_in_database = ISC_TRUE;
1585
1586 /*
1587 * If this is a soft binding, we will check to see if we are
1588 * suggesting the existing database entry to the client.
1589 */
1590 } else if ((status != ISC_R_CANCELED) && !reply->static_lease &&
1591 (reply->old_ia_na != NULL)) {
1592 if (ia_na_equal(reply->old_ia_na, reply->ia_na)) {
1593 lease_in_database = ISC_TRUE;
1594 }
1595 }
1596
1597 cleanup:
1598 if (packet_ia != NULL)
1599 option_state_dereference(&packet_ia, MDL);
1600 if (reply->reply_ia != NULL)
1601 option_state_dereference(&reply->reply_ia, MDL);
1602 if (ia_data.data != NULL)
1603 data_string_forget(&ia_data, MDL);
1604 if (data.data != NULL)
1605 data_string_forget(&data, MDL);
1606 if (reply->ia_na != NULL)
1607 ia_na_dereference(&reply->ia_na, MDL);
1608 if (reply->old_ia_na != NULL)
1609 ia_na_dereference(&reply->old_ia_na, MDL);
1610 if (reply->lease != NULL) {
1611 if (!lease_in_database) {
1612 release_lease6(reply->lease->ipv6_pool, reply->lease);
1613 }
1614 iaaddr_dereference(&reply->lease, MDL);
1615 }
1616 if (reply->fixed.data != NULL)
1617 data_string_forget(&reply->fixed, MDL);
1618
1619 /*
1620 * ISC_R_CANCELED is a status code used by the addr processing to
1621 * indicate we're replying with a status code. This is still a
1622 * success at higher layers.
1623 */
1624 return((status == ISC_R_CANCELED) ? ISC_R_SUCCESS : status);
1625 }
1626
1627 /*
1628 * Process an IAADDR within a given IA_NA, storing any IAADDR reply contents
1629 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
1630 * in the event we are replying with a status code and do not wish to process
1631 * more IAADDRs within this IA.
1632 */
1633 static isc_result_t
1634 reply_process_addr(struct reply_state *reply, struct option_cache *addr) {
1635 u_int32_t pref_life, valid_life;
1636 struct binding_scope **scope;
1637 struct group *group;
1638 struct subnet *subnet;
1639 struct iaddr tmp_addr;
1640 struct option_cache *oc;
1641 struct data_string iaaddr, data;
1642 isc_result_t status = ISC_R_SUCCESS;
1643
1644 /* Initializes values that will be cleaned up. */
1645 memset(&iaaddr, 0, sizeof(iaaddr));
1646 memset(&data, 0, sizeof(data));
1647 /* Note that reply->lease may be set by address_is_owned() */
1648
1649 /*
1650 * There is no point trying to process an incoming address if there
1651 * is no room for an outgoing address.
1652 */
1653 if ((reply->cursor + 28) > sizeof(reply->buf)) {
1654 log_error("reply_process_addr: Out of room for address.");
1655 return ISC_R_NOSPACE;
1656 }
1657
1658 /* Extract this IAADDR option. */
1659 if (!evaluate_option_cache(&iaaddr, reply->packet, NULL, NULL,
1660 reply->packet->options, NULL, &global_scope,
1661 addr, MDL) ||
1662 (iaaddr.len < IAADDR_OFFSET)) {
1663 log_error("reply_process_addr: error evaluating IAADDR.");
1664 status = ISC_R_FAILURE;
1665 goto cleanup;
1666 }
1667
1668 /* The first 16 bytes are the IPv6 address. */
1669 pref_life = getULong(iaaddr.data + 16);
1670 valid_life = getULong(iaaddr.data + 20);
1671
1672 if ((reply->client_valid == 0) ||
1673 (reply->client_valid > valid_life))
1674 reply->client_valid = valid_life;
1675
1676 if ((reply->client_prefer == 0) ||
1677 (reply->client_prefer > pref_life))
1678 reply->client_prefer = pref_life;
1679
1680 /*
1681 * Clients may choose to send :: as an address, with the idea to give
1682 * hints about preferred-lifetime or valid-lifetime.
1683 */
1684 tmp_addr.len = 16;
1685 memset(tmp_addr.iabuf, 0, 16);
1686 if (!memcmp(iaaddr.data, tmp_addr.iabuf, 16)) {
1687 /* Status remains success; we just ignore this one. */
1688 goto cleanup;
1689 }
1690
1691 /* tmp_addr len remains 16 */
1692 memcpy(tmp_addr.iabuf, iaaddr.data, 16);
1693
1694 /*
1695 * Verify that this address is on the client's network.
1696 */
1697 for (subnet = reply->shared->subnets ; subnet != NULL ;
1698 subnet = subnet->next_sibling) {
1699 if (addr_eq(subnet_number(tmp_addr, subnet->netmask),
1700 subnet->net))
1701 break;
1702 }
1703
1704 /* Address not found on shared network. */
1705 if (subnet == NULL) {
1706 /* Ignore this address on 'soft' bindings. */
1707 if (reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT)
1708 /* status remains success */
1709 goto cleanup;
1710
1711 /*
1712 * RFC3315 section 18.2.1:
1713 *
1714 * If the server finds that the prefix on one or more IP
1715 * addresses in any IA in the message from the client is not
1716 * appropriate for the link to which the client is connected,
1717 * the server MUST return the IA to the client with a Status
1718 * Code option with the value NotOnLink.
1719 */
1720 if (reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) {
1721 /* Rewind the IA_NA to empty. */
1722 option_state_dereference(&reply->reply_ia, MDL);
1723 if (!option_state_allocate(&reply->reply_ia, MDL)) {
1724 log_error("reply_process_addr: No memory for "
1725 "option state wipe.");
1726 status = ISC_R_NOMEMORY;
1727 goto cleanup;
1728 }
1729
1730 /* Append a NotOnLink status code. */
1731 if (!set_status_code(STATUS_NotOnLink,
1732 "Address not for use on this "
1733 "link.", reply->reply_ia)) {
1734 log_error("reply_process_addr: Failure "
1735 "setting status code.");
1736 status = ISC_R_FAILURE;
1737 goto cleanup;
1738 }
1739
1740 /* Fin (no more IAADDRs). */
1741 status = ISC_R_CANCELED;
1742 goto cleanup;
1743 }
1744
1745 /*
1746 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
1747 *
1748 * If the server finds that any of the addresses are not
1749 * appropriate for the link to which the client is attached,
1750 * the server returns the address to the client with lifetimes
1751 * of 0.
1752 */
1753 if ((reply->packet->dhcpv6_msg_type != DHCPV6_RENEW) &&
1754 (reply->packet->dhcpv6_msg_type != DHCPV6_REBIND)) {
1755 log_error("It is impossible to lease a client that is "
1756 "not sending a solicit, request, renew, or "
1757 "rebind.");
1758 status = ISC_R_FAILURE;
1759 goto cleanup;
1760 }
1761
1762 reply->send_prefer = reply->send_valid = 0;
1763 goto send_addr;
1764 }
1765
1766 /* Verify the address belongs to the client. */
1767 if (!address_is_owned(reply, &tmp_addr)) {
1768 /*
1769 * For solicit and request, any addresses included are
1770 * 'requested' addresses. For rebind, we actually have
1771 * no direction on what to do from 3315 section 18.2.4!
1772 * So I think the best bet is to try and give it out, and if
1773 * we can't, zero lifetimes.
1774 */
1775 if ((reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) ||
1776 (reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) ||
1777 (reply->packet->dhcpv6_msg_type == DHCPV6_REBIND)) {
1778 status = reply_process_try_addr(reply, &tmp_addr);
1779
1780 /* Either error out or skip this address. */
1781 if ((status != ISC_R_SUCCESS) &&
1782 (status != ISC_R_ADDRINUSE))
1783 goto cleanup;
1784
1785 if (reply->lease == NULL) {
1786 if (reply->packet->dhcpv6_msg_type ==
1787 DHCPV6_REBIND) {
1788 reply->send_prefer = 0;
1789 reply->send_valid = 0;
1790 goto send_addr;
1791 }
1792
1793 /* status remains success - ignore */
1794 goto cleanup;
1795 }
1796 /*
1797 * RFC3315 section 18.2.3:
1798 *
1799 * If the server cannot find a client entry for the IA the
1800 * server returns the IA containing no addresses with a Status
1801 * Code option set to NoBinding in the Reply message.
1802 *
1803 * On mismatch we (ab)use this pretending we have not the IA
1804 * as soon as we have not an address.
1805 */
1806 } else if (reply->packet->dhcpv6_msg_type == DHCPV6_RENEW) {
1807 /* Rewind the IA_NA to empty. */
1808 option_state_dereference(&reply->reply_ia, MDL);
1809 if (!option_state_allocate(&reply->reply_ia, MDL)) {
1810 log_error("reply_process_addr: No memory for "
1811 "option state wipe.");
1812 status = ISC_R_NOMEMORY;
1813 goto cleanup;
1814 }
1815
1816 /* Append a NoBinding status code. */
1817 if (!set_status_code(STATUS_NoBinding,
1818 "Address not bound to this "
1819 "interface.", reply->reply_ia)) {
1820 log_error("reply_process_addr: Unable to "
1821 "attach status code.");
1822 status = ISC_R_FAILURE;
1823 goto cleanup;
1824 }
1825
1826 /* Fin (no more IAADDRs). */
1827 status = ISC_R_CANCELED;
1828 goto cleanup;
1829 } else {
1830 log_error("It is impossible to lease a client that is "
1831 "not sending a solicit, request, renew, or "
1832 "rebind message.");
1833 status = ISC_R_FAILURE;
1834 goto cleanup;
1835 }
1836 }
1837
1838 if (reply->static_lease) {
1839 if (reply->host == NULL)
1840 log_fatal("Impossible condition at %s:%d.", MDL);
1841
1842 scope = &global_scope;
1843 group = reply->host->group;
1844 } else {
1845 if (reply->lease == NULL)
1846 log_fatal("Impossible condition at %s:%d.", MDL);
1847
1848 scope = &reply->lease->scope;
1849 group = reply->shared->group;
1850 }
1851
1852 /*
1853 * If client_resources is nonzero, then the reply_process_is_addressed
1854 * function has executed configuration state into the reply option
1855 * cache. We will use that valid cache to derive configuration for
1856 * whether or not to engage in additional addresses, and similar.
1857 */
1858 if (reply->client_resources != 0) {
1859 unsigned limit = 1;
1860
1861 /*
1862 * Does this client have "enough" addresses already? Default
1863 * to one. Everybody gets one, and one should be enough for
1864 * anybody.
1865 */
1866 oc = lookup_option(&server_universe, reply->opt_state,
1867 SV_LIMIT_ADDRS_PER_IA);
1868 if (oc != NULL) {
1869 if (!evaluate_option_cache(&data, reply->packet,
1870 NULL, NULL,
1871 reply->packet->options,
1872 reply->opt_state,
1873 scope, oc, MDL) ||
1874 (data.len != 4)) {
1875 log_error("reply_process_addr: unable to "
1876 "evaluate addrs-per-ia value.");
1877 status = ISC_R_FAILURE;
1878 goto cleanup;
1879 }
1880
1881 limit = getULong(data.data);
1882 data_string_forget(&data, MDL);
1883 }
1884
1885 /*
1886 * If we wish to limit the client to a certain number of
1887 * addresses, then omit the address from the reply.
1888 */
1889 if (reply->client_resources >= limit)
1890 goto cleanup;
1891 }
1892
1893 status = reply_process_is_addressed(reply, scope, group);
1894 if (status != ISC_R_SUCCESS)
1895 goto cleanup;
1896
1897 send_addr:
1898 status = reply_process_send_addr(reply, &tmp_addr);
1899
1900 cleanup:
1901 if (iaaddr.data != NULL)
1902 data_string_forget(&iaaddr, MDL);
1903 if (data.data != NULL)
1904 data_string_forget(&data, MDL);
1905 if (reply->lease != NULL)
1906 iaaddr_dereference(&reply->lease, MDL);
1907
1908 return status;
1909 }
1910
1911 /*
1912 * Verify the address belongs to the client. If we've got a host
1913 * record with a fixed address, it has to be the assigned address
1914 * (fault out all else). Otherwise it's a dynamic address, so lookup
1915 * that address and make sure it belongs to this DUID:IAID pair.
1916 */
1917 static isc_boolean_t
1918 address_is_owned(struct reply_state *reply, struct iaddr *addr) {
1919 int i;
1920
1921 /*
1922 * This faults out addresses that don't match fixed addresses.
1923 */
1924 if (reply->static_lease) {
1925 if (reply->fixed.data == NULL)
1926 log_fatal("Impossible condition at %s:%d.", MDL);
1927
1928 if (memcmp(addr->iabuf, reply->fixed.data, 16) == 0)
1929 return ISC_TRUE;
1930
1931 return ISC_FALSE;
1932 }
1933
1934 if ((reply->old_ia_na == NULL) || (reply->old_ia_na->num_iaaddr == 0))
1935 return ISC_FALSE;
1936
1937 for (i = 0 ; i < reply->old_ia_na->num_iaaddr ; i++) {
1938 struct iaaddr *tmp;
1939
1940 tmp = reply->old_ia_na->iaaddr[i];
1941
1942 if (memcmp(addr->iabuf, &tmp->addr, 16) == 0) {
1943 iaaddr_reference(&reply->lease, tmp, MDL);
1944 return ISC_TRUE;
1945 }
1946 }
1947
1948 return ISC_FALSE;
1949 }
1950
1951 /*
1952 * This function only returns failure on 'hard' failures. If it succeeds,
1953 * it will leave a lease structure behind.
1954 */
1955 static isc_result_t
1956 reply_process_try_addr(struct reply_state *reply, struct iaddr *addr) {
1957 isc_result_t status = ISC_R_FAILURE;
1958 struct ipv6_pool *pool;
1959 int i;
1960 struct data_string data_addr;
1961
1962 if ((reply == NULL) || (reply->shared == NULL) ||
1963 (reply->shared->ipv6_pools == NULL) || (addr == NULL) ||
1964 (reply->lease != NULL))
1965 return ISC_R_INVALIDARG;
1966
1967 memset(&data_addr, 0, sizeof(data_addr));
1968 data_addr.len = addr->len;
1969 data_addr.data = addr->iabuf;
1970
1971 for (i = 0 ; (pool = reply->shared->ipv6_pools[i]) != NULL ; i++) {
1972 status = try_client_v6_address(&reply->lease, pool,
1973 &data_addr);
1974 if (status == ISC_R_SUCCESS)
1975 break;
1976 }
1977
1978 /* Note that this is just pedantry. There is no allocation to free. */
1979 data_string_forget(&data_addr, MDL);
1980 /* Return just the most recent status... */
1981 return status;
1982 }
1983
1984 /* Look around for an address to give the client. First, look through the
1985 * old IA for addresses we can extend. Second, try to allocate a new address.
1986 * Finally, actually add that address into the current reply IA.
1987 */
1988 static isc_result_t
1989 find_client_address(struct reply_state *reply) {
1990 struct iaddr send_addr;
1991 isc_result_t status = ISC_R_NORESOURCES;
1992 struct iaaddr *lease, *best_lease = NULL;
1993 struct binding_scope **scope;
1994 struct group *group;
1995 int i;
1996
1997 if (reply->host != NULL)
1998 group = reply->host->group;
1999 else
2000 group = reply->shared->group;
2001
2002 if (reply->static_lease) {
2003 if (reply->host == NULL)
2004 return ISC_R_INVALIDARG;
2005
2006 send_addr.len = 16;
2007 memcpy(send_addr.iabuf, reply->fixed.data, 16);
2008
2009 status = ISC_R_SUCCESS;
2010 scope = &global_scope;
2011 goto send_addr;
2012 }
2013
2014 if (reply->old_ia_na != NULL) {
2015 for (i = 0 ; i < reply->old_ia_na->num_iaaddr ; i++) {
2016 lease = reply->old_ia_na->iaaddr[i];
2017
2018 best_lease = lease_compare(lease, best_lease);
2019 }
2020 }
2021
2022 /* Try to pick a new address if we didn't find one, or if we found an
2023 * abandoned lease.
2024 */
2025 if ((best_lease == NULL) || (best_lease->state == FTS_ABANDONED)) {
2026 status = pick_v6_address(&reply->lease, reply->shared,
2027 &reply->client_id);
2028 } else if (best_lease != NULL) {
2029 iaaddr_reference(&reply->lease, best_lease, MDL);
2030 status = ISC_R_SUCCESS;
2031 }
2032
2033 /* Pick the abandoned lease as a last resort. */
2034 if ((status == ISC_R_NORESOURCES) && (best_lease != NULL)) {
2035 /* I don't see how this is supposed to be done right now. */
2036 log_error("Reclaiming abandoned addresses is not yet "
2037 "supported. Treating this as an out of space "
2038 "condition.");
2039 /* lease_reference(&reply->lease, best_lease, MDL); */
2040 }
2041
2042 /* Give up now if we didn't find a lease. */
2043 if (status != ISC_R_SUCCESS)
2044 return status;
2045
2046 if (reply->lease == NULL)
2047 log_fatal("Impossible condition at %s:%d.", MDL);
2048
2049 scope = &reply->lease->scope;
2050 group = reply->shared->group;
2051
2052 send_addr.len = 16;
2053 memcpy(send_addr.iabuf, &reply->lease->addr, 16);
2054
2055 send_addr:
2056 status = reply_process_is_addressed(reply, scope, group);
2057 if (status != ISC_R_SUCCESS)
2058 return status;
2059
2060 status = reply_process_send_addr(reply, &send_addr);
2061 return status;
2062 }
2063
2064 /* Once an address is found for a client, perform several common functions;
2065 * Calculate and store valid and preferred lease times, draw client options
2066 * into the option state.
2067 */
2068 static isc_result_t
2069 reply_process_is_addressed(struct reply_state *reply,
2070 struct binding_scope **scope, struct group *group)
2071 {
2072 isc_result_t status = ISC_R_SUCCESS;
2073 struct data_string data;
2074 struct option_cache *oc;
2075
2076 /* Initialize values we will cleanup. */
2077 memset(&data, 0, sizeof(data));
2078
2079 /* Execute relevant options into root scope. */
2080 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
2081 reply->packet->options, reply->opt_state,
2082 scope, group, root_group);
2083
2084 /* Determine valid lifetime. */
2085 if (reply->client_valid == 0)
2086 reply->send_valid = DEFAULT_DEFAULT_LEASE_TIME;
2087 else
2088 reply->send_valid = reply->client_valid;
2089
2090 oc = lookup_option(&server_universe, reply->opt_state,
2091 SV_DEFAULT_LEASE_TIME);
2092 if (oc != NULL) {
2093 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
2094 reply->packet->options,
2095 reply->opt_state,
2096 scope, oc, MDL) ||
2097 (data.len != 4)) {
2098 log_error("reply_process_is_addressed: unable to "
2099 "evaluate default lease time");
2100 status = ISC_R_FAILURE;
2101 goto cleanup;
2102 }
2103
2104 reply->send_valid = getULong(data.data);
2105 data_string_forget(&data, MDL);
2106 }
2107
2108 if (reply->client_prefer == 0)
2109 reply->send_prefer = reply->send_valid;
2110 else
2111 reply->send_prefer = reply->client_prefer;
2112
2113 if (reply->send_prefer >= reply->send_valid)
2114 reply->send_prefer = (reply->send_valid / 2) +
2115 (reply->send_valid / 8);
2116
2117 oc = lookup_option(&server_universe, reply->opt_state,
2118 SV_PREFER_LIFETIME);
2119 if (oc != NULL) {
2120 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
2121 reply->packet->options,
2122 reply->opt_state,
2123 scope, oc, MDL) ||
2124 (data.len != 4)) {
2125 log_error("reply_process_is_addressed: unable to "
2126 "evaluate preferred lease time");
2127 status = ISC_R_FAILURE;
2128 goto cleanup;
2129 }
2130
2131 reply->send_prefer = getULong(data.data);
2132 data_string_forget(&data, MDL);
2133 }
2134
2135 /* Note lowest values for later calculation of renew/rebind times. */
2136 if (reply->prefer > reply->send_prefer)
2137 reply->prefer = reply->send_prefer;
2138
2139 if (reply->valid > reply->send_valid)
2140 reply->valid = reply->send_valid;
2141
2142 #if 0
2143 /*
2144 * XXX: Old 4.0.0 alpha code would change the host {} record
2145 * XXX: uid upon lease assignment. This was intended to cover the
2146 * XXX: case where a client first identifies itself using vendor
2147 * XXX: options in a solicit, or request, but later neglects to include
2148 * XXX: these options in a Renew or Rebind. It is not clear that this
2149 * XXX: is required, and has some startling ramifications (such as
2150 * XXX: how to recover this dynamic host {} state across restarts).
2151 */
2152 if (reply->host != NULL)
2153 change_host_uid(host, reply->client_id->data,
2154 reply->client_id->len);
2155 #endif /* 0 */
2156
2157 /* Perform dynamic lease related update work. */
2158 if (reply->lease != NULL) {
2159 /* Advance (or rewind) the valid lifetime. */
2160 reply->lease->valid_lifetime_end_time = cur_time +
2161 reply->send_valid;
2162 renew_lease6(reply->lease->ipv6_pool, reply->lease);
2163
2164 status = ia_na_add_iaaddr(reply->ia_na, reply->lease, MDL);
2165 if (status != ISC_R_SUCCESS) {
2166 log_fatal("reply_process_addr: Unable to attach lease "
2167 "to new IA: %s", isc_result_totext(status));
2168 }
2169
2170 /*
2171 * If this is a new lease, make sure it is attached somewhere.
2172 */
2173 if (reply->lease->ia_na == NULL) {
2174 ia_na_reference(&reply->lease->ia_na, reply->ia_na,
2175 MDL);
2176 }
2177 }
2178
2179 /* Bring a copy of the relevant options into the IA scope. */
2180 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
2181 reply->packet->options, reply->reply_ia,
2182 scope, group, root_group);
2183
2184 cleanup:
2185 if (data.data != NULL)
2186 data_string_forget(&data, MDL);
2187
2188 if (status == ISC_R_SUCCESS)
2189 reply->client_resources++;
2190
2191 return status;
2192 }
2193
2194 /* Simply send an IAADDR within the IA_NA scope as described. */
2195 static isc_result_t
2196 reply_process_send_addr(struct reply_state *reply, struct iaddr *addr) {
2197 isc_result_t status = ISC_R_SUCCESS;
2198 struct data_string data;
2199
2200 memset(&data, 0, sizeof(data));
2201
2202 /* Now append the lease. */
2203 data.len = IAADDR_OFFSET;
2204 if (!buffer_allocate(&data.buffer, data.len, MDL)) {
2205 log_error("reply_process_send_addr: out of memory allocating "
2206 "new IAADDR buffer.");
2207 status = ISC_R_NOMEMORY;
2208 goto cleanup;
2209 }
2210 data.data = data.buffer->data;
2211
2212 memcpy(data.buffer->data, addr->iabuf, 16);
2213 putULong(data.buffer->data + 16, reply->send_prefer);
2214 putULong(data.buffer->data + 20, reply->send_valid);
2215
2216 if (!append_option_buffer(&dhcpv6_universe, reply->reply_ia,
2217 data.buffer, data.buffer->data,
2218 data.len, D6O_IAADDR, 0)) {
2219 log_error("reply_process_send_addr: unable to save IAADDR "
2220 "option");
2221 status = ISC_R_FAILURE;
2222 goto cleanup;
2223 }
2224
2225 reply->ia_addrs_included = ISC_TRUE;
2226
2227 cleanup:
2228 if (data.data != NULL)
2229 data_string_forget(&data, MDL);
2230
2231 return status;
2232 }
2233
2234 /* Choose the better of two leases. */
2235 static struct iaaddr *
2236 lease_compare(struct iaaddr *alpha, struct iaaddr *beta) {
2237 if (alpha == NULL)
2238 return beta;
2239 if (beta == NULL)
2240 return alpha;
2241
2242 switch(alpha->state) {
2243 case FTS_ACTIVE:
2244 switch(beta->state) {
2245 case FTS_ACTIVE:
2246 /* Choose the lease with the longest lifetime (most
2247 * likely the most recently allocated).
2248 */
2249 if (alpha->valid_lifetime_end_time <
2250 beta->valid_lifetime_end_time)
2251 return beta;
2252 else
2253 return alpha;
2254
2255 case FTS_EXPIRED:
2256 case FTS_ABANDONED:
2257 return alpha;
2258
2259 default:
2260 log_fatal("Impossible condition at %s:%d.", MDL);
2261 }
2262 break;
2263
2264 case FTS_EXPIRED:
2265 switch (beta->state) {
2266 case FTS_ACTIVE:
2267 return beta;
2268
2269 case FTS_EXPIRED:
2270 /* Choose the most recently expired lease. */
2271 if (alpha->valid_lifetime_end_time <
2272 beta->valid_lifetime_end_time)
2273 return beta;
2274 else
2275 return alpha;
2276
2277 case FTS_ABANDONED:
2278 return alpha;
2279
2280 default:
2281 log_fatal("Impossible condition at %s:%d.", MDL);
2282 }
2283 break;
2284
2285 case FTS_ABANDONED:
2286 switch (beta->state) {
2287 case FTS_ACTIVE:
2288 case FTS_EXPIRED:
2289 return alpha;
2290
2291 case FTS_ABANDONED:
2292 /* Choose the lease that was abandoned longest ago. */
2293 if (alpha->valid_lifetime_end_time <
2294 beta->valid_lifetime_end_time)
2295 return alpha;
2296
2297 default:
2298 log_fatal("Impossible condition at %s:%d.", MDL);
2299 }
2300 break;
2301
2302 default:
2303 log_fatal("Impossible condition at %s:%d.", MDL);
2304 }
2305
2306 log_fatal("Triple impossible condition at %s:%d.", MDL);
2307 return NULL;
2308 }
2309
2310 /*
2311 * Solicit is how a client starts requesting addresses.
2312 *
2313 * If the client asks for rapid commit, and we support it, we will
2314 * allocate the addresses and reply.
2315 *
2316 * Otherwise we will send an advertise message.
2317 */
2318
2319 static void
2320 dhcpv6_solicit(struct data_string *reply_ret, struct packet *packet) {
2321 struct data_string client_id;
2322
2323 /*
2324 * Validate our input.
2325 */
2326 if (!valid_client_msg(packet, &client_id)) {
2327 return;
2328 }
2329
2330 lease_to_client(reply_ret, packet, &client_id, NULL);
2331
2332 /*
2333 * Clean up.
2334 */
2335 data_string_forget(&client_id, MDL);
2336 }
2337
2338 /*
2339 * Request is how a client actually requests addresses.
2340 *
2341 * Very similar to Solicit handling, except the server DUID is required.
2342 */
2343
2344 /* TODO: reject unicast messages, unless we set unicast option */
2345 static void
2346 dhcpv6_request(struct data_string *reply_ret, struct packet *packet) {
2347 struct data_string client_id;
2348 struct data_string server_id;
2349
2350 /*
2351 * Validate our input.
2352 */
2353 if (!valid_client_resp(packet, &client_id, &server_id)) {
2354 return;
2355 }
2356
2357 /*
2358 * Issue our lease.
2359 */
2360 lease_to_client(reply_ret, packet, &client_id, &server_id);
2361
2362 /*
2363 * Cleanup.
2364 */
2365 data_string_forget(&client_id, MDL);
2366 data_string_forget(&server_id, MDL);
2367 }
2368
2369 /* Find a DHCPv6 packet's shared network from hints in the packet.
2370 */
2371 static isc_result_t
2372 shared_network_from_packet6(struct shared_network **shared,
2373 struct packet *packet)
2374 {
2375 const struct packet *chk_packet;
2376 const struct in6_addr *link_addr, *first_link_addr;
2377 struct iaddr tmp_addr;
2378 struct subnet *subnet;
2379 isc_result_t status;
2380
2381 if ((shared == NULL) || (*shared != NULL) || (packet == NULL))
2382 return ISC_R_INVALIDARG;
2383
2384 /*
2385 * First, find the link address where the packet from the client
2386 * first appeared (if this packet was relayed).
2387 */
2388 first_link_addr = NULL;
2389 chk_packet = packet->dhcpv6_container_packet;
2390 while (chk_packet != NULL) {
2391 link_addr = &chk_packet->dhcpv6_link_address;
2392 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr) &&
2393 !IN6_IS_ADDR_LINKLOCAL(link_addr)) {
2394 first_link_addr = link_addr;
2395 }
2396 chk_packet = chk_packet->dhcpv6_container_packet;
2397 }
2398
2399 /*
2400 * If there is a relayed link address, find the subnet associated
2401 * with that, and use that to get the appropriate
2402 * shared_network.
2403 */
2404 if (first_link_addr != NULL) {
2405 tmp_addr.len = sizeof(*first_link_addr);
2406 memcpy(tmp_addr.iabuf,
2407 first_link_addr, sizeof(*first_link_addr));
2408 subnet = NULL;
2409 if (!find_subnet(&subnet, tmp_addr, MDL)) {
2410 log_debug("No subnet found for link-address %s.",
2411 piaddr(tmp_addr));
2412 return ISC_R_NOTFOUND;
2413 }
2414 status = shared_network_reference(shared,
2415 subnet->shared_network, MDL);
2416 subnet_dereference(&subnet, MDL);
2417
2418 /*
2419 * If there is no link address, we will use the interface
2420 * that this packet came in on to pick the shared_network.
2421 */
2422 } else {
2423 status = shared_network_reference(shared,
2424 packet->interface->shared_network,
2425 MDL);
2426 }
2427
2428 return status;
2429 }
2430
2431 /*
2432 * When a client thinks it might be on a new link, it sends a
2433 * Confirm message.
2434 *
2435 * From RFC3315 section 18.2.2:
2436 *
2437 * When the server receives a Confirm message, the server determines
2438 * whether the addresses in the Confirm message are appropriate for the
2439 * link to which the client is attached. If all of the addresses in the
2440 * Confirm message pass this test, the server returns a status of
2441 * Success. If any of the addresses do not pass this test, the server
2442 * returns a status of NotOnLink. If the server is unable to perform
2443 * this test (for example, the server does not have information about
2444 * prefixes on the link to which the client is connected), or there were
2445 * no addresses in any of the IAs sent by the client, the server MUST
2446 * NOT send a reply to the client.
2447 */
2448
2449 static void
2450 dhcpv6_confirm(struct data_string *reply_ret, struct packet *packet) {
2451 struct shared_network *shared;
2452 struct subnet *subnet;
2453 struct option_cache *ia, *ta, *oc;
2454 struct data_string cli_enc_opt_data, iaaddr, client_id, packet_oro;
2455 struct option_state *cli_enc_opt_state, *opt_state;
2456 struct iaddr cli_addr;
2457 int pass;
2458 isc_boolean_t inappropriate, has_addrs;
2459 char reply_data[65536];
2460 struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data;
2461 int reply_ofs = (int)((char *)reply->options - (char *)reply);
2462
2463 /*
2464 * Basic client message validation.
2465 */
2466 memset(&client_id, 0, sizeof(client_id));
2467 if (!valid_client_msg(packet, &client_id)) {
2468 return;
2469 }
2470
2471 /* Do not process Confirms that do not have IA's we do not recognize.
2472 */
2473 ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
2474 ta = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_TA);
2475 if ((ia == NULL) && (ta == NULL))
2476 return;
2477
2478 /*
2479 * Bit of variable initialization.
2480 */
2481 opt_state = cli_enc_opt_state = NULL;
2482 memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
2483 memset(&iaaddr, 0, sizeof(iaaddr));
2484 memset(&packet_oro, 0, sizeof(packet_oro));
2485
2486 /* Determine what shared network the client is connected to. We
2487 * must not respond if we don't have any information about the
2488 * network the client is on.
2489 */
2490 shared = NULL;
2491 if ((shared_network_from_packet6(&shared, packet) != ISC_R_SUCCESS) ||
2492 (shared == NULL))
2493 goto exit;
2494
2495 /* If there are no recorded subnets, then we have no
2496 * information about this subnet - ignore Confirms.
2497 */
2498 subnet = shared->subnets;
2499 if (subnet == NULL)
2500 goto exit;
2501
2502 /* Are the addresses in all the IA's appropriate for that link? */
2503 has_addrs = inappropriate = ISC_FALSE;
2504 pass = D6O_IA_NA;
2505 while(!inappropriate) {
2506 /* If we've reached the end of the IA_NA pass, move to the
2507 * IA_TA pass.
2508 */
2509 if ((pass == D6O_IA_NA) && (ia == NULL)) {
2510 pass = D6O_IA_TA;
2511 ia = ta;
2512 }
2513
2514 /* If we've reached the end of all passes, we're done. */
2515 if (ia == NULL)
2516 break;
2517
2518 if (((pass == D6O_IA_NA) &&
2519 !get_encapsulated_IA_state(&cli_enc_opt_state,
2520 &cli_enc_opt_data,
2521 packet, ia, IA_NA_OFFSET)) ||
2522 ((pass == D6O_IA_TA) &&
2523 !get_encapsulated_IA_state(&cli_enc_opt_state,
2524 &cli_enc_opt_data,
2525 packet, ia, IA_TA_OFFSET))) {
2526 goto exit;
2527 }
2528
2529 oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
2530 D6O_IAADDR);
2531
2532 for ( ; oc != NULL ; oc = oc->next) {
2533 if (!evaluate_option_cache(&iaaddr, packet, NULL, NULL,
2534 packet->options, NULL,
2535 &global_scope, oc, MDL) ||
2536 (iaaddr.len < IAADDR_OFFSET)) {
2537 log_error("dhcpv6_confirm: "
2538 "error evaluating IAADDR.");
2539 goto exit;
2540 }
2541
2542 /* Copy out the IPv6 address for processing. */
2543 cli_addr.len = 16;
2544 memcpy(cli_addr.iabuf, iaaddr.data, 16);
2545
2546 data_string_forget(&iaaddr, MDL);
2547
2548 /* Record that we've processed at least one address. */
2549 has_addrs = ISC_TRUE;
2550
2551 /* Find out if any subnets cover this address. */
2552 for (subnet = shared->subnets ; subnet != NULL ;
2553 subnet = subnet->next_sibling) {
2554 if (addr_eq(subnet_number(cli_addr,
2555 subnet->netmask),
2556 subnet->net))
2557 break;
2558 }
2559
2560 /* If we reach the end of the subnet list, and no
2561 * subnet matches the client address, then it must
2562 * be inappropriate to the link (so far as our
2563 * configuration says). Once we've found one
2564 * inappropriate address, there is no reason to
2565 * continue searching.
2566 */
2567 if (subnet == NULL) {
2568 inappropriate = ISC_TRUE;
2569 break;
2570 }
2571 }
2572
2573 option_state_dereference(&cli_enc_opt_state, MDL);
2574 data_string_forget(&cli_enc_opt_data, MDL);
2575
2576 /* Advance to the next IA_*. */
2577 ia = ia->next;
2578 }
2579
2580 /* If the client supplied no addresses, do not reply. */
2581 if (!has_addrs)
2582 goto exit;
2583
2584 /*
2585 * Set up reply.
2586 */
2587 if (!start_reply(packet, &client_id, NULL, &opt_state, reply)) {
2588 goto exit;
2589 }
2590
2591 /*
2592 * Set our status.
2593 */
2594 if (inappropriate) {
2595 if (!set_status_code(STATUS_NotOnLink,
2596 "Some of the addresses are not on link.",
2597 opt_state)) {
2598 goto exit;
2599 }
2600 } else {
2601 if (!set_status_code(STATUS_Success,
2602 "All addresses still on link.",
2603 opt_state)) {
2604 goto exit;
2605 }
2606 }
2607
2608 /*
2609 * Only one option: add it.
2610 */
2611 reply_ofs += store_options6(reply_data+reply_ofs,
2612 sizeof(reply_data)-reply_ofs,
2613 opt_state, packet,
2614 required_opts, &packet_oro);
2615
2616 /*
2617 * Return our reply to the caller.
2618 */
2619 reply_ret->len = reply_ofs;
2620 reply_ret->buffer = NULL;
2621 if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) {
2622 log_fatal("No memory to store reply.");
2623 }
2624 reply_ret->data = reply_ret->buffer->data;
2625 memcpy(reply_ret->buffer->data, reply, reply_ofs);
2626
2627 exit:
2628 /* Cleanup any stale data strings. */
2629 if (cli_enc_opt_data.buffer != NULL)
2630 data_string_forget(&cli_enc_opt_data, MDL);
2631 if (iaaddr.buffer != NULL)
2632 data_string_forget(&iaaddr, MDL);
2633 if (client_id.buffer != NULL)
2634 data_string_forget(&client_id, MDL);
2635 if (packet_oro.buffer != NULL)
2636 data_string_forget(&packet_oro, MDL);
2637
2638 /* Release any stale option states. */
2639 if (cli_enc_opt_state != NULL)
2640 option_state_dereference(&cli_enc_opt_state, MDL);
2641 if (opt_state != NULL)
2642 option_state_dereference(&opt_state, MDL);
2643 }
2644
2645 /*
2646 * Renew is when a client wants to extend its lease, at time T1.
2647 *
2648 * We handle this the same as if the client wants a new lease, except
2649 * for the error code of when addresses don't match.
2650 */
2651
2652 /* TODO: reject unicast messages, unless we set unicast option */
2653 static void
2654 dhcpv6_renew(struct data_string *reply, struct packet *packet) {
2655 struct data_string client_id;
2656 struct data_string server_id;
2657
2658 /*
2659 * Validate the request.
2660 */
2661 if (!valid_client_resp(packet, &client_id, &server_id)) {
2662 return;
2663 }
2664
2665 /*
2666 * Renew our lease.
2667 */
2668 lease_to_client(reply, packet, &client_id, &server_id);
2669
2670 /*
2671 * Cleanup.
2672 */
2673 data_string_forget(&server_id, MDL);
2674 data_string_forget(&client_id, MDL);
2675 }
2676
2677 /*
2678 * Rebind is when a client wants to extend its lease, at time T2.
2679 *
2680 * We handle this the same as if the client wants a new lease, except
2681 * for the error code of when addresses don't match.
2682 */
2683
2684 static void
2685 dhcpv6_rebind(struct data_string *reply, struct packet *packet) {
2686 struct data_string client_id;
2687
2688 if (!valid_client_msg(packet, &client_id)) {
2689 return;
2690 }
2691
2692 lease_to_client(reply, packet, &client_id, NULL);
2693
2694 data_string_forget(&client_id, MDL);
2695 }
2696
2697 static void
2698 ia_na_match_decline(const struct data_string *client_id,
2699 const struct data_string *iaaddr,
2700 struct iaaddr *lease)
2701 {
2702 char tmp_addr[INET6_ADDRSTRLEN];
2703
2704 log_error("Client %s reports address %s is "
2705 "already in use by another host!",
2706 print_hex_1(client_id->len, client_id->data, 60),
2707 inet_ntop(AF_INET6, iaaddr->data,
2708 tmp_addr, sizeof(tmp_addr)));
2709 if (lease != NULL) {
2710 decline_lease6(lease->ipv6_pool, lease);
2711 write_ia(lease->ia_na);
2712 }
2713 }
2714
2715 static void
2716 ia_na_nomatch_decline(const struct data_string *client_id,
2717 const struct data_string *iaaddr,
2718 u_int32_t *ia_na_id,
2719 struct packet *packet,
2720 char *reply_data,
2721 int *reply_ofs,
2722 int reply_len)
2723 {
2724 char tmp_addr[INET6_ADDRSTRLEN];
2725 struct option_state *host_opt_state;
2726 int len;
2727
2728 log_info("Client %s declines address %s, which is not offered to it.",
2729 print_hex_1(client_id->len, client_id->data, 60),
2730 inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
2731
2732 /*
2733 * Create state for this IA_NA.
2734 */
2735 host_opt_state = NULL;
2736 if (!option_state_allocate(&host_opt_state, MDL)) {
2737 log_error("ia_na_nomatch_decline: out of memory "
2738 "allocating option_state.");
2739 goto exit;
2740 }
2741
2742 if (!set_status_code(STATUS_NoBinding, "Decline for unknown address.",
2743 host_opt_state)) {
2744 goto exit;
2745 }
2746
2747 /*
2748 * Insure we have enough space
2749 */
2750 if (reply_len < (*reply_ofs + 16)) {
2751 log_error("ia_na_nomatch_decline: "
2752 "out of space for reply packet.");
2753 goto exit;
2754 }
2755
2756 /*
2757 * Put our status code into the reply packet.
2758 */
2759 len = store_options6(reply_data+(*reply_ofs)+16,
2760 reply_len-(*reply_ofs)-16,
2761 host_opt_state, packet,
2762 required_opts_STATUS_CODE, NULL);
2763
2764 /*
2765 * Store the non-encapsulated option data for this
2766 * IA_NA into our reply packet. Defined in RFC 3315,
2767 * section 22.4.
2768 */
2769 /* option number */
2770 putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_NA);
2771 /* option length */
2772 putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
2773 /* IA_NA, copied from the client */
2774 memcpy(reply_data+(*reply_ofs)+4, ia_na_id, 4);
2775 /* t1 and t2, odd that we need them, but here it is */
2776 putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
2777 putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
2778
2779 /*
2780 * Get ready for next IA_NA.
2781 */
2782 *reply_ofs += (len + 16);
2783
2784 exit:
2785 option_state_dereference(&host_opt_state, MDL);
2786 }
2787
2788 static void
2789 iterate_over_ia_na(struct data_string *reply_ret,
2790 struct packet *packet,
2791 const struct data_string *client_id,
2792 const struct data_string *server_id,
2793 const char *packet_type,
2794 void (*ia_na_match)(),
2795 void (*ia_na_nomatch)())
2796 {
2797 struct option_state *opt_state;
2798 struct host_decl *packet_host;
2799 struct option_cache *ia;
2800 struct option_cache *oc;
2801 /* cli_enc_... variables come from the IA_NA/IA_TA options */
2802 struct data_string cli_enc_opt_data;
2803 struct option_state *cli_enc_opt_state;
2804 struct host_decl *host;
2805 struct option_state *host_opt_state;
2806 struct data_string iaaddr;
2807 struct data_string fixed_addr;
2808 int iaaddr_is_found;
2809 char reply_data[65536];
2810 struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data;
2811 int reply_ofs = (int)((char *)reply->options - (char *)reply);
2812 char status_msg[32];
2813 struct iaaddr *lease;
2814 struct ia_na *existing_ia_na;
2815 int i;
2816 struct data_string key;
2817 u_int32_t iaid;
2818
2819 /*
2820 * Initialize to empty values, in case we have to exit early.
2821 */
2822 opt_state = NULL;
2823 memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
2824 cli_enc_opt_state = NULL;
2825 memset(&iaaddr, 0, sizeof(iaaddr));
2826 memset(&fixed_addr, 0, sizeof(fixed_addr));
2827 host_opt_state = NULL;
2828 lease = NULL;
2829
2830 /*
2831 * Find the host record that matches from the packet, if any.
2832 */
2833 packet_host = NULL;
2834 if (!find_hosts_by_uid(&packet_host,
2835 client_id->data, client_id->len, MDL)) {
2836 packet_host = NULL;
2837 /*
2838 * Note: In general, we don't expect a client to provide
2839 * enough information to match by option for these
2840 * types of messages, but if we don't have a UID
2841 * match we can check anyway.
2842 */
2843 if (!find_hosts_by_option(&packet_host,
2844 packet, packet->options, MDL)) {
2845 packet_host = NULL;
2846 }
2847 }
2848
2849 /*
2850 * Set our reply information.
2851 */
2852 reply->msg_type = DHCPV6_REPLY;
2853 memcpy(reply->transaction_id, packet->dhcpv6_transaction_id,
2854 sizeof(reply->transaction_id));
2855
2856 /*
2857 * Build our option state for reply.
2858 */
2859 opt_state = NULL;
2860 if (!option_state_allocate(&opt_state, MDL)) {
2861 log_error("iterate_over_ia_na: no memory for option_state.");
2862 goto exit;
2863 }
2864 execute_statements_in_scope(NULL, packet, NULL, NULL,
2865 packet->options, opt_state,
2866 &global_scope, root_group, NULL);
2867
2868 /*
2869 * RFC 3315, section 18.2.7 tells us which options to include.
2870 */
2871 oc = lookup_option(&dhcpv6_universe, opt_state, D6O_SERVERID);
2872 if (oc == NULL) {
2873 if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
2874 (unsigned char *)server_duid.data,
2875 server_duid.len, D6O_SERVERID, 0)) {
2876 log_error("iterate_over_ia_na: "
2877 "error saving server identifier.");
2878 goto exit;
2879 }
2880 }
2881
2882 if (!save_option_buffer(&dhcpv6_universe, opt_state,
2883 client_id->buffer,
2884 (unsigned char *)client_id->data,
2885 client_id->len,
2886 D6O_CLIENTID, 0)) {
2887 log_error("iterate_over_ia_na: "
2888 "error saving client identifier.");
2889 goto exit;
2890 }
2891
2892 snprintf(status_msg, sizeof(status_msg), "%s received.", packet_type);
2893 if (!set_status_code(STATUS_Success, status_msg, opt_state)) {
2894 goto exit;
2895 }
2896
2897 /*
2898 * Add our options that are not associated with any IA_NA or IA_TA.
2899 */
2900 reply_ofs += store_options6(reply_data+reply_ofs,
2901 sizeof(reply_data)-reply_ofs,
2902 opt_state, packet,
2903 required_opts, NULL);
2904
2905 /*
2906 * Loop through the IA_NA reported by the client, and deal with
2907 * addresses reported as already in use.
2908 */
2909 for (ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
2910 ia != NULL; ia = ia->next) {
2911 iaaddr_is_found = 0;
2912
2913 if (!get_encapsulated_IA_state(&cli_enc_opt_state,
2914 &cli_enc_opt_data,
2915 packet, ia, IA_NA_OFFSET)) {
2916 goto exit;
2917 }
2918
2919 iaid = getULong(cli_enc_opt_data.data);
2920
2921 /*
2922 * XXX: It is possible that we can get multiple addresses
2923 * sent by the client. We don't send multiple
2924 * addresses, so this indicates a client error.
2925 * We should check for multiple IAADDR options, log
2926 * if found, and set as an error.
2927 */
2928 oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
2929 D6O_IAADDR);
2930 if (oc == NULL) {
2931 /* no address given for this IA, ignore */
2932 option_state_dereference(&cli_enc_opt_state, MDL);
2933 data_string_forget(&cli_enc_opt_data, MDL);
2934 continue;
2935 }
2936
2937 memset(&iaaddr, 0, sizeof(iaaddr));
2938 if (!evaluate_option_cache(&iaaddr, packet, NULL, NULL,
2939 packet->options, NULL,
2940 &global_scope, oc, MDL)) {
2941 log_error("iterate_over_ia_na: "
2942 "error evaluating IAADDR.");
2943 goto exit;
2944 }
2945
2946 /*
2947 * Now we need to figure out which host record matches
2948 * this IA_NA and IAADDR.
2949 *
2950 * XXX: We don't currently track IA_NA separately, but
2951 * we will need to do this!
2952 */
2953 host = NULL;
2954 if (!find_hosts_by_option(&host, packet,
2955 cli_enc_opt_state, MDL)) {
2956 if (packet_host != NULL) {
2957 host = packet_host;
2958 } else {
2959 host = NULL;
2960 }
2961 }
2962 while (host != NULL) {
2963 if (host->fixed_addr != NULL) {
2964 if (!evaluate_option_cache(&fixed_addr, NULL,
2965 NULL, NULL, NULL,
2966 NULL, &global_scope,
2967 host->fixed_addr,
2968 MDL)) {
2969 log_error("iterate_over_ia_na: error "
2970 "evaluating host address.");
2971 goto exit;
2972 }
2973 if ((iaaddr.len >= 16) &&
2974 !memcmp(fixed_addr.data, iaaddr.data, 16)) {
2975 data_string_forget(&fixed_addr, MDL);
2976 break;
2977 }
2978 data_string_forget(&fixed_addr, MDL);
2979 }
2980 host = host->n_ipaddr;
2981 }
2982
2983 if ((host == NULL) && (iaaddr.len >= IAADDR_OFFSET)) {
2984 /*
2985 * Find existing IA_NA.
2986 */
2987 if (ia_make_key(&key, iaid,
2988 (char *)client_id->data,
2989 client_id->len,
2990 MDL) != ISC_R_SUCCESS) {
2991 log_fatal("iterate_over_ia_na: no memory for "
2992 "key.");
2993 }
2994
2995 existing_ia_na = NULL;
2996 if (ia_na_hash_lookup(&existing_ia_na, ia_na_active,
2997 (unsigned char *)key.data,
2998 key.len, MDL)) {
2999 /*
3000 * Make sure this address is in the IA_NA.
3001 */
3002 for (i=0; i<existing_ia_na->num_iaaddr; i++) {
3003 struct iaaddr *tmp;
3004 struct in6_addr *in6_addr;
3005
3006 tmp = existing_ia_na->iaaddr[i];
3007 in6_addr = &tmp->addr;
3008 if (memcmp(in6_addr,
3009 iaaddr.data, 16) == 0) {
3010 iaaddr_reference(&lease,
3011 tmp, MDL);
3012 break;
3013 }
3014 }
3015 }
3016
3017 data_string_forget(&key, MDL);
3018 }
3019
3020 if ((host != NULL) || (lease != NULL)) {
3021 ia_na_match(client_id, &iaaddr, lease);
3022 } else {
3023 ia_na_nomatch(client_id, &iaaddr,
3024 (u_int32_t *)cli_enc_opt_data.data,
3025 packet, reply_data, &reply_ofs,
3026 sizeof(reply_data));
3027 }
3028
3029 if (lease != NULL) {
3030 iaaddr_dereference(&lease, MDL);
3031 }
3032
3033 data_string_forget(&iaaddr, MDL);
3034 option_state_dereference(&cli_enc_opt_state, MDL);
3035 data_string_forget(&cli_enc_opt_data, MDL);
3036 }
3037
3038 /*
3039 * Return our reply to the caller.
3040 */
3041 reply_ret->len = reply_ofs;
3042 reply_ret->buffer = NULL;
3043 if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) {
3044 log_fatal("No memory to store reply.");
3045 }
3046 reply_ret->data = reply_ret->buffer->data;
3047 memcpy(reply_ret->buffer->data, reply, reply_ofs);
3048
3049 exit:
3050 if (lease != NULL) {
3051 iaaddr_dereference(&lease, MDL);
3052 }
3053 if (host_opt_state != NULL) {
3054 option_state_dereference(&host_opt_state, MDL);
3055 }
3056 if (fixed_addr.buffer != NULL) {
3057 data_string_forget(&fixed_addr, MDL);
3058 }
3059 if (iaaddr.buffer != NULL) {
3060 data_string_forget(&iaaddr, MDL);
3061 }
3062 if (cli_enc_opt_state != NULL) {
3063 option_state_dereference(&cli_enc_opt_state, MDL);
3064 }
3065 if (cli_enc_opt_data.buffer != NULL) {
3066 data_string_forget(&cli_enc_opt_data, MDL);
3067 }
3068 if (opt_state != NULL) {
3069 option_state_dereference(&opt_state, MDL);
3070 }
3071 }
3072
3073 /*
3074 * Decline means a client has detected that something else is using an
3075 * address we gave it.
3076 *
3077 * Since we're only dealing with fixed leases for now, there's not
3078 * much we can do, other that log the occurrence.
3079 *
3080 * When we start issuing addresses from pools, then we will have to
3081 * record our declined addresses and issue another. In general with
3082 * IPv6 there is no worry about DoS by clients exhausting space, but
3083 * we still need to be aware of this possibility.
3084 */
3085
3086 /* TODO: reject unicast messages, unless we set unicast option */
3087 /* TODO: IA_TA */
3088 static void
3089 dhcpv6_decline(struct data_string *reply, struct packet *packet) {
3090 struct data_string client_id;
3091 struct data_string server_id;
3092
3093 /*
3094 * Validate our input.
3095 */
3096 if (!valid_client_resp(packet, &client_id, &server_id)) {
3097 return;
3098 }
3099
3100 /*
3101 * And operate on each IA_NA in this packet.
3102 */
3103 iterate_over_ia_na(reply, packet, &client_id, &server_id, "Decline",
3104 ia_na_match_decline, ia_na_nomatch_decline);
3105 }
3106
3107 static void
3108 ia_na_match_release(const struct data_string *client_id,
3109 const struct data_string *iaaddr,
3110 struct iaaddr *lease)
3111 {
3112 char tmp_addr[INET6_ADDRSTRLEN];
3113
3114 log_info("Client %s releases address %s",
3115 print_hex_1(client_id->len, client_id->data, 60),
3116 inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
3117 if (lease != NULL) {
3118 release_lease6(lease->ipv6_pool, lease);
3119 write_ia(lease->ia_na);
3120 }
3121 }
3122
3123 static void
3124 ia_na_nomatch_release(const struct data_string *client_id,
3125 const struct data_string *iaaddr,
3126 u_int32_t *ia_na_id,
3127 struct packet *packet,
3128 char *reply_data,
3129 int *reply_ofs,
3130 int reply_len)
3131 {
3132 char tmp_addr[INET6_ADDRSTRLEN];
3133 struct option_state *host_opt_state;
3134 int len;
3135
3136 log_info("Client %s releases address %s, which is not leased to it.",
3137 print_hex_1(client_id->len, client_id->data, 60),
3138 inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
3139
3140 /*
3141 * Create state for this IA_NA.
3142 */
3143 host_opt_state = NULL;
3144 if (!option_state_allocate(&host_opt_state, MDL)) {
3145 log_error("ia_na_nomatch_release: out of memory "
3146 "allocating option_state.");
3147 goto exit;
3148 }
3149
3150 if (!set_status_code(STATUS_NoBinding,
3151 "Release for non-leased address.",
3152 host_opt_state)) {
3153 goto exit;
3154 }
3155
3156 /*
3157 * Insure we have enough space
3158 */
3159 if (reply_len < (*reply_ofs + 16)) {
3160 log_error("ia_na_nomatch_release: "
3161 "out of space for reply packet.");
3162 goto exit;
3163 }
3164
3165 /*
3166 * Put our status code into the reply packet.
3167 */
3168 len = store_options6(reply_data+(*reply_ofs)+16,
3169 reply_len-(*reply_ofs)-16,
3170 host_opt_state, packet,
3171 required_opts_STATUS_CODE, NULL);
3172
3173 /*
3174 * Store the non-encapsulated option data for this
3175 * IA_NA into our reply packet. Defined in RFC 3315,
3176 * section 22.4.
3177 */
3178 /* option number */
3179 putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_NA);
3180 /* option length */
3181 putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
3182 /* IA_NA, copied from the client */
3183 memcpy(reply_data+(*reply_ofs)+4, ia_na_id, 4);
3184 /* t1 and t2, odd that we need them, but here it is */
3185 putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
3186 putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
3187
3188 /*
3189 * Get ready for next IA_NA.
3190 */
3191 *reply_ofs += (len + 16);
3192
3193 exit:
3194 option_state_dereference(&host_opt_state, MDL);
3195 }
3196
3197 /*
3198 * Release means a client is done with the addresses.
3199 */
3200
3201 /* TODO: reject unicast messages, unless we set unicast option */
3202 static void
3203 dhcpv6_release(struct data_string *reply, struct packet *packet) {
3204 struct data_string client_id;
3205 struct data_string server_id;
3206
3207 /*
3208 * Validate our input.
3209 */
3210 if (!valid_client_resp(packet, &client_id, &server_id)) {
3211 return;
3212 }
3213
3214 /*
3215 * And operate on each IA_NA in this packet.
3216 */
3217 iterate_over_ia_na(reply, packet, &client_id, &server_id, "Release",
3218 ia_na_match_release, ia_na_nomatch_release);
3219
3220 data_string_forget(&server_id, MDL);
3221 data_string_forget(&client_id, MDL);
3222 }
3223
3224 /*
3225 * Information-Request is used by clients who have obtained an address
3226 * from other means, but want configuration information from the server.
3227 */
3228
3229 static void
3230 dhcpv6_information_request(struct data_string *reply, struct packet *packet) {
3231 struct data_string client_id;
3232 struct data_string server_id;
3233
3234 /*
3235 * Validate our input.
3236 */
3237 if (!valid_client_info_req(packet, &server_id)) {
3238 return;
3239 }
3240
3241 /*
3242 * Get our client ID, if there is one.
3243 */
3244 memset(&client_id, 0, sizeof(client_id));
3245 if (get_client_id(packet, &client_id) != ISC_R_SUCCESS) {
3246 data_string_forget(&client_id, MDL);
3247 }
3248
3249 /*
3250 * Use the lease_to_client() function. This will work fine,
3251 * because the valid_client_info_req() insures that we
3252 * don't have any IA_NA or IA_TA that would cause us to
3253 * allocate addresses to the client.
3254 */
3255 lease_to_client(reply, packet, &client_id,
3256 server_id.data != NULL ? &server_id : NULL);
3257
3258 /*
3259 * Cleanup.
3260 */
3261 if (client_id.data != NULL) {
3262 data_string_forget(&client_id, MDL);
3263 }
3264 data_string_forget(&server_id, MDL);
3265 }
3266
3267 /*
3268 * The Relay-forw message is sent by relays. It typically contains a
3269 * single option, which encapsulates an entire packet.
3270 *
3271 * We need to build an encapsulated reply.
3272 */
3273
3274 /* XXX: this is very, very similar to do_packet6(), and should probably
3275 be combined in a clever way */
3276 static void
3277 dhcpv6_relay_forw(struct data_string *reply_ret, struct packet *packet) {
3278 struct dhcpv6_relay_packet reply;
3279 struct option_cache *oc;
3280 struct data_string enc_opt_data;
3281 struct packet *enc_packet;
3282 unsigned char msg_type;
3283 const struct dhcpv6_packet *msg;
3284 const struct dhcpv6_relay_packet *relay;
3285 struct data_string enc_reply;
3286 char link_addr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
3287 char peer_addr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
3288 struct data_string interface_id;
3289
3290 /*
3291 * Initialize variables for early exit.
3292 */
3293 memset(&enc_opt_data, 0, sizeof(enc_opt_data));
3294 enc_packet = NULL;
3295 memset(&enc_reply, 0, sizeof(enc_reply));
3296 memset(&interface_id, 0, sizeof(interface_id));
3297
3298 /*
3299 * Get our encapsulated relay message.
3300 */
3301 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_RELAY_MSG);
3302 if (oc == NULL) {
3303 inet_ntop(AF_INET6, &packet->dhcpv6_link_address,
3304 link_addr, sizeof(link_addr));
3305 inet_ntop(AF_INET6, &packet->dhcpv6_peer_address,
3306 peer_addr, sizeof(peer_addr));
3307 log_info("Relay-forward from %s with link address=%s and "
3308 "peer address=%s missing Relay Message option.",
3309 piaddr(packet->client_addr), link_addr, peer_addr);
3310 goto exit;
3311 }
3312
3313 memset(&enc_opt_data, 0, sizeof(enc_opt_data));
3314 if (!evaluate_option_cache(&enc_opt_data, NULL, NULL, NULL,
3315 NULL, NULL, &global_scope, oc, MDL)) {
3316 log_error("dhcpv6_forw_relay: error evaluating "
3317 "relayed message.");
3318 goto exit;
3319 }
3320
3321 if (!packet6_len_okay((char *)enc_opt_data.data, enc_opt_data.len)) {
3322 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
3323 goto exit;
3324 }
3325
3326 /*
3327 * Build a packet structure from this encapsulated packet.
3328 */
3329 enc_packet = NULL;
3330 if (!packet_allocate(&enc_packet, MDL)) {
3331 log_error("dhcpv6_forw_relay: "
3332 "no memory for encapsulated packet.");
3333 goto exit;
3334 }
3335
3336 if (!option_state_allocate(&enc_packet->options, MDL)) {
3337 log_error("dhcpv6_forw_relay: "
3338 "no memory for encapsulated packet's options.");
3339 goto exit;
3340 }
3341
3342 enc_packet->client_port = packet->client_port;
3343 enc_packet->client_addr = packet->client_addr;
3344 enc_packet->dhcpv6_container_packet = packet;
3345
3346 msg_type = enc_opt_data.data[0];
3347 if ((msg_type == DHCPV6_RELAY_FORW) ||
3348 (msg_type == DHCPV6_RELAY_REPL)) {
3349 relay = (struct dhcpv6_relay_packet *)enc_opt_data.data;
3350 enc_packet->dhcpv6_msg_type = relay->msg_type;
3351
3352 /* relay-specific data */
3353 enc_packet->dhcpv6_hop_count = relay->hop_count;
3354 memcpy(&enc_packet->dhcpv6_link_address,
3355 relay->link_address, sizeof(relay->link_address));
3356 memcpy(&enc_packet->dhcpv6_peer_address,
3357 relay->peer_address, sizeof(relay->peer_address));
3358
3359 if (!parse_option_buffer(enc_packet->options,
3360 relay->options,
3361 enc_opt_data.len-sizeof(*relay),
3362 &dhcpv6_universe)) {
3363 /* no logging here, as parse_option_buffer() logs all
3364 cases where it fails */
3365 goto exit;
3366 }
3367 } else {
3368 msg = (struct dhcpv6_packet *)enc_opt_data.data;
3369 enc_packet->dhcpv6_msg_type = msg->msg_type;
3370
3371 /* message-specific data */
3372 memcpy(enc_packet->dhcpv6_transaction_id,
3373 msg->transaction_id,
3374 sizeof(enc_packet->dhcpv6_transaction_id));
3375
3376 if (!parse_option_buffer(enc_packet->options,
3377 msg->options,
3378 enc_opt_data.len-sizeof(*msg),
3379 &dhcpv6_universe)) {
3380 /* no logging here, as parse_option_buffer() logs all
3381 cases where it fails */
3382 goto exit;
3383 }
3384 }
3385
3386 /*
3387 * This is recursive. It is possible to exceed maximum packet size.
3388 * XXX: This will cause the packet send to fail.
3389 */
3390 build_dhcpv6_reply(&enc_reply, enc_packet);
3391
3392 /*
3393 * If we got no encapsulated data, then it is discarded, and
3394 * our reply-forw is also discarded.
3395 */
3396 if (enc_reply.data == NULL) {
3397 goto exit;
3398 }
3399
3400 /*
3401 * Append the interface-id if present
3402 */
3403 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_INTERFACE_ID);
3404 if (oc != NULL) {
3405 memset(&interface_id, 0, sizeof(interface_id));
3406 if (!evaluate_option_cache(&interface_id, NULL, NULL, NULL,
3407 NULL, NULL, &global_scope,
3408 oc, MDL)) {
3409 log_error("dhcpv6_forw_relay: error evaluating "
3410 "Interface ID.");
3411 goto exit;
3412 }
3413 }
3414
3415 /*
3416 * Packet header stuff all comes from the forward message.
3417 */
3418 reply.msg_type = DHCPV6_RELAY_REPL;
3419 reply.hop_count = packet->dhcpv6_hop_count;
3420 memcpy(reply.link_address, &packet->dhcpv6_link_address,
3421 sizeof(reply.link_address));
3422 memcpy(reply.peer_address, &packet->dhcpv6_peer_address,
3423 sizeof(reply.peer_address));
3424
3425 /*
3426 * Copy our encapsulated stuff for caller.
3427 */
3428 reply_ret->len = sizeof(reply) + 4 + enc_reply.len;
3429 if (interface_id.data != NULL) {
3430 reply_ret->len += 4 + interface_id.len;
3431 }
3432 /*
3433 * XXX: We should not allow this to happen, perhaps by letting
3434 * build_dhcp_reply() know our space remaining.
3435 */
3436 if (reply_ret->len >= 65536) {
3437 log_error("dhcpv6_forw_relay: RELAY-REPL too big (%d bytes)",
3438 reply_ret->len);
3439 goto exit;
3440 }
3441 reply_ret->buffer = NULL;
3442 if (!buffer_allocate(&reply_ret->buffer, reply_ret->len, MDL)) {
3443 log_fatal("No memory to store reply.");
3444 }
3445 reply_ret->data = reply_ret->buffer->data;
3446 memcpy(reply_ret->buffer->data, &reply, sizeof(reply));
3447 putShort(reply_ret->buffer->data+sizeof(reply), D6O_RELAY_MSG);
3448 putShort(reply_ret->buffer->data+sizeof(reply)+2, enc_reply.len);
3449 memcpy(reply_ret->buffer->data+sizeof(reply)+4,
3450 enc_reply.data, enc_reply.len);
3451 if (interface_id.data != NULL) {
3452 putShort(reply_ret->buffer->data+sizeof(reply)+4+enc_reply.len,
3453 D6O_INTERFACE_ID);
3454 putShort(reply_ret->buffer->data+sizeof(reply)+6+enc_reply.len,
3455 interface_id.len);
3456 memcpy(reply_ret->buffer->data+sizeof(reply)+8+enc_reply.len,
3457 interface_id.data, interface_id.len);
3458 }
3459
3460 exit:
3461 if (interface_id.data != NULL) {
3462 data_string_forget(&interface_id, MDL);
3463 }
3464 if (enc_reply.data != NULL) {
3465 data_string_forget(&enc_reply, MDL);
3466 }
3467 if (enc_opt_data.data != NULL) {
3468 data_string_forget(&enc_opt_data, MDL);
3469 }
3470 if (enc_packet != NULL) {
3471 packet_dereference(&enc_packet, MDL);
3472 }
3473 }
3474
3475 static void
3476 dhcpv6_discard(struct packet *packet) {
3477 /* INSIST(packet->msg_type > 0); */
3478 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
3479
3480 log_debug("Discarding %s from %s; message type not handled by server",
3481 dhcpv6_type_names[packet->dhcpv6_msg_type],
3482 piaddr(packet->client_addr));
3483 }
3484
3485 static void
3486 build_dhcpv6_reply(struct data_string *reply, struct packet *packet) {
3487 memset(reply, 0, sizeof(*reply));
3488 switch (packet->dhcpv6_msg_type) {
3489 case DHCPV6_SOLICIT:
3490 dhcpv6_solicit(reply, packet);
3491 break;
3492 case DHCPV6_ADVERTISE:
3493 dhcpv6_discard(packet);
3494 break;
3495 case DHCPV6_REQUEST:
3496 dhcpv6_request(reply, packet);
3497 break;
3498 case DHCPV6_CONFIRM:
3499 dhcpv6_confirm(reply, packet);
3500 break;
3501 case DHCPV6_RENEW:
3502 dhcpv6_renew(reply, packet);
3503 break;
3504 case DHCPV6_REBIND:
3505 dhcpv6_rebind(reply, packet);
3506 break;
3507 case DHCPV6_REPLY:
3508 dhcpv6_discard(packet);
3509 break;
3510 case DHCPV6_RELEASE:
3511 dhcpv6_release(reply, packet);
3512 break;
3513 case DHCPV6_DECLINE:
3514 dhcpv6_decline(reply, packet);
3515 break;
3516 case DHCPV6_RECONFIGURE:
3517 dhcpv6_discard(packet);
3518 break;
3519 case DHCPV6_INFORMATION_REQUEST:
3520 dhcpv6_information_request(reply, packet);
3521 break;
3522 case DHCPV6_RELAY_FORW:
3523 dhcpv6_relay_forw(reply, packet);
3524 break;
3525 case DHCPV6_RELAY_REPL:
3526 dhcpv6_discard(packet);
3527 break;
3528 default:
3529 /* XXX: would be nice if we had "notice" level,
3530 as syslog, for this */
3531 log_info("Discarding unknown DHCPv6 message type %d "
3532 "from %s", packet->dhcpv6_msg_type,
3533 piaddr(packet->client_addr));
3534 }
3535 }
3536
3537 static void
3538 log_packet_in(const struct packet *packet) {
3539 struct data_string s;
3540 u_int32_t tid;
3541 char tmp_addr[INET6_ADDRSTRLEN];
3542 const void *addr;
3543
3544 memset(&s, 0, sizeof(s));
3545
3546 if (packet->dhcpv6_msg_type < dhcpv6_type_name_max) {
3547 data_string_sprintfa(&s, "%s message from %s port %d",
3548 dhcpv6_type_names[packet->dhcpv6_msg_type],
3549 piaddr(packet->client_addr),
3550 ntohs(packet->client_port));
3551 } else {
3552 data_string_sprintfa(&s,
3553 "Unknown message type %d from %s port %d",
3554 packet->dhcpv6_msg_type,
3555 piaddr(packet->client_addr),
3556 ntohs(packet->client_port));
3557 }
3558 if ((packet->dhcpv6_msg_type == DHCPV6_RELAY_FORW) ||
3559 (packet->dhcpv6_msg_type == DHCPV6_RELAY_REPL)) {
3560 addr = &packet->dhcpv6_link_address;
3561 data_string_sprintfa(&s, ", link address %s",
3562 inet_ntop(AF_INET6, addr,
3563 tmp_addr, sizeof(tmp_addr)));
3564 addr = &packet->dhcpv6_peer_address;
3565 data_string_sprintfa(&s, ", peer address %s",
3566 inet_ntop(AF_INET6, addr,
3567 tmp_addr, sizeof(tmp_addr)));
3568 } else {
3569 tid = 0;
3570 memcpy(((char *)&tid)+1, packet->dhcpv6_transaction_id, 3);
3571 data_string_sprintfa(&s, ", transaction ID 0x%06X", tid);
3572
3573 /*
3574 oc = lookup_option(&dhcpv6_universe, packet->options,
3575 D6O_CLIENTID);
3576 if (oc != NULL) {
3577 memset(&tmp_ds, 0, sizeof(tmp_ds_));
3578 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
3579 packet->options, NULL,
3580 &global_scope, oc, MDL)) {
3581 log_error("Error evaluating Client Identifier");
3582 } else {
3583 data_strint_sprintf(&s, ", client ID %s",
3584
3585 data_string_forget(&tmp_ds, MDL);
3586 }
3587 }
3588 */
3589
3590 }
3591 log_info("%s", s.data);
3592
3593 data_string_forget(&s, MDL);
3594 }
3595
3596 void
3597 dhcpv6(struct packet *packet) {
3598 struct data_string reply;
3599 struct sockaddr_in6 to_addr;
3600 int send_ret;
3601
3602 /*
3603 * Log a message that we received this packet.
3604 */
3605 log_packet_in(packet);
3606
3607 /*
3608 * Build our reply packet.
3609 */
3610 build_dhcpv6_reply(&reply, packet);
3611
3612 if (reply.data != NULL) {
3613 /*
3614 * Send our reply, if we have one.
3615 */
3616 memset(&to_addr, 0, sizeof(to_addr));
3617 to_addr.sin6_family = AF_INET6;
3618 if ((packet->dhcpv6_msg_type == DHCPV6_RELAY_FORW) ||
3619 (packet->dhcpv6_msg_type == DHCPV6_RELAY_REPL)) {
3620 to_addr.sin6_port = local_port;
3621 } else {
3622 to_addr.sin6_port = remote_port;
3623 }
3624 /* For testing, we reply to the sending port, so we don't need a root client */
3625 to_addr.sin6_port = packet->client_port;
3626 memcpy(&to_addr.sin6_addr, packet->client_addr.iabuf,
3627 sizeof(to_addr.sin6_addr));
3628
3629 log_info("Sending %s to %s port %d",
3630 dhcpv6_type_names[reply.data[0]],
3631 piaddr(packet->client_addr),
3632 ntohs(to_addr.sin6_port));
3633
3634 send_ret = send_packet6(packet->interface,
3635 reply.data, reply.len, &to_addr);
3636 if (send_ret != reply.len) {
3637 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
3638 send_ret, reply.len);
3639 }
3640 data_string_forget(&reply, MDL);
3641 }
3642 }
3643
3644 static void
3645 seek_shared_host(struct host_decl **hp, struct shared_network *shared) {
3646 struct host_decl *nofixed = NULL;
3647 struct host_decl *seek, *hold = NULL;
3648
3649 /*
3650 * Seek forward through fixed addresses for the right broadcast
3651 * domain.
3652 */
3653 host_reference(&hold, *hp, MDL);
3654 host_dereference(hp, MDL);
3655 seek = hold;
3656 while (seek != NULL) {
3657 if (seek->fixed_addr == NULL)
3658 nofixed = seek;
3659 else if (fixed_matches_shared(seek, shared))
3660 break;
3661
3662 seek = seek->n_ipaddr;
3663 }
3664
3665 if ((seek == NULL) && (nofixed != NULL))
3666 seek = nofixed;
3667
3668 if (seek != NULL)
3669 host_reference(hp, seek, MDL);
3670 }
3671
3672 static isc_boolean_t
3673 fixed_matches_shared(struct host_decl *host, struct shared_network *shared) {
3674 struct subnet *subnet;
3675 struct data_string addr;
3676 isc_boolean_t matched;
3677 struct iaddr fixed;
3678
3679 if (host->fixed_addr == NULL)
3680 return ISC_FALSE;
3681
3682 memset(&addr, 0, sizeof(addr));
3683 if (!evaluate_option_cache(&addr, NULL, NULL, NULL, NULL, NULL,
3684 &global_scope, host->fixed_addr, MDL))
3685 return ISC_FALSE;
3686
3687 if (addr.len < 16) {
3688 data_string_forget(&addr, MDL);
3689 return ISC_FALSE;
3690 }
3691
3692 fixed.len = 16;
3693 memcpy(fixed.iabuf, addr.data, 16);
3694
3695 matched = ISC_FALSE;
3696 for (subnet = shared->subnets ; subnet != NULL ;
3697 subnet = subnet->next_sibling) {
3698 if (addr_eq(subnet_number(fixed, subnet->netmask),
3699 subnet->net)) {
3700 matched = ISC_TRUE;
3701 break;
3702 }
3703 }
3704
3705 data_string_forget(&addr, MDL);
3706 return matched;
3707 }
3708
3709 #endif /* DHCPv6 */
3710