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