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