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