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