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