]> git.ipfire.org Git - thirdparty/dhcp.git/blob - server/dhcpv6.c
[master] Server(v6) releases pre-existing leases when client roams to new network
[thirdparty/dhcp.git] / server / dhcpv6.c
1 /*
2 * Copyright (C) 2006-2017 by Internet Systems Consortium, Inc. ("ISC")
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
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 /*! \file server/dhcpv6.c */
18
19 #include "dhcpd.h"
20
21 #ifdef DHCPv6
22
23 #ifdef DHCP4o6
24 static void forw_dhcpv4_query(struct packet *packet);
25 static void send_dhcpv4_response(struct data_string *raw);
26
27 static void recv_dhcpv4_query(struct data_string *raw);
28 static void dhcp4o6_dhcpv4_query(struct data_string *reply_ret,
29 struct packet *packet);
30 #endif
31
32 /*
33 * We use print_hex_1() to output DUID values. We could actually output
34 * the DUID with more information... MAC address if using type 1 or 3,
35 * and so on. However, RFC 3315 contains Grave Warnings against actually
36 * attempting to understand a DUID.
37 */
38
39 /*
40 * TODO: gettext() or other method of localization for the messages
41 * for status codes (and probably for log formats eventually)
42 * TODO: refactoring (simplify, simplify, simplify)
43 * TODO: support multiple shared_networks on each interface (this
44 * will allow the server to issue multiple IPv6 addresses to
45 * a single interface)
46 */
47
48 /*
49 * DHCPv6 Reply workflow assist. A Reply packet is built by various
50 * different functions; this gives us one location where we keep state
51 * regarding a reply.
52 */
53 struct reply_state {
54 /* root level persistent state */
55 struct shared_network *shared;
56 struct host_decl *host;
57 struct subnet *subnet; /* Used to match fixed-addrs to subnet scopes. */
58 struct option_state *opt_state;
59 struct packet *packet;
60 struct data_string client_id;
61
62 /* IA level persistent state */
63 unsigned ia_count;
64 unsigned pd_count;
65 unsigned client_resources;
66 isc_boolean_t resources_included;
67 isc_boolean_t static_lease;
68 unsigned static_prefixes;
69 struct ia_xx *ia;
70 struct ia_xx *old_ia;
71 struct option_state *reply_ia;
72 struct data_string fixed;
73 struct iaddrcidrnet fixed_pref; /* static prefix for logging */
74
75 /* IAADDR/PREFIX level persistent state */
76 struct iasubopt *lease;
77
78 /*
79 * "t1", "t2", preferred, and valid lifetimes records for calculating
80 * t1 and t2 (min/max).
81 */
82 u_int32_t renew, rebind, min_prefer, min_valid;
83
84 /* Client-requested valid and preferred lifetimes. */
85 u_int32_t client_valid, client_prefer;
86
87 /* Chosen values to transmit for valid and preferred lifetimes. */
88 u_int32_t send_valid, send_prefer;
89
90 /* Preferred prefix length (-1 is any). */
91 int preflen;
92
93 /* Index into the data field that has been consumed. */
94 unsigned cursor;
95
96 /* Space for the on commit statements for a fixed host */
97 struct on_star on_star;
98
99 union reply_buffer {
100 unsigned char data[65536];
101 struct dhcpv6_packet reply;
102 } buf;
103 };
104
105 /*
106 * Prototypes local to this file.
107 */
108 static int get_encapsulated_IA_state(struct option_state **enc_opt_state,
109 struct data_string *enc_opt_data,
110 struct packet *packet,
111 struct option_cache *oc,
112 int offset);
113 static void build_dhcpv6_reply(struct data_string *, struct packet *);
114 static isc_result_t shared_network_from_packet6(struct shared_network **shared,
115 struct packet *packet);
116 static void seek_shared_host(struct host_decl **hp,
117 struct shared_network *shared);
118 static isc_boolean_t fixed_matches_shared(struct host_decl *host,
119 struct shared_network *shared);
120 static isc_result_t reply_process_ia_na(struct reply_state *reply,
121 struct option_cache *ia);
122 static isc_result_t reply_process_ia_ta(struct reply_state *reply,
123 struct option_cache *ia);
124 static isc_result_t reply_process_addr(struct reply_state *reply,
125 struct option_cache *addr);
126 static isc_boolean_t address_is_owned(struct reply_state *reply,
127 struct iaddr *addr);
128 static isc_boolean_t temporary_is_available(struct reply_state *reply,
129 struct iaddr *addr);
130 static isc_result_t find_client_temporaries(struct reply_state *reply);
131 static isc_result_t reply_process_try_addr(struct reply_state *reply,
132 struct iaddr *addr);
133 static isc_result_t find_client_address(struct reply_state *reply);
134 static isc_result_t reply_process_is_addressed(struct reply_state *reply,
135 struct binding_scope **scope,
136 struct group *group);
137 static isc_result_t reply_process_send_addr(struct reply_state *reply,
138 struct iaddr *addr);
139 static struct iasubopt *lease_compare(struct iasubopt *alpha,
140 struct iasubopt *beta);
141 static isc_result_t reply_process_ia_pd(struct reply_state *reply,
142 struct option_cache *ia_pd);
143 static struct group *find_group_by_prefix(struct reply_state *reply);
144 static isc_result_t reply_process_prefix(struct reply_state *reply,
145 struct option_cache *pref);
146 static isc_boolean_t prefix_is_owned(struct reply_state *reply,
147 struct iaddrcidrnet *pref);
148 static isc_result_t find_client_prefix(struct reply_state *reply);
149 static isc_result_t reply_process_try_prefix(struct reply_state *reply,
150 struct iaddrcidrnet *pref);
151 static isc_result_t reply_process_is_prefixed(struct reply_state *reply,
152 struct binding_scope **scope,
153 struct group *group);
154 static isc_result_t reply_process_send_prefix(struct reply_state *reply,
155 struct iaddrcidrnet *pref);
156 static struct iasubopt *prefix_compare(struct reply_state *reply,
157 struct iasubopt *alpha,
158 struct iasubopt *beta);
159 static void schedule_lease_timeout_reply(struct reply_state *reply);
160
161 static int eval_prefix_mode(int thislen, int preflen, int prefix_mode);
162 static isc_result_t pick_v6_prefix_helper(struct reply_state *reply,
163 int prefix_mode);
164
165 static void unicast_reject(struct data_string *reply_ret, struct packet *packet,
166 const struct data_string *client_id,
167 const struct data_string *server_id);
168
169 static isc_boolean_t is_unicast_option_defined(struct packet *packet);
170 static isc_result_t shared_network_from_requested_addr (struct shared_network
171 **shared,
172 struct packet* packet);
173 static isc_result_t get_first_ia_addr_val (struct packet* packet, int addr_type,
174 struct iaddr* iaddr);
175
176 static void
177 set_reply_tee_times(struct reply_state* reply, unsigned ia_cursor);
178
179 static const char *iasubopt_plen_str(struct iasubopt *lease);
180 static int release_on_roam(struct reply_state *reply);
181
182 #ifdef DHCP4o6
183 /*
184 * \brief Omapi I/O handler
185 *
186 * The inter-process communication receive handler.
187 * Get the message, put it into the raw data_string
188 * and call \ref send_dhcpv4_response() (DHCPv6 side) or
189 * \ref recv_dhcpv4_query() (DHCPv4 side)
190 *
191 * \param h the OMAPI object
192 * \return a result for I/O success or error (used by the I/O subsystem)
193 */
194 isc_result_t dhcpv4o6_handler(omapi_object_t *h) {
195 char buf[65536];
196 struct data_string raw;
197 int cc;
198
199 if (h->type != dhcp4o6_type)
200 return DHCP_R_INVALIDARG;
201
202 cc = recv(dhcp4o6_fd, buf, sizeof(buf), 0);
203
204 if (cc < DHCP_FIXED_NON_UDP + 32)
205 return ISC_R_UNEXPECTED;
206 memset(&raw, 0, sizeof(raw));
207 if (!buffer_allocate(&raw.buffer, cc, MDL)) {
208 log_error("dhcpv4o6_handler: no memory buffer.");
209 return ISC_R_NOMEMORY;
210 }
211 raw.data = raw.buffer->data;
212 raw.len = cc;
213 memcpy(raw.buffer->data, buf, cc);
214
215 if (local_family == AF_INET6) {
216 send_dhcpv4_response(&raw);
217 } else {
218 recv_dhcpv4_query(&raw);
219 }
220
221 data_string_forget(&raw, MDL);
222
223 return ISC_R_SUCCESS;
224 }
225
226 /*
227 * \brief Send the DHCPv4-response back to the DHCPv6 side
228 * (DHCPv6 server function)
229 *
230 * Format: interface:16 + address:16 + DHCPv6 DHCPv4-response message
231 *
232 * \param raw the IPC message content
233 */
234 static void send_dhcpv4_response(struct data_string *raw) {
235 struct interface_info *ip;
236 char name[16 + 1];
237 struct sockaddr_in6 to_addr;
238 char pbuf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
239 int send_ret;
240
241 memset(name, 0, sizeof(name));
242 memcpy(name, raw->data, 16);
243 for (ip = interfaces; ip != NULL; ip = ip->next) {
244 if (!strcmp(name, ip->name))
245 break;
246 }
247 if (ip == NULL) {
248 log_error("send_dhcpv4_response: can't find interface %s.",
249 name);
250 return;
251 }
252
253 memset(&to_addr, 0, sizeof(to_addr));
254 to_addr.sin6_family = AF_INET6;
255 memcpy(&to_addr.sin6_addr, raw->data + 16, 16);
256 if ((raw->data[32] == DHCPV6_RELAY_FORW) ||
257 (raw->data[32] == DHCPV6_RELAY_REPL)) {
258 to_addr.sin6_port = local_port;
259 } else {
260 to_addr.sin6_port = remote_port;
261 }
262
263 log_info("send_dhcpv4_response(): sending %s on %s to %s port %d",
264 dhcpv6_type_names[raw->data[32]],
265 name,
266 inet_ntop(AF_INET6, raw->data + 16, pbuf, sizeof(pbuf)),
267 ntohs(to_addr.sin6_port));
268
269 send_ret = send_packet6(ip, raw->data + 32, raw->len - 32, &to_addr);
270 if (send_ret < 0) {
271 log_error("send_dhcpv4_response: send_packet6(): %m");
272 } else if (send_ret != raw->len - 32) {
273 log_error("send_dhcpv4_response: send_packet6() "
274 "sent %d of %d bytes",
275 send_ret, raw->len - 32);
276 }
277 }
278 #endif /* DHCP4o6 */
279
280 /*
281 * Schedule lease timeouts for all of the iasubopts in the reply.
282 * This is currently used to schedule timeouts for soft leases.
283 */
284
285 static void
286 schedule_lease_timeout_reply(struct reply_state *reply) {
287 struct iasubopt *tmp;
288 int i;
289
290 /* sanity check the reply */
291 if ((reply == NULL) || (reply->ia == NULL) || (reply->ia->iasubopt == NULL))
292 return;
293
294 /* walk through the list, scheduling as we go */
295 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
296 tmp = reply->ia->iasubopt[i];
297 schedule_lease_timeout(tmp->ipv6_pool);
298 }
299 }
300
301 /*
302 * This function returns the time since DUID time start for the
303 * given time_t value.
304 */
305 static u_int32_t
306 duid_time(time_t when) {
307 /*
308 * This time is modulo 2^32.
309 */
310 while ((when - DUID_TIME_EPOCH) > 4294967295u) {
311 /* use 2^31 to avoid spurious compiler warnings */
312 when -= 2147483648u;
313 when -= 2147483648u;
314 }
315
316 return when - DUID_TIME_EPOCH;
317 }
318
319
320 /*
321 * Server DUID.
322 *
323 * This must remain the same for the lifetime of this server, because
324 * clients return the server DUID that we sent them in Request packets.
325 *
326 * We pick the server DUID like this:
327 *
328 * 1. Check dhcpd.conf - any value the administrator has configured
329 * overrides any possible values.
330 * 2. Check the leases.txt - we want to use the previous value if
331 * possible.
332 * 3. Check if dhcpd.conf specifies a type of server DUID to use,
333 * and generate that type.
334 * 4. Generate a type 1 (time + hardware address) DUID.
335 */
336 static struct data_string server_duid;
337
338 /*
339 * Check if the server_duid has been set.
340 */
341 isc_boolean_t
342 server_duid_isset(void) {
343 return (server_duid.data != NULL);
344 }
345
346 /*
347 * Return the server_duid.
348 */
349 void
350 copy_server_duid(struct data_string *ds, const char *file, int line) {
351 data_string_copy(ds, &server_duid, file, line);
352 }
353
354 /*
355 * Set the server DUID to a specified value. This is used when
356 * the server DUID is stored in persistent memory (basically the
357 * leases.txt file).
358 */
359 void
360 set_server_duid(struct data_string *new_duid) {
361 /* INSIST(new_duid != NULL); */
362 /* INSIST(new_duid->data != NULL); */
363
364 if (server_duid_isset()) {
365 data_string_forget(&server_duid, MDL);
366 }
367 data_string_copy(&server_duid, new_duid, MDL);
368 }
369
370
371 /*
372 * Set the server DUID based on the D6O_SERVERID option. This handles
373 * the case where the administrator explicitly put it in the dhcpd.conf
374 * file.
375 */
376 isc_result_t
377 set_server_duid_from_option(void) {
378 struct option_state *opt_state;
379 struct option_cache *oc;
380 struct data_string option_duid;
381 isc_result_t ret_val;
382
383 opt_state = NULL;
384 if (!option_state_allocate(&opt_state, MDL)) {
385 log_fatal("No memory for server DUID.");
386 }
387
388 execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL,
389 opt_state, &global_scope, root_group,
390 NULL, NULL);
391
392 oc = lookup_option(&dhcpv6_universe, opt_state, D6O_SERVERID);
393 if (oc == NULL) {
394 ret_val = ISC_R_NOTFOUND;
395 } else {
396 memset(&option_duid, 0, sizeof(option_duid));
397 if (!evaluate_option_cache(&option_duid, NULL, NULL, NULL,
398 opt_state, NULL, &global_scope,
399 oc, MDL)) {
400 ret_val = ISC_R_UNEXPECTED;
401 } else {
402 set_server_duid(&option_duid);
403 data_string_forget(&option_duid, MDL);
404 ret_val = ISC_R_SUCCESS;
405 }
406 }
407
408 option_state_dereference(&opt_state, MDL);
409
410 return ret_val;
411 }
412
413 /*
414 * DUID layout, as defined in RFC 3315, section 9.
415 *
416 * We support type 1 (hardware address plus time) and type 3 (hardware
417 * address).
418 *
419 * We can support type 2 for specific vendors in the future, if they
420 * publish the specification. And of course there may be additional
421 * types later.
422 */
423 static int server_duid_type = DUID_LLT;
424
425 /*
426 * Set the DUID type.
427 */
428 void
429 set_server_duid_type(int type) {
430 server_duid_type = type;
431 }
432
433 /*
434 * Generate a new server DUID. This is done if there was no DUID in
435 * the leases.txt or in the dhcpd.conf file.
436 */
437 isc_result_t
438 generate_new_server_duid(void) {
439 struct interface_info *p;
440 u_int32_t time_val;
441 struct data_string generated_duid;
442
443 /*
444 * Verify we have a type that we support.
445 */
446 if ((server_duid_type != DUID_LL) && (server_duid_type != DUID_LLT)) {
447 log_error("Invalid DUID type %d specified, "
448 "only LL and LLT types supported", server_duid_type);
449 return DHCP_R_INVALIDARG;
450 }
451
452 /*
453 * Find an interface with a hardware address.
454 * Any will do. :)
455 */
456 for (p = interfaces; p != NULL; p = p->next) {
457 if (p->hw_address.hlen > 0) {
458 break;
459 }
460 }
461 if (p == NULL) {
462 return ISC_R_UNEXPECTED;
463 }
464
465 /*
466 * Build our DUID.
467 */
468 memset(&generated_duid, 0, sizeof(generated_duid));
469 if (server_duid_type == DUID_LLT) {
470 time_val = duid_time(time(NULL));
471 generated_duid.len = 8 + p->hw_address.hlen - 1;
472 if (!buffer_allocate(&generated_duid.buffer,
473 generated_duid.len, MDL)) {
474 log_fatal("No memory for server DUID.");
475 }
476 generated_duid.data = generated_duid.buffer->data;
477 putUShort(generated_duid.buffer->data, DUID_LLT);
478 putUShort(generated_duid.buffer->data + 2,
479 p->hw_address.hbuf[0]);
480 putULong(generated_duid.buffer->data + 4, time_val);
481 memcpy(generated_duid.buffer->data + 8,
482 p->hw_address.hbuf+1, p->hw_address.hlen-1);
483 } else if (server_duid_type == DUID_LL) {
484 generated_duid.len = 4 + p->hw_address.hlen - 1;
485 if (!buffer_allocate(&generated_duid.buffer,
486 generated_duid.len, MDL)) {
487 log_fatal("No memory for server DUID.");
488 }
489 generated_duid.data = generated_duid.buffer->data;
490 putUShort(generated_duid.buffer->data, DUID_LL);
491 putUShort(generated_duid.buffer->data + 2,
492 p->hw_address.hbuf[0]);
493 memcpy(generated_duid.buffer->data + 4,
494 p->hw_address.hbuf+1, p->hw_address.hlen-1);
495 } else {
496 log_fatal("Unsupported server DUID type %d.", server_duid_type);
497 }
498
499 set_server_duid(&generated_duid);
500 data_string_forget(&generated_duid, MDL);
501
502 return ISC_R_SUCCESS;
503 }
504
505 /*
506 * Get the client identifier from the packet.
507 */
508 isc_result_t
509 get_client_id(struct packet *packet, struct data_string *client_id) {
510 struct option_cache *oc;
511
512 /*
513 * Verify our client_id structure is empty.
514 */
515 if ((client_id->data != NULL) || (client_id->len != 0)) {
516 return DHCP_R_INVALIDARG;
517 }
518
519 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_CLIENTID);
520 if (oc == NULL) {
521 return ISC_R_NOTFOUND;
522 }
523
524 if (!evaluate_option_cache(client_id, packet, NULL, NULL,
525 packet->options, NULL,
526 &global_scope, oc, MDL)) {
527 return ISC_R_FAILURE;
528 }
529
530 return ISC_R_SUCCESS;
531 }
532
533 /*
534 * Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
535 *
536 * Servers MUST discard any Solicit messages that do not include a
537 * Client Identifier option or that do include a Server Identifier
538 * option.
539 */
540 int
541 valid_client_msg(struct packet *packet, struct data_string *client_id) {
542 int ret_val;
543 struct option_cache *oc;
544 struct data_string data;
545
546 ret_val = 0;
547 memset(client_id, 0, sizeof(*client_id));
548 memset(&data, 0, sizeof(data));
549
550 switch (get_client_id(packet, client_id)) {
551 case ISC_R_SUCCESS:
552 break;
553 case ISC_R_NOTFOUND:
554 log_debug("Discarding %s from %s; "
555 "client identifier missing",
556 dhcpv6_type_names[packet->dhcpv6_msg_type],
557 piaddr(packet->client_addr));
558 goto exit;
559 default:
560 log_error("Error processing %s from %s; "
561 "unable to evaluate Client Identifier",
562 dhcpv6_type_names[packet->dhcpv6_msg_type],
563 piaddr(packet->client_addr));
564 goto exit;
565 }
566
567 /*
568 * Required by RFC 3315, section 15.
569 */
570 if (packet->unicast) {
571 log_debug("Discarding %s from %s; packet sent unicast "
572 "(CLIENTID %s)",
573 dhcpv6_type_names[packet->dhcpv6_msg_type],
574 piaddr(packet->client_addr),
575 print_hex_1(client_id->len, client_id->data, 60));
576 goto exit;
577 }
578
579
580 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
581 if (oc != NULL) {
582 if (evaluate_option_cache(&data, packet, NULL, NULL,
583 packet->options, NULL,
584 &global_scope, oc, MDL)) {
585 log_debug("Discarding %s from %s; "
586 "server identifier found "
587 "(CLIENTID %s, SERVERID %s)",
588 dhcpv6_type_names[packet->dhcpv6_msg_type],
589 piaddr(packet->client_addr),
590 print_hex_1(client_id->len,
591 client_id->data, 60),
592 print_hex_2(data.len,
593 data.data, 60));
594 } else {
595 log_debug("Discarding %s from %s; "
596 "server identifier found "
597 "(CLIENTID %s)",
598 dhcpv6_type_names[packet->dhcpv6_msg_type],
599 print_hex_1(client_id->len,
600 client_id->data, 60),
601 piaddr(packet->client_addr));
602 }
603 goto exit;
604 }
605
606 /* looks good */
607 ret_val = 1;
608
609 exit:
610 if (data.len > 0) {
611 data_string_forget(&data, MDL);
612 }
613 if (!ret_val) {
614 if (client_id->len > 0) {
615 data_string_forget(client_id, MDL);
616 }
617 }
618 return ret_val;
619 }
620
621 /*
622 * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8,
623 * 15.9 (slightly different wording, but same meaning):
624 *
625 * Servers MUST discard any received Request message that meet any of
626 * the following conditions:
627 *
628 * - the message does not include a Server Identifier option.
629 * - the contents of the Server Identifier option do not match the
630 * server's DUID.
631 * - the message does not include a Client Identifier option.
632 */
633 int
634 valid_client_resp(struct packet *packet,
635 struct data_string *client_id,
636 struct data_string *server_id)
637 {
638 int ret_val;
639 struct option_cache *oc;
640
641 /* INSIST((duid.data != NULL) && (duid.len > 0)); */
642
643 ret_val = 0;
644 memset(client_id, 0, sizeof(*client_id));
645 memset(server_id, 0, sizeof(*server_id));
646
647 switch (get_client_id(packet, client_id)) {
648 case ISC_R_SUCCESS:
649 break;
650 case ISC_R_NOTFOUND:
651 log_debug("Discarding %s from %s; "
652 "client identifier missing",
653 dhcpv6_type_names[packet->dhcpv6_msg_type],
654 piaddr(packet->client_addr));
655 goto exit;
656 default:
657 log_error("Error processing %s from %s; "
658 "unable to evaluate Client Identifier",
659 dhcpv6_type_names[packet->dhcpv6_msg_type],
660 piaddr(packet->client_addr));
661 goto exit;
662 }
663
664 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
665 if (oc == NULL) {
666 log_debug("Discarding %s from %s: "
667 "server identifier missing (CLIENTID %s)",
668 dhcpv6_type_names[packet->dhcpv6_msg_type],
669 piaddr(packet->client_addr),
670 print_hex_1(client_id->len, client_id->data, 60));
671 goto exit;
672 }
673 if (!evaluate_option_cache(server_id, packet, NULL, NULL,
674 packet->options, NULL,
675 &global_scope, oc, MDL)) {
676 log_error("Error processing %s from %s; "
677 "unable to evaluate Server Identifier (CLIENTID %s)",
678 dhcpv6_type_names[packet->dhcpv6_msg_type],
679 piaddr(packet->client_addr),
680 print_hex_1(client_id->len, client_id->data, 60));
681 goto exit;
682 }
683 if ((server_duid.len != server_id->len) ||
684 (memcmp(server_duid.data, server_id->data, server_duid.len) != 0)) {
685 log_debug("Discarding %s from %s; "
686 "not our server identifier "
687 "(CLIENTID %s, SERVERID %s, server DUID %s)",
688 dhcpv6_type_names[packet->dhcpv6_msg_type],
689 piaddr(packet->client_addr),
690 print_hex_1(client_id->len, client_id->data, 60),
691 print_hex_2(server_id->len, server_id->data, 60),
692 print_hex_3(server_duid.len, server_duid.data, 60));
693 goto exit;
694 }
695
696 /* looks good */
697 ret_val = 1;
698
699 exit:
700 if (!ret_val) {
701 if (server_id->len > 0) {
702 data_string_forget(server_id, MDL);
703 }
704 if (client_id->len > 0) {
705 data_string_forget(client_id, MDL);
706 }
707 }
708 return ret_val;
709 }
710
711 /*
712 * Information request validation, defined in RFC 3315, section 15.12:
713 *
714 * Servers MUST discard any received Information-request message that
715 * meets any of the following conditions:
716 *
717 * - The message includes a Server Identifier option and the DUID in
718 * the option does not match the server's DUID.
719 *
720 * - The message includes an IA option.
721 */
722 int
723 valid_client_info_req(struct packet *packet, struct data_string *server_id) {
724 int ret_val;
725 struct option_cache *oc;
726 struct data_string client_id;
727 char client_id_str[80]; /* print_hex_1() uses maximum 60 characters,
728 plus a few more for extra information */
729
730 ret_val = 0;
731 memset(server_id, 0, sizeof(*server_id));
732 memset(&client_id, 0, sizeof(client_id));
733
734 /*
735 * Make a string that we can print out to give more
736 * information about the client if we need to.
737 *
738 * By RFC 3315, Section 18.1.5 clients SHOULD have a
739 * client-id on an Information-request packet, but it
740 * is not strictly necessary.
741 */
742 if (get_client_id(packet, &client_id) == ISC_R_SUCCESS) {
743 snprintf(client_id_str, sizeof(client_id_str), " (CLIENTID %s)",
744 print_hex_1(client_id.len, client_id.data, 60));
745 data_string_forget(&client_id, MDL);
746 } else {
747 client_id_str[0] = '\0';
748 }
749
750 /*
751 * Required by RFC 3315, section 15.
752 */
753 if (packet->unicast) {
754 log_debug("Discarding %s from %s; packet sent unicast%s",
755 dhcpv6_type_names[packet->dhcpv6_msg_type],
756 piaddr(packet->client_addr), client_id_str);
757 goto exit;
758 }
759
760 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
761 if (oc != NULL) {
762 log_debug("Discarding %s from %s; "
763 "IA_NA option present%s",
764 dhcpv6_type_names[packet->dhcpv6_msg_type],
765 piaddr(packet->client_addr), client_id_str);
766 goto exit;
767 }
768 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_TA);
769 if (oc != NULL) {
770 log_debug("Discarding %s from %s; "
771 "IA_TA option present%s",
772 dhcpv6_type_names[packet->dhcpv6_msg_type],
773 piaddr(packet->client_addr), client_id_str);
774 goto exit;
775 }
776 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
777 if (oc != NULL) {
778 log_debug("Discarding %s from %s; "
779 "IA_PD option present%s",
780 dhcpv6_type_names[packet->dhcpv6_msg_type],
781 piaddr(packet->client_addr), client_id_str);
782 goto exit;
783 }
784
785 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
786 if (oc != NULL) {
787 if (!evaluate_option_cache(server_id, packet, NULL, NULL,
788 packet->options, NULL,
789 &global_scope, oc, MDL)) {
790 log_error("Error processing %s from %s; "
791 "unable to evaluate Server Identifier%s",
792 dhcpv6_type_names[packet->dhcpv6_msg_type],
793 piaddr(packet->client_addr), client_id_str);
794 goto exit;
795 }
796 if ((server_duid.len != server_id->len) ||
797 (memcmp(server_duid.data, server_id->data,
798 server_duid.len) != 0)) {
799 log_debug("Discarding %s from %s; "
800 "not our server identifier "
801 "(SERVERID %s, server DUID %s)%s",
802 dhcpv6_type_names[packet->dhcpv6_msg_type],
803 piaddr(packet->client_addr),
804 print_hex_1(server_id->len,
805 server_id->data, 60),
806 print_hex_2(server_duid.len,
807 server_duid.data, 60),
808 client_id_str);
809 goto exit;
810 }
811 }
812
813 /* looks good */
814 ret_val = 1;
815
816 exit:
817 if (!ret_val) {
818 if (server_id->len > 0) {
819 data_string_forget(server_id, MDL);
820 }
821 }
822 return ret_val;
823 }
824
825 /*
826 * Options that we want to send, in addition to what was requested
827 * via the ORO.
828 */
829 static const int required_opts[] = {
830 D6O_CLIENTID,
831 D6O_SERVERID,
832 D6O_STATUS_CODE,
833 D6O_PREFERENCE,
834 0
835 };
836 static const int required_opts_solicit[] = {
837 D6O_CLIENTID,
838 D6O_SERVERID,
839 D6O_IA_NA,
840 D6O_IA_TA,
841 D6O_IA_PD,
842 D6O_RAPID_COMMIT,
843 D6O_STATUS_CODE,
844 D6O_RECONF_ACCEPT,
845 D6O_PREFERENCE,
846 0
847 };
848 static const int required_opts_agent[] = {
849 D6O_INTERFACE_ID,
850 D6O_RELAY_MSG,
851 0
852 };
853 static const int required_opts_IA[] = {
854 D6O_IAADDR,
855 D6O_STATUS_CODE,
856 0
857 };
858 static const int required_opts_IA_PD[] = {
859 D6O_IAPREFIX,
860 D6O_STATUS_CODE,
861 0
862 };
863 static const int required_opts_STATUS_CODE[] = {
864 D6O_STATUS_CODE,
865 0
866 };
867 #ifdef DHCP4o6
868 static const int required_opts_4o6[] = {
869 D6O_DHCPV4_MSG,
870 0
871 };
872 #endif
873
874 static const int unicast_reject_opts[] = {
875 D6O_CLIENTID,
876 D6O_SERVERID,
877 D6O_STATUS_CODE,
878 0
879 };
880
881
882 /*
883 * Extracts from packet contents an IA_* option, storing the IA structure
884 * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
885 * in enc_opt_state for later lookup and evaluation. The 'offset' indicates
886 * where in the IA_* the DHCPv6 options commence.
887 */
888 static int
889 get_encapsulated_IA_state(struct option_state **enc_opt_state,
890 struct data_string *enc_opt_data,
891 struct packet *packet,
892 struct option_cache *oc,
893 int offset)
894 {
895 /*
896 * Get the raw data for the encapsulated options.
897 */
898 memset(enc_opt_data, 0, sizeof(*enc_opt_data));
899 if (!evaluate_option_cache(enc_opt_data, packet,
900 NULL, NULL, packet->options, NULL,
901 &global_scope, oc, MDL)) {
902 log_error("get_encapsulated_IA_state: "
903 "error evaluating raw option.");
904 return 0;
905 }
906 if (enc_opt_data->len < offset) {
907 log_error("get_encapsulated_IA_state: raw option too small.");
908 data_string_forget(enc_opt_data, MDL);
909 return 0;
910 }
911
912 /*
913 * Now create the option state structure, and pass it to the
914 * function that parses options.
915 */
916 *enc_opt_state = NULL;
917 if (!option_state_allocate(enc_opt_state, MDL)) {
918 log_error("get_encapsulated_IA_state: no memory for options.");
919 data_string_forget(enc_opt_data, MDL);
920 return 0;
921 }
922 if (!parse_option_buffer(*enc_opt_state,
923 enc_opt_data->data + offset,
924 enc_opt_data->len - offset,
925 &dhcpv6_universe)) {
926 log_error("get_encapsulated_IA_state: error parsing options.");
927 option_state_dereference(enc_opt_state, MDL);
928 data_string_forget(enc_opt_data, MDL);
929 return 0;
930 }
931
932 return 1;
933 }
934
935 static int
936 set_status_code(u_int16_t status_code, const char *status_message,
937 struct option_state *opt_state)
938 {
939 struct data_string d;
940 int ret_val;
941
942 memset(&d, 0, sizeof(d));
943 d.len = sizeof(status_code) + strlen(status_message);
944 if (!buffer_allocate(&d.buffer, d.len, MDL)) {
945 log_fatal("set_status_code: no memory for status code.");
946 }
947 d.data = d.buffer->data;
948 putUShort(d.buffer->data, status_code);
949 memcpy(d.buffer->data + sizeof(status_code),
950 status_message, d.len - sizeof(status_code));
951 if (!save_option_buffer(&dhcpv6_universe, opt_state,
952 d.buffer, (unsigned char *)d.data, d.len,
953 D6O_STATUS_CODE, 0)) {
954 log_error("set_status_code: error saving status code.");
955 ret_val = 0;
956 } else {
957 ret_val = 1;
958 }
959 data_string_forget(&d, MDL);
960 return ret_val;
961 }
962
963 void check_pool6_threshold(struct reply_state *reply,
964 struct iasubopt *lease)
965 {
966 struct ipv6_pond *pond;
967 isc_uint64_t used, count, high_threshold;
968 int poolhigh = 0, poollow = 0;
969 char *shared_name = "no name";
970 char tmp_addr[INET6_ADDRSTRLEN];
971
972 if ((lease->ipv6_pool == NULL) || (lease->ipv6_pool->ipv6_pond == NULL))
973 return;
974 pond = lease->ipv6_pool->ipv6_pond;
975
976 /* If the address range is too large to track, just skip all this. */
977 if (pond->jumbo_range == 1) {
978 return;
979 }
980
981 count = pond->num_total;
982 used = pond->num_active;
983
984 /* get network name for logging */
985 if ((pond->shared_network != NULL) &&
986 (pond->shared_network->name != NULL)) {
987 shared_name = pond->shared_network->name;
988 }
989
990 /* The logged flag indicates if we have already crossed the high
991 * threshold and emitted a log message. If it is set we check to
992 * see if we have re-crossed the low threshold and need to reset
993 * things. When we cross the high threshold we determine what
994 * the low threshold is and save it into the low_threshold value.
995 * When we cross that threshold we reset the logged flag and
996 * the low_threshold to 0 which allows the high threshold message
997 * to be emitted once again.
998 * if we haven't recrossed the boundry we don't need to do anything.
999 */
1000 if (pond->logged !=0) {
1001 if (used <= pond->low_threshold) {
1002 pond->low_threshold = 0;
1003 pond->logged = 0;
1004 log_error("Pool threshold reset - shared subnet: %s; "
1005 "address: %s; low threshold %llu/%llu.",
1006 shared_name,
1007 inet_ntop(AF_INET6, &lease->addr,
1008 tmp_addr, sizeof(tmp_addr)),
1009 used, count);
1010 }
1011 return;
1012 }
1013
1014 /* find the high threshold */
1015 if (get_option_int(&poolhigh, &server_universe, reply->packet, NULL,
1016 NULL, reply->packet->options, reply->opt_state,
1017 reply->opt_state, &lease->scope,
1018 SV_LOG_THRESHOLD_HIGH, MDL) == 0) {
1019 /* no threshold bail out */
1020 return;
1021 }
1022
1023 /* We do have a threshold for this pool, see if its valid */
1024 if ((poolhigh <= 0) || (poolhigh > 100)) {
1025 /* not valid */
1026 return;
1027 }
1028
1029 /* we have a valid value, have we exceeded it */
1030 high_threshold = FIND_POND6_PERCENT(count, poolhigh);
1031 if (used < high_threshold) {
1032 /* nope, no more to do */
1033 return;
1034 }
1035
1036 /* we've exceeded it, output a message */
1037 log_error("Pool threshold exceeded - shared subnet: %s; "
1038 "address: %s; high threshold %d%% %llu/%llu.",
1039 shared_name,
1040 inet_ntop(AF_INET6, &lease->addr, tmp_addr, sizeof(tmp_addr)),
1041 poolhigh, used, count);
1042
1043 /* handle the low threshold now, if we don't
1044 * have one we default to 0. */
1045 if ((get_option_int(&poollow, &server_universe, reply->packet, NULL,
1046 NULL, reply->packet->options, reply->opt_state,
1047 reply->opt_state, &lease->scope,
1048 SV_LOG_THRESHOLD_LOW, MDL) == 0) ||
1049 (poollow > 100)) {
1050 poollow = 0;
1051 }
1052
1053 /*
1054 * If the low theshold is higher than the high threshold we continue to log
1055 * If it isn't then we set the flag saying we already logged and determine
1056 * what the reset threshold is.
1057 */
1058 if (poollow < poolhigh) {
1059 pond->logged = 1;
1060 pond->low_threshold = FIND_POND6_PERCENT(count, poollow);
1061 }
1062 }
1063
1064 /*
1065 * We have a set of operations we do to set up the reply packet, which
1066 * is the same for many message types.
1067 */
1068 static int
1069 start_reply(struct packet *packet,
1070 const struct data_string *client_id,
1071 const struct data_string *server_id,
1072 struct option_state **opt_state,
1073 struct dhcpv6_packet *reply)
1074 {
1075 struct option_cache *oc;
1076 const unsigned char *server_id_data;
1077 int server_id_len;
1078
1079 /*
1080 * Build our option state for reply.
1081 */
1082 *opt_state = NULL;
1083 if (!option_state_allocate(opt_state, MDL)) {
1084 log_error("start_reply: no memory for option_state.");
1085 return 0;
1086 }
1087 execute_statements_in_scope(NULL, packet, NULL, NULL,
1088 packet->options, *opt_state,
1089 &global_scope, root_group, NULL, NULL);
1090
1091 /*
1092 * A small bit of special handling for Solicit messages.
1093 *
1094 * We could move the logic into a flag, but for now just check
1095 * explicitly.
1096 */
1097 if (packet->dhcpv6_msg_type == DHCPV6_SOLICIT) {
1098 reply->msg_type = DHCPV6_ADVERTISE;
1099
1100 /*
1101 * If:
1102 * - this message type supports rapid commit (Solicit), and
1103 * - the server is configured to supply a rapid commit, and
1104 * - the client requests a rapid commit,
1105 * Then we add a rapid commit option, and send Reply (instead
1106 * of an Advertise).
1107 */
1108 oc = lookup_option(&dhcpv6_universe,
1109 *opt_state, D6O_RAPID_COMMIT);
1110 if (oc != NULL) {
1111 oc = lookup_option(&dhcpv6_universe,
1112 packet->options, D6O_RAPID_COMMIT);
1113 if (oc != NULL) {
1114 /* Rapid-commit in action. */
1115 reply->msg_type = DHCPV6_REPLY;
1116 } else {
1117 /* Don't want a rapid-commit in advertise. */
1118 delete_option(&dhcpv6_universe,
1119 *opt_state, D6O_RAPID_COMMIT);
1120 }
1121 }
1122 } else {
1123 reply->msg_type = DHCPV6_REPLY;
1124 /* Delete the rapid-commit from the sent options. */
1125 oc = lookup_option(&dhcpv6_universe,
1126 *opt_state, D6O_RAPID_COMMIT);
1127 if (oc != NULL) {
1128 delete_option(&dhcpv6_universe,
1129 *opt_state, D6O_RAPID_COMMIT);
1130 }
1131 }
1132
1133 /*
1134 * Use the client's transaction identifier for the reply.
1135 */
1136 memcpy(reply->transaction_id, packet->dhcpv6_transaction_id,
1137 sizeof(reply->transaction_id));
1138
1139 /*
1140 * RFC 3315, section 18.2 says we need server identifier and
1141 * client identifier.
1142 *
1143 * If the server ID is defined via the configuration file, then
1144 * it will already be present in the option state at this point,
1145 * so we don't need to set it.
1146 *
1147 * If we have a server ID passed in from the caller,
1148 * use that, otherwise use the global DUID.
1149 */
1150 oc = lookup_option(&dhcpv6_universe, *opt_state, D6O_SERVERID);
1151 if (oc == NULL) {
1152 if (server_id == NULL) {
1153 server_id_data = server_duid.data;
1154 server_id_len = server_duid.len;
1155 } else {
1156 server_id_data = server_id->data;
1157 server_id_len = server_id->len;
1158 }
1159 if (!save_option_buffer(&dhcpv6_universe, *opt_state,
1160 NULL, (unsigned char *)server_id_data,
1161 server_id_len, D6O_SERVERID, 0)) {
1162 log_error("start_reply: "
1163 "error saving server identifier.");
1164 return 0;
1165 }
1166 }
1167
1168 if (client_id->buffer != NULL) {
1169 if (!save_option_buffer(&dhcpv6_universe, *opt_state,
1170 client_id->buffer,
1171 (unsigned char *)client_id->data,
1172 client_id->len,
1173 D6O_CLIENTID, 0)) {
1174 log_error("start_reply: error saving "
1175 "client identifier.");
1176 return 0;
1177 }
1178 }
1179
1180 /*
1181 * If the client accepts reconfiguration, let it know that we
1182 * will send them.
1183 *
1184 * Note: we don't actually do this yet, but DOCSIS requires we
1185 * claim to.
1186 */
1187 oc = lookup_option(&dhcpv6_universe, packet->options,
1188 D6O_RECONF_ACCEPT);
1189 if (oc != NULL) {
1190 if (!save_option_buffer(&dhcpv6_universe, *opt_state,
1191 NULL, (unsigned char *)"", 0,
1192 D6O_RECONF_ACCEPT, 0)) {
1193 log_error("start_reply: "
1194 "error saving RECONF_ACCEPT option.");
1195 option_state_dereference(opt_state, MDL);
1196 return 0;
1197 }
1198 }
1199
1200 return 1;
1201 }
1202
1203 /*
1204 * Try to get the IPv6 address the client asked for from the
1205 * pool.
1206 *
1207 * addr is the result (should be a pointer to NULL on entry)
1208 * pool is the pool to search in
1209 * requested_addr is the address the client wants
1210 */
1211 static isc_result_t
1212 try_client_v6_address(struct iasubopt **addr,
1213 struct ipv6_pool *pool,
1214 const struct data_string *requested_addr)
1215 {
1216 struct in6_addr tmp_addr;
1217 isc_result_t result;
1218
1219 if (requested_addr->len < sizeof(tmp_addr)) {
1220 return DHCP_R_INVALIDARG;
1221 }
1222 memcpy(&tmp_addr, requested_addr->data, sizeof(tmp_addr));
1223 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr)) {
1224 return ISC_R_FAILURE;
1225 }
1226
1227 /*
1228 * The address is not covered by this (or possibly any) dynamic
1229 * range.
1230 */
1231 if (!ipv6_in_pool(&tmp_addr, pool)) {
1232 return ISC_R_ADDRNOTAVAIL;
1233 }
1234
1235 if (lease6_exists(pool, &tmp_addr)) {
1236 return ISC_R_ADDRINUSE;
1237 }
1238
1239 result = iasubopt_allocate(addr, MDL);
1240 if (result != ISC_R_SUCCESS) {
1241 return result;
1242 }
1243 (*addr)->addr = tmp_addr;
1244 (*addr)->plen = 0;
1245
1246 /* Default is soft binding for 2 minutes. */
1247 result = add_lease6(pool, *addr, cur_time + 120);
1248 if (result != ISC_R_SUCCESS) {
1249 iasubopt_dereference(addr, MDL);
1250 }
1251 return result;
1252 }
1253
1254 /*!
1255 *
1256 * \brief Get an IPv6 address for the client.
1257 *
1258 * Attempt to find a usable address for the client. We walk through
1259 * the ponds checking for permit and deny then through the pools
1260 * seeing if they have an available address.
1261 *
1262 * \param reply = the state structure for the current work on this request
1263 * if we create a lease we return it using reply->lease
1264 *
1265 * \return
1266 * ISC_R_SUCCESS = we were able to find an address and are returning a
1267 * pointer to the lease
1268 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1269 * is probabalistic. We don't exhaustively try the
1270 * address range, instead we hash the duid and if
1271 * the address derived from the hash is in use we
1272 * hash the address. After a number of failures we
1273 * conclude the pool is basically full.
1274 */
1275 static isc_result_t
1276 pick_v6_address(struct reply_state *reply)
1277 {
1278 struct ipv6_pool *p = NULL;
1279 struct ipv6_pond *pond;
1280 int i;
1281 int start_pool;
1282 unsigned int attempts;
1283 char tmp_buf[INET6_ADDRSTRLEN];
1284 struct iasubopt **addr = &reply->lease;
1285 isc_uint64_t total = 0;
1286 isc_uint64_t active = 0;
1287 isc_uint64_t abandoned = 0;
1288 int jumbo_range = 0;
1289 char *shared_name = (reply->shared->name ?
1290 reply->shared->name : "(no name)");
1291
1292 /*
1293 * Do a quick walk through of the ponds and pools
1294 * to see if we have any NA address pools
1295 */
1296 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
1297 if (pond->ipv6_pools == NULL)
1298 continue;
1299
1300 for (i = 0; (p = pond->ipv6_pools[i]) != NULL; i++) {
1301 if (p->pool_type == D6O_IA_NA)
1302 break;
1303 }
1304 if (p != NULL)
1305 break;
1306 }
1307
1308 /* If we get here and p is NULL we have no useful pools */
1309 if (p == NULL) {
1310 log_debug("Unable to pick client address: "
1311 "no IPv6 pools on this shared network");
1312 return ISC_R_NORESOURCES;
1313 }
1314
1315 /*
1316 * We have at least one pool that could provide an address
1317 * Now we walk through the ponds and pools again and check
1318 * to see if the client is permitted and if an address is
1319 * available
1320 *
1321 * Within a given pond we start looking at the last pool we
1322 * allocated from, unless it had a collision trying to allocate
1323 * an address. This will tend to move us into less-filled pools.
1324 */
1325
1326 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
1327 isc_result_t result = ISC_R_FAILURE;
1328
1329 if (((pond->prohibit_list != NULL) &&
1330 (permitted(reply->packet, pond->prohibit_list))) ||
1331 ((pond->permit_list != NULL) &&
1332 (!permitted(reply->packet, pond->permit_list))))
1333 continue;
1334
1335 #ifdef EUI_64
1336 /* If pond is EUI-64 but client duid isn't a valid EUI-64
1337 * id, then skip this pond */
1338 if (pond->use_eui_64 &&
1339 !valid_eui_64_duid(&reply->ia->iaid_duid, IAID_LEN)) {
1340 continue;
1341 }
1342 #endif
1343
1344 start_pool = pond->last_ipv6_pool;
1345 i = start_pool;
1346 do {
1347 p = pond->ipv6_pools[i];
1348 if (p->pool_type == D6O_IA_NA) {
1349 #ifdef EUI_64
1350 if (pond->use_eui_64) {
1351 result =
1352 create_lease6_eui_64(p, addr,
1353 &reply->ia->iaid_duid,
1354 cur_time + 120);
1355 }
1356 else
1357 #endif
1358 {
1359 result =
1360 create_lease6(p, addr, &attempts,
1361 &reply->ia->iaid_duid,
1362 cur_time + 120);
1363
1364 }
1365
1366 if (result == ISC_R_SUCCESS) {
1367 /*
1368 * Record the pool used (or next one if
1369 * there was a collision).
1370 */
1371 if (attempts > 1) {
1372 i++;
1373 if (pond->ipv6_pools[i]
1374 == NULL) {
1375 i = 0;
1376 }
1377 }
1378
1379 pond->last_ipv6_pool = i;
1380
1381 log_debug("Picking pool address %s",
1382 inet_ntop(AF_INET6,
1383 &((*addr)->addr),
1384 tmp_buf, sizeof(tmp_buf)));
1385 return (ISC_R_SUCCESS);
1386 }
1387 }
1388
1389 i++;
1390 if (pond->ipv6_pools[i] == NULL) {
1391 i = 0;
1392 }
1393 } while (i != start_pool);
1394
1395 if (result == ISC_R_NORESOURCES) {
1396 jumbo_range += pond->jumbo_range;
1397 total += pond->num_total;
1398 active += pond->num_active;
1399 abandoned += pond->num_abandoned;
1400 }
1401 }
1402
1403 /*
1404 * If we failed to pick an IPv6 address from any of the subnets.
1405 * Presumably that means we have no addresses for the client.
1406 */
1407 if (jumbo_range != 0) {
1408 log_debug("Unable to pick client address: "
1409 "no addresses available - shared network %s: "
1410 " 2^64-1 < total, %llu active, %llu abandoned",
1411 shared_name, active - abandoned, abandoned);
1412 } else {
1413 log_debug("Unable to pick client address: "
1414 "no addresses available - shared network %s: "
1415 "%llu total, %llu active, %llu abandoned",
1416 shared_name, total, active - abandoned, abandoned);
1417 }
1418
1419 return ISC_R_NORESOURCES;
1420 }
1421
1422 /*
1423 * Try to get the IPv6 prefix the client asked for from the
1424 * prefix pool.
1425 *
1426 * pref is the result (should be a pointer to NULL on entry)
1427 * pool is the prefix pool to search in
1428 * requested_pref is the address the client wants
1429 */
1430 static isc_result_t
1431 try_client_v6_prefix(struct iasubopt **pref,
1432 struct ipv6_pool *pool,
1433 const struct data_string *requested_pref)
1434 {
1435 u_int8_t tmp_plen;
1436 struct in6_addr tmp_pref;
1437 struct iaddr ia;
1438 isc_result_t result;
1439
1440 if (requested_pref->len < sizeof(tmp_plen) + sizeof(tmp_pref)) {
1441 return DHCP_R_INVALIDARG;
1442 }
1443
1444 tmp_plen = (int) requested_pref->data[0];
1445 if ((tmp_plen < 3) || (tmp_plen > 128)) {
1446 return ISC_R_FAILURE;
1447 }
1448
1449 memcpy(&tmp_pref, requested_pref->data + 1, sizeof(tmp_pref));
1450 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref)) {
1451 return ISC_R_FAILURE;
1452 }
1453
1454 ia.len = 16;
1455 memcpy(&ia.iabuf, &tmp_pref, 16);
1456 if (!is_cidr_mask_valid(&ia, (int) tmp_plen)) {
1457 return ISC_R_FAILURE;
1458 }
1459
1460 if (!ipv6_in_pool(&tmp_pref, pool) ||
1461 ((int)tmp_plen != pool->units)) {
1462 return ISC_R_ADDRNOTAVAIL;
1463 }
1464
1465 if (prefix6_exists(pool, &tmp_pref, tmp_plen)) {
1466 return ISC_R_ADDRINUSE;
1467 }
1468
1469 result = iasubopt_allocate(pref, MDL);
1470 if (result != ISC_R_SUCCESS) {
1471 return result;
1472 }
1473
1474 (*pref)->addr = tmp_pref;
1475 (*pref)->plen = tmp_plen;
1476
1477 /* Default is soft binding for 2 minutes. */
1478 result = add_lease6(pool, *pref, cur_time + 120);
1479 if (result != ISC_R_SUCCESS) {
1480 iasubopt_dereference(pref, MDL);
1481 }
1482
1483 return result;
1484 }
1485
1486 /*!
1487 *
1488 * \brief Get an IPv6 prefix for the client.
1489 *
1490 * Attempt to find a usable prefix for the client. Based upon the prefix
1491 * length mode and the plen supplied by the client (if one), we make one
1492 * or more calls to pick_v6_prefix_helper() to find a prefix as follows:
1493 *
1494 * PLM_IGNORE or client specifies a plen of zero, use the first available
1495 * prefix regardless of it's length.
1496 *
1497 * PLM_PREFER – look for an exact match to client's plen first, if none
1498 * found, use the first available prefix of any length
1499 *
1500 * PLM_EXACT – look for an exact match first, if none found then fail. This
1501 * is the default behavior.
1502 *
1503 * PLM_MAXIMUM - look for an exact match first, then the first available whose
1504 * prefix length is less than client's plen, otherwise fail.
1505 *
1506 * PLM_MINIMUM - look for an exact match first, then the first available whose
1507 * prefix length is greater than client's plen, otherwise fail.
1508 *
1509 * Note that the selection mode is configurable at the global scope only via
1510 * prefix-len-mode.
1511 *
1512 * \param reply = the state structure for the current work on this request
1513 * if we create a lease we return it using reply->lease
1514 *
1515 * \return
1516 * ISC_R_SUCCESS = we were able to find an prefix and are returning a
1517 * pointer to the lease
1518 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1519 * is probabalistic. We don't exhaustively try the
1520 * address range, instead we hash the duid and if
1521 * the address derived from the hash is in use we
1522 * hash the address. After a number of failures we
1523 * conclude the pool is basically full.
1524 */
1525 static isc_result_t
1526 pick_v6_prefix(struct reply_state *reply) {
1527 struct ipv6_pool *p = NULL;
1528 struct ipv6_pond *pond;
1529 int i;
1530 isc_result_t result;
1531
1532 /*
1533 * Do a quick walk through of the ponds and pools
1534 * to see if we have any prefix pools
1535 */
1536 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
1537 if (pond->ipv6_pools == NULL)
1538 continue;
1539
1540 for (i = 0; (p = pond->ipv6_pools[i]) != NULL; i++) {
1541 if (p->pool_type == D6O_IA_PD)
1542 break;
1543 }
1544 if (p != NULL)
1545 break;
1546 }
1547
1548 /* If we get here and p is NULL we have no useful pools */
1549 if (p == NULL) {
1550 log_debug("Unable to pick client prefix: "
1551 "no IPv6 pools on this shared network");
1552 return ISC_R_NORESOURCES;
1553 }
1554
1555 if (reply->preflen <= 0) {
1556 /* If we didn't get a plen (-1) or client plen is 0, then just
1557 * select first available (same as PLM_INGORE) */
1558 result = pick_v6_prefix_helper(reply, PLM_IGNORE);
1559 } else {
1560 switch (prefix_length_mode) {
1561 case PLM_PREFER:
1562 /* First we look for an exact match, if not found
1563 * then first available */
1564 result = pick_v6_prefix_helper(reply, PLM_EXACT);
1565 if (result != ISC_R_SUCCESS) {
1566 result = pick_v6_prefix_helper(reply,
1567 PLM_IGNORE);
1568 }
1569 break;
1570
1571 case PLM_EXACT:
1572 /* Match exactly or fail */
1573 result = pick_v6_prefix_helper(reply, PLM_EXACT);
1574 break;
1575
1576 case PLM_MINIMUM:
1577 case PLM_MAXIMUM:
1578 /* First we look for an exact match, if not found
1579 * then first available by mode */
1580 result = pick_v6_prefix_helper(reply, PLM_EXACT);
1581 if (result != ISC_R_SUCCESS) {
1582 result = pick_v6_prefix_helper(reply,
1583 prefix_length_mode);
1584 }
1585 break;
1586
1587 default:
1588 /* First available */
1589 result = pick_v6_prefix_helper(reply, PLM_IGNORE);
1590 break;
1591 }
1592 }
1593
1594 if (result == ISC_R_SUCCESS) {
1595 char tmp_buf[INET6_ADDRSTRLEN];
1596
1597 log_debug("Picking pool prefix %s/%u",
1598 inet_ntop(AF_INET6, &(reply->lease->addr),
1599 tmp_buf, sizeof(tmp_buf)),
1600 (unsigned)(reply->lease->plen));
1601 return (ISC_R_SUCCESS);
1602 }
1603
1604 /*
1605 * If we failed to pick an IPv6 prefix
1606 * Presumably that means we have no prefixes for the client.
1607 */
1608 log_debug("Unable to pick client prefix: no prefixes available");
1609 return ISC_R_NORESOURCES;
1610 }
1611
1612 /*!
1613 *
1614 * \brief Get an IPv6 prefix for the client based upon selection mode.
1615 *
1616 * We walk through the ponds checking for permit and deny. If a pond is
1617 * permissable to use, loop through its PD pools checking prefix lengths
1618 * against the client plen based on the prefix length mode, looking for
1619 * available prefixes.
1620 *
1621 * \param reply = the state structure for the current work on this request
1622 * if we create a lease we return it using reply->lease
1623 * \prefix_mode = selection mode to use
1624 *
1625 * \return
1626 * ISC_R_SUCCESS = we were able to find a prefix and are returning a
1627 * pointer to the lease
1628 * ISC_R_NORESOURCES = there don't appear to be any free addresses. This
1629 * is probabalistic. We don't exhaustively try the
1630 * address range, instead we hash the duid and if
1631 * the address derived from the hash is in use we
1632 * hash the address. After a number of failures we
1633 * conclude the pool is basically full.
1634 */
1635 isc_result_t
1636 pick_v6_prefix_helper(struct reply_state *reply, int prefix_mode) {
1637 struct ipv6_pool *p = NULL;
1638 struct ipv6_pond *pond;
1639 int i;
1640 unsigned int attempts;
1641 struct iasubopt **pref = &reply->lease;
1642
1643 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
1644 if (((pond->prohibit_list != NULL) &&
1645 (permitted(reply->packet, pond->prohibit_list))) ||
1646 ((pond->permit_list != NULL) &&
1647 (!permitted(reply->packet, pond->permit_list))))
1648 continue;
1649
1650 for (i = 0; (p = pond->ipv6_pools[i]) != NULL; i++) {
1651 if ((p->pool_type == D6O_IA_PD) &&
1652 (eval_prefix_mode(p->units, reply->preflen,
1653 prefix_mode) == 1) &&
1654 (create_prefix6(p, pref, &attempts,
1655 &reply->ia->iaid_duid,
1656 cur_time + 120) == ISC_R_SUCCESS)) {
1657 return (ISC_R_SUCCESS);
1658 }
1659 }
1660 }
1661
1662 return ISC_R_NORESOURCES;
1663 }
1664
1665 /*!
1666 *
1667 * \brief Test a prefix length against another based on prefix length mode
1668 *
1669 * \param len - prefix length to test
1670 * \param preflen - preferred prefix length against which to test
1671 * \param prefix_mode - prefix selection mode with which to test
1672 *
1673 * Note that the case of preferred length of 0 is not short-cut here as it
1674 * is assumed to be done at a higher level.
1675 *
1676 * \return 1 if the given length is usable based upon mode and a preferred
1677 * length, 0 if not.
1678 */
1679 int
1680 eval_prefix_mode(int len, int preflen, int prefix_mode) {
1681 int use_it = 1;
1682 switch (prefix_mode) {
1683 case PLM_EXACT:
1684 use_it = (len == preflen);
1685 break;
1686 case PLM_MINIMUM:
1687 /* they asked for a prefix length no "shorter" than preflen */
1688 use_it = (len >= preflen);
1689 break;
1690 case PLM_MAXIMUM:
1691 /* they asked for a prefix length no "longer" than preflen */
1692 use_it = (len <= preflen);
1693 break;
1694 default:
1695 /* otherwise use it */
1696 break;
1697 }
1698
1699 return (use_it);
1700 }
1701
1702 /*
1703 *! \file server/dhcpv6.c
1704 *
1705 * \brief construct a reply containing information about a client's lease
1706 *
1707 * lease_to_client() is called from several messages to construct a
1708 * reply that contains all that we know about the client's correct lease
1709 * (or projected lease).
1710 *
1711 * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
1712 * send what we "may" give them on a request.
1713 *
1714 * Request - "Hard" binding, but ignore supplied addresses (just provide what
1715 * the client should really use).
1716 *
1717 * Renew - "Hard" binding, but client-supplied addresses are 'real'. Error
1718 * Rebind out any "wrong" addresses the client sends. This means we send
1719 * an empty IA_NA with a status code of NoBinding or NotOnLink or
1720 * possibly send the address with zeroed lifetimes.
1721 *
1722 * Information-Request - No binding.
1723 *
1724 * The basic structure is to traverse the client-supplied data first, and
1725 * validate and echo back any contents that can be. If the client-supplied
1726 * data does not error out (on renew/rebind as above), but we did not send
1727 * any addresses, attempt to allocate one.
1728 *
1729 * At the end of the this function we call commit_leases_timed() to
1730 * fsync and rotate the file as necessary. commit_leases_timed() will
1731 * check that we have written at least one lease to the file and that
1732 * some time has passed before doing any fsync or file rewrite so we
1733 * don't bother tracking if we did a write_ia during this function.
1734 */
1735 /* TODO: look at client hints for lease times */
1736
1737 static void
1738 lease_to_client(struct data_string *reply_ret,
1739 struct packet *packet,
1740 const struct data_string *client_id,
1741 const struct data_string *server_id)
1742 {
1743 static struct reply_state reply;
1744 struct option_cache *oc;
1745 struct data_string packet_oro;
1746 int i;
1747
1748 memset(&packet_oro, 0, sizeof(packet_oro));
1749
1750 /* Locate the client. */
1751 if (shared_network_from_packet6(&reply.shared,
1752 packet) != ISC_R_SUCCESS)
1753 goto exit;
1754
1755 /*
1756 * Initialize the reply.
1757 */
1758 packet_reference(&reply.packet, packet, MDL);
1759 data_string_copy(&reply.client_id, client_id, MDL);
1760
1761 if (!start_reply(packet, client_id, server_id, &reply.opt_state,
1762 &reply.buf.reply))
1763 goto exit;
1764
1765 /* Set the write cursor to just past the reply header. */
1766 reply.cursor = REPLY_OPTIONS_INDEX;
1767
1768 /*
1769 * Get the ORO from the packet, if any.
1770 */
1771 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_ORO);
1772 if (oc != NULL) {
1773 if (!evaluate_option_cache(&packet_oro, packet,
1774 NULL, NULL,
1775 packet->options, NULL,
1776 &global_scope, oc, MDL)) {
1777 log_error("lease_to_client: error evaluating ORO.");
1778 goto exit;
1779 }
1780 }
1781
1782 /*
1783 * Find a host record that matches the packet, if any, and is
1784 * valid for the shared network the client is on.
1785 */
1786 if (find_hosts6(&reply.host, packet, client_id, MDL)) {
1787 packet->known = 1;
1788 seek_shared_host(&reply.host, reply.shared);
1789 }
1790
1791 /* Process the client supplied IA's onto the reply buffer. */
1792 reply.ia_count = 0;
1793 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
1794
1795 for (; oc != NULL ; oc = oc->next) {
1796 isc_result_t status;
1797
1798 /* Start counting resources (addresses) offered. */
1799 reply.client_resources = 0;
1800 reply.resources_included = ISC_FALSE;
1801
1802 status = reply_process_ia_na(&reply, oc);
1803
1804 /*
1805 * We continue to try other IA's whether we can address
1806 * this one or not. Any other result is an immediate fail.
1807 */
1808 if ((status != ISC_R_SUCCESS) &&
1809 (status != ISC_R_NORESOURCES))
1810 goto exit;
1811 }
1812 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_TA);
1813 for (; oc != NULL ; oc = oc->next) {
1814 isc_result_t status;
1815
1816 /* Start counting resources (addresses) offered. */
1817 reply.client_resources = 0;
1818 reply.resources_included = ISC_FALSE;
1819
1820 status = reply_process_ia_ta(&reply, oc);
1821
1822 /*
1823 * We continue to try other IA's whether we can address
1824 * this one or not. Any other result is an immediate fail.
1825 */
1826 if ((status != ISC_R_SUCCESS) &&
1827 (status != ISC_R_NORESOURCES))
1828 goto exit;
1829 }
1830
1831 /* Same for IA_PD's. */
1832 reply.pd_count = 0;
1833 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
1834 for (; oc != NULL ; oc = oc->next) {
1835 isc_result_t status;
1836
1837 /* Start counting resources (prefixes) offered. */
1838 reply.client_resources = 0;
1839 reply.resources_included = ISC_FALSE;
1840
1841 status = reply_process_ia_pd(&reply, oc);
1842
1843 /*
1844 * We continue to try other IA_PD's whether we can address
1845 * this one or not. Any other result is an immediate fail.
1846 */
1847 if ((status != ISC_R_SUCCESS) &&
1848 (status != ISC_R_NORESOURCES))
1849 goto exit;
1850 }
1851
1852 /*
1853 * Make no reply if we gave no resources and is not
1854 * for Information-Request.
1855 */
1856 if ((reply.ia_count == 0) && (reply.pd_count == 0)) {
1857 if (reply.packet->dhcpv6_msg_type !=
1858 DHCPV6_INFORMATION_REQUEST)
1859 goto exit;
1860
1861 /*
1862 * Because we only execute statements on a per-IA basis,
1863 * we need to execute statements in any non-IA reply to
1864 * source configuration.
1865 */
1866 execute_statements_in_scope(NULL, reply.packet, NULL, NULL,
1867 reply.packet->options,
1868 reply.opt_state, &global_scope,
1869 reply.shared->group, root_group,
1870 NULL);
1871
1872 /* Execute statements from class scopes. */
1873 for (i = reply.packet->class_count; i > 0; i--) {
1874 execute_statements_in_scope(NULL, reply.packet,
1875 NULL, NULL,
1876 reply.packet->options,
1877 reply.opt_state,
1878 &global_scope,
1879 reply.packet->classes[i - 1]->group,
1880 reply.shared->group, NULL);
1881 }
1882
1883 /* Bring in any configuration from a host record. */
1884 if (reply.host != NULL)
1885 execute_statements_in_scope(NULL, reply.packet,
1886 NULL, NULL,
1887 reply.packet->options,
1888 reply.opt_state,
1889 &global_scope,
1890 reply.host->group,
1891 reply.shared->group, NULL);
1892 }
1893
1894 /*
1895 * RFC3315 section 17.2.2 (Solicit):
1896 *
1897 * If the server will not assign any addresses to any IAs in a
1898 * subsequent Request from the client, the server MUST send an
1899 * Advertise message to the client that includes only a Status
1900 * Code option with code NoAddrsAvail and a status message for
1901 * the user, a Server Identifier option with the server's DUID,
1902 * and a Client Identifier option with the client's DUID.
1903 *
1904 * This has been updated by an errata such that the server
1905 * can always send an IA.
1906 *
1907 * Section 18.2.1 (Request):
1908 *
1909 * If the server cannot assign any addresses to an IA in the
1910 * message from the client, the server MUST include the IA in
1911 * the Reply message with no addresses in the IA and a Status
1912 * Code option in the IA containing status code NoAddrsAvail.
1913 *
1914 * Section 18.1.8 (Client Behavior):
1915 *
1916 * Leave unchanged any information about addresses the client has
1917 * recorded in the IA but that were not included in the IA from
1918 * the server.
1919 * Sends a Renew/Rebind if the IA is not in the Reply message.
1920 */
1921
1922 /*
1923 * Having stored the client's IA's, store any options that
1924 * will fit in the remaining space.
1925 */
1926 reply.cursor += store_options6((char *)reply.buf.data + reply.cursor,
1927 sizeof(reply.buf) - reply.cursor,
1928 reply.opt_state, reply.packet,
1929 required_opts_solicit,
1930 &packet_oro);
1931
1932 /* Return our reply to the caller. */
1933 reply_ret->len = reply.cursor;
1934 reply_ret->buffer = NULL;
1935 if (!buffer_allocate(&reply_ret->buffer, reply.cursor, MDL)) {
1936 log_fatal("No memory to store Reply.");
1937 }
1938 memcpy(reply_ret->buffer->data, reply.buf.data, reply.cursor);
1939 reply_ret->data = reply_ret->buffer->data;
1940
1941 /* If appropriate commit and rotate the lease file */
1942 (void) commit_leases_timed();
1943
1944 exit:
1945 /* Cleanup. */
1946 if (reply.shared != NULL)
1947 shared_network_dereference(&reply.shared, MDL);
1948 if (reply.host != NULL)
1949 host_dereference(&reply.host, MDL);
1950 if (reply.opt_state != NULL)
1951 option_state_dereference(&reply.opt_state, MDL);
1952 if (reply.packet != NULL)
1953 packet_dereference(&reply.packet, MDL);
1954 if (reply.client_id.data != NULL)
1955 data_string_forget(&reply.client_id, MDL);
1956 if (packet_oro.buffer != NULL)
1957 data_string_forget(&packet_oro, MDL);
1958 reply.renew = reply.rebind = reply.min_prefer = reply.min_valid = 0;
1959 reply.cursor = 0;
1960 }
1961
1962 /* Process a client-supplied IA_NA. This may append options to the tail of
1963 * the reply packet being built in the reply_state structure.
1964 */
1965 static isc_result_t
1966 reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) {
1967 isc_result_t status = ISC_R_SUCCESS;
1968 u_int32_t iaid;
1969 unsigned ia_cursor;
1970 struct option_state *packet_ia;
1971 struct option_cache *oc;
1972 struct data_string ia_data, data;
1973
1974 /* Initialize values that will get cleaned up on return. */
1975 packet_ia = NULL;
1976 memset(&ia_data, 0, sizeof(ia_data));
1977 memset(&data, 0, sizeof(data));
1978 /*
1979 * Note that find_client_address() may set reply->lease.
1980 */
1981
1982 /* Make sure there is at least room for the header. */
1983 if ((reply->cursor + IA_NA_OFFSET + 4) > sizeof(reply->buf)) {
1984 log_error("reply_process_ia_na: Reply too long for IA.");
1985 return ISC_R_NOSPACE;
1986 }
1987
1988
1989 /* Fetch the IA_NA contents. */
1990 if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
1991 ia, IA_NA_OFFSET)) {
1992 log_error("reply_process_ia_na: error evaluating ia");
1993 status = ISC_R_FAILURE;
1994 goto cleanup;
1995 }
1996
1997 /* Extract IA_NA header contents. */
1998 iaid = getULong(ia_data.data);
1999 reply->renew = getULong(ia_data.data + 4);
2000 reply->rebind = getULong(ia_data.data + 8);
2001
2002 /* Create an IA_NA structure. */
2003 if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data,
2004 reply->client_id.len, MDL) != ISC_R_SUCCESS) {
2005 log_error("reply_process_ia_na: no memory for ia.");
2006 status = ISC_R_NOMEMORY;
2007 goto cleanup;
2008 }
2009 reply->ia->ia_type = D6O_IA_NA;
2010
2011 /* Cache pre-existing IA, if any. */
2012 ia_hash_lookup(&reply->old_ia, ia_na_active,
2013 (unsigned char *)reply->ia->iaid_duid.data,
2014 reply->ia->iaid_duid.len, MDL);
2015
2016 /*
2017 * Create an option cache to carry the IA_NA option contents, and
2018 * execute any user-supplied values into it.
2019 */
2020 if (!option_state_allocate(&reply->reply_ia, MDL)) {
2021 status = ISC_R_NOMEMORY;
2022 goto cleanup;
2023 }
2024
2025 /* Check & cache the fixed host record. */
2026 if ((reply->host != NULL) && (reply->host->fixed_addr != NULL)) {
2027 struct iaddr tmp_addr;
2028
2029 if (!evaluate_option_cache(&reply->fixed, NULL, NULL, NULL,
2030 NULL, NULL, &global_scope,
2031 reply->host->fixed_addr, MDL)) {
2032 log_error("reply_process_ia_na: unable to evaluate "
2033 "fixed address.");
2034 status = ISC_R_FAILURE;
2035 goto cleanup;
2036 }
2037
2038 if (reply->fixed.len < 16) {
2039 log_error("reply_process_ia_na: invalid fixed address.");
2040 status = DHCP_R_INVALIDARG;
2041 goto cleanup;
2042 }
2043
2044 /* Find the static lease's subnet. */
2045 tmp_addr.len = 16;
2046 memcpy(tmp_addr.iabuf, reply->fixed.data, 16);
2047
2048 if (find_grouped_subnet(&reply->subnet, reply->shared,
2049 tmp_addr, MDL) == 0)
2050 log_fatal("Impossible condition at %s:%d.", MDL);
2051
2052 reply->static_lease = ISC_TRUE;
2053 } else
2054 reply->static_lease = ISC_FALSE;
2055
2056 /*
2057 * Save the cursor position at the start of the IA, so we can
2058 * set length and adjust t1/t2 values later. We write a temporary
2059 * header out now just in case we decide to adjust the packet
2060 * within sub-process functions.
2061 */
2062 ia_cursor = reply->cursor;
2063
2064 /* Initialize the IA_NA header. First the code. */
2065 putUShort(reply->buf.data + reply->cursor, (unsigned)D6O_IA_NA);
2066 reply->cursor += 2;
2067
2068 /* Then option length. */
2069 putUShort(reply->buf.data + reply->cursor, 0x0Cu);
2070 reply->cursor += 2;
2071
2072 /* Then IA_NA header contents; IAID. */
2073 putULong(reply->buf.data + reply->cursor, iaid);
2074 reply->cursor += 4;
2075
2076 /* We store the client's t1 for now, and may over-ride it later. */
2077 putULong(reply->buf.data + reply->cursor, reply->renew);
2078 reply->cursor += 4;
2079
2080 /* We store the client's t2 for now, and may over-ride it later. */
2081 putULong(reply->buf.data + reply->cursor, reply->rebind);
2082 reply->cursor += 4;
2083
2084 /*
2085 * For each address in this IA_NA, decide what to do about it.
2086 *
2087 * Guidelines:
2088 *
2089 * The client leaves unchanged any information about addresses
2090 * it has recorded but are not included ("cancel/break" below).
2091 * A not included IA ("cleanup" below) could give a Renew/Rebind.
2092 */
2093 oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAADDR);
2094 reply->min_valid = reply->min_prefer = INFINITE_TIME;
2095 reply->client_valid = reply->client_prefer = 0;
2096 for (; oc != NULL ; oc = oc->next) {
2097 status = reply_process_addr(reply, oc);
2098
2099 /*
2100 * Canceled means we did not allocate addresses to the
2101 * client, but we're "done" with this IA - we set a status
2102 * code. So transmit this reply, e.g., move on to the next
2103 * IA.
2104 */
2105 if (status == ISC_R_CANCELED)
2106 break;
2107
2108 if ((status != ISC_R_SUCCESS) &&
2109 (status != ISC_R_ADDRINUSE) &&
2110 (status != ISC_R_ADDRNOTAVAIL))
2111 goto cleanup;
2112 }
2113
2114 reply->ia_count++;
2115
2116 /*
2117 * If we fell through the above and never gave the client
2118 * an address, give it one now.
2119 */
2120 if ((status != ISC_R_CANCELED) && (reply->client_resources == 0)) {
2121 status = find_client_address(reply);
2122
2123 if (status == ISC_R_NORESOURCES) {
2124 switch (reply->packet->dhcpv6_msg_type) {
2125 case DHCPV6_SOLICIT:
2126 /*
2127 * No address for any IA is handled
2128 * by the caller.
2129 */
2130 /* FALL THROUGH */
2131
2132 case DHCPV6_REQUEST:
2133 /* Section 18.2.1 (Request):
2134 *
2135 * If the server cannot assign any addresses to
2136 * an IA in the message from the client, the
2137 * server MUST include the IA in the Reply
2138 * message with no addresses in the IA and a
2139 * Status Code option in the IA containing
2140 * status code NoAddrsAvail.
2141 */
2142 option_state_dereference(&reply->reply_ia, MDL);
2143 if (!option_state_allocate(&reply->reply_ia,
2144 MDL))
2145 {
2146 log_error("reply_process_ia_na: No "
2147 "memory for option state "
2148 "wipe.");
2149 status = ISC_R_NOMEMORY;
2150 goto cleanup;
2151 }
2152
2153 if (!set_status_code(STATUS_NoAddrsAvail,
2154 "No addresses available "
2155 "for this interface.",
2156 reply->reply_ia)) {
2157 log_error("reply_process_ia_na: Unable "
2158 "to set NoAddrsAvail status "
2159 "code.");
2160 status = ISC_R_FAILURE;
2161 goto cleanup;
2162 }
2163
2164 status = ISC_R_SUCCESS;
2165 break;
2166
2167 default:
2168 /*
2169 * RFC 3315 does not tell us to emit a status
2170 * code in this condition, or anything else.
2171 *
2172 * If we included non-allocated addresses
2173 * (zeroed lifetimes) in an IA, then the client
2174 * will deconfigure them.
2175 *
2176 * So we want to include the IA even if we
2177 * can't give it a new address if it includes
2178 * zeroed lifetime addresses.
2179 *
2180 * We don't want to include the IA if we
2181 * provide zero addresses including zeroed
2182 * lifetimes.
2183 */
2184 if (reply->resources_included)
2185 status = ISC_R_SUCCESS;
2186 else
2187 goto cleanup;
2188 break;
2189 }
2190 }
2191
2192 if (status != ISC_R_SUCCESS)
2193 goto cleanup;
2194 }
2195
2196 reply->cursor += store_options6((char *)reply->buf.data + reply->cursor,
2197 sizeof(reply->buf) - reply->cursor,
2198 reply->reply_ia, reply->packet,
2199 required_opts_IA, NULL);
2200
2201 /* Reset the length of this IA to match what was just written. */
2202 putUShort(reply->buf.data + ia_cursor + 2,
2203 reply->cursor - (ia_cursor + 4));
2204
2205 /* Calculate T1/T2 and stuff them in the reply */
2206 set_reply_tee_times(reply, ia_cursor);
2207
2208 /*
2209 * yes, goto's aren't the best but we also want to avoid extra
2210 * indents
2211 */
2212 if (status == ISC_R_CANCELED)
2213 goto cleanup;
2214
2215 /*
2216 * Handle static leases, we always log stuff and if it's
2217 * a hard binding we run any commit statements that we have
2218 */
2219 if (reply->static_lease) {
2220 char tmp_addr[INET6_ADDRSTRLEN];
2221 log_info("%s NA: address %s to client with duid %s iaid = %d "
2222 "static",
2223 dhcpv6_type_names[reply->buf.reply.msg_type],
2224 inet_ntop(AF_INET6, reply->fixed.data, tmp_addr,
2225 sizeof(tmp_addr)),
2226 print_hex_1(reply->client_id.len,
2227 reply->client_id.data, 60),
2228 iaid);
2229
2230 if ((reply->buf.reply.msg_type == DHCPV6_REPLY) &&
2231 (reply->on_star.on_commit != NULL)) {
2232 execute_statements(NULL, reply->packet, NULL, NULL,
2233 reply->packet->options,
2234 reply->opt_state, NULL,
2235 reply->on_star.on_commit, NULL);
2236 executable_statement_dereference
2237 (&reply->on_star.on_commit, MDL);
2238 }
2239 goto cleanup;
2240 }
2241
2242 /*
2243 * If we have any addresses log what we are doing.
2244 */
2245 if (reply->ia->num_iasubopt != 0) {
2246 struct iasubopt *tmp;
2247 int i;
2248 char tmp_addr[INET6_ADDRSTRLEN];
2249
2250 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
2251 tmp = reply->ia->iasubopt[i];
2252
2253 log_info("%s NA: address %s to client with duid %s "
2254 "iaid = %d valid for %u seconds",
2255 dhcpv6_type_names[reply->buf.reply.msg_type],
2256 inet_ntop(AF_INET6, &tmp->addr,
2257 tmp_addr, sizeof(tmp_addr)),
2258 print_hex_1(reply->client_id.len,
2259 reply->client_id.data, 60),
2260 iaid, tmp->valid);
2261 }
2262 }
2263
2264 /*
2265 * If this is not a 'soft' binding, consume the new changes into
2266 * the database (if any have been attached to the ia_na).
2267 *
2268 * Loop through the assigned dynamic addresses, referencing the
2269 * leases onto this IA_NA rather than any old ones, and updating
2270 * pool timers for each (if any).
2271 */
2272
2273 if ((reply->ia->num_iasubopt != 0) &&
2274 (reply->buf.reply.msg_type == DHCPV6_REPLY)) {
2275 struct iasubopt *tmp;
2276 struct data_string *ia_id;
2277 int i;
2278
2279 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
2280 tmp = reply->ia->iasubopt[i];
2281
2282 if (tmp->ia != NULL)
2283 ia_dereference(&tmp->ia, MDL);
2284 ia_reference(&tmp->ia, reply->ia, MDL);
2285
2286 /* Commit 'hard' bindings. */
2287 renew_lease6(tmp->ipv6_pool, tmp);
2288 schedule_lease_timeout(tmp->ipv6_pool);
2289
2290 /* If we have anything to do on commit do it now */
2291 if (tmp->on_star.on_commit != NULL) {
2292 execute_statements(NULL, reply->packet,
2293 NULL, NULL,
2294 reply->packet->options,
2295 reply->opt_state,
2296 &tmp->scope,
2297 tmp->on_star.on_commit,
2298 &tmp->on_star);
2299 executable_statement_dereference
2300 (&tmp->on_star.on_commit, MDL);
2301 }
2302
2303 #if defined (NSUPDATE)
2304 /*
2305 * Perform ddns updates.
2306 */
2307 oc = lookup_option(&server_universe, reply->opt_state,
2308 SV_DDNS_UPDATES);
2309 if ((oc == NULL) ||
2310 evaluate_boolean_option_cache(NULL, reply->packet,
2311 NULL, NULL,
2312 reply->packet->options,
2313 reply->opt_state,
2314 &tmp->scope,
2315 oc, MDL)) {
2316 ddns_updates(reply->packet, NULL, NULL,
2317 tmp, NULL, reply->opt_state);
2318 }
2319 #endif
2320 /* Do our threshold check. */
2321 check_pool6_threshold(reply, tmp);
2322 }
2323
2324 /* Remove any old ia from the hash. */
2325 if (reply->old_ia != NULL) {
2326 if (!release_on_roam(reply)) {
2327 ia_id = &reply->old_ia->iaid_duid;
2328 ia_hash_delete(ia_na_active,
2329 (unsigned char *)ia_id->data,
2330 ia_id->len, MDL);
2331 }
2332
2333 ia_dereference(&reply->old_ia, MDL);
2334 }
2335
2336 /* Put new ia into the hash. */
2337 reply->ia->cltt = cur_time;
2338 ia_id = &reply->ia->iaid_duid;
2339 ia_hash_add(ia_na_active, (unsigned char *)ia_id->data,
2340 ia_id->len, reply->ia, MDL);
2341
2342 write_ia(reply->ia);
2343 } else {
2344 schedule_lease_timeout_reply(reply);
2345 }
2346
2347 cleanup:
2348 if (packet_ia != NULL)
2349 option_state_dereference(&packet_ia, MDL);
2350 if (reply->reply_ia != NULL)
2351 option_state_dereference(&reply->reply_ia, MDL);
2352 if (ia_data.data != NULL)
2353 data_string_forget(&ia_data, MDL);
2354 if (data.data != NULL)
2355 data_string_forget(&data, MDL);
2356 if (reply->ia != NULL)
2357 ia_dereference(&reply->ia, MDL);
2358 if (reply->old_ia != NULL)
2359 ia_dereference(&reply->old_ia, MDL);
2360 if (reply->lease != NULL)
2361 iasubopt_dereference(&reply->lease, MDL);
2362 if (reply->fixed.data != NULL)
2363 data_string_forget(&reply->fixed, MDL);
2364 if (reply->subnet != NULL)
2365 subnet_dereference(&reply->subnet, MDL);
2366 if (reply->on_star.on_expiry != NULL)
2367 executable_statement_dereference
2368 (&reply->on_star.on_expiry, MDL);
2369 if (reply->on_star.on_release != NULL)
2370 executable_statement_dereference
2371 (&reply->on_star.on_release, MDL);
2372
2373 /*
2374 * ISC_R_CANCELED is a status code used by the addr processing to
2375 * indicate we're replying with a status code. This is still a
2376 * success at higher layers.
2377 */
2378 return((status == ISC_R_CANCELED) ? ISC_R_SUCCESS : status);
2379 }
2380
2381 /*
2382 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
2383 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
2384 * in the event we are replying with a status code and do not wish to process
2385 * more IAADDRs within this IA.
2386 */
2387 static isc_result_t
2388 reply_process_addr(struct reply_state *reply, struct option_cache *addr) {
2389 u_int32_t pref_life, valid_life;
2390 struct binding_scope **scope;
2391 struct group *group;
2392 struct subnet *subnet;
2393 struct iaddr tmp_addr;
2394 struct option_cache *oc;
2395 struct data_string iaaddr, data;
2396 isc_result_t status = ISC_R_SUCCESS;
2397 #ifdef EUI_64
2398 int invalid_for_eui_64 = 0;
2399 #endif
2400
2401 /* Initializes values that will be cleaned up. */
2402 memset(&iaaddr, 0, sizeof(iaaddr));
2403 memset(&data, 0, sizeof(data));
2404 /* Note that reply->lease may be set by address_is_owned() */
2405
2406 /*
2407 * There is no point trying to process an incoming address if there
2408 * is no room for an outgoing address.
2409 */
2410 if ((reply->cursor + 28) > sizeof(reply->buf)) {
2411 log_error("reply_process_addr: Out of room for address.");
2412 return ISC_R_NOSPACE;
2413 }
2414
2415 /* Extract this IAADDR option. */
2416 if (!evaluate_option_cache(&iaaddr, reply->packet, NULL, NULL,
2417 reply->packet->options, NULL, &global_scope,
2418 addr, MDL) ||
2419 (iaaddr.len < IAADDR_OFFSET)) {
2420 log_error("reply_process_addr: error evaluating IAADDR.");
2421 status = ISC_R_FAILURE;
2422 goto cleanup;
2423 }
2424
2425 /* The first 16 bytes are the IPv6 address. */
2426 pref_life = getULong(iaaddr.data + 16);
2427 valid_life = getULong(iaaddr.data + 20);
2428
2429 if ((reply->client_valid == 0) ||
2430 (reply->client_valid > valid_life))
2431 reply->client_valid = valid_life;
2432
2433 if ((reply->client_prefer == 0) ||
2434 (reply->client_prefer > pref_life))
2435 reply->client_prefer = pref_life;
2436
2437 /*
2438 * Clients may choose to send :: as an address, with the idea to give
2439 * hints about preferred-lifetime or valid-lifetime.
2440 */
2441 tmp_addr.len = 16;
2442 memset(tmp_addr.iabuf, 0, 16);
2443 if (!memcmp(iaaddr.data, tmp_addr.iabuf, 16)) {
2444 /* Status remains success; we just ignore this one. */
2445 goto cleanup;
2446 }
2447
2448 /* tmp_addr len remains 16 */
2449 memcpy(tmp_addr.iabuf, iaaddr.data, 16);
2450
2451 /*
2452 * Verify that this address is on the client's network.
2453 */
2454 for (subnet = reply->shared->subnets ; subnet != NULL ;
2455 subnet = subnet->next_sibling) {
2456 if (addr_eq(subnet_number(tmp_addr, subnet->netmask),
2457 subnet->net))
2458 break;
2459 }
2460
2461 #ifdef EUI_64
2462 if (subnet) {
2463 /* If the requested address falls into an EUI-64 pool, then
2464 * we need to verify if it has EUI-64 duid AND the requested
2465 * address is correct for that duid. If not we treat it just
2466 * like an not-on-link request. */
2467 struct ipv6_pool* pool = NULL;
2468 struct in6_addr* addr = (struct in6_addr*)(iaaddr.data);
2469 if ((find_ipv6_pool(&pool, D6O_IA_NA, addr) == ISC_R_SUCCESS)
2470 && (pool->ipv6_pond->use_eui_64) &&
2471 (!valid_for_eui_64_pool(pool, &reply->client_id, 0, addr))) {
2472 log_debug ("Requested address: %s,"
2473 " not valid for EUI-64 pool",
2474 pin6_addr(addr));
2475 invalid_for_eui_64 = 1;
2476 }
2477 }
2478 #endif
2479
2480 /* Address not found on shared network. */
2481 #ifdef EUI_64
2482 if ((subnet == NULL) || invalid_for_eui_64) {
2483 #else
2484 if (subnet == NULL) {
2485 #endif
2486 /* Ignore this address on 'soft' bindings. */
2487 if (reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) {
2488 /* disable rapid commit */
2489 reply->buf.reply.msg_type = DHCPV6_ADVERTISE;
2490 delete_option(&dhcpv6_universe,
2491 reply->opt_state,
2492 D6O_RAPID_COMMIT);
2493 /* status remains success */
2494 goto cleanup;
2495 }
2496
2497 /*
2498 * RFC3315 section 18.2.1:
2499 *
2500 * If the server finds that the prefix on one or more IP
2501 * addresses in any IA in the message from the client is not
2502 * appropriate for the link to which the client is connected,
2503 * the server MUST return the IA to the client with a Status
2504 * Code option with the value NotOnLink.
2505 */
2506 if (reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) {
2507 /* Rewind the IA_NA to empty. */
2508 option_state_dereference(&reply->reply_ia, MDL);
2509 if (!option_state_allocate(&reply->reply_ia, MDL)) {
2510 log_error("reply_process_addr: No memory for "
2511 "option state wipe.");
2512 status = ISC_R_NOMEMORY;
2513 goto cleanup;
2514 }
2515
2516 /* Append a NotOnLink status code. */
2517 if (!set_status_code(STATUS_NotOnLink,
2518 "Address not for use on this "
2519 "link.", reply->reply_ia)) {
2520 log_error("reply_process_addr: Failure "
2521 "setting status code.");
2522 status = ISC_R_FAILURE;
2523 goto cleanup;
2524 }
2525
2526 /* Fin (no more IAADDRs). */
2527 status = ISC_R_CANCELED;
2528 goto cleanup;
2529 }
2530
2531 /*
2532 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
2533 *
2534 * If the server finds that any of the addresses are not
2535 * appropriate for the link to which the client is attached,
2536 * the server returns the address to the client with lifetimes
2537 * of 0.
2538 */
2539 if ((reply->packet->dhcpv6_msg_type != DHCPV6_RENEW) &&
2540 (reply->packet->dhcpv6_msg_type != DHCPV6_REBIND)) {
2541 log_error("It is impossible to lease a client that is "
2542 "not sending a solicit, request, renew, or "
2543 "rebind.");
2544 status = ISC_R_FAILURE;
2545 goto cleanup;
2546 }
2547
2548 reply->send_prefer = reply->send_valid = 0;
2549 goto send_addr;
2550 }
2551
2552
2553 /* Verify the address belongs to the client. */
2554 if (!address_is_owned(reply, &tmp_addr)) {
2555 /*
2556 * For solicit and request, any addresses included are
2557 * 'requested' addresses. For rebind, we actually have
2558 * no direction on what to do from 3315 section 18.2.4!
2559 * So I think the best bet is to try and give it out, and if
2560 * we can't, zero lifetimes.
2561 */
2562 if ((reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) ||
2563 (reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) ||
2564 (reply->packet->dhcpv6_msg_type == DHCPV6_REBIND)) {
2565 status = reply_process_try_addr(reply, &tmp_addr);
2566
2567 /*
2568 * If the address is in use, or isn't in any dynamic
2569 * range, continue as normal. If any other error was
2570 * found, error out.
2571 */
2572 if ((status != ISC_R_SUCCESS) &&
2573 (status != ISC_R_ADDRINUSE) &&
2574 (status != ISC_R_ADDRNOTAVAIL))
2575 goto cleanup;
2576
2577 /*
2578 * If we didn't honor this lease, for solicit and
2579 * request we simply omit it from our answer. For
2580 * rebind, we send it with zeroed lifetimes.
2581 */
2582 if (reply->lease == NULL) {
2583 if (reply->packet->dhcpv6_msg_type ==
2584 DHCPV6_REBIND) {
2585 reply->send_prefer = 0;
2586 reply->send_valid = 0;
2587 goto send_addr;
2588 }
2589
2590 /* status remains success - ignore */
2591 goto cleanup;
2592 }
2593 /*
2594 * RFC3315 section 18.2.3:
2595 *
2596 * If the server cannot find a client entry for the IA the
2597 * server returns the IA containing no addresses with a Status
2598 * Code option set to NoBinding in the Reply message.
2599 *
2600 * On mismatch we (ab)use this pretending we have not the IA
2601 * as soon as we have not an address.
2602 */
2603 } else if (reply->packet->dhcpv6_msg_type == DHCPV6_RENEW) {
2604 /* Rewind the IA_NA to empty. */
2605 option_state_dereference(&reply->reply_ia, MDL);
2606 if (!option_state_allocate(&reply->reply_ia, MDL)) {
2607 log_error("reply_process_addr: No memory for "
2608 "option state wipe.");
2609 status = ISC_R_NOMEMORY;
2610 goto cleanup;
2611 }
2612
2613 /* Append a NoBinding status code. */
2614 if (!set_status_code(STATUS_NoBinding,
2615 "Address not bound to this "
2616 "interface.", reply->reply_ia)) {
2617 log_error("reply_process_addr: Unable to "
2618 "attach status code.");
2619 status = ISC_R_FAILURE;
2620 goto cleanup;
2621 }
2622
2623 /* Fin (no more IAADDRs). */
2624 status = ISC_R_CANCELED;
2625 goto cleanup;
2626 } else {
2627 log_error("It is impossible to lease a client that is "
2628 "not sending a solicit, request, renew, or "
2629 "rebind message.");
2630 status = ISC_R_FAILURE;
2631 goto cleanup;
2632 }
2633 }
2634
2635 if (reply->static_lease) {
2636 if (reply->host == NULL)
2637 log_fatal("Impossible condition at %s:%d.", MDL);
2638
2639 scope = &global_scope;
2640 group = reply->subnet->group;
2641 } else {
2642 if (reply->lease == NULL)
2643 log_fatal("Impossible condition at %s:%d.", MDL);
2644
2645 scope = &reply->lease->scope;
2646 group = reply->lease->ipv6_pool->ipv6_pond->group;
2647 }
2648
2649 /*
2650 * If client_resources is nonzero, then the reply_process_is_addressed
2651 * function has executed configuration state into the reply option
2652 * cache. We will use that valid cache to derive configuration for
2653 * whether or not to engage in additional addresses, and similar.
2654 */
2655 if (reply->client_resources != 0) {
2656 unsigned limit = 1;
2657
2658 /*
2659 * Does this client have "enough" addresses already? Default
2660 * to one. Everybody gets one, and one should be enough for
2661 * anybody.
2662 */
2663 oc = lookup_option(&server_universe, reply->opt_state,
2664 SV_LIMIT_ADDRS_PER_IA);
2665 if (oc != NULL) {
2666 if (!evaluate_option_cache(&data, reply->packet,
2667 NULL, NULL,
2668 reply->packet->options,
2669 reply->opt_state,
2670 scope, oc, MDL) ||
2671 (data.len != 4)) {
2672 log_error("reply_process_addr: unable to "
2673 "evaluate addrs-per-ia value.");
2674 status = ISC_R_FAILURE;
2675 goto cleanup;
2676 }
2677
2678 limit = getULong(data.data);
2679 data_string_forget(&data, MDL);
2680 }
2681
2682 /*
2683 * If we wish to limit the client to a certain number of
2684 * addresses, then omit the address from the reply.
2685 */
2686 if (reply->client_resources >= limit)
2687 goto cleanup;
2688 }
2689
2690 status = reply_process_is_addressed(reply, scope, group);
2691 if (status != ISC_R_SUCCESS)
2692 goto cleanup;
2693
2694 send_addr:
2695 status = reply_process_send_addr(reply, &tmp_addr);
2696
2697 cleanup:
2698 if (iaaddr.data != NULL)
2699 data_string_forget(&iaaddr, MDL);
2700 if (data.data != NULL)
2701 data_string_forget(&data, MDL);
2702 if (reply->lease != NULL)
2703 iasubopt_dereference(&reply->lease, MDL);
2704
2705 return status;
2706 }
2707
2708 /*
2709 * Verify the address belongs to the client. If we've got a host
2710 * record with a fixed address, it has to be the assigned address
2711 * (fault out all else). Otherwise it's a dynamic address, so lookup
2712 * that address and make sure it belongs to this DUID:IAID pair.
2713 */
2714 static isc_boolean_t
2715 address_is_owned(struct reply_state *reply, struct iaddr *addr) {
2716 int i;
2717 struct ipv6_pond *pond;
2718
2719 /*
2720 * This faults out addresses that don't match fixed addresses.
2721 */
2722 if (reply->static_lease) {
2723 if (reply->fixed.data == NULL)
2724 log_fatal("Impossible condition at %s:%d.", MDL);
2725
2726 if (memcmp(addr->iabuf, reply->fixed.data, 16) == 0)
2727 return (ISC_TRUE);
2728
2729 return (ISC_FALSE);
2730 }
2731
2732 if ((reply->old_ia == NULL) || (reply->old_ia->num_iasubopt == 0))
2733 return (ISC_FALSE);
2734
2735 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
2736 struct iasubopt *tmp;
2737
2738 tmp = reply->old_ia->iasubopt[i];
2739
2740 if (memcmp(addr->iabuf, &tmp->addr, 16) == 0) {
2741 if (lease6_usable(tmp) == ISC_FALSE) {
2742 return (ISC_FALSE);
2743 }
2744
2745 pond = tmp->ipv6_pool->ipv6_pond;
2746 if (((pond->prohibit_list != NULL) &&
2747 (permitted(reply->packet, pond->prohibit_list))) ||
2748 ((pond->permit_list != NULL) &&
2749 (!permitted(reply->packet, pond->permit_list))))
2750 return (ISC_FALSE);
2751
2752 iasubopt_reference(&reply->lease, tmp, MDL);
2753
2754 return (ISC_TRUE);
2755 }
2756 }
2757
2758 return (ISC_FALSE);
2759 }
2760
2761 /* Process a client-supplied IA_TA. This may append options to the tail of
2762 * the reply packet being built in the reply_state structure.
2763 */
2764 static isc_result_t
2765 reply_process_ia_ta(struct reply_state *reply, struct option_cache *ia) {
2766 isc_result_t status = ISC_R_SUCCESS;
2767 u_int32_t iaid;
2768 unsigned ia_cursor;
2769 struct option_state *packet_ia;
2770 struct option_cache *oc;
2771 struct data_string ia_data, data;
2772 struct data_string iaaddr;
2773 u_int32_t pref_life, valid_life;
2774 struct iaddr tmp_addr;
2775
2776 /* Initialize values that will get cleaned up on return. */
2777 packet_ia = NULL;
2778 memset(&ia_data, 0, sizeof(ia_data));
2779 memset(&data, 0, sizeof(data));
2780 memset(&iaaddr, 0, sizeof(iaaddr));
2781
2782 /* Make sure there is at least room for the header. */
2783 if ((reply->cursor + IA_TA_OFFSET + 4) > sizeof(reply->buf)) {
2784 log_error("reply_process_ia_ta: Reply too long for IA.");
2785 return ISC_R_NOSPACE;
2786 }
2787
2788
2789 /* Fetch the IA_TA contents. */
2790 if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
2791 ia, IA_TA_OFFSET)) {
2792 log_error("reply_process_ia_ta: error evaluating ia");
2793 status = ISC_R_FAILURE;
2794 goto cleanup;
2795 }
2796
2797 /* Extract IA_TA header contents. */
2798 iaid = getULong(ia_data.data);
2799
2800 /* Create an IA_TA structure. */
2801 if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data,
2802 reply->client_id.len, MDL) != ISC_R_SUCCESS) {
2803 log_error("reply_process_ia_ta: no memory for ia.");
2804 status = ISC_R_NOMEMORY;
2805 goto cleanup;
2806 }
2807 reply->ia->ia_type = D6O_IA_TA;
2808
2809 /* Cache pre-existing IA, if any. */
2810 ia_hash_lookup(&reply->old_ia, ia_ta_active,
2811 (unsigned char *)reply->ia->iaid_duid.data,
2812 reply->ia->iaid_duid.len, MDL);
2813
2814 /*
2815 * Create an option cache to carry the IA_TA option contents, and
2816 * execute any user-supplied values into it.
2817 */
2818 if (!option_state_allocate(&reply->reply_ia, MDL)) {
2819 status = ISC_R_NOMEMORY;
2820 goto cleanup;
2821 }
2822
2823 /*
2824 * Temporary leases are dynamic by definition.
2825 */
2826 reply->static_lease = ISC_FALSE;
2827
2828 /*
2829 * Save the cursor position at the start of the IA, so we can
2830 * set length later. We write a temporary
2831 * header out now just in case we decide to adjust the packet
2832 * within sub-process functions.
2833 */
2834 ia_cursor = reply->cursor;
2835
2836 /* Initialize the IA_TA header. First the code. */
2837 putUShort(reply->buf.data + reply->cursor, (unsigned)D6O_IA_TA);
2838 reply->cursor += 2;
2839
2840 /* Then option length. */
2841 putUShort(reply->buf.data + reply->cursor, 0x04u);
2842 reply->cursor += 2;
2843
2844 /* Then IA_TA header contents; IAID. */
2845 putULong(reply->buf.data + reply->cursor, iaid);
2846 reply->cursor += 4;
2847
2848 /*
2849 * Deal with an IAADDR for lifetimes.
2850 * For all or none, process IAADDRs as hints.
2851 */
2852 reply->min_valid = reply->min_prefer = INFINITE_TIME;
2853 reply->client_valid = reply->client_prefer = 0;
2854 oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAADDR);
2855 for (; oc != NULL; oc = oc->next) {
2856 memset(&iaaddr, 0, sizeof(iaaddr));
2857 if (!evaluate_option_cache(&iaaddr, reply->packet,
2858 NULL, NULL,
2859 reply->packet->options, NULL,
2860 &global_scope, oc, MDL) ||
2861 (iaaddr.len < IAADDR_OFFSET)) {
2862 log_error("reply_process_ia_ta: error "
2863 "evaluating IAADDR.");
2864 status = ISC_R_FAILURE;
2865 goto cleanup;
2866 }
2867 /* The first 16 bytes are the IPv6 address. */
2868 pref_life = getULong(iaaddr.data + 16);
2869 valid_life = getULong(iaaddr.data + 20);
2870
2871 if ((reply->client_valid == 0) ||
2872 (reply->client_valid > valid_life))
2873 reply->client_valid = valid_life;
2874
2875 if ((reply->client_prefer == 0) ||
2876 (reply->client_prefer > pref_life))
2877 reply->client_prefer = pref_life;
2878
2879 /* Nothing more if something has failed. */
2880 if (status == ISC_R_CANCELED)
2881 continue;
2882
2883 tmp_addr.len = 16;
2884 memcpy(tmp_addr.iabuf, iaaddr.data, 16);
2885 if (!temporary_is_available(reply, &tmp_addr))
2886 goto bad_temp;
2887 status = reply_process_is_addressed(reply,
2888 &reply->lease->scope,
2889 reply->lease->ipv6_pool->ipv6_pond->group);
2890 if (status != ISC_R_SUCCESS)
2891 goto bad_temp;
2892 status = reply_process_send_addr(reply, &tmp_addr);
2893 if (status != ISC_R_SUCCESS)
2894 goto bad_temp;
2895 if (reply->lease != NULL)
2896 iasubopt_dereference(&reply->lease, MDL);
2897 continue;
2898
2899 bad_temp:
2900 /* Rewind the IA_TA to empty. */
2901 option_state_dereference(&reply->reply_ia, MDL);
2902 if (!option_state_allocate(&reply->reply_ia, MDL)) {
2903 status = ISC_R_NOMEMORY;
2904 goto cleanup;
2905 }
2906 status = ISC_R_CANCELED;
2907 reply->client_resources = 0;
2908 reply->resources_included = ISC_FALSE;
2909 if (reply->lease != NULL)
2910 iasubopt_dereference(&reply->lease, MDL);
2911 }
2912 reply->ia_count++;
2913
2914 /*
2915 * Give the client temporary addresses.
2916 */
2917 if (reply->client_resources != 0)
2918 goto store;
2919 status = find_client_temporaries(reply);
2920 if (status == ISC_R_NORESOURCES) {
2921 switch (reply->packet->dhcpv6_msg_type) {
2922 case DHCPV6_SOLICIT:
2923 /*
2924 * No address for any IA is handled
2925 * by the caller.
2926 */
2927 /* FALL THROUGH */
2928
2929 case DHCPV6_REQUEST:
2930 /* Section 18.2.1 (Request):
2931 *
2932 * If the server cannot assign any addresses to
2933 * an IA in the message from the client, the
2934 * server MUST include the IA in the Reply
2935 * message with no addresses in the IA and a
2936 * Status Code option in the IA containing
2937 * status code NoAddrsAvail.
2938 */
2939 option_state_dereference(&reply->reply_ia, MDL);
2940 if (!option_state_allocate(&reply->reply_ia, MDL)) {
2941 log_error("reply_process_ia_ta: No "
2942 "memory for option state wipe.");
2943 status = ISC_R_NOMEMORY;
2944 goto cleanup;
2945 }
2946
2947 if (!set_status_code(STATUS_NoAddrsAvail,
2948 "No addresses available "
2949 "for this interface.",
2950 reply->reply_ia)) {
2951 log_error("reply_process_ia_ta: Unable "
2952 "to set NoAddrsAvail status code.");
2953 status = ISC_R_FAILURE;
2954 goto cleanup;
2955 }
2956
2957 status = ISC_R_SUCCESS;
2958 break;
2959
2960 default:
2961 /*
2962 * We don't want to include the IA if we
2963 * provide zero addresses including zeroed
2964 * lifetimes.
2965 */
2966 if (reply->resources_included)
2967 status = ISC_R_SUCCESS;
2968 else
2969 goto cleanup;
2970 break;
2971 }
2972 } else if (status != ISC_R_SUCCESS)
2973 goto cleanup;
2974
2975 store:
2976 reply->cursor += store_options6((char *)reply->buf.data + reply->cursor,
2977 sizeof(reply->buf) - reply->cursor,
2978 reply->reply_ia, reply->packet,
2979 required_opts_IA, NULL);
2980
2981 /* Reset the length of this IA to match what was just written. */
2982 putUShort(reply->buf.data + ia_cursor + 2,
2983 reply->cursor - (ia_cursor + 4));
2984
2985 /*
2986 * yes, goto's aren't the best but we also want to avoid extra
2987 * indents
2988 */
2989 if (status == ISC_R_CANCELED)
2990 goto cleanup;
2991
2992 /*
2993 * If we have any addresses log what we are doing.
2994 */
2995 if (reply->ia->num_iasubopt != 0) {
2996 struct iasubopt *tmp;
2997 int i;
2998 char tmp_addr[INET6_ADDRSTRLEN];
2999
3000 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
3001 tmp = reply->ia->iasubopt[i];
3002
3003 log_info("%s TA: address %s to client with duid %s "
3004 "iaid = %d valid for %u seconds",
3005 dhcpv6_type_names[reply->buf.reply.msg_type],
3006 inet_ntop(AF_INET6, &tmp->addr,
3007 tmp_addr, sizeof(tmp_addr)),
3008 print_hex_1(reply->client_id.len,
3009 reply->client_id.data, 60),
3010 iaid,
3011 tmp->valid);
3012 }
3013 }
3014
3015 /*
3016 * For hard bindings we consume the new changes into
3017 * the database (if any have been attached to the ia_ta).
3018 *
3019 * Loop through the assigned dynamic addresses, referencing the
3020 * leases onto this IA_TA rather than any old ones, and updating
3021 * pool timers for each (if any).
3022 */
3023 if ((reply->ia->num_iasubopt != 0) &&
3024 (reply->buf.reply.msg_type == DHCPV6_REPLY)) {
3025 struct iasubopt *tmp;
3026 struct data_string *ia_id;
3027 int i;
3028
3029 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
3030 tmp = reply->ia->iasubopt[i];
3031
3032 if (tmp->ia != NULL)
3033 ia_dereference(&tmp->ia, MDL);
3034 ia_reference(&tmp->ia, reply->ia, MDL);
3035
3036 /* Commit 'hard' bindings. */
3037 renew_lease6(tmp->ipv6_pool, tmp);
3038 schedule_lease_timeout(tmp->ipv6_pool);
3039
3040 /* If we have anything to do on commit do it now */
3041 if (tmp->on_star.on_commit != NULL) {
3042 execute_statements(NULL, reply->packet,
3043 NULL, NULL,
3044 reply->packet->options,
3045 reply->opt_state,
3046 &tmp->scope,
3047 tmp->on_star.on_commit,
3048 &tmp->on_star);
3049 executable_statement_dereference
3050 (&tmp->on_star.on_commit, MDL);
3051 }
3052
3053 #if defined (NSUPDATE)
3054 /*
3055 * Perform ddns updates.
3056 */
3057 oc = lookup_option(&server_universe, reply->opt_state,
3058 SV_DDNS_UPDATES);
3059 if ((oc == NULL) ||
3060 evaluate_boolean_option_cache(NULL, reply->packet,
3061 NULL, NULL,
3062 reply->packet->options,
3063 reply->opt_state,
3064 &tmp->scope,
3065 oc, MDL)) {
3066 ddns_updates(reply->packet, NULL, NULL,
3067 tmp, NULL, reply->opt_state);
3068 }
3069 #endif
3070 /* Do our threshold check. */
3071 check_pool6_threshold(reply, tmp);
3072 }
3073
3074 /* Remove any old ia from the hash. */
3075 if (reply->old_ia != NULL) {
3076 if (!release_on_roam(reply)) {
3077 ia_id = &reply->old_ia->iaid_duid;
3078 ia_hash_delete(ia_ta_active,
3079 (unsigned char *)ia_id->data,
3080 ia_id->len, MDL);
3081 }
3082
3083 ia_dereference(&reply->old_ia, MDL);
3084 }
3085
3086 /* Put new ia into the hash. */
3087 reply->ia->cltt = cur_time;
3088 ia_id = &reply->ia->iaid_duid;
3089 ia_hash_add(ia_ta_active, (unsigned char *)ia_id->data,
3090 ia_id->len, reply->ia, MDL);
3091
3092 write_ia(reply->ia);
3093 } else {
3094 schedule_lease_timeout_reply(reply);
3095 }
3096
3097 cleanup:
3098 if (packet_ia != NULL)
3099 option_state_dereference(&packet_ia, MDL);
3100 if (iaaddr.data != NULL)
3101 data_string_forget(&iaaddr, MDL);
3102 if (reply->reply_ia != NULL)
3103 option_state_dereference(&reply->reply_ia, MDL);
3104 if (ia_data.data != NULL)
3105 data_string_forget(&ia_data, MDL);
3106 if (data.data != NULL)
3107 data_string_forget(&data, MDL);
3108 if (reply->ia != NULL)
3109 ia_dereference(&reply->ia, MDL);
3110 if (reply->old_ia != NULL)
3111 ia_dereference(&reply->old_ia, MDL);
3112 if (reply->lease != NULL)
3113 iasubopt_dereference(&reply->lease, MDL);
3114
3115 /*
3116 * ISC_R_CANCELED is a status code used by the addr processing to
3117 * indicate we're replying with other addresses. This is still a
3118 * success at higher layers.
3119 */
3120 return((status == ISC_R_CANCELED) ? ISC_R_SUCCESS : status);
3121 }
3122
3123 /*
3124 * Verify the temporary address is available.
3125 */
3126 static isc_boolean_t
3127 temporary_is_available(struct reply_state *reply, struct iaddr *addr) {
3128 struct in6_addr tmp_addr;
3129 struct subnet *subnet;
3130 struct ipv6_pool *pool = NULL;
3131 struct ipv6_pond *pond = NULL;
3132 int i;
3133
3134 memcpy(&tmp_addr, addr->iabuf, sizeof(tmp_addr));
3135 /*
3136 * Clients may choose to send :: as an address, with the idea to give
3137 * hints about preferred-lifetime or valid-lifetime.
3138 * So this is not a request for this address.
3139 */
3140 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr))
3141 return ISC_FALSE;
3142
3143 /*
3144 * Verify that this address is on the client's network.
3145 */
3146 for (subnet = reply->shared->subnets ; subnet != NULL ;
3147 subnet = subnet->next_sibling) {
3148 if (addr_eq(subnet_number(*addr, subnet->netmask),
3149 subnet->net))
3150 break;
3151 }
3152
3153 /* Address not found on shared network. */
3154 if (subnet == NULL)
3155 return ISC_FALSE;
3156
3157 /*
3158 * Check if this address is owned (must be before next step).
3159 */
3160 if (address_is_owned(reply, addr))
3161 return ISC_TRUE;
3162
3163 /*
3164 * Verify that this address is in a temporary pool and try to get it.
3165 */
3166 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
3167 if (((pond->prohibit_list != NULL) &&
3168 (permitted(reply->packet, pond->prohibit_list))) ||
3169 ((pond->permit_list != NULL) &&
3170 (!permitted(reply->packet, pond->permit_list))))
3171 continue;
3172
3173 for (i = 0 ; (pool = pond->ipv6_pools[i]) != NULL ; i++) {
3174 if (pool->pool_type != D6O_IA_TA)
3175 continue;
3176
3177 if (ipv6_in_pool(&tmp_addr, pool))
3178 break;
3179 }
3180
3181 if (pool != NULL)
3182 break;
3183 }
3184
3185 if (pool == NULL)
3186 return ISC_FALSE;
3187 if (lease6_exists(pool, &tmp_addr))
3188 return ISC_FALSE;
3189 if (iasubopt_allocate(&reply->lease, MDL) != ISC_R_SUCCESS)
3190 return ISC_FALSE;
3191 reply->lease->addr = tmp_addr;
3192 reply->lease->plen = 0;
3193 /* Default is soft binding for 2 minutes. */
3194 if (add_lease6(pool, reply->lease, cur_time + 120) != ISC_R_SUCCESS)
3195 return ISC_FALSE;
3196
3197 return ISC_TRUE;
3198 }
3199
3200 /*
3201 * Get a temporary address per prefix.
3202 */
3203 static isc_result_t
3204 find_client_temporaries(struct reply_state *reply) {
3205 int i;
3206 struct ipv6_pool *p = NULL;
3207 struct ipv6_pond *pond;
3208 isc_result_t status = ISC_R_NORESOURCES;;
3209 unsigned int attempts;
3210 struct iaddr send_addr;
3211
3212 /*
3213 * Do a quick walk through of the ponds and pools
3214 * to see if we have any prefix pools
3215 */
3216 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
3217 if (pond->ipv6_pools == NULL)
3218 continue;
3219
3220 for (i = 0; (p = pond->ipv6_pools[i]) != NULL; i++) {
3221 if (p->pool_type == D6O_IA_TA)
3222 break;
3223 }
3224 if (p != NULL)
3225 break;
3226 }
3227
3228 /* If we get here and p is NULL we have no useful pools */
3229 if (p == NULL) {
3230 log_debug("Unable to get client addresses: "
3231 "no IPv6 pools on this shared network");
3232 return ISC_R_NORESOURCES;
3233 }
3234
3235 /*
3236 * We have at least one pool that could provide an address
3237 * Now we walk through the ponds and pools again and check
3238 * to see if the client is permitted and if an address is
3239 * available
3240 */
3241
3242 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
3243 if (((pond->prohibit_list != NULL) &&
3244 (permitted(reply->packet, pond->prohibit_list))) ||
3245 ((pond->permit_list != NULL) &&
3246 (!permitted(reply->packet, pond->permit_list))))
3247 continue;
3248
3249 for (i = 0; (p = pond->ipv6_pools[i]) != NULL; i++) {
3250 if (p->pool_type != D6O_IA_TA) {
3251 continue;
3252 }
3253
3254 /*
3255 * Get an address in this temporary pool.
3256 */
3257 status = create_lease6(p, &reply->lease, &attempts,
3258 &reply->client_id,
3259 cur_time + 120);
3260
3261 if (status != ISC_R_SUCCESS) {
3262 log_debug("Unable to get a temporary address.");
3263 goto cleanup;
3264 }
3265
3266 status = reply_process_is_addressed(reply,
3267 &reply->lease->scope,
3268 pond->group);
3269 if (status != ISC_R_SUCCESS) {
3270 goto cleanup;
3271 }
3272 send_addr.len = 16;
3273 memcpy(send_addr.iabuf, &reply->lease->addr, 16);
3274 status = reply_process_send_addr(reply, &send_addr);
3275 if (status != ISC_R_SUCCESS) {
3276 goto cleanup;
3277 }
3278 /*
3279 * reply->lease can't be null as we use it above
3280 * add check if that changes
3281 */
3282 iasubopt_dereference(&reply->lease, MDL);
3283 }
3284 }
3285
3286 cleanup:
3287 if (reply->lease != NULL) {
3288 iasubopt_dereference(&reply->lease, MDL);
3289 }
3290 return status;
3291 }
3292
3293 /*
3294 * This function only returns failure on 'hard' failures. If it succeeds,
3295 * it will leave a lease structure behind.
3296 */
3297 static isc_result_t
3298 reply_process_try_addr(struct reply_state *reply, struct iaddr *addr) {
3299 isc_result_t status = ISC_R_ADDRNOTAVAIL;
3300 struct ipv6_pool *pool = NULL;
3301 struct ipv6_pond *pond = NULL;
3302 int i;
3303 struct data_string data_addr;
3304
3305 if ((reply == NULL) || (reply->shared == NULL) ||
3306 (addr == NULL) || (reply->lease != NULL))
3307 return (DHCP_R_INVALIDARG);
3308
3309 /*
3310 * Do a quick walk through of the ponds and pools
3311 * to see if we have any NA address pools
3312 */
3313 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
3314 if (pond->ipv6_pools == NULL)
3315 continue;
3316
3317 for (i = 0; ; i++) {
3318 pool = pond->ipv6_pools[i];
3319 if ((pool == NULL) ||
3320 (pool->pool_type == D6O_IA_NA))
3321 break;
3322 }
3323 if (pool != NULL)
3324 break;
3325 }
3326
3327 /* If we get here and p is NULL we have no useful pools */
3328 if (pool == NULL) {
3329 return (ISC_R_ADDRNOTAVAIL);
3330 }
3331
3332 memset(&data_addr, 0, sizeof(data_addr));
3333 data_addr.len = addr->len;
3334 data_addr.data = addr->iabuf;
3335
3336 /*
3337 * We have at least one pool that could provide an address
3338 * Now we walk through the ponds and pools again and check
3339 * to see if the client is permitted and if an address is
3340 * available
3341 *
3342 * Within a given pond we start looking at the last pool we
3343 * allocated from, unless it had a collision trying to allocate
3344 * an address. This will tend to move us into less-filled pools.
3345 */
3346
3347 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
3348 if (((pond->prohibit_list != NULL) &&
3349 (permitted(reply->packet, pond->prohibit_list))) ||
3350 ((pond->permit_list != NULL) &&
3351 (!permitted(reply->packet, pond->permit_list))))
3352 continue;
3353
3354 for (i = 0 ; (pool = pond->ipv6_pools[i]) != NULL ; i++) {
3355 if (pool->pool_type != D6O_IA_NA)
3356 continue;
3357
3358 status = try_client_v6_address(&reply->lease, pool,
3359 &data_addr);
3360 if (status == ISC_R_SUCCESS)
3361 break;
3362 }
3363
3364 if (status == ISC_R_SUCCESS)
3365 break;
3366 }
3367
3368 /* Note that this is just pedantry. There is no allocation to free. */
3369 data_string_forget(&data_addr, MDL);
3370 /* Return just the most recent status... */
3371 return (status);
3372 }
3373
3374 /* Look around for an address to give the client. First, look through the
3375 * old IA for addresses we can extend. Second, try to allocate a new address.
3376 * Finally, actually add that address into the current reply IA.
3377 */
3378 static isc_result_t
3379 find_client_address(struct reply_state *reply) {
3380 struct iaddr send_addr;
3381 isc_result_t status = ISC_R_NORESOURCES;
3382 struct iasubopt *lease, *best_lease = NULL;
3383 struct binding_scope **scope;
3384 struct group *group;
3385 int i;
3386
3387 if (reply->static_lease) {
3388 if (reply->host == NULL)
3389 return DHCP_R_INVALIDARG;
3390
3391 send_addr.len = 16;
3392 memcpy(send_addr.iabuf, reply->fixed.data, 16);
3393
3394 scope = &global_scope;
3395 group = reply->subnet->group;
3396 goto send_addr;
3397 }
3398
3399 if (reply->old_ia != NULL) {
3400 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
3401 struct shared_network *candidate_shared;
3402 struct ipv6_pond *pond;
3403
3404 lease = reply->old_ia->iasubopt[i];
3405 candidate_shared = lease->ipv6_pool->shared_network;
3406 pond = lease->ipv6_pool->ipv6_pond;
3407
3408 /*
3409 * Look for the best lease on the client's shared
3410 * network, that is still permitted
3411 */
3412
3413 if ((candidate_shared != reply->shared) ||
3414 (lease6_usable(lease) != ISC_TRUE))
3415 continue;
3416
3417 if (((pond->prohibit_list != NULL) &&
3418 (permitted(reply->packet, pond->prohibit_list))) ||
3419 ((pond->permit_list != NULL) &&
3420 (!permitted(reply->packet, pond->permit_list))))
3421 continue;
3422
3423 best_lease = lease_compare(lease, best_lease);
3424 }
3425 }
3426
3427 /* Try to pick a new address if we didn't find one, or if we found an
3428 * abandoned lease.
3429 */
3430 if ((best_lease == NULL) || (best_lease->state == FTS_ABANDONED)) {
3431 status = pick_v6_address(reply);
3432 } else if (best_lease != NULL) {
3433 iasubopt_reference(&reply->lease, best_lease, MDL);
3434 status = ISC_R_SUCCESS;
3435 }
3436
3437 /* Pick the abandoned lease as a last resort. */
3438 if ((status == ISC_R_NORESOURCES) && (best_lease != NULL)) {
3439 /* I don't see how this is supposed to be done right now. */
3440 log_error("Best match for DUID %s is an abandoned address,"
3441 " This may be a result of multiple clients attempting"
3442 " to use this DUID",
3443 print_hex_1(reply->client_id.len,
3444 reply->client_id.data, 60));
3445 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
3446 }
3447
3448 /* Give up now if we didn't find a lease. */
3449 if (status != ISC_R_SUCCESS)
3450 return status;
3451
3452 if (reply->lease == NULL)
3453 log_fatal("Impossible condition at %s:%d.", MDL);
3454
3455 /* Draw binding scopes from the lease's binding scope, and config
3456 * from the lease's containing subnet and higher. Note that it may
3457 * be desirable to place the group attachment directly in the pool.
3458 */
3459 scope = &reply->lease->scope;
3460 group = reply->lease->ipv6_pool->ipv6_pond->group;
3461
3462 send_addr.len = 16;
3463 memcpy(send_addr.iabuf, &reply->lease->addr, 16);
3464
3465 send_addr:
3466 status = reply_process_is_addressed(reply, scope, group);
3467 if (status != ISC_R_SUCCESS)
3468 return status;
3469
3470 status = reply_process_send_addr(reply, &send_addr);
3471 return status;
3472 }
3473
3474 /* Once an address is found for a client, perform several common functions;
3475 * Calculate and store valid and preferred lease times, draw client options
3476 * into the option state.
3477 */
3478 static isc_result_t
3479 reply_process_is_addressed(struct reply_state *reply,
3480 struct binding_scope **scope, struct group *group)
3481 {
3482 isc_result_t status = ISC_R_SUCCESS;
3483 struct data_string data;
3484 struct option_cache *oc;
3485 struct option_state *tmp_options = NULL;
3486 struct on_star *on_star;
3487 int i;
3488
3489 /* Initialize values we will cleanup. */
3490 memset(&data, 0, sizeof(data));
3491
3492 /*
3493 * Find the proper on_star block to use. We use the
3494 * one in the lease if we have a lease or the one in
3495 * the reply if we don't have a lease because this is
3496 * a static instance
3497 */
3498 if (reply->lease) {
3499 on_star = &reply->lease->on_star;
3500 } else {
3501 on_star = &reply->on_star;
3502 }
3503
3504 /*
3505 * Bring in the root configuration. We only do this to bring
3506 * in the on * statements, as we didn't have the lease available
3507 * we did it the first time.
3508 */
3509 option_state_allocate(&tmp_options, MDL);
3510 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3511 reply->packet->options, tmp_options,
3512 &global_scope, root_group, NULL,
3513 on_star);
3514 if (tmp_options != NULL) {
3515 option_state_dereference(&tmp_options, MDL);
3516 }
3517
3518 /*
3519 * Bring configured options into the root packet level cache - start
3520 * with the lease's closest enclosing group (passed in by the caller
3521 * as 'group').
3522 */
3523 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3524 reply->packet->options, reply->opt_state,
3525 scope, group, root_group, on_star);
3526
3527 /* Execute statements from class scopes. */
3528 for (i = reply->packet->class_count; i > 0; i--) {
3529 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3530 reply->packet->options,
3531 reply->opt_state, scope,
3532 reply->packet->classes[i - 1]->group,
3533 group, on_star);
3534 }
3535
3536 /*
3537 * If there is a host record, over-ride with values configured there,
3538 * without re-evaluating configuration from the previously executed
3539 * group or its common enclosers.
3540 */
3541 if (reply->host != NULL)
3542 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3543 reply->packet->options,
3544 reply->opt_state, scope,
3545 reply->host->group, group,
3546 on_star);
3547
3548 /* Determine valid lifetime. */
3549 if (reply->client_valid == 0)
3550 reply->send_valid = DEFAULT_DEFAULT_LEASE_TIME;
3551 else
3552 reply->send_valid = reply->client_valid;
3553
3554 oc = lookup_option(&server_universe, reply->opt_state,
3555 SV_DEFAULT_LEASE_TIME);
3556 if (oc != NULL) {
3557 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
3558 reply->packet->options,
3559 reply->opt_state,
3560 scope, oc, MDL) ||
3561 (data.len != 4)) {
3562 log_error("reply_process_is_addressed: unable to "
3563 "evaluate default lease time");
3564 status = ISC_R_FAILURE;
3565 goto cleanup;
3566 }
3567
3568 reply->send_valid = getULong(data.data);
3569 data_string_forget(&data, MDL);
3570 }
3571
3572 /* Check to see if the lease time would cause us to wrap
3573 * in which case we make it infinite.
3574 * The following doesn't work on at least some systems:
3575 * (cur_time + reply->send_valid < cur_time)
3576 */
3577 if (reply->send_valid != INFINITE_TIME) {
3578 time_t test_time = cur_time + reply->send_valid;
3579 if (test_time < cur_time)
3580 reply->send_valid = INFINITE_TIME;
3581 }
3582
3583 if (reply->client_prefer == 0)
3584 reply->send_prefer = reply->send_valid;
3585 else
3586 reply->send_prefer = reply->client_prefer;
3587
3588 if ((reply->send_prefer >= reply->send_valid) &&
3589 (reply->send_valid != INFINITE_TIME))
3590 reply->send_prefer = (reply->send_valid / 2) +
3591 (reply->send_valid / 8);
3592
3593 oc = lookup_option(&server_universe, reply->opt_state,
3594 SV_PREFER_LIFETIME);
3595 if (oc != NULL) {
3596 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
3597 reply->packet->options,
3598 reply->opt_state,
3599 scope, oc, MDL) ||
3600 (data.len != 4)) {
3601 log_error("reply_process_is_addressed: unable to "
3602 "evaluate preferred lease time");
3603 status = ISC_R_FAILURE;
3604 goto cleanup;
3605 }
3606
3607 reply->send_prefer = getULong(data.data);
3608 data_string_forget(&data, MDL);
3609 }
3610
3611 /* Note lowest values for later calculation of renew/rebind times. */
3612 if (reply->min_prefer > reply->send_prefer)
3613 reply->min_prefer = reply->send_prefer;
3614
3615 if (reply->min_valid > reply->send_valid)
3616 reply->min_valid = reply->send_valid;
3617
3618 #if 0
3619 /*
3620 * XXX: Old 4.0.0 alpha code would change the host {} record
3621 * XXX: uid upon lease assignment. This was intended to cover the
3622 * XXX: case where a client first identifies itself using vendor
3623 * XXX: options in a solicit, or request, but later neglects to include
3624 * XXX: these options in a Renew or Rebind. It is not clear that this
3625 * XXX: is required, and has some startling ramifications (such as
3626 * XXX: how to recover this dynamic host {} state across restarts).
3627 */
3628 if (reply->host != NULL)
3629 change_host_uid(host, reply->client_id->data,
3630 reply->client_id->len);
3631 #endif /* 0 */
3632
3633 /* Perform dynamic lease related update work. */
3634 if (reply->lease != NULL) {
3635 /* Cached lifetimes */
3636 reply->lease->prefer = reply->send_prefer;
3637 reply->lease->valid = reply->send_valid;
3638
3639 /* Advance (or rewind) the valid lifetime.
3640 * In the protocol 0xFFFFFFFF is infinite
3641 * when connecting to the lease file MAX_TIME is
3642 */
3643 if (reply->buf.reply.msg_type == DHCPV6_REPLY) {
3644 if (reply->send_valid == INFINITE_TIME) {
3645 reply->lease->soft_lifetime_end_time = MAX_TIME;
3646 } else {
3647 reply->lease->soft_lifetime_end_time =
3648 cur_time + reply->send_valid;
3649 }
3650 /* Wait before renew! */
3651 }
3652
3653 status = ia_add_iasubopt(reply->ia, reply->lease, MDL);
3654 if (status != ISC_R_SUCCESS) {
3655 log_fatal("reply_process_is_addressed: Unable to "
3656 "attach lease to new IA: %s",
3657 isc_result_totext(status));
3658 }
3659
3660 /*
3661 * If this is a new lease, make sure it is attached somewhere.
3662 */
3663 if (reply->lease->ia == NULL) {
3664 ia_reference(&reply->lease->ia, reply->ia, MDL);
3665 }
3666 }
3667
3668 /* Bring a copy of the relevant options into the IA scope. */
3669 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3670 reply->packet->options, reply->reply_ia,
3671 scope, group, root_group, NULL);
3672
3673 /* Execute statements from class scopes. */
3674 for (i = reply->packet->class_count; i > 0; i--) {
3675 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3676 reply->packet->options,
3677 reply->reply_ia, scope,
3678 reply->packet->classes[i - 1]->group,
3679 group, NULL);
3680 }
3681
3682 /*
3683 * And bring in host record configuration, if any, but not to overlap
3684 * the previous group or its common enclosers.
3685 */
3686 if (reply->host != NULL)
3687 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3688 reply->packet->options,
3689 reply->reply_ia, scope,
3690 reply->host->group, group, NULL);
3691
3692 cleanup:
3693 if (data.data != NULL)
3694 data_string_forget(&data, MDL);
3695
3696 if (status == ISC_R_SUCCESS)
3697 reply->client_resources++;
3698
3699 return status;
3700 }
3701
3702 /* Simply send an IAADDR within the IA scope as described. */
3703 static isc_result_t
3704 reply_process_send_addr(struct reply_state *reply, struct iaddr *addr) {
3705 isc_result_t status = ISC_R_SUCCESS;
3706 struct data_string data;
3707
3708 memset(&data, 0, sizeof(data));
3709
3710 /* Now append the lease. */
3711 data.len = IAADDR_OFFSET;
3712 if (!buffer_allocate(&data.buffer, data.len, MDL)) {
3713 log_error("reply_process_send_addr: out of memory"
3714 "allocating new IAADDR buffer.");
3715 status = ISC_R_NOMEMORY;
3716 goto cleanup;
3717 }
3718 data.data = data.buffer->data;
3719
3720 memcpy(data.buffer->data, addr->iabuf, 16);
3721 putULong(data.buffer->data + 16, reply->send_prefer);
3722 putULong(data.buffer->data + 20, reply->send_valid);
3723
3724 if (!append_option_buffer(&dhcpv6_universe, reply->reply_ia,
3725 data.buffer, data.buffer->data,
3726 data.len, D6O_IAADDR, 0)) {
3727 log_error("reply_process_send_addr: unable "
3728 "to save IAADDR option");
3729 status = ISC_R_FAILURE;
3730 goto cleanup;
3731 }
3732
3733 reply->resources_included = ISC_TRUE;
3734
3735 cleanup:
3736 if (data.data != NULL)
3737 data_string_forget(&data, MDL);
3738
3739 return status;
3740 }
3741
3742 /* Choose the better of two leases. */
3743 static struct iasubopt *
3744 lease_compare(struct iasubopt *alpha, struct iasubopt *beta) {
3745 if (alpha == NULL)
3746 return beta;
3747 if (beta == NULL)
3748 return alpha;
3749
3750 switch(alpha->state) {
3751 case FTS_ACTIVE:
3752 switch(beta->state) {
3753 case FTS_ACTIVE:
3754 /* Choose the lease with the longest lifetime (most
3755 * likely the most recently allocated).
3756 */
3757 if (alpha->hard_lifetime_end_time <
3758 beta->hard_lifetime_end_time)
3759 return beta;
3760 else
3761 return alpha;
3762
3763 case FTS_EXPIRED:
3764 case FTS_ABANDONED:
3765 return alpha;
3766
3767 default:
3768 log_fatal("Impossible condition at %s:%d.", MDL);
3769 }
3770 break;
3771
3772 case FTS_EXPIRED:
3773 switch (beta->state) {
3774 case FTS_ACTIVE:
3775 return beta;
3776
3777 case FTS_EXPIRED:
3778 /* Choose the most recently expired lease. */
3779 if (alpha->hard_lifetime_end_time <
3780 beta->hard_lifetime_end_time)
3781 return beta;
3782 else if ((alpha->hard_lifetime_end_time ==
3783 beta->hard_lifetime_end_time) &&
3784 (alpha->soft_lifetime_end_time <
3785 beta->soft_lifetime_end_time))
3786 return beta;
3787 else
3788 return alpha;
3789
3790 case FTS_ABANDONED:
3791 return alpha;
3792
3793 default:
3794 log_fatal("Impossible condition at %s:%d.", MDL);
3795 }
3796 break;
3797
3798 case FTS_ABANDONED:
3799 switch (beta->state) {
3800 case FTS_ACTIVE:
3801 case FTS_EXPIRED:
3802 return alpha;
3803
3804 case FTS_ABANDONED:
3805 /* Choose the lease that was abandoned longest ago. */
3806 if (alpha->hard_lifetime_end_time <
3807 beta->hard_lifetime_end_time)
3808 return alpha;
3809 else
3810 return beta;
3811
3812 default:
3813 log_fatal("Impossible condition at %s:%d.", MDL);
3814 }
3815 break;
3816
3817 default:
3818 log_fatal("Impossible condition at %s:%d.", MDL);
3819 }
3820
3821 log_fatal("Triple impossible condition at %s:%d.", MDL);
3822 return NULL;
3823 }
3824
3825 /* Process a client-supplied IA_PD. This may append options to the tail of
3826 * the reply packet being built in the reply_state structure.
3827 */
3828 static isc_result_t
3829 reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia) {
3830 isc_result_t status = ISC_R_SUCCESS;
3831 u_int32_t iaid;
3832 unsigned ia_cursor;
3833 struct option_state *packet_ia;
3834 struct option_cache *oc;
3835 struct data_string ia_data, data;
3836
3837 /* Initialize values that will get cleaned up on return. */
3838 packet_ia = NULL;
3839 memset(&ia_data, 0, sizeof(ia_data));
3840 memset(&data, 0, sizeof(data));
3841 /*
3842 * Note that find_client_prefix() may set reply->lease.
3843 */
3844
3845 /* Make sure there is at least room for the header. */
3846 if ((reply->cursor + IA_PD_OFFSET + 4) > sizeof(reply->buf)) {
3847 log_error("reply_process_ia_pd: Reply too long for IA.");
3848 return ISC_R_NOSPACE;
3849 }
3850
3851
3852 /* Fetch the IA_PD contents. */
3853 if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
3854 ia, IA_PD_OFFSET)) {
3855 log_error("reply_process_ia_pd: error evaluating ia");
3856 status = ISC_R_FAILURE;
3857 goto cleanup;
3858 }
3859
3860 /* Extract IA_PD header contents. */
3861 iaid = getULong(ia_data.data);
3862 reply->renew = getULong(ia_data.data + 4);
3863 reply->rebind = getULong(ia_data.data + 8);
3864
3865 /* Create an IA_PD structure. */
3866 if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data,
3867 reply->client_id.len, MDL) != ISC_R_SUCCESS) {
3868 log_error("reply_process_ia_pd: no memory for ia.");
3869 status = ISC_R_NOMEMORY;
3870 goto cleanup;
3871 }
3872 reply->ia->ia_type = D6O_IA_PD;
3873
3874 /* Cache pre-existing IA_PD, if any. */
3875 ia_hash_lookup(&reply->old_ia, ia_pd_active,
3876 (unsigned char *)reply->ia->iaid_duid.data,
3877 reply->ia->iaid_duid.len, MDL);
3878
3879 /*
3880 * Create an option cache to carry the IA_PD option contents, and
3881 * execute any user-supplied values into it.
3882 */
3883 if (!option_state_allocate(&reply->reply_ia, MDL)) {
3884 status = ISC_R_NOMEMORY;
3885 goto cleanup;
3886 }
3887
3888 /* Check & count the fixed prefix host records. */
3889 reply->static_prefixes = 0;
3890 if ((reply->host != NULL) && (reply->host->fixed_prefix != NULL)) {
3891 struct iaddrcidrnetlist *fp;
3892
3893 for (fp = reply->host->fixed_prefix; fp != NULL;
3894 fp = fp->next) {
3895 reply->static_prefixes += 1;
3896 }
3897 }
3898
3899 /*
3900 * Save the cursor position at the start of the IA_PD, so we can
3901 * set length and adjust t1/t2 values later. We write a temporary
3902 * header out now just in case we decide to adjust the packet
3903 * within sub-process functions.
3904 */
3905 ia_cursor = reply->cursor;
3906
3907 /* Initialize the IA_PD header. First the code. */
3908 putUShort(reply->buf.data + reply->cursor, (unsigned)D6O_IA_PD);
3909 reply->cursor += 2;
3910
3911 /* Then option length. */
3912 putUShort(reply->buf.data + reply->cursor, 0x0Cu);
3913 reply->cursor += 2;
3914
3915 /* Then IA_PD header contents; IAID. */
3916 putULong(reply->buf.data + reply->cursor, iaid);
3917 reply->cursor += 4;
3918
3919 /* We store the client's t1 for now, and may over-ride it later. */
3920 putULong(reply->buf.data + reply->cursor, reply->renew);
3921 reply->cursor += 4;
3922
3923 /* We store the client's t2 for now, and may over-ride it later. */
3924 putULong(reply->buf.data + reply->cursor, reply->rebind);
3925 reply->cursor += 4;
3926
3927 /*
3928 * For each prefix in this IA_PD, decide what to do about it.
3929 */
3930 oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAPREFIX);
3931 reply->min_valid = reply->min_prefer = INFINITE_TIME;
3932 reply->client_valid = reply->client_prefer = 0;
3933 reply->preflen = -1;
3934 for (; oc != NULL ; oc = oc->next) {
3935 status = reply_process_prefix(reply, oc);
3936
3937 /*
3938 * Canceled means we did not allocate prefixes to the
3939 * client, but we're "done" with this IA - we set a status
3940 * code. So transmit this reply, e.g., move on to the next
3941 * IA.
3942 */
3943 if (status == ISC_R_CANCELED)
3944 break;
3945
3946 if ((status != ISC_R_SUCCESS) &&
3947 (status != ISC_R_ADDRINUSE) &&
3948 (status != ISC_R_ADDRNOTAVAIL))
3949 goto cleanup;
3950 }
3951
3952 reply->pd_count++;
3953
3954 /*
3955 * If we fell through the above and never gave the client
3956 * a prefix, give it one now.
3957 */
3958 if ((status != ISC_R_CANCELED) && (reply->client_resources == 0)) {
3959 status = find_client_prefix(reply);
3960
3961 if (status == ISC_R_NORESOURCES) {
3962 switch (reply->packet->dhcpv6_msg_type) {
3963 case DHCPV6_SOLICIT:
3964 /*
3965 * No prefix for any IA is handled
3966 * by the caller.
3967 */
3968 /* FALL THROUGH */
3969
3970 case DHCPV6_REQUEST:
3971 /* Same than for addresses. */
3972 option_state_dereference(&reply->reply_ia, MDL);
3973 if (!option_state_allocate(&reply->reply_ia,
3974 MDL))
3975 {
3976 log_error("reply_process_ia_pd: No "
3977 "memory for option state "
3978 "wipe.");
3979 status = ISC_R_NOMEMORY;
3980 goto cleanup;
3981 }
3982
3983 if (!set_status_code(STATUS_NoPrefixAvail,
3984 "No prefixes available "
3985 "for this interface.",
3986 reply->reply_ia)) {
3987 log_error("reply_process_ia_pd: "
3988 "Unable to set "
3989 "NoPrefixAvail status "
3990 "code.");
3991 status = ISC_R_FAILURE;
3992 goto cleanup;
3993 }
3994
3995 status = ISC_R_SUCCESS;
3996 break;
3997
3998 default:
3999 if (reply->resources_included)
4000 status = ISC_R_SUCCESS;
4001 else
4002 goto cleanup;
4003 break;
4004 }
4005 }
4006
4007 if (status != ISC_R_SUCCESS)
4008 goto cleanup;
4009 }
4010
4011 reply->cursor += store_options6((char *)reply->buf.data + reply->cursor,
4012 sizeof(reply->buf) - reply->cursor,
4013 reply->reply_ia, reply->packet,
4014 required_opts_IA_PD, NULL);
4015
4016 /* Reset the length of this IA_PD to match what was just written. */
4017 putUShort(reply->buf.data + ia_cursor + 2,
4018 reply->cursor - (ia_cursor + 4));
4019
4020 /* Calculate T1/T2 and stuff them in the reply */
4021 set_reply_tee_times(reply, ia_cursor);
4022
4023 /*
4024 * yes, goto's aren't the best but we also want to avoid extra
4025 * indents
4026 */
4027 if (status == ISC_R_CANCELED)
4028 goto cleanup;
4029
4030 /*
4031 * Handle static prefixes, we always log stuff and if it's
4032 * a hard binding we run any commit statements that we have
4033 */
4034 if (reply->static_prefixes != 0) {
4035 char tmp_addr[INET6_ADDRSTRLEN];
4036 log_info("%s PD: address %s/%d to client with duid %s "
4037 "iaid = %d static",
4038 dhcpv6_type_names[reply->buf.reply.msg_type],
4039 inet_ntop(AF_INET6, reply->fixed_pref.lo_addr.iabuf,
4040 tmp_addr, sizeof(tmp_addr)),
4041 reply->fixed_pref.bits,
4042 print_hex_1(reply->client_id.len,
4043 reply->client_id.data, 60),
4044 iaid);
4045 if ((reply->buf.reply.msg_type == DHCPV6_REPLY) &&
4046 (reply->on_star.on_commit != NULL)) {
4047 execute_statements(NULL, reply->packet, NULL, NULL,
4048 reply->packet->options,
4049 reply->opt_state,
4050 NULL, reply->on_star.on_commit,
4051 NULL);
4052 executable_statement_dereference
4053 (&reply->on_star.on_commit, MDL);
4054 }
4055 goto cleanup;
4056 }
4057
4058 /*
4059 * If we have any addresses log what we are doing.
4060 */
4061 if (reply->ia->num_iasubopt != 0) {
4062 struct iasubopt *tmp;
4063 int i;
4064 char tmp_addr[INET6_ADDRSTRLEN];
4065
4066 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
4067 tmp = reply->ia->iasubopt[i];
4068
4069 log_info("%s PD: address %s/%d to client with duid %s"
4070 " iaid = %d valid for %u seconds",
4071 dhcpv6_type_names[reply->buf.reply.msg_type],
4072 inet_ntop(AF_INET6, &tmp->addr,
4073 tmp_addr, sizeof(tmp_addr)),
4074 (int)tmp->plen,
4075 print_hex_1(reply->client_id.len,
4076 reply->client_id.data, 60),
4077 iaid, tmp->valid);
4078 }
4079 }
4080
4081 /*
4082 * If this is not a 'soft' binding, consume the new changes into
4083 * the database (if any have been attached to the ia_pd).
4084 *
4085 * Loop through the assigned dynamic prefixes, referencing the
4086 * prefixes onto this IA_PD rather than any old ones, and updating
4087 * prefix pool timers for each (if any).
4088 */
4089 if ((reply->buf.reply.msg_type == DHCPV6_REPLY) &&
4090 (reply->ia->num_iasubopt != 0)) {
4091 struct iasubopt *tmp;
4092 struct data_string *ia_id;
4093 int i;
4094
4095 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
4096 tmp = reply->ia->iasubopt[i];
4097
4098 if (tmp->ia != NULL)
4099 ia_dereference(&tmp->ia, MDL);
4100 ia_reference(&tmp->ia, reply->ia, MDL);
4101
4102 /* Commit 'hard' bindings. */
4103 renew_lease6(tmp->ipv6_pool, tmp);
4104 schedule_lease_timeout(tmp->ipv6_pool);
4105
4106 /* If we have anything to do on commit do it now */
4107 if (tmp->on_star.on_commit != NULL) {
4108 execute_statements(NULL, reply->packet,
4109 NULL, NULL,
4110 reply->packet->options,
4111 reply->opt_state,
4112 &tmp->scope,
4113 tmp->on_star.on_commit,
4114 &tmp->on_star);
4115 executable_statement_dereference
4116 (&tmp->on_star.on_commit, MDL);
4117 }
4118
4119 /* Do our threshold check. */
4120 check_pool6_threshold(reply, tmp);
4121 }
4122
4123 /* Remove any old ia from the hash. */
4124 if (reply->old_ia != NULL) {
4125 if (!release_on_roam(reply)) {
4126 ia_id = &reply->old_ia->iaid_duid;
4127 ia_hash_delete(ia_pd_active,
4128 (unsigned char *)ia_id->data,
4129 ia_id->len, MDL);
4130 }
4131
4132 ia_dereference(&reply->old_ia, MDL);
4133 }
4134
4135 /* Put new ia into the hash. */
4136 reply->ia->cltt = cur_time;
4137 ia_id = &reply->ia->iaid_duid;
4138 ia_hash_add(ia_pd_active, (unsigned char *)ia_id->data,
4139 ia_id->len, reply->ia, MDL);
4140
4141 write_ia(reply->ia);
4142 } else {
4143 schedule_lease_timeout_reply(reply);
4144 }
4145
4146 cleanup:
4147 if (packet_ia != NULL)
4148 option_state_dereference(&packet_ia, MDL);
4149 if (reply->reply_ia != NULL)
4150 option_state_dereference(&reply->reply_ia, MDL);
4151 if (ia_data.data != NULL)
4152 data_string_forget(&ia_data, MDL);
4153 if (data.data != NULL)
4154 data_string_forget(&data, MDL);
4155 if (reply->ia != NULL)
4156 ia_dereference(&reply->ia, MDL);
4157 if (reply->old_ia != NULL)
4158 ia_dereference(&reply->old_ia, MDL);
4159 if (reply->lease != NULL)
4160 iasubopt_dereference(&reply->lease, MDL);
4161 if (reply->on_star.on_expiry != NULL)
4162 executable_statement_dereference
4163 (&reply->on_star.on_expiry, MDL);
4164 if (reply->on_star.on_release != NULL)
4165 executable_statement_dereference
4166 (&reply->on_star.on_release, MDL);
4167
4168 /*
4169 * ISC_R_CANCELED is a status code used by the prefix processing to
4170 * indicate we're replying with a status code. This is still a
4171 * success at higher layers.
4172 */
4173 return((status == ISC_R_CANCELED) ? ISC_R_SUCCESS : status);
4174 }
4175
4176 /*!
4177 *
4178 * \brief Find the proper scoping group for use with a v6 static prefix.
4179 *
4180 * We start by trying to find a subnet based on the given prefix and
4181 * the shared network. If we don't find one then the prefix has been
4182 * declared outside of any subnets. If there is a static address
4183 * associated with the host we use it to try and find a subnet (this
4184 * should succeed). If there isn't a static address we fall back
4185 * to the shared subnet itself.
4186 * Once we have a subnet we extract the group from it and return it.
4187 *
4188 * \param reply - the reply structure we use to collect information
4189 * we will use the fields shared, fixed_pref and host
4190 * from the structure
4191 *
4192 * \return a pointer to the group structure to use for scoping
4193 */
4194
4195 static struct group *
4196 find_group_by_prefix(struct reply_state *reply) {
4197 /* default group if we don't find anything better */
4198 struct group *group = reply->shared->group;
4199 struct subnet *subnet = NULL;
4200 struct iaddr tmp_addr;
4201 struct data_string fixed_addr;
4202
4203 /* Try with the prefix first */
4204 if (find_grouped_subnet(&subnet, reply->shared,
4205 reply->fixed_pref.lo_addr, MDL) != 0) {
4206 group = subnet->group;
4207 subnet_dereference(&subnet, MDL);
4208 return (group);
4209 }
4210
4211 /* Didn't find a subnet via prefix, what about fixed address */
4212 /* The caller has already tested reply->host != NULL */
4213
4214 memset(&fixed_addr, 0, sizeof(fixed_addr));
4215
4216 if ((reply->host->fixed_addr != NULL) &&
4217 (evaluate_option_cache(&fixed_addr, NULL, NULL, NULL,
4218 NULL, NULL, &global_scope,
4219 reply->host->fixed_addr, MDL))) {
4220 if (fixed_addr.len >= 16) {
4221 tmp_addr.len = 16;
4222 memcpy(tmp_addr.iabuf, fixed_addr.data, 16);
4223 if (find_grouped_subnet(&subnet, reply->shared,
4224 tmp_addr, MDL) != 0) {
4225 group = subnet->group;
4226 subnet_dereference(&subnet, MDL);
4227 }
4228 }
4229 data_string_forget(&fixed_addr, MDL);
4230 }
4231
4232 /* return whatever we got */
4233 return (group);
4234 }
4235
4236 /*
4237 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
4238 * contents into the reply's current ia_pd-scoped option cache. Returns
4239 * ISC_R_CANCELED in the event we are replying with a status code and do
4240 * not wish to process more IAPREFIXes within this IA_PD.
4241 */
4242 static isc_result_t
4243 reply_process_prefix(struct reply_state *reply, struct option_cache *pref) {
4244 u_int32_t pref_life, valid_life;
4245 struct binding_scope **scope;
4246 struct iaddrcidrnet tmp_pref;
4247 struct option_cache *oc;
4248 struct data_string iapref, data;
4249 isc_result_t status = ISC_R_SUCCESS;
4250 struct group *group;
4251
4252 /* Initializes values that will be cleaned up. */
4253 memset(&iapref, 0, sizeof(iapref));
4254 memset(&data, 0, sizeof(data));
4255 /* Note that reply->lease may be set by prefix_is_owned() */
4256
4257 /*
4258 * There is no point trying to process an incoming prefix if there
4259 * is no room for an outgoing prefix.
4260 */
4261 if ((reply->cursor + 29) > sizeof(reply->buf)) {
4262 log_error("reply_process_prefix: Out of room for prefix.");
4263 return ISC_R_NOSPACE;
4264 }
4265
4266 /* Extract this IAPREFIX option. */
4267 if (!evaluate_option_cache(&iapref, reply->packet, NULL, NULL,
4268 reply->packet->options, NULL, &global_scope,
4269 pref, MDL) ||
4270 (iapref.len < IAPREFIX_OFFSET)) {
4271 log_error("reply_process_prefix: error evaluating IAPREFIX.");
4272 status = ISC_R_FAILURE;
4273 goto cleanup;
4274 }
4275
4276 /*
4277 * Layout: preferred and valid lifetimes followed by the prefix
4278 * length and the IPv6 address.
4279 */
4280 pref_life = getULong(iapref.data);
4281 valid_life = getULong(iapref.data + 4);
4282
4283 if ((reply->client_valid == 0) ||
4284 (reply->client_valid > valid_life))
4285 reply->client_valid = valid_life;
4286
4287 if ((reply->client_prefer == 0) ||
4288 (reply->client_prefer > pref_life))
4289 reply->client_prefer = pref_life;
4290
4291 /*
4292 * Clients may choose to send ::/0 as a prefix, with the idea to give
4293 * hints about preferred-lifetime or valid-lifetime.
4294 */
4295 tmp_pref.lo_addr.len = 16;
4296 memset(tmp_pref.lo_addr.iabuf, 0, 16);
4297 if ((iapref.data[8] == 0) &&
4298 (memcmp(iapref.data + 9, tmp_pref.lo_addr.iabuf, 16) == 0)) {
4299 /* Status remains success; we just ignore this one. */
4300 goto cleanup;
4301 }
4302
4303 /*
4304 * Clients may choose to send ::/X as a prefix to specify a
4305 * preferred/requested prefix length. Note X is never zero here.
4306 */
4307 tmp_pref.bits = (int) iapref.data[8];
4308 if (reply->preflen < 0) {
4309 /* Cache the first preferred prefix length. */
4310 reply->preflen = tmp_pref.bits;
4311 }
4312 if (memcmp(iapref.data + 9, tmp_pref.lo_addr.iabuf, 16) == 0) {
4313 goto cleanup;
4314 }
4315
4316 memcpy(tmp_pref.lo_addr.iabuf, iapref.data + 9, 16);
4317
4318 /* Verify the prefix belongs to the client. */
4319 if (!prefix_is_owned(reply, &tmp_pref)) {
4320 /* Same than for addresses. */
4321 if ((reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) ||
4322 (reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) ||
4323 (reply->packet->dhcpv6_msg_type == DHCPV6_REBIND)) {
4324 status = reply_process_try_prefix(reply, &tmp_pref);
4325
4326 /* Either error out or skip this prefix. */
4327 if ((status != ISC_R_SUCCESS) &&
4328 (status != ISC_R_ADDRINUSE) &&
4329 (status != ISC_R_ADDRNOTAVAIL))
4330 goto cleanup;
4331
4332 if (reply->lease == NULL) {
4333 if (reply->packet->dhcpv6_msg_type ==
4334 DHCPV6_REBIND) {
4335 reply->send_prefer = 0;
4336 reply->send_valid = 0;
4337 goto send_pref;
4338 }
4339
4340 /* status remains success - ignore */
4341 goto cleanup;
4342 }
4343 /*
4344 * RFC3633 section 18.2.3:
4345 *
4346 * If the delegating router cannot find a binding
4347 * for the requesting router's IA_PD the delegating
4348 * router returns the IA_PD containing no prefixes
4349 * with a Status Code option set to NoBinding in the
4350 * Reply message.
4351 *
4352 * On mismatch we (ab)use this pretending we have not the IA
4353 * as soon as we have not a prefix.
4354 */
4355 } else if (reply->packet->dhcpv6_msg_type == DHCPV6_RENEW) {
4356 /* Rewind the IA_PD to empty. */
4357 option_state_dereference(&reply->reply_ia, MDL);
4358 if (!option_state_allocate(&reply->reply_ia, MDL)) {
4359 log_error("reply_process_prefix: No memory "
4360 "for option state wipe.");
4361 status = ISC_R_NOMEMORY;
4362 goto cleanup;
4363 }
4364
4365 /* Append a NoBinding status code. */
4366 if (!set_status_code(STATUS_NoBinding,
4367 "Prefix not bound to this "
4368 "interface.", reply->reply_ia)) {
4369 log_error("reply_process_prefix: Unable to "
4370 "attach status code.");
4371 status = ISC_R_FAILURE;
4372 goto cleanup;
4373 }
4374
4375 /* Fin (no more IAPREFIXes). */
4376 status = ISC_R_CANCELED;
4377 goto cleanup;
4378 } else {
4379 log_error("It is impossible to lease a client that is "
4380 "not sending a solicit, request, renew, or "
4381 "rebind message.");
4382 status = ISC_R_FAILURE;
4383 goto cleanup;
4384 }
4385 }
4386
4387 if (reply->static_prefixes > 0) {
4388 if (reply->host == NULL)
4389 log_fatal("Impossible condition at %s:%d.", MDL);
4390
4391 scope = &global_scope;
4392
4393 /* Copy the static prefix for logging and finding the group */
4394 memcpy(&reply->fixed_pref, &tmp_pref, sizeof(tmp_pref));
4395
4396 /* Try to find a group for the static prefix */
4397 group = find_group_by_prefix(reply);
4398 } else {
4399 if (reply->lease == NULL)
4400 log_fatal("Impossible condition at %s:%d.", MDL);
4401
4402 scope = &reply->lease->scope;
4403 group = reply->lease->ipv6_pool->ipv6_pond->group;
4404 }
4405
4406 /*
4407 * If client_resources is nonzero, then the reply_process_is_prefixed
4408 * function has executed configuration state into the reply option
4409 * cache. We will use that valid cache to derive configuration for
4410 * whether or not to engage in additional prefixes, and similar.
4411 */
4412 if (reply->client_resources != 0) {
4413 unsigned limit = 1;
4414
4415 /*
4416 * Does this client have "enough" prefixes already? Default
4417 * to one. Everybody gets one, and one should be enough for
4418 * anybody.
4419 */
4420 oc = lookup_option(&server_universe, reply->opt_state,
4421 SV_LIMIT_PREFS_PER_IA);
4422 if (oc != NULL) {
4423 if (!evaluate_option_cache(&data, reply->packet,
4424 NULL, NULL,
4425 reply->packet->options,
4426 reply->opt_state,
4427 scope, oc, MDL) ||
4428 (data.len != 4)) {
4429 log_error("reply_process_prefix: unable to "
4430 "evaluate prefs-per-ia value.");
4431 status = ISC_R_FAILURE;
4432 goto cleanup;
4433 }
4434
4435 limit = getULong(data.data);
4436 data_string_forget(&data, MDL);
4437 }
4438
4439 /*
4440 * If we wish to limit the client to a certain number of
4441 * prefixes, then omit the prefix from the reply.
4442 */
4443 if (reply->client_resources >= limit)
4444 goto cleanup;
4445 }
4446
4447 status = reply_process_is_prefixed(reply, scope, group);
4448 if (status != ISC_R_SUCCESS)
4449 goto cleanup;
4450
4451 send_pref:
4452 status = reply_process_send_prefix(reply, &tmp_pref);
4453
4454 cleanup:
4455 if (iapref.data != NULL)
4456 data_string_forget(&iapref, MDL);
4457 if (data.data != NULL)
4458 data_string_forget(&data, MDL);
4459 if (reply->lease != NULL)
4460 iasubopt_dereference(&reply->lease, MDL);
4461
4462 return status;
4463 }
4464
4465 /*
4466 * Verify the prefix belongs to the client. If we've got a host
4467 * record with fixed prefixes, it has to be an assigned prefix
4468 * (fault out all else). Otherwise it's a dynamic prefix, so lookup
4469 * that prefix and make sure it belongs to this DUID:IAID pair.
4470 */
4471 static isc_boolean_t
4472 prefix_is_owned(struct reply_state *reply, struct iaddrcidrnet *pref) {
4473 struct iaddrcidrnetlist *l;
4474 int i;
4475 struct ipv6_pond *pond;
4476
4477 /*
4478 * This faults out prefixes that don't match fixed prefixes.
4479 */
4480 if (reply->static_prefixes > 0) {
4481 for (l = reply->host->fixed_prefix; l != NULL; l = l->next) {
4482 if ((pref->bits == l->cidrnet.bits) &&
4483 (memcmp(pref->lo_addr.iabuf,
4484 l->cidrnet.lo_addr.iabuf, 16) == 0))
4485 return (ISC_TRUE);
4486 }
4487 return (ISC_FALSE);
4488 }
4489
4490 if ((reply->old_ia == NULL) ||
4491 (reply->old_ia->num_iasubopt == 0))
4492 return (ISC_FALSE);
4493
4494 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
4495 struct iasubopt *tmp;
4496
4497 tmp = reply->old_ia->iasubopt[i];
4498
4499 if ((pref->bits == (int) tmp->plen) &&
4500 (memcmp(pref->lo_addr.iabuf, &tmp->addr, 16) == 0)) {
4501 if (lease6_usable(tmp) == ISC_FALSE) {
4502 return (ISC_FALSE);
4503 }
4504
4505 pond = tmp->ipv6_pool->ipv6_pond;
4506 if (((pond->prohibit_list != NULL) &&
4507 (permitted(reply->packet, pond->prohibit_list))) ||
4508 ((pond->permit_list != NULL) &&
4509 (!permitted(reply->packet, pond->permit_list))))
4510 return (ISC_FALSE);
4511
4512 iasubopt_reference(&reply->lease, tmp, MDL);
4513 return (ISC_TRUE);
4514 }
4515 }
4516
4517 return (ISC_FALSE);
4518 }
4519
4520 /*
4521 * This function only returns failure on 'hard' failures. If it succeeds,
4522 * it will leave a prefix structure behind.
4523 */
4524 static isc_result_t
4525 reply_process_try_prefix(struct reply_state *reply,
4526 struct iaddrcidrnet *pref) {
4527 isc_result_t status = ISC_R_ADDRNOTAVAIL;
4528 struct ipv6_pool *pool = NULL;
4529 struct ipv6_pond *pond = NULL;
4530 int i;
4531 struct data_string data_pref;
4532
4533 if ((reply == NULL) || (reply->shared == NULL) ||
4534 (pref == NULL) || (reply->lease != NULL))
4535 return (DHCP_R_INVALIDARG);
4536
4537 /*
4538 * Do a quick walk through of the ponds and pools
4539 * to see if we have any prefix pools
4540 */
4541 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
4542 if (pond->ipv6_pools == NULL)
4543 continue;
4544
4545 for (i = 0; (pool = pond->ipv6_pools[i]) != NULL; i++) {
4546 if (pool->pool_type == D6O_IA_PD)
4547 break;
4548 }
4549 if (pool != NULL)
4550 break;
4551 }
4552
4553 /* If we get here and p is NULL we have no useful pools */
4554 if (pool == NULL) {
4555 return (ISC_R_ADDRNOTAVAIL);
4556 }
4557
4558 memset(&data_pref, 0, sizeof(data_pref));
4559 data_pref.len = 17;
4560 if (!buffer_allocate(&data_pref.buffer, data_pref.len, MDL)) {
4561 log_error("reply_process_try_prefix: out of memory.");
4562 return (ISC_R_NOMEMORY);
4563 }
4564 data_pref.data = data_pref.buffer->data;
4565 data_pref.buffer->data[0] = (u_int8_t) pref->bits;
4566 memcpy(data_pref.buffer->data + 1, pref->lo_addr.iabuf, 16);
4567
4568 /*
4569 * We have at least one pool that could provide a prefix
4570 * Now we walk through the ponds and pools again and check
4571 * to see if the client is permitted and if an prefix is
4572 * available
4573 *
4574 */
4575
4576 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
4577 if (((pond->prohibit_list != NULL) &&
4578 (permitted(reply->packet, pond->prohibit_list))) ||
4579 ((pond->permit_list != NULL) &&
4580 (!permitted(reply->packet, pond->permit_list))))
4581 continue;
4582
4583 for (i = 0; (pool = pond->ipv6_pools[i]) != NULL; i++) {
4584 if (pool->pool_type != D6O_IA_PD) {
4585 continue;
4586 }
4587
4588 status = try_client_v6_prefix(&reply->lease, pool,
4589 &data_pref);
4590 /* If we found it in this pool (either in use or available),
4591 there is no need to look further. */
4592 if ( (status == ISC_R_SUCCESS) || (status == ISC_R_ADDRINUSE) )
4593 break;
4594 }
4595 if ( (status == ISC_R_SUCCESS) || (status == ISC_R_ADDRINUSE) )
4596 break;
4597 }
4598
4599 data_string_forget(&data_pref, MDL);
4600 /* Return just the most recent status... */
4601 return (status);
4602 }
4603
4604 /* Look around for a prefix to give the client. First, look through the old
4605 * IA_PD for prefixes we can extend. Second, try to allocate a new prefix.
4606 * Finally, actually add that prefix into the current reply IA_PD.
4607 */
4608 static isc_result_t
4609 find_client_prefix(struct reply_state *reply) {
4610 struct iaddrcidrnet send_pref;
4611 isc_result_t status = ISC_R_NORESOURCES;
4612 struct iasubopt *prefix, *best_prefix = NULL;
4613 struct binding_scope **scope;
4614 int i;
4615 struct group *group;
4616
4617 if (reply->static_prefixes > 0) {
4618 struct iaddrcidrnetlist *l;
4619
4620 if (reply->host == NULL)
4621 return DHCP_R_INVALIDARG;
4622
4623 for (l = reply->host->fixed_prefix; l != NULL; l = l->next) {
4624 if (l->cidrnet.bits == reply->preflen)
4625 break;
4626 }
4627 if (l == NULL) {
4628 /*
4629 * If no fixed prefix has the preferred length,
4630 * get the first one.
4631 */
4632 l = reply->host->fixed_prefix;
4633 }
4634 memcpy(&send_pref, &l->cidrnet, sizeof(send_pref));
4635
4636 scope = &global_scope;
4637
4638 /* Copy the prefix for logging purposes */
4639 memcpy(&reply->fixed_pref, &l->cidrnet, sizeof(send_pref));
4640
4641 /* Try to find a group for the static prefix */
4642 group = find_group_by_prefix(reply);
4643
4644 goto send_pref;
4645 }
4646
4647 if (reply->old_ia != NULL) {
4648 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
4649 struct shared_network *candidate_shared;
4650 struct ipv6_pond *pond;
4651
4652 prefix = reply->old_ia->iasubopt[i];
4653 candidate_shared = prefix->ipv6_pool->shared_network;
4654 pond = prefix->ipv6_pool->ipv6_pond;
4655
4656 /*
4657 * Consider this prefix if it is in a global pool or
4658 * if it is scoped in a pool under the client's shared
4659 * network.
4660 */
4661 if (((candidate_shared != NULL) &&
4662 (candidate_shared != reply->shared)) ||
4663 (lease6_usable(prefix) != ISC_TRUE))
4664 continue;
4665
4666 /*
4667 * And check if the prefix is still permitted
4668 */
4669
4670 if (((pond->prohibit_list != NULL) &&
4671 (permitted(reply->packet, pond->prohibit_list))) ||
4672 ((pond->permit_list != NULL) &&
4673 (!permitted(reply->packet, pond->permit_list))))
4674 continue;
4675
4676 best_prefix = prefix_compare(reply, prefix,
4677 best_prefix);
4678 }
4679
4680 /*
4681 * If we have prefix length hint and we're not igoring them,
4682 * then toss the best match if it doesn't match the hint,
4683 * unless this is in response to a rebind. In the latter
4684 * case we're supposed to return it with zero lifetimes.
4685 * (See rt45780) */
4686 if (best_prefix && (reply->preflen > 0)
4687 && (prefix_length_mode != PLM_IGNORE)
4688 && (reply->preflen != best_prefix->plen)
4689 && (reply->packet->dhcpv6_msg_type != DHCPV6_REBIND)) {
4690 best_prefix = NULL;
4691 }
4692 }
4693
4694 /* Try to pick a new prefix if we didn't find one, or if we found an
4695 * abandoned prefix.
4696 */
4697 if ((best_prefix == NULL) || (best_prefix->state == FTS_ABANDONED)) {
4698 status = pick_v6_prefix(reply);
4699 } else if (best_prefix != NULL) {
4700 iasubopt_reference(&reply->lease, best_prefix, MDL);
4701 status = ISC_R_SUCCESS;
4702 }
4703
4704 /* Pick the abandoned prefix as a last resort. */
4705 if ((status == ISC_R_NORESOURCES) && (best_prefix != NULL)) {
4706 /* I don't see how this is supposed to be done right now. */
4707 log_error("Reclaiming abandoned prefixes is not yet "
4708 "supported. Treating this as an out of space "
4709 "condition.");
4710 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
4711 }
4712
4713 /* Give up now if we didn't find a prefix. */
4714 if (status != ISC_R_SUCCESS)
4715 return status;
4716
4717 if (reply->lease == NULL)
4718 log_fatal("Impossible condition at %s:%d.", MDL);
4719
4720 scope = &reply->lease->scope;
4721 group = reply->lease->ipv6_pool->ipv6_pond->group;
4722
4723 send_pref.lo_addr.len = 16;
4724 memcpy(send_pref.lo_addr.iabuf, &reply->lease->addr, 16);
4725 send_pref.bits = (int) reply->lease->plen;
4726
4727 send_pref:
4728 status = reply_process_is_prefixed(reply, scope, group);
4729 if (status != ISC_R_SUCCESS)
4730 return status;
4731
4732 status = reply_process_send_prefix(reply, &send_pref);
4733 return status;
4734 }
4735
4736 /* Once a prefix is found for a client, perform several common functions;
4737 * Calculate and store valid and preferred prefix times, draw client options
4738 * into the option state.
4739 */
4740 static isc_result_t
4741 reply_process_is_prefixed(struct reply_state *reply,
4742 struct binding_scope **scope, struct group *group)
4743 {
4744 isc_result_t status = ISC_R_SUCCESS;
4745 struct data_string data;
4746 struct option_cache *oc;
4747 struct option_state *tmp_options = NULL;
4748 struct on_star *on_star;
4749 int i;
4750
4751 /* Initialize values we will cleanup. */
4752 memset(&data, 0, sizeof(data));
4753
4754 /*
4755 * Find the proper on_star block to use. We use the
4756 * one in the lease if we have a lease or the one in
4757 * the reply if we don't have a lease because this is
4758 * a static instance
4759 */
4760 if (reply->lease) {
4761 on_star = &reply->lease->on_star;
4762 } else {
4763 on_star = &reply->on_star;
4764 }
4765
4766 /*
4767 * Bring in the root configuration. We only do this to bring
4768 * in the on * statements, as we didn't have the lease available
4769 * we we did it the first time.
4770 */
4771 option_state_allocate(&tmp_options, MDL);
4772 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4773 reply->packet->options, tmp_options,
4774 &global_scope, root_group, NULL,
4775 on_star);
4776 if (tmp_options != NULL) {
4777 option_state_dereference(&tmp_options, MDL);
4778 }
4779
4780 /*
4781 * Bring configured options into the root packet level cache - start
4782 * with the lease's closest enclosing group (passed in by the caller
4783 * as 'group').
4784 */
4785 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4786 reply->packet->options, reply->opt_state,
4787 scope, group, root_group, on_star);
4788
4789 /* Execute statements from class scopes. */
4790 for (i = reply->packet->class_count; i > 0; i--) {
4791 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4792 reply->packet->options,
4793 reply->opt_state, scope,
4794 reply->packet->classes[i - 1]->group,
4795 group, on_star);
4796 }
4797
4798 /*
4799 * If there is a host record, over-ride with values configured there,
4800 * without re-evaluating configuration from the previously executed
4801 * group or its common enclosers.
4802 */
4803 if (reply->host != NULL)
4804 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4805 reply->packet->options,
4806 reply->opt_state, scope,
4807 reply->host->group, group,
4808 on_star);
4809
4810 /* Determine valid lifetime. */
4811 if (reply->client_valid == 0)
4812 reply->send_valid = DEFAULT_DEFAULT_LEASE_TIME;
4813 else
4814 reply->send_valid = reply->client_valid;
4815
4816 oc = lookup_option(&server_universe, reply->opt_state,
4817 SV_DEFAULT_LEASE_TIME);
4818 if (oc != NULL) {
4819 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
4820 reply->packet->options,
4821 reply->opt_state,
4822 scope, oc, MDL) ||
4823 (data.len != 4)) {
4824 log_error("reply_process_is_prefixed: unable to "
4825 "evaluate default prefix time");
4826 status = ISC_R_FAILURE;
4827 goto cleanup;
4828 }
4829
4830 reply->send_valid = getULong(data.data);
4831 data_string_forget(&data, MDL);
4832 }
4833
4834 /* Check to see if the lease time would cause us to wrap
4835 * in which case we make it infinite.
4836 * The following doesn't work on at least some systems:
4837 * (cur_time + reply->send_valid < cur_time)
4838 */
4839 if (reply->send_valid != INFINITE_TIME) {
4840 time_t test_time = cur_time + reply->send_valid;
4841 if (test_time < cur_time)
4842 reply->send_valid = INFINITE_TIME;
4843 }
4844
4845 if (reply->client_prefer == 0)
4846 reply->send_prefer = reply->send_valid;
4847 else
4848 reply->send_prefer = reply->client_prefer;
4849
4850 if ((reply->send_prefer >= reply->send_valid) &&
4851 (reply->send_valid != INFINITE_TIME))
4852 reply->send_prefer = (reply->send_valid / 2) +
4853 (reply->send_valid / 8);
4854
4855 oc = lookup_option(&server_universe, reply->opt_state,
4856 SV_PREFER_LIFETIME);
4857 if (oc != NULL) {
4858 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
4859 reply->packet->options,
4860 reply->opt_state,
4861 scope, oc, MDL) ||
4862 (data.len != 4)) {
4863 log_error("reply_process_is_prefixed: unable to "
4864 "evaluate preferred prefix time");
4865 status = ISC_R_FAILURE;
4866 goto cleanup;
4867 }
4868
4869 reply->send_prefer = getULong(data.data);
4870 data_string_forget(&data, MDL);
4871 }
4872
4873 /* Note lowest values for later calculation of renew/rebind times. */
4874 if (reply->min_prefer > reply->send_prefer)
4875 reply->min_prefer = reply->send_prefer;
4876
4877 if (reply->min_valid > reply->send_valid)
4878 reply->min_valid = reply->send_valid;
4879
4880 /* Perform dynamic prefix related update work. */
4881 if (reply->lease != NULL) {
4882 /* Cached lifetimes */
4883 reply->lease->prefer = reply->send_prefer;
4884 reply->lease->valid = reply->send_valid;
4885
4886 /* Advance (or rewind) the valid lifetime.
4887 * In the protocol 0xFFFFFFFF is infinite
4888 * when connecting to the lease file MAX_TIME is
4889 */
4890 if (reply->buf.reply.msg_type == DHCPV6_REPLY) {
4891 if (reply->send_valid == INFINITE_TIME) {
4892 reply->lease->soft_lifetime_end_time = MAX_TIME;
4893 } else {
4894 reply->lease->soft_lifetime_end_time =
4895 cur_time + reply->send_valid;
4896 }
4897 /* Wait before renew! */
4898 }
4899
4900 status = ia_add_iasubopt(reply->ia, reply->lease, MDL);
4901 if (status != ISC_R_SUCCESS) {
4902 log_fatal("reply_process_is_prefixed: Unable to "
4903 "attach prefix to new IA_PD: %s",
4904 isc_result_totext(status));
4905 }
4906
4907 /*
4908 * If this is a new prefix, make sure it is attached somewhere.
4909 */
4910 if (reply->lease->ia == NULL) {
4911 ia_reference(&reply->lease->ia, reply->ia, MDL);
4912 }
4913 }
4914
4915 /* Bring a copy of the relevant options into the IA_PD scope. */
4916 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4917 reply->packet->options, reply->reply_ia,
4918 scope, group, root_group, NULL);
4919
4920 /* Execute statements from class scopes. */
4921 for (i = reply->packet->class_count; i > 0; i--) {
4922 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4923 reply->packet->options,
4924 reply->reply_ia, scope,
4925 reply->packet->classes[i - 1]->group,
4926 group, NULL);
4927 }
4928
4929 /*
4930 * And bring in host record configuration, if any, but not to overlap
4931 * the previous group or its common enclosers.
4932 */
4933 if (reply->host != NULL)
4934 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4935 reply->packet->options,
4936 reply->reply_ia, scope,
4937 reply->host->group, group, NULL);
4938
4939 cleanup:
4940 if (data.data != NULL)
4941 data_string_forget(&data, MDL);
4942
4943 if (status == ISC_R_SUCCESS)
4944 reply->client_resources++;
4945
4946 return status;
4947 }
4948
4949 /* Simply send an IAPREFIX within the IA_PD scope as described. */
4950 static isc_result_t
4951 reply_process_send_prefix(struct reply_state *reply,
4952 struct iaddrcidrnet *pref) {
4953 isc_result_t status = ISC_R_SUCCESS;
4954 struct data_string data;
4955
4956 memset(&data, 0, sizeof(data));
4957
4958 /* Now append the prefix. */
4959 data.len = IAPREFIX_OFFSET;
4960 if (!buffer_allocate(&data.buffer, data.len, MDL)) {
4961 log_error("reply_process_send_prefix: out of memory"
4962 "allocating new IAPREFIX buffer.");
4963 status = ISC_R_NOMEMORY;
4964 goto cleanup;
4965 }
4966 data.data = data.buffer->data;
4967
4968 putULong(data.buffer->data, reply->send_prefer);
4969 putULong(data.buffer->data + 4, reply->send_valid);
4970 data.buffer->data[8] = pref->bits;
4971 memcpy(data.buffer->data + 9, pref->lo_addr.iabuf, 16);
4972
4973 if (!append_option_buffer(&dhcpv6_universe, reply->reply_ia,
4974 data.buffer, data.buffer->data,
4975 data.len, D6O_IAPREFIX, 0)) {
4976 log_error("reply_process_send_prefix: unable "
4977 "to save IAPREFIX option");
4978 status = ISC_R_FAILURE;
4979 goto cleanup;
4980 }
4981
4982 reply->resources_included = ISC_TRUE;
4983
4984 cleanup:
4985 if (data.data != NULL)
4986 data_string_forget(&data, MDL);
4987
4988 return status;
4989 }
4990
4991 /* Choose the better of two prefixes. */
4992 static struct iasubopt *
4993 prefix_compare(struct reply_state *reply,
4994 struct iasubopt *alpha, struct iasubopt *beta) {
4995 if (alpha == NULL)
4996 return beta;
4997 if (beta == NULL)
4998 return alpha;
4999
5000 if (reply->preflen >= 0) {
5001 if ((alpha->plen == reply->preflen) &&
5002 (beta->plen != reply->preflen))
5003 return alpha;
5004 if ((beta->plen == reply->preflen) &&
5005 (alpha->plen != reply->preflen))
5006 return beta;
5007 }
5008
5009 switch(alpha->state) {
5010 case FTS_ACTIVE:
5011 switch(beta->state) {
5012 case FTS_ACTIVE:
5013 /* Choose the prefix with the longest lifetime (most
5014 * likely the most recently allocated).
5015 */
5016 if (alpha->hard_lifetime_end_time <
5017 beta->hard_lifetime_end_time)
5018 return beta;
5019 else
5020 return alpha;
5021
5022 case FTS_EXPIRED:
5023 case FTS_ABANDONED:
5024 return alpha;
5025
5026 default:
5027 log_fatal("Impossible condition at %s:%d.", MDL);
5028 }
5029 break;
5030
5031 case FTS_EXPIRED:
5032 switch (beta->state) {
5033 case FTS_ACTIVE:
5034 return beta;
5035
5036 case FTS_EXPIRED:
5037 /* Choose the most recently expired prefix. */
5038 if (alpha->hard_lifetime_end_time <
5039 beta->hard_lifetime_end_time)
5040 return beta;
5041 else if ((alpha->hard_lifetime_end_time ==
5042 beta->hard_lifetime_end_time) &&
5043 (alpha->soft_lifetime_end_time <
5044 beta->soft_lifetime_end_time))
5045 return beta;
5046 else
5047 return alpha;
5048
5049 case FTS_ABANDONED:
5050 return alpha;
5051
5052 default:
5053 log_fatal("Impossible condition at %s:%d.", MDL);
5054 }
5055 break;
5056
5057 case FTS_ABANDONED:
5058 switch (beta->state) {
5059 case FTS_ACTIVE:
5060 case FTS_EXPIRED:
5061 return alpha;
5062
5063 case FTS_ABANDONED:
5064 /* Choose the prefix that was abandoned longest ago. */
5065 if (alpha->hard_lifetime_end_time <
5066 beta->hard_lifetime_end_time)
5067 return alpha;
5068 else
5069 return beta;
5070
5071 default:
5072 log_fatal("Impossible condition at %s:%d.", MDL);
5073 }
5074 break;
5075
5076 default:
5077 log_fatal("Impossible condition at %s:%d.", MDL);
5078 }
5079
5080 log_fatal("Triple impossible condition at %s:%d.", MDL);
5081 return NULL;
5082 }
5083
5084 /*
5085 * Solicit is how a client starts requesting addresses.
5086 *
5087 * If the client asks for rapid commit, and we support it, we will
5088 * allocate the addresses and reply.
5089 *
5090 * Otherwise we will send an advertise message.
5091 */
5092
5093 static void
5094 dhcpv6_solicit(struct data_string *reply_ret, struct packet *packet) {
5095 struct data_string client_id;
5096
5097 /*
5098 * Validate our input.
5099 */
5100 if (!valid_client_msg(packet, &client_id)) {
5101 return;
5102 }
5103
5104 lease_to_client(reply_ret, packet, &client_id, NULL);
5105
5106 /*
5107 * Clean up.
5108 */
5109 data_string_forget(&client_id, MDL);
5110 }
5111
5112 /*
5113 * Request is how a client actually requests addresses.
5114 *
5115 * Very similar to Solicit handling, except the server DUID is required.
5116 */
5117
5118 static void
5119 dhcpv6_request(struct data_string *reply_ret, struct packet *packet) {
5120 struct data_string client_id;
5121 struct data_string server_id;
5122
5123 /*
5124 * Validate our input.
5125 */
5126 if (!valid_client_resp(packet, &client_id, &server_id)) {
5127 return;
5128 }
5129
5130 /* If the REQUEST arrived via unicast and unicast option isn't set,
5131 * reject it per RFC 3315, Sec 18.2.1 */
5132 if (packet->unicast == ISC_TRUE &&
5133 is_unicast_option_defined(packet) == ISC_FALSE) {
5134 unicast_reject(reply_ret, packet, &client_id, &server_id);
5135 } else {
5136 /*
5137 * Issue our lease.
5138 */
5139 lease_to_client(reply_ret, packet, &client_id, &server_id);
5140 }
5141
5142 /*
5143 * Cleanup.
5144 */
5145 data_string_forget(&client_id, MDL);
5146 data_string_forget(&server_id, MDL);
5147 }
5148
5149 /* Find a DHCPv6 packet's shared network from hints in the packet.
5150 */
5151 static isc_result_t
5152 shared_network_from_packet6(struct shared_network **shared,
5153 struct packet *packet)
5154 {
5155 const struct packet *chk_packet;
5156 const struct in6_addr *link_addr, *first_link_addr;
5157 struct iaddr tmp_addr;
5158 struct subnet *subnet;
5159 isc_result_t status;
5160
5161 if ((shared == NULL) || (*shared != NULL) || (packet == NULL))
5162 return DHCP_R_INVALIDARG;
5163
5164 /*
5165 * First, find the link address where the packet from the client
5166 * first appeared (if this packet was relayed).
5167 */
5168 first_link_addr = NULL;
5169 chk_packet = packet->dhcpv6_container_packet;
5170 while (chk_packet != NULL) {
5171 link_addr = &chk_packet->dhcpv6_link_address;
5172 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr) &&
5173 !IN6_IS_ADDR_LINKLOCAL(link_addr)) {
5174 first_link_addr = link_addr;
5175 break;
5176 }
5177 chk_packet = chk_packet->dhcpv6_container_packet;
5178 }
5179
5180 /*
5181 * If there is a relayed link address, find the subnet associated
5182 * with that, and use that to get the appropriate
5183 * shared_network.
5184 */
5185 if (first_link_addr != NULL) {
5186 tmp_addr.len = sizeof(*first_link_addr);
5187 memcpy(tmp_addr.iabuf,
5188 first_link_addr, sizeof(*first_link_addr));
5189 subnet = NULL;
5190 if (!find_subnet(&subnet, tmp_addr, MDL)) {
5191 log_debug("No subnet found for link-address %s.",
5192 piaddr(tmp_addr));
5193 return ISC_R_NOTFOUND;
5194 }
5195 status = shared_network_reference(shared,
5196 subnet->shared_network, MDL);
5197 subnet_dereference(&subnet, MDL);
5198
5199 /*
5200 * If there is no link address, we will use the interface
5201 * that this packet came in on to pick the shared_network.
5202 */
5203 } else if (packet->interface != NULL) {
5204 status = shared_network_reference(shared,
5205 packet->interface->shared_network,
5206 MDL);
5207 if (packet->dhcpv6_container_packet != NULL) {
5208 log_info("[L2 Relay] No link address in relay packet "
5209 "assuming L2 relay and using receiving "
5210 "interface");
5211 }
5212
5213 } else {
5214 /*
5215 * We shouldn't be able to get here but if there is no link
5216 * address and no interface we don't know where to get the
5217 * pool from log an error and return an error.
5218 */
5219 log_error("No interface and no link address "
5220 "can't determine pool");
5221 status = DHCP_R_INVALIDARG;
5222 }
5223
5224 return status;
5225 }
5226
5227 /*
5228 * When a client thinks it might be on a new link, it sends a
5229 * Confirm message.
5230 *
5231 * From RFC3315 section 18.2.2:
5232 *
5233 * When the server receives a Confirm message, the server determines
5234 * whether the addresses in the Confirm message are appropriate for the
5235 * link to which the client is attached. If all of the addresses in the
5236 * Confirm message pass this test, the server returns a status of
5237 * Success. If any of the addresses do not pass this test, the server
5238 * returns a status of NotOnLink. If the server is unable to perform
5239 * this test (for example, the server does not have information about
5240 * prefixes on the link to which the client is connected), or there were
5241 * no addresses in any of the IAs sent by the client, the server MUST
5242 * NOT send a reply to the client.
5243 */
5244
5245 static void
5246 dhcpv6_confirm(struct data_string *reply_ret, struct packet *packet) {
5247 struct shared_network *shared;
5248 struct subnet *subnet;
5249 struct option_cache *ia, *ta, *oc;
5250 struct data_string cli_enc_opt_data, iaaddr, client_id, packet_oro;
5251 struct option_state *cli_enc_opt_state, *opt_state;
5252 struct iaddr cli_addr;
5253 int pass;
5254 isc_boolean_t inappropriate, has_addrs;
5255 char reply_data[65536];
5256 struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data;
5257 int reply_ofs = (int)(offsetof(struct dhcpv6_packet, options));
5258
5259 /*
5260 * Basic client message validation.
5261 */
5262 memset(&client_id, 0, sizeof(client_id));
5263 if (!valid_client_msg(packet, &client_id)) {
5264 return;
5265 }
5266
5267 /*
5268 * Do not process Confirms that do not have IA's we do not recognize.
5269 */
5270 ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
5271 ta = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_TA);
5272 if ((ia == NULL) && (ta == NULL))
5273 return;
5274
5275 /*
5276 * IA_PD's are simply ignored.
5277 */
5278 delete_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
5279
5280 /*
5281 * Bit of variable initialization.
5282 */
5283 opt_state = cli_enc_opt_state = NULL;
5284 memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
5285 memset(&iaaddr, 0, sizeof(iaaddr));
5286 memset(&packet_oro, 0, sizeof(packet_oro));
5287
5288 /* Determine what shared network the client is connected to. We
5289 * must not respond if we don't have any information about the
5290 * network the client is on.
5291 */
5292 shared = NULL;
5293 if ((shared_network_from_packet6(&shared, packet) != ISC_R_SUCCESS) ||
5294 (shared == NULL))
5295 goto exit;
5296
5297 /* If there are no recorded subnets, then we have no
5298 * information about this subnet - ignore Confirms.
5299 */
5300 subnet = shared->subnets;
5301 if (subnet == NULL)
5302 goto exit;
5303
5304 /* Are the addresses in all the IA's appropriate for that link? */
5305 has_addrs = inappropriate = ISC_FALSE;
5306 pass = D6O_IA_NA;
5307 while(!inappropriate) {
5308 /* If we've reached the end of the IA_NA pass, move to the
5309 * IA_TA pass.
5310 */
5311 if ((pass == D6O_IA_NA) && (ia == NULL)) {
5312 pass = D6O_IA_TA;
5313 ia = ta;
5314 }
5315
5316 /* If we've reached the end of all passes, we're done. */
5317 if (ia == NULL)
5318 break;
5319
5320 if (((pass == D6O_IA_NA) &&
5321 !get_encapsulated_IA_state(&cli_enc_opt_state,
5322 &cli_enc_opt_data,
5323 packet, ia, IA_NA_OFFSET)) ||
5324 ((pass == D6O_IA_TA) &&
5325 !get_encapsulated_IA_state(&cli_enc_opt_state,
5326 &cli_enc_opt_data,
5327 packet, ia, IA_TA_OFFSET))) {
5328 goto exit;
5329 }
5330
5331 oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
5332 D6O_IAADDR);
5333
5334 for ( ; oc != NULL ; oc = oc->next) {
5335 if (!evaluate_option_cache(&iaaddr, packet, NULL, NULL,
5336 packet->options, NULL,
5337 &global_scope, oc, MDL) ||
5338 (iaaddr.len < IAADDR_OFFSET)) {
5339 log_error("dhcpv6_confirm: "
5340 "error evaluating IAADDR.");
5341 goto exit;
5342 }
5343
5344 /* Copy out the IPv6 address for processing. */
5345 cli_addr.len = 16;
5346 memcpy(cli_addr.iabuf, iaaddr.data, 16);
5347
5348 data_string_forget(&iaaddr, MDL);
5349
5350 /* Record that we've processed at least one address. */
5351 has_addrs = ISC_TRUE;
5352
5353 /* Find out if any subnets cover this address. */
5354 for (subnet = shared->subnets ; subnet != NULL ;
5355 subnet = subnet->next_sibling) {
5356 if (addr_eq(subnet_number(cli_addr,
5357 subnet->netmask),
5358 subnet->net))
5359 break;
5360 }
5361
5362 /* If we reach the end of the subnet list, and no
5363 * subnet matches the client address, then it must
5364 * be inappropriate to the link (so far as our
5365 * configuration says). Once we've found one
5366 * inappropriate address, there is no reason to
5367 * continue searching.
5368 */
5369 if (subnet == NULL) {
5370 inappropriate = ISC_TRUE;
5371 break;
5372 }
5373 }
5374
5375 option_state_dereference(&cli_enc_opt_state, MDL);
5376 data_string_forget(&cli_enc_opt_data, MDL);
5377
5378 /* Advance to the next IA_*. */
5379 ia = ia->next;
5380 }
5381
5382 /* If the client supplied no addresses, do not reply. */
5383 if (!has_addrs)
5384 goto exit;
5385
5386 /*
5387 * Set up reply.
5388 */
5389 if (!start_reply(packet, &client_id, NULL, &opt_state, reply)) {
5390 goto exit;
5391 }
5392
5393 /*
5394 * Set our status.
5395 */
5396 if (inappropriate) {
5397 if (!set_status_code(STATUS_NotOnLink,
5398 "Some of the addresses are not on link.",
5399 opt_state)) {
5400 goto exit;
5401 }
5402 } else {
5403 if (!set_status_code(STATUS_Success,
5404 "All addresses still on link.",
5405 opt_state)) {
5406 goto exit;
5407 }
5408 }
5409
5410 /*
5411 * Only one option: add it.
5412 */
5413 reply_ofs += store_options6(reply_data+reply_ofs,
5414 sizeof(reply_data)-reply_ofs,
5415 opt_state, packet,
5416 required_opts, &packet_oro);
5417
5418 /*
5419 * Return our reply to the caller.
5420 */
5421 reply_ret->len = reply_ofs;
5422 reply_ret->buffer = NULL;
5423 if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) {
5424 log_fatal("No memory to store reply.");
5425 }
5426 reply_ret->data = reply_ret->buffer->data;
5427 memcpy(reply_ret->buffer->data, reply, reply_ofs);
5428
5429 exit:
5430 /* Cleanup any stale data strings. */
5431 if (cli_enc_opt_data.buffer != NULL)
5432 data_string_forget(&cli_enc_opt_data, MDL);
5433 if (iaaddr.buffer != NULL)
5434 data_string_forget(&iaaddr, MDL);
5435 if (client_id.buffer != NULL)
5436 data_string_forget(&client_id, MDL);
5437 if (packet_oro.buffer != NULL)
5438 data_string_forget(&packet_oro, MDL);
5439
5440 /* Release any stale option states. */
5441 if (cli_enc_opt_state != NULL)
5442 option_state_dereference(&cli_enc_opt_state, MDL);
5443 if (opt_state != NULL)
5444 option_state_dereference(&opt_state, MDL);
5445 }
5446
5447 /*
5448 * Renew is when a client wants to extend its lease/prefix, at time T1.
5449 *
5450 * We handle this the same as if the client wants a new lease/prefix,
5451 * except for the error code of when addresses don't match.
5452 */
5453
5454 static void
5455 dhcpv6_renew(struct data_string *reply, struct packet *packet) {
5456 struct data_string client_id;
5457 struct data_string server_id;
5458
5459 /*
5460 * Validate the request.
5461 */
5462 if (!valid_client_resp(packet, &client_id, &server_id)) {
5463 return;
5464 }
5465
5466 /* If the RENEW arrived via unicast and unicast option isn't set,
5467 * reject it per RFC 3315, Sec 18.2.3 */
5468 if (packet->unicast == ISC_TRUE &&
5469 is_unicast_option_defined(packet) == ISC_FALSE) {
5470 unicast_reject(reply, packet, &client_id, &server_id);
5471 } else {
5472 /*
5473 * Renew our lease.
5474 */
5475 lease_to_client(reply, packet, &client_id, &server_id);
5476 }
5477
5478 /*
5479 * Cleanup.
5480 */
5481 data_string_forget(&server_id, MDL);
5482 data_string_forget(&client_id, MDL);
5483 }
5484
5485 /*
5486 * Rebind is when a client wants to extend its lease, at time T2.
5487 *
5488 * We handle this the same as if the client wants a new lease, except
5489 * for the error code of when addresses don't match.
5490 */
5491
5492 static void
5493 dhcpv6_rebind(struct data_string *reply, struct packet *packet) {
5494 struct data_string client_id;
5495
5496 if (!valid_client_msg(packet, &client_id)) {
5497 return;
5498 }
5499
5500 lease_to_client(reply, packet, &client_id, NULL);
5501
5502 data_string_forget(&client_id, MDL);
5503 }
5504
5505 static void
5506 ia_na_match_decline(const struct data_string *client_id,
5507 const struct data_string *iaaddr,
5508 struct iasubopt *lease)
5509 {
5510 char tmp_addr[INET6_ADDRSTRLEN];
5511
5512 log_error("Client %s reports address %s is "
5513 "already in use by another host!",
5514 print_hex_1(client_id->len, client_id->data, 60),
5515 inet_ntop(AF_INET6, iaaddr->data,
5516 tmp_addr, sizeof(tmp_addr)));
5517 if (lease != NULL) {
5518 decline_lease6(lease->ipv6_pool, lease);
5519 lease->ia->cltt = cur_time;
5520 write_ia(lease->ia);
5521 }
5522 }
5523
5524 static void
5525 ia_na_nomatch_decline(const struct data_string *client_id,
5526 const struct data_string *iaaddr,
5527 u_int32_t *ia_na_id,
5528 struct packet *packet,
5529 char *reply_data,
5530 int *reply_ofs,
5531 int reply_len)
5532 {
5533 char tmp_addr[INET6_ADDRSTRLEN];
5534 struct option_state *host_opt_state;
5535 int len;
5536
5537 log_info("Client %s declines address %s, which is not offered to it.",
5538 print_hex_1(client_id->len, client_id->data, 60),
5539 inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
5540
5541 /*
5542 * Create state for this IA_NA.
5543 */
5544 host_opt_state = NULL;
5545 if (!option_state_allocate(&host_opt_state, MDL)) {
5546 log_error("ia_na_nomatch_decline: out of memory "
5547 "allocating option_state.");
5548 goto exit;
5549 }
5550
5551 if (!set_status_code(STATUS_NoBinding, "Decline for unknown address.",
5552 host_opt_state)) {
5553 goto exit;
5554 }
5555
5556 /*
5557 * Insure we have enough space
5558 */
5559 if (reply_len < (*reply_ofs + 16)) {
5560 log_error("ia_na_nomatch_decline: "
5561 "out of space for reply packet.");
5562 goto exit;
5563 }
5564
5565 /*
5566 * Put our status code into the reply packet.
5567 */
5568 len = store_options6(reply_data+(*reply_ofs)+16,
5569 reply_len-(*reply_ofs)-16,
5570 host_opt_state, packet,
5571 required_opts_STATUS_CODE, NULL);
5572
5573 /*
5574 * Store the non-encapsulated option data for this
5575 * IA_NA into our reply packet. Defined in RFC 3315,
5576 * section 22.4.
5577 */
5578 /* option number */
5579 putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_NA);
5580 /* option length */
5581 putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
5582 /* IA_NA, copied from the client */
5583 memcpy(reply_data+(*reply_ofs)+4, ia_na_id, 4);
5584 /* t1 and t2, odd that we need them, but here it is */
5585 putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
5586 putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
5587
5588 /*
5589 * Get ready for next IA_NA.
5590 */
5591 *reply_ofs += (len + 16);
5592
5593 exit:
5594 option_state_dereference(&host_opt_state, MDL);
5595 }
5596
5597 static void
5598 iterate_over_ia_na(struct data_string *reply_ret,
5599 struct packet *packet,
5600 const struct data_string *client_id,
5601 const struct data_string *server_id,
5602 const char *packet_type,
5603 void (*ia_na_match)(),
5604 void (*ia_na_nomatch)())
5605 {
5606 struct option_state *opt_state;
5607 struct host_decl *packet_host;
5608 struct option_cache *ia;
5609 struct option_cache *oc;
5610 /* cli_enc_... variables come from the IA_NA/IA_TA options */
5611 struct data_string cli_enc_opt_data;
5612 struct option_state *cli_enc_opt_state;
5613 struct host_decl *host;
5614 struct data_string iaaddr;
5615 struct data_string fixed_addr;
5616 char reply_data[65536];
5617 struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data;
5618 int reply_ofs = (int)(offsetof(struct dhcpv6_packet, options));
5619 char status_msg[32];
5620 struct iasubopt *lease;
5621 struct ia_xx *existing_ia_na;
5622 int i;
5623 struct data_string key;
5624 u_int32_t iaid;
5625
5626 /*
5627 * Initialize to empty values, in case we have to exit early.
5628 */
5629 opt_state = NULL;
5630 memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
5631 cli_enc_opt_state = NULL;
5632 memset(&iaaddr, 0, sizeof(iaaddr));
5633 memset(&fixed_addr, 0, sizeof(fixed_addr));
5634 lease = NULL;
5635
5636 /*
5637 * Find the host record that matches from the packet, if any.
5638 */
5639 packet_host = NULL;
5640 find_hosts6(&packet_host, packet, client_id, MDL);
5641
5642 /*
5643 * Set our reply information.
5644 */
5645 reply->msg_type = DHCPV6_REPLY;
5646 memcpy(reply->transaction_id, packet->dhcpv6_transaction_id,
5647 sizeof(reply->transaction_id));
5648
5649 /*
5650 * Build our option state for reply.
5651 */
5652 opt_state = NULL;
5653 if (!option_state_allocate(&opt_state, MDL)) {
5654 log_error("iterate_over_ia_na: no memory for option_state.");
5655 goto exit;
5656 }
5657 execute_statements_in_scope(NULL, packet, NULL, NULL,
5658 packet->options, opt_state,
5659 &global_scope, root_group, NULL, NULL);
5660
5661 /*
5662 * RFC 3315, section 18.2.7 tells us which options to include.
5663 */
5664 oc = lookup_option(&dhcpv6_universe, opt_state, D6O_SERVERID);
5665 if (oc == NULL) {
5666 if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
5667 (unsigned char *)server_duid.data,
5668 server_duid.len, D6O_SERVERID, 0)) {
5669 log_error("iterate_over_ia_na: "
5670 "error saving server identifier.");
5671 goto exit;
5672 }
5673 }
5674
5675 if (!save_option_buffer(&dhcpv6_universe, opt_state,
5676 client_id->buffer,
5677 (unsigned char *)client_id->data,
5678 client_id->len,
5679 D6O_CLIENTID, 0)) {
5680 log_error("iterate_over_ia_na: "
5681 "error saving client identifier.");
5682 goto exit;
5683 }
5684
5685 snprintf(status_msg, sizeof(status_msg), "%s received.", packet_type);
5686 if (!set_status_code(STATUS_Success, status_msg, opt_state)) {
5687 goto exit;
5688 }
5689
5690 /*
5691 * Add our options that are not associated with any IA_NA or IA_TA.
5692 */
5693 reply_ofs += store_options6(reply_data+reply_ofs,
5694 sizeof(reply_data)-reply_ofs,
5695 opt_state, packet,
5696 required_opts, NULL);
5697
5698 /*
5699 * Loop through the IA_NA reported by the client, and deal with
5700 * addresses reported as already in use.
5701 */
5702 for (ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
5703 ia != NULL; ia = ia->next) {
5704
5705 if (!get_encapsulated_IA_state(&cli_enc_opt_state,
5706 &cli_enc_opt_data,
5707 packet, ia, IA_NA_OFFSET)) {
5708 goto exit;
5709 }
5710
5711 iaid = getULong(cli_enc_opt_data.data);
5712
5713 /*
5714 * XXX: It is possible that we can get multiple addresses
5715 * sent by the client. We don't send multiple
5716 * addresses, so this indicates a client error.
5717 * We should check for multiple IAADDR options, log
5718 * if found, and set as an error.
5719 */
5720 oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
5721 D6O_IAADDR);
5722 if (oc == NULL) {
5723 /* no address given for this IA, ignore */
5724 option_state_dereference(&cli_enc_opt_state, MDL);
5725 data_string_forget(&cli_enc_opt_data, MDL);
5726 continue;
5727 }
5728
5729 memset(&iaaddr, 0, sizeof(iaaddr));
5730 if (!evaluate_option_cache(&iaaddr, packet, NULL, NULL,
5731 packet->options, NULL,
5732 &global_scope, oc, MDL)) {
5733 log_error("iterate_over_ia_na: "
5734 "error evaluating IAADDR.");
5735 goto exit;
5736 }
5737
5738 /*
5739 * Now we need to figure out which host record matches
5740 * this IA_NA and IAADDR (encapsulated option contents
5741 * matching a host record by option).
5742 *
5743 * XXX: We don't currently track IA_NA separately, but
5744 * we will need to do this!
5745 */
5746 host = NULL;
5747 if (!find_hosts_by_option(&host, packet,
5748 cli_enc_opt_state, MDL)) {
5749 if (packet_host != NULL) {
5750 host = packet_host;
5751 } else {
5752 host = NULL;
5753 }
5754 }
5755 while (host != NULL) {
5756 if (host->fixed_addr != NULL) {
5757 if (!evaluate_option_cache(&fixed_addr, NULL,
5758 NULL, NULL, NULL,
5759 NULL, &global_scope,
5760 host->fixed_addr,
5761 MDL)) {
5762 log_error("iterate_over_ia_na: error "
5763 "evaluating host address.");
5764 goto exit;
5765 }
5766 if ((iaaddr.len >= 16) &&
5767 !memcmp(fixed_addr.data, iaaddr.data, 16)) {
5768 data_string_forget(&fixed_addr, MDL);
5769 break;
5770 }
5771 data_string_forget(&fixed_addr, MDL);
5772 }
5773 host = host->n_ipaddr;
5774 }
5775
5776 if ((host == NULL) && (iaaddr.len >= IAADDR_OFFSET)) {
5777 /*
5778 * Find existing IA_NA.
5779 */
5780 if (ia_make_key(&key, iaid,
5781 (char *)client_id->data,
5782 client_id->len,
5783 MDL) != ISC_R_SUCCESS) {
5784 log_fatal("iterate_over_ia_na: no memory for "
5785 "key.");
5786 }
5787
5788 existing_ia_na = NULL;
5789 if (ia_hash_lookup(&existing_ia_na, ia_na_active,
5790 (unsigned char *)key.data,
5791 key.len, MDL)) {
5792 /*
5793 * Make sure this address is in the IA_NA.
5794 */
5795 for (i=0; i<existing_ia_na->num_iasubopt; i++) {
5796 struct iasubopt *tmp;
5797 struct in6_addr *in6_addr;
5798
5799 tmp = existing_ia_na->iasubopt[i];
5800 in6_addr = &tmp->addr;
5801 if (memcmp(in6_addr,
5802 iaaddr.data, 16) == 0) {
5803 iasubopt_reference(&lease,
5804 tmp, MDL);
5805 break;
5806 }
5807 }
5808 }
5809
5810 data_string_forget(&key, MDL);
5811 }
5812
5813 if ((host != NULL) || (lease != NULL)) {
5814 ia_na_match(client_id, &iaaddr, lease);
5815 } else {
5816 ia_na_nomatch(client_id, &iaaddr,
5817 (u_int32_t *)cli_enc_opt_data.data,
5818 packet, reply_data, &reply_ofs,
5819 sizeof(reply_data));
5820 }
5821
5822 if (lease != NULL) {
5823 iasubopt_dereference(&lease, MDL);
5824 }
5825
5826 data_string_forget(&iaaddr, MDL);
5827 option_state_dereference(&cli_enc_opt_state, MDL);
5828 data_string_forget(&cli_enc_opt_data, MDL);
5829 }
5830
5831 /*
5832 * Return our reply to the caller.
5833 */
5834 reply_ret->len = reply_ofs;
5835 reply_ret->buffer = NULL;
5836 if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) {
5837 log_fatal("No memory to store reply.");
5838 }
5839 reply_ret->data = reply_ret->buffer->data;
5840 memcpy(reply_ret->buffer->data, reply, reply_ofs);
5841
5842 exit:
5843 if (lease != NULL) {
5844 iasubopt_dereference(&lease, MDL);
5845 }
5846 if (fixed_addr.buffer != NULL) {
5847 data_string_forget(&fixed_addr, MDL);
5848 }
5849 if (iaaddr.buffer != NULL) {
5850 data_string_forget(&iaaddr, MDL);
5851 }
5852 if (cli_enc_opt_state != NULL) {
5853 option_state_dereference(&cli_enc_opt_state, MDL);
5854 }
5855 if (cli_enc_opt_data.buffer != NULL) {
5856 data_string_forget(&cli_enc_opt_data, MDL);
5857 }
5858 if (opt_state != NULL) {
5859 option_state_dereference(&opt_state, MDL);
5860 }
5861 }
5862
5863 /*
5864 * Decline means a client has detected that something else is using an
5865 * address we gave it.
5866 *
5867 * Since we're only dealing with fixed leases for now, there's not
5868 * much we can do, other that log the occurrence.
5869 *
5870 * When we start issuing addresses from pools, then we will have to
5871 * record our declined addresses and issue another. In general with
5872 * IPv6 there is no worry about DoS by clients exhausting space, but
5873 * we still need to be aware of this possibility.
5874 */
5875
5876 /* TODO: IA_TA */
5877 static void
5878 dhcpv6_decline(struct data_string *reply, struct packet *packet) {
5879 struct data_string client_id;
5880 struct data_string server_id;
5881
5882 /*
5883 * Validate our input.
5884 */
5885 if (!valid_client_resp(packet, &client_id, &server_id)) {
5886 return;
5887 }
5888
5889 /* If the DECLINE arrived via unicast and unicast option isn't set,
5890 * reject it per RFC 3315, Sec 18.2.7 */
5891 if (packet->unicast == ISC_TRUE &&
5892 is_unicast_option_defined(packet) == ISC_FALSE) {
5893 unicast_reject(reply, packet, &client_id, &server_id);
5894 } else {
5895 /*
5896 * Undefined for IA_PD.
5897 */
5898 delete_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
5899
5900 /*
5901 * And operate on each IA_NA in this packet.
5902 */
5903 iterate_over_ia_na(reply, packet, &client_id, &server_id,
5904 "Decline", ia_na_match_decline,
5905 ia_na_nomatch_decline);
5906
5907 }
5908
5909 data_string_forget(&server_id, MDL);
5910 data_string_forget(&client_id, MDL);
5911 }
5912
5913 static void
5914 ia_na_match_release(const struct data_string *client_id,
5915 const struct data_string *iaaddr,
5916 struct iasubopt *lease)
5917 {
5918 char tmp_addr[INET6_ADDRSTRLEN];
5919
5920 log_info("Client %s releases address %s",
5921 print_hex_1(client_id->len, client_id->data, 60),
5922 inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
5923 if (lease != NULL) {
5924 release_lease6(lease->ipv6_pool, lease);
5925 lease->ia->cltt = cur_time;
5926 write_ia(lease->ia);
5927 }
5928 }
5929
5930 static void
5931 ia_na_nomatch_release(const struct data_string *client_id,
5932 const struct data_string *iaaddr,
5933 u_int32_t *ia_na_id,
5934 struct packet *packet,
5935 char *reply_data,
5936 int *reply_ofs,
5937 int reply_len)
5938 {
5939 char tmp_addr[INET6_ADDRSTRLEN];
5940 struct option_state *host_opt_state;
5941 int len;
5942
5943 log_info("Client %s releases address %s, which is not leased to it.",
5944 print_hex_1(client_id->len, client_id->data, 60),
5945 inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
5946
5947 /*
5948 * Create state for this IA_NA.
5949 */
5950 host_opt_state = NULL;
5951 if (!option_state_allocate(&host_opt_state, MDL)) {
5952 log_error("ia_na_nomatch_release: out of memory "
5953 "allocating option_state.");
5954 goto exit;
5955 }
5956
5957 if (!set_status_code(STATUS_NoBinding,
5958 "Release for non-leased address.",
5959 host_opt_state)) {
5960 goto exit;
5961 }
5962
5963 /*
5964 * Insure we have enough space
5965 */
5966 if (reply_len < (*reply_ofs + 16)) {
5967 log_error("ia_na_nomatch_release: "
5968 "out of space for reply packet.");
5969 goto exit;
5970 }
5971
5972 /*
5973 * Put our status code into the reply packet.
5974 */
5975 len = store_options6(reply_data+(*reply_ofs)+16,
5976 reply_len-(*reply_ofs)-16,
5977 host_opt_state, packet,
5978 required_opts_STATUS_CODE, NULL);
5979
5980 /*
5981 * Store the non-encapsulated option data for this
5982 * IA_NA into our reply packet. Defined in RFC 3315,
5983 * section 22.4.
5984 */
5985 /* option number */
5986 putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_NA);
5987 /* option length */
5988 putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
5989 /* IA_NA, copied from the client */
5990 memcpy(reply_data+(*reply_ofs)+4, ia_na_id, 4);
5991 /* t1 and t2, odd that we need them, but here it is */
5992 putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
5993 putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
5994
5995 /*
5996 * Get ready for next IA_NA.
5997 */
5998 *reply_ofs += (len + 16);
5999
6000 exit:
6001 option_state_dereference(&host_opt_state, MDL);
6002 }
6003
6004 static void
6005 ia_pd_match_release(const struct data_string *client_id,
6006 const struct data_string *iapref,
6007 struct iasubopt *prefix)
6008 {
6009 char tmp_addr[INET6_ADDRSTRLEN];
6010
6011 log_info("Client %s releases prefix %s/%u",
6012 print_hex_1(client_id->len, client_id->data, 60),
6013 inet_ntop(AF_INET6, iapref->data + 9,
6014 tmp_addr, sizeof(tmp_addr)),
6015 (unsigned) getUChar(iapref->data + 8));
6016 if (prefix != NULL) {
6017 release_lease6(prefix->ipv6_pool, prefix);
6018 prefix->ia->cltt = cur_time;
6019 write_ia(prefix->ia);
6020 }
6021 }
6022
6023 static void
6024 ia_pd_nomatch_release(const struct data_string *client_id,
6025 const struct data_string *iapref,
6026 u_int32_t *ia_pd_id,
6027 struct packet *packet,
6028 char *reply_data,
6029 int *reply_ofs,
6030 int reply_len)
6031 {
6032 char tmp_addr[INET6_ADDRSTRLEN];
6033 struct option_state *host_opt_state;
6034 int len;
6035
6036 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
6037 print_hex_1(client_id->len, client_id->data, 60),
6038 inet_ntop(AF_INET6, iapref->data + 9,
6039 tmp_addr, sizeof(tmp_addr)),
6040 (unsigned) getUChar(iapref->data + 8));
6041
6042 /*
6043 * Create state for this IA_PD.
6044 */
6045 host_opt_state = NULL;
6046 if (!option_state_allocate(&host_opt_state, MDL)) {
6047 log_error("ia_pd_nomatch_release: out of memory "
6048 "allocating option_state.");
6049 goto exit;
6050 }
6051
6052 if (!set_status_code(STATUS_NoBinding,
6053 "Release for non-leased prefix.",
6054 host_opt_state)) {
6055 goto exit;
6056 }
6057
6058 /*
6059 * Insure we have enough space
6060 */
6061 if (reply_len < (*reply_ofs + 16)) {
6062 log_error("ia_pd_nomatch_release: "
6063 "out of space for reply packet.");
6064 goto exit;
6065 }
6066
6067 /*
6068 * Put our status code into the reply packet.
6069 */
6070 len = store_options6(reply_data+(*reply_ofs)+16,
6071 reply_len-(*reply_ofs)-16,
6072 host_opt_state, packet,
6073 required_opts_STATUS_CODE, NULL);
6074
6075 /*
6076 * Store the non-encapsulated option data for this
6077 * IA_PD into our reply packet. Defined in RFC 3315,
6078 * section 22.4.
6079 */
6080 /* option number */
6081 putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_PD);
6082 /* option length */
6083 putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
6084 /* IA_PD, copied from the client */
6085 memcpy(reply_data+(*reply_ofs)+4, ia_pd_id, 4);
6086 /* t1 and t2, odd that we need them, but here it is */
6087 putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
6088 putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
6089
6090 /*
6091 * Get ready for next IA_PD.
6092 */
6093 *reply_ofs += (len + 16);
6094
6095 exit:
6096 option_state_dereference(&host_opt_state, MDL);
6097 }
6098
6099 static void
6100 iterate_over_ia_pd(struct data_string *reply_ret,
6101 struct packet *packet,
6102 const struct data_string *client_id,
6103 const struct data_string *server_id,
6104 const char *packet_type,
6105 void (*ia_pd_match)(),
6106 void (*ia_pd_nomatch)())
6107 {
6108 struct data_string reply_new;
6109 int reply_len;
6110 struct option_state *opt_state;
6111 struct host_decl *packet_host;
6112 struct option_cache *ia;
6113 struct option_cache *oc;
6114 /* cli_enc_... variables come from the IA_PD options */
6115 struct data_string cli_enc_opt_data;
6116 struct option_state *cli_enc_opt_state;
6117 struct host_decl *host;
6118 struct data_string iaprefix;
6119 char reply_data[65536];
6120 int reply_ofs;
6121 struct iasubopt *prefix;
6122 struct ia_xx *existing_ia_pd;
6123 int i;
6124 struct data_string key;
6125 u_int32_t iaid;
6126
6127 /*
6128 * Initialize to empty values, in case we have to exit early.
6129 */
6130 memset(&reply_new, 0, sizeof(reply_new));
6131 opt_state = NULL;
6132 memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
6133 cli_enc_opt_state = NULL;
6134 memset(&iaprefix, 0, sizeof(iaprefix));
6135 prefix = NULL;
6136
6137 /*
6138 * Compute the available length for the reply.
6139 */
6140 reply_len = sizeof(reply_data) - reply_ret->len;
6141 reply_ofs = 0;
6142
6143 /*
6144 * Find the host record that matches from the packet, if any.
6145 */
6146 packet_host = NULL;
6147 find_hosts6(&packet_host, packet, client_id, MDL);
6148
6149 /*
6150 * Build our option state for reply.
6151 */
6152 opt_state = NULL;
6153 if (!option_state_allocate(&opt_state, MDL)) {
6154 log_error("iterate_over_ia_pd: no memory for option_state.");
6155 goto exit;
6156 }
6157 execute_statements_in_scope(NULL, packet, NULL, NULL,
6158 packet->options, opt_state,
6159 &global_scope, root_group, NULL, NULL);
6160
6161 /*
6162 * Loop through the IA_PD reported by the client, and deal with
6163 * prefixes reported as already in use.
6164 */
6165 for (ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
6166 ia != NULL; ia = ia->next) {
6167
6168 if (!get_encapsulated_IA_state(&cli_enc_opt_state,
6169 &cli_enc_opt_data,
6170 packet, ia, IA_PD_OFFSET)) {
6171 goto exit;
6172 }
6173
6174 iaid = getULong(cli_enc_opt_data.data);
6175
6176 oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
6177 D6O_IAPREFIX);
6178 if (oc == NULL) {
6179 /* no prefix given for this IA_PD, ignore */
6180 option_state_dereference(&cli_enc_opt_state, MDL);
6181 data_string_forget(&cli_enc_opt_data, MDL);
6182 continue;
6183 }
6184
6185 for (; oc != NULL; oc = oc->next) {
6186 memset(&iaprefix, 0, sizeof(iaprefix));
6187 if (!evaluate_option_cache(&iaprefix, packet, NULL, NULL,
6188 packet->options, NULL,
6189 &global_scope, oc, MDL)) {
6190 log_error("iterate_over_ia_pd: "
6191 "error evaluating IAPREFIX.");
6192 goto exit;
6193 }
6194
6195 /*
6196 * Now we need to figure out which host record matches
6197 * this IA_PD and IAPREFIX (encapsulated option contents
6198 * matching a host record by option).
6199 *
6200 * XXX: We don't currently track IA_PD separately, but
6201 * we will need to do this!
6202 */
6203 host = NULL;
6204 if (!find_hosts_by_option(&host, packet,
6205 cli_enc_opt_state, MDL)) {
6206 if (packet_host != NULL) {
6207 host = packet_host;
6208 } else {
6209 host = NULL;
6210 }
6211 }
6212 while (host != NULL) {
6213 if (host->fixed_prefix != NULL) {
6214 struct iaddrcidrnetlist *l;
6215 int plen = (int) getUChar(iaprefix.data + 8);
6216
6217 for (l = host->fixed_prefix; l != NULL;
6218 l = l->next) {
6219 if (plen != l->cidrnet.bits)
6220 continue;
6221 if (memcmp(iaprefix.data + 9,
6222 l->cidrnet.lo_addr.iabuf,
6223 16) == 0)
6224 break;
6225 }
6226 if ((l != NULL) && (iaprefix.len >= 17))
6227 break;
6228 }
6229 host = host->n_ipaddr;
6230 }
6231
6232 if ((host == NULL) && (iaprefix.len >= IAPREFIX_OFFSET)) {
6233 /*
6234 * Find existing IA_PD.
6235 */
6236 if (ia_make_key(&key, iaid,
6237 (char *)client_id->data,
6238 client_id->len,
6239 MDL) != ISC_R_SUCCESS) {
6240 log_fatal("iterate_over_ia_pd: no memory for "
6241 "key.");
6242 }
6243
6244 existing_ia_pd = NULL;
6245 if (ia_hash_lookup(&existing_ia_pd, ia_pd_active,
6246 (unsigned char *)key.data,
6247 key.len, MDL)) {
6248 /*
6249 * Make sure this prefix is in the IA_PD.
6250 */
6251 for (i = 0;
6252 i < existing_ia_pd->num_iasubopt;
6253 i++) {
6254 struct iasubopt *tmp;
6255 u_int8_t plen;
6256
6257 plen = getUChar(iaprefix.data + 8);
6258 tmp = existing_ia_pd->iasubopt[i];
6259 if ((tmp->plen == plen) &&
6260 (memcmp(&tmp->addr,
6261 iaprefix.data + 9,
6262 16) == 0)) {
6263 iasubopt_reference(&prefix,
6264 tmp, MDL);
6265 break;
6266 }
6267 }
6268 }
6269
6270 data_string_forget(&key, MDL);
6271 }
6272
6273 if ((host != NULL) || (prefix != NULL)) {
6274 ia_pd_match(client_id, &iaprefix, prefix);
6275 } else {
6276 ia_pd_nomatch(client_id, &iaprefix,
6277 (u_int32_t *)cli_enc_opt_data.data,
6278 packet, reply_data, &reply_ofs,
6279 reply_len - reply_ofs);
6280 }
6281
6282 if (prefix != NULL) {
6283 iasubopt_dereference(&prefix, MDL);
6284 }
6285
6286 data_string_forget(&iaprefix, MDL);
6287 }
6288
6289 option_state_dereference(&cli_enc_opt_state, MDL);
6290 data_string_forget(&cli_enc_opt_data, MDL);
6291 }
6292
6293 /*
6294 * Return our reply to the caller.
6295 * The IA_NA routine has already filled at least the header.
6296 */
6297 reply_new.len = reply_ret->len + reply_ofs;
6298 if (!buffer_allocate(&reply_new.buffer, reply_new.len, MDL)) {
6299 log_fatal("No memory to store reply.");
6300 }
6301 reply_new.data = reply_new.buffer->data;
6302 memcpy(reply_new.buffer->data,
6303 reply_ret->buffer->data, reply_ret->len);
6304 memcpy(reply_new.buffer->data + reply_ret->len,
6305 reply_data, reply_ofs);
6306 data_string_forget(reply_ret, MDL);
6307 data_string_copy(reply_ret, &reply_new, MDL);
6308 data_string_forget(&reply_new, MDL);
6309
6310 exit:
6311 if (prefix != NULL) {
6312 iasubopt_dereference(&prefix, MDL);
6313 }
6314 if (iaprefix.buffer != NULL) {
6315 data_string_forget(&iaprefix, MDL);
6316 }
6317 if (cli_enc_opt_state != NULL) {
6318 option_state_dereference(&cli_enc_opt_state, MDL);
6319 }
6320 if (cli_enc_opt_data.buffer != NULL) {
6321 data_string_forget(&cli_enc_opt_data, MDL);
6322 }
6323 if (opt_state != NULL) {
6324 option_state_dereference(&opt_state, MDL);
6325 }
6326 }
6327
6328 /*
6329 * Release means a client is done with the leases.
6330 */
6331
6332 static void
6333 dhcpv6_release(struct data_string *reply, struct packet *packet) {
6334 struct data_string client_id;
6335 struct data_string server_id;
6336
6337 /*
6338 * Validate our input.
6339 */
6340 if (!valid_client_resp(packet, &client_id, &server_id)) {
6341 return;
6342 }
6343
6344 /* If the RELEASE arrived via unicast and unicast option isn't set,
6345 * reject it per RFC 3315, Sec 18.2.6 */
6346 if (packet->unicast == ISC_TRUE &&
6347 is_unicast_option_defined(packet) == ISC_FALSE) {
6348 unicast_reject(reply, packet, &client_id, &server_id);
6349 } else {
6350 /*
6351 * And operate on each IA_NA in this packet.
6352 */
6353 iterate_over_ia_na(reply, packet, &client_id, &server_id,
6354 "Release", ia_na_match_release,
6355 ia_na_nomatch_release);
6356
6357 /*
6358 * And operate on each IA_PD in this packet.
6359 */
6360 iterate_over_ia_pd(reply, packet, &client_id, &server_id,
6361 "Release", ia_pd_match_release,
6362 ia_pd_nomatch_release);
6363 }
6364
6365 data_string_forget(&server_id, MDL);
6366 data_string_forget(&client_id, MDL);
6367 }
6368
6369 /*
6370 * Information-Request is used by clients who have obtained an address
6371 * from other means, but want configuration information from the server.
6372 */
6373
6374 static void
6375 dhcpv6_information_request(struct data_string *reply, struct packet *packet) {
6376 struct data_string client_id;
6377 struct data_string server_id;
6378
6379 /*
6380 * Validate our input.
6381 */
6382 if (!valid_client_info_req(packet, &server_id)) {
6383 return;
6384 }
6385
6386 /*
6387 * Get our client ID, if there is one.
6388 */
6389 memset(&client_id, 0, sizeof(client_id));
6390 if (get_client_id(packet, &client_id) != ISC_R_SUCCESS) {
6391 data_string_forget(&client_id, MDL);
6392 }
6393
6394 /*
6395 * Use the lease_to_client() function. This will work fine,
6396 * because the valid_client_info_req() insures that we
6397 * don't have any IA that would cause us to allocate
6398 * resources to the client.
6399 */
6400 lease_to_client(reply, packet, &client_id,
6401 server_id.data != NULL ? &server_id : NULL);
6402
6403 /*
6404 * Cleanup.
6405 */
6406 if (client_id.data != NULL) {
6407 data_string_forget(&client_id, MDL);
6408 }
6409 data_string_forget(&server_id, MDL);
6410 }
6411
6412 /*
6413 * The Relay-forw message is sent by relays. It typically contains a
6414 * single option, which encapsulates an entire packet.
6415 *
6416 * We need to build an encapsulated reply.
6417 */
6418
6419 /* XXX: this is very, very similar to do_packet6(), and should probably
6420 be combined in a clever way */
6421 /* DHCPv6 server side */
6422 static void
6423 dhcpv6_relay_forw(struct data_string *reply_ret, struct packet *packet) {
6424 struct option_cache *oc;
6425 struct data_string enc_opt_data;
6426 struct packet *enc_packet;
6427 unsigned char msg_type;
6428 const struct dhcpv6_packet *msg;
6429 const struct dhcpv6_relay_packet *relay;
6430 struct data_string enc_reply;
6431 char link_addr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6432 char peer_addr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6433 struct data_string a_opt, packet_ero;
6434 struct option_state *opt_state;
6435 static char reply_data[65536];
6436 struct dhcpv6_relay_packet *reply;
6437 int reply_ofs;
6438
6439 /*
6440 * Initialize variables for early exit.
6441 */
6442 opt_state = NULL;
6443 memset(&a_opt, 0, sizeof(a_opt));
6444 memset(&packet_ero, 0, sizeof(packet_ero));
6445 memset(&enc_reply, 0, sizeof(enc_reply));
6446 memset(&enc_opt_data, 0, sizeof(enc_opt_data));
6447 enc_packet = NULL;
6448
6449 /*
6450 * Get our encapsulated relay message.
6451 */
6452 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_RELAY_MSG);
6453 if (oc == NULL) {
6454 inet_ntop(AF_INET6, &packet->dhcpv6_link_address,
6455 link_addr, sizeof(link_addr));
6456 inet_ntop(AF_INET6, &packet->dhcpv6_peer_address,
6457 peer_addr, sizeof(peer_addr));
6458 log_info("Relay-forward from %s with link address=%s and "
6459 "peer address=%s missing Relay Message option.",
6460 piaddr(packet->client_addr), link_addr, peer_addr);
6461 goto exit;
6462 }
6463
6464 if (!evaluate_option_cache(&enc_opt_data, NULL, NULL, NULL,
6465 NULL, NULL, &global_scope, oc, MDL)) {
6466 /* should be dhcpv6_relay_forw */
6467 log_error("dhcpv6_forw_relay: error evaluating "
6468 "relayed message.");
6469 goto exit;
6470 }
6471
6472 if (!packet6_len_okay((char *)enc_opt_data.data, enc_opt_data.len)) {
6473 /* should be dhcpv6_relay_forw */
6474 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
6475 goto exit;
6476 }
6477
6478 /*
6479 * Build a packet structure from this encapsulated packet.
6480 */
6481 enc_packet = NULL;
6482 if (!packet_allocate(&enc_packet, MDL)) {
6483 /* should be dhcpv6_relay_forw */
6484 log_error("dhcpv6_forw_relay: "
6485 "no memory for encapsulated packet.");
6486 goto exit;
6487 }
6488
6489 if (!option_state_allocate(&enc_packet->options, MDL)) {
6490 /* should be dhcpv6_relay_forw */
6491 log_error("dhcpv6_forw_relay: "
6492 "no memory for encapsulated packet's options.");
6493 goto exit;
6494 }
6495
6496 enc_packet->client_port = packet->client_port;
6497 enc_packet->client_addr = packet->client_addr;
6498 interface_reference(&enc_packet->interface, packet->interface, MDL);
6499 enc_packet->dhcpv6_container_packet = packet;
6500
6501 msg_type = enc_opt_data.data[0];
6502 if ((msg_type == DHCPV6_RELAY_FORW) ||
6503 (msg_type == DHCPV6_RELAY_REPL)) {
6504 int relaylen = (int)(offsetof(struct dhcpv6_relay_packet, options));
6505 relay = (struct dhcpv6_relay_packet *)enc_opt_data.data;
6506 enc_packet->dhcpv6_msg_type = relay->msg_type;
6507
6508 /* relay-specific data */
6509 enc_packet->dhcpv6_hop_count = relay->hop_count;
6510 memcpy(&enc_packet->dhcpv6_link_address,
6511 relay->link_address, sizeof(relay->link_address));
6512 memcpy(&enc_packet->dhcpv6_peer_address,
6513 relay->peer_address, sizeof(relay->peer_address));
6514
6515 if (!parse_option_buffer(enc_packet->options,
6516 relay->options,
6517 enc_opt_data.len - relaylen,
6518 &dhcpv6_universe)) {
6519 /* no logging here, as parse_option_buffer() logs all
6520 cases where it fails */
6521 goto exit;
6522 }
6523 } else if ((msg_type == DHCPV6_DHCPV4_QUERY) ||
6524 (msg_type == DHCPV6_DHCPV4_RESPONSE)) {
6525 #ifdef DHCP4o6
6526 if (!dhcpv4_over_dhcpv6 ||
6527 (msg_type == DHCPV6_DHCPV4_RESPONSE)) {
6528 log_error("dhcpv6_relay_forw: "
6529 "unsupported %s message type.",
6530 dhcpv6_type_names[msg_type]);
6531 goto exit;
6532 }
6533 forw_dhcpv4_query(packet);
6534 goto exit;
6535 #else /* DHCP4o6 */
6536 log_error("dhcpv6_relay_forw: unsupported %s message type.",
6537 dhcpv6_type_names[msg_type]);
6538 goto exit;
6539 #endif /* DHCP4o6 */
6540 } else {
6541 int msglen = (int)(offsetof(struct dhcpv6_packet, options));
6542 msg = (struct dhcpv6_packet *)enc_opt_data.data;
6543 enc_packet->dhcpv6_msg_type = msg->msg_type;
6544
6545 /* message-specific data */
6546 memcpy(enc_packet->dhcpv6_transaction_id,
6547 msg->transaction_id,
6548 sizeof(enc_packet->dhcpv6_transaction_id));
6549
6550 if (!parse_option_buffer(enc_packet->options,
6551 msg->options,
6552 enc_opt_data.len - msglen,
6553 &dhcpv6_universe)) {
6554 /* no logging here, as parse_option_buffer() logs all
6555 cases where it fails */
6556 goto exit;
6557 }
6558 }
6559
6560 /*
6561 * This is recursive. It is possible to exceed maximum packet size.
6562 * XXX: This will cause the packet send to fail.
6563 */
6564 build_dhcpv6_reply(&enc_reply, enc_packet);
6565
6566 /*
6567 * If we got no encapsulated data, then it is discarded, and
6568 * our reply-forw is also discarded.
6569 */
6570 if (enc_reply.data == NULL) {
6571 goto exit;
6572 }
6573
6574 /*
6575 * Now we can use the reply_data buffer.
6576 * Packet header stuff all comes from the forward message.
6577 */
6578 reply = (struct dhcpv6_relay_packet *)reply_data;
6579 reply->msg_type = DHCPV6_RELAY_REPL;
6580 reply->hop_count = packet->dhcpv6_hop_count;
6581 memcpy(reply->link_address, &packet->dhcpv6_link_address,
6582 sizeof(reply->link_address));
6583 memcpy(reply->peer_address, &packet->dhcpv6_peer_address,
6584 sizeof(reply->peer_address));
6585 reply_ofs = (int)(offsetof(struct dhcpv6_relay_packet, options));
6586
6587 /*
6588 * Get the reply option state.
6589 */
6590 opt_state = NULL;
6591 if (!option_state_allocate(&opt_state, MDL)) {
6592 log_error("dhcpv6_relay_forw: no memory for option state.");
6593 goto exit;
6594 }
6595
6596 /*
6597 * Append the interface-id if present.
6598 */
6599 oc = lookup_option(&dhcpv6_universe, packet->options,
6600 D6O_INTERFACE_ID);
6601 if (oc != NULL) {
6602 if (!evaluate_option_cache(&a_opt, packet,
6603 NULL, NULL,
6604 packet->options, NULL,
6605 &global_scope, oc, MDL)) {
6606 log_error("dhcpv6_relay_forw: error evaluating "
6607 "Interface ID.");
6608 goto exit;
6609 }
6610 if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
6611 (unsigned char *)a_opt.data,
6612 a_opt.len,
6613 D6O_INTERFACE_ID, 0)) {
6614 log_error("dhcpv6_relay_forw: error saving "
6615 "Interface ID.");
6616 goto exit;
6617 }
6618 data_string_forget(&a_opt, MDL);
6619 }
6620
6621 /*
6622 * Append our encapsulated stuff for caller.
6623 */
6624 if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
6625 (unsigned char *)enc_reply.data,
6626 enc_reply.len,
6627 D6O_RELAY_MSG, 0)) {
6628 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
6629 goto exit;
6630 }
6631
6632 /*
6633 * Get the ERO if any.
6634 */
6635 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_ERO);
6636 if (oc != NULL) {
6637 unsigned req;
6638 int i;
6639
6640 if (!evaluate_option_cache(&packet_ero, packet,
6641 NULL, NULL,
6642 packet->options, NULL,
6643 &global_scope, oc, MDL) ||
6644 (packet_ero.len & 1)) {
6645 log_error("dhcpv6_relay_forw: error evaluating ERO.");
6646 goto exit;
6647 }
6648
6649 /* Decode and apply the ERO. */
6650 for (i = 0; i < packet_ero.len; i += 2) {
6651 req = getUShort(packet_ero.data + i);
6652 /* Already in the reply? */
6653 oc = lookup_option(&dhcpv6_universe, opt_state, req);
6654 if (oc != NULL)
6655 continue;
6656 /* Get it from the packet if present. */
6657 oc = lookup_option(&dhcpv6_universe,
6658 packet->options,
6659 req);
6660 if (oc == NULL)
6661 continue;
6662 if (!evaluate_option_cache(&a_opt, packet,
6663 NULL, NULL,
6664 packet->options, NULL,
6665 &global_scope, oc, MDL)) {
6666 log_error("dhcpv6_relay_forw: error "
6667 "evaluating option %u.", req);
6668 goto exit;
6669 }
6670 if (!save_option_buffer(&dhcpv6_universe,
6671 opt_state,
6672 NULL,
6673 (unsigned char *)a_opt.data,
6674 a_opt.len,
6675 req,
6676 0)) {
6677 log_error("dhcpv6_relay_forw: error saving "
6678 "option %u.", req);
6679 goto exit;
6680 }
6681 data_string_forget(&a_opt, MDL);
6682 }
6683 }
6684
6685 reply_ofs += store_options6(reply_data + reply_ofs,
6686 sizeof(reply_data) - reply_ofs,
6687 opt_state, packet,
6688 required_opts_agent, &packet_ero);
6689
6690 /*
6691 * Return our reply to the caller.
6692 */
6693 reply_ret->len = reply_ofs;
6694 reply_ret->buffer = NULL;
6695 if (!buffer_allocate(&reply_ret->buffer, reply_ret->len, MDL)) {
6696 log_fatal("No memory to store reply.");
6697 }
6698 reply_ret->data = reply_ret->buffer->data;
6699 memcpy(reply_ret->buffer->data, reply_data, reply_ofs);
6700
6701 exit:
6702 if (opt_state != NULL)
6703 option_state_dereference(&opt_state, MDL);
6704 if (a_opt.data != NULL) {
6705 data_string_forget(&a_opt, MDL);
6706 }
6707 if (packet_ero.data != NULL) {
6708 data_string_forget(&packet_ero, MDL);
6709 }
6710 if (enc_reply.data != NULL) {
6711 data_string_forget(&enc_reply, MDL);
6712 }
6713 if (enc_opt_data.data != NULL) {
6714 data_string_forget(&enc_opt_data, MDL);
6715 }
6716 if (enc_packet != NULL) {
6717 packet_dereference(&enc_packet, MDL);
6718 }
6719 }
6720
6721 #ifdef DHCP4o6
6722 /* \brief Internal processing of a relayed DHCPv4-query
6723 * (DHCPv4 server side)
6724 *
6725 * Code copied from \ref dhcpv6_relay_forw() which itself is
6726 * from \ref do_packet6().
6727 *
6728 * \param reply_ret pointer to the response
6729 * \param packet the query
6730 */
6731 static void
6732 dhcp4o6_relay_forw(struct data_string *reply_ret, struct packet *packet) {
6733 struct option_cache *oc;
6734 struct data_string enc_opt_data;
6735 struct packet *enc_packet;
6736 unsigned char msg_type;
6737 const struct dhcpv6_relay_packet *relay;
6738 const struct dhcpv4_over_dhcpv6_packet *msg;
6739 struct data_string enc_reply;
6740 char link_addr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6741 char peer_addr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6742 struct data_string a_opt, packet_ero;
6743 struct option_state *opt_state;
6744 static char reply_data[65536];
6745 struct dhcpv6_relay_packet *reply;
6746 int reply_ofs;
6747
6748 /*
6749 * Initialize variables for early exit.
6750 */
6751 opt_state = NULL;
6752 memset(&a_opt, 0, sizeof(a_opt));
6753 memset(&packet_ero, 0, sizeof(packet_ero));
6754 memset(&enc_reply, 0, sizeof(enc_reply));
6755 memset(&enc_opt_data, 0, sizeof(enc_opt_data));
6756 enc_packet = NULL;
6757
6758 /*
6759 * Get our encapsulated relay message.
6760 */
6761 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_RELAY_MSG);
6762 if (oc == NULL) {
6763 inet_ntop(AF_INET6, &packet->dhcpv6_link_address,
6764 link_addr, sizeof(link_addr));
6765 inet_ntop(AF_INET6, &packet->dhcpv6_peer_address,
6766 peer_addr, sizeof(peer_addr));
6767 log_info("Relay-forward from %s with link address=%s and "
6768 "peer address=%s missing Relay Message option.",
6769 piaddr(packet->client_addr), link_addr, peer_addr);
6770 goto exit;
6771 }
6772
6773 if (!evaluate_option_cache(&enc_opt_data, NULL, NULL, NULL,
6774 NULL, NULL, &global_scope, oc, MDL)) {
6775 log_error("dhcp4o6_relay_forw: error evaluating "
6776 "relayed message.");
6777 goto exit;
6778 }
6779
6780 if (!packet6_len_okay((char *)enc_opt_data.data, enc_opt_data.len)) {
6781 log_error("dhcp4o6_relay_forw: "
6782 "encapsulated packet too short.");
6783 goto exit;
6784 }
6785
6786 /*
6787 * Build a packet structure from this encapsulated packet.
6788 */
6789 if (!packet_allocate(&enc_packet, MDL)) {
6790 log_error("dhcp4o6_relay_forw: "
6791 "no memory for encapsulated packet.");
6792 goto exit;
6793 }
6794
6795 if (!option_state_allocate(&enc_packet->options, MDL)) {
6796 log_error("dhcp4o6_relay_forw: "
6797 "no memory for encapsulated packet's options.");
6798 goto exit;
6799 }
6800
6801 enc_packet->client_port = packet->client_port;
6802 enc_packet->client_addr = packet->client_addr;
6803 interface_reference(&enc_packet->interface, packet->interface, MDL);
6804 enc_packet->dhcpv6_container_packet = packet;
6805
6806 msg_type = enc_opt_data.data[0];
6807 if ((msg_type == DHCPV6_RELAY_FORW) ||
6808 (msg_type == DHCPV6_RELAY_REPL)) {
6809 int relaylen = (int)(offsetof(struct dhcpv6_relay_packet, options));
6810 relay = (struct dhcpv6_relay_packet *)enc_opt_data.data;
6811 enc_packet->dhcpv6_msg_type = relay->msg_type;
6812
6813 /* relay-specific data */
6814 enc_packet->dhcpv6_hop_count = relay->hop_count;
6815 memcpy(&enc_packet->dhcpv6_link_address,
6816 relay->link_address, sizeof(relay->link_address));
6817 memcpy(&enc_packet->dhcpv6_peer_address,
6818 relay->peer_address, sizeof(relay->peer_address));
6819
6820 if (!parse_option_buffer(enc_packet->options,
6821 relay->options,
6822 enc_opt_data.len - relaylen,
6823 &dhcpv6_universe)) {
6824 /* no logging here, as parse_option_buffer() logs all
6825 cases where it fails */
6826 goto exit;
6827 }
6828 } else if ((msg_type == DHCPV6_DHCPV4_QUERY) ||
6829 (msg_type == DHCPV6_DHCPV4_RESPONSE)) {
6830 int msglen =
6831 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet, options));
6832 msg = (struct dhcpv4_over_dhcpv6_packet *)enc_opt_data.data;
6833 enc_packet->dhcpv6_msg_type = msg->msg_type;
6834
6835 /* message-specific data */
6836 memcpy(enc_packet->dhcp4o6_flags,
6837 msg->flags,
6838 sizeof(enc_packet->dhcp4o6_flags));
6839
6840 if (!parse_option_buffer(enc_packet->options,
6841 msg->options,
6842 enc_opt_data.len - msglen,
6843 &dhcpv6_universe)) {
6844 /* no logging here, as parse_option_buffer() logs all
6845 cases where it fails */
6846 goto exit;
6847 }
6848 } else {
6849 log_error("dhcp4o6_relay_forw: unexpected message of type %d.",
6850 (int)msg_type);
6851 goto exit;
6852 }
6853
6854 /*
6855 * This is recursive. It is possible to exceed maximum packet size.
6856 * XXX: This will cause the packet send to fail.
6857 */
6858 build_dhcpv6_reply(&enc_reply, enc_packet);
6859
6860 /*
6861 * If we got no encapsulated data, then it is discarded, and
6862 * our reply-forw is also discarded.
6863 */
6864 if (enc_reply.data == NULL) {
6865 goto exit;
6866 }
6867
6868 /*
6869 * Now we can use the reply_data buffer.
6870 * Packet header stuff all comes from the forward message.
6871 */
6872 reply = (struct dhcpv6_relay_packet *)reply_data;
6873 reply->msg_type = DHCPV6_RELAY_REPL;
6874 reply->hop_count = packet->dhcpv6_hop_count;
6875 memcpy(reply->link_address, &packet->dhcpv6_link_address,
6876 sizeof(reply->link_address));
6877 memcpy(reply->peer_address, &packet->dhcpv6_peer_address,
6878 sizeof(reply->peer_address));
6879 reply_ofs = (int)(offsetof(struct dhcpv6_relay_packet, options));
6880
6881 /*
6882 * Get the reply option state.
6883 */
6884 if (!option_state_allocate(&opt_state, MDL)) {
6885 log_error("dhcp4o6_relay_forw: no memory for option state.");
6886 goto exit;
6887 }
6888
6889 /*
6890 * Append the interface-id if present.
6891 */
6892 oc = lookup_option(&dhcpv6_universe, packet->options,
6893 D6O_INTERFACE_ID);
6894 if (oc != NULL) {
6895 if (!evaluate_option_cache(&a_opt, packet,
6896 NULL, NULL,
6897 packet->options, NULL,
6898 &global_scope, oc, MDL)) {
6899 log_error("dhcp4o6_relay_forw: error evaluating "
6900 "Interface ID.");
6901 goto exit;
6902 }
6903 if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
6904 (unsigned char *)a_opt.data,
6905 a_opt.len,
6906 D6O_INTERFACE_ID, 0)) {
6907 log_error("dhcp4o6_relay_forw: error saving "
6908 "Interface ID.");
6909 goto exit;
6910 }
6911 data_string_forget(&a_opt, MDL);
6912 }
6913
6914 /*
6915 * Append our encapsulated stuff for caller.
6916 */
6917 if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
6918 (unsigned char *)enc_reply.data,
6919 enc_reply.len,
6920 D6O_RELAY_MSG, 0)) {
6921 log_error("dhcp4o6_relay_forw: error saving Relay MSG.");
6922 goto exit;
6923 }
6924
6925 /*
6926 * Get the ERO if any.
6927 */
6928 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_ERO);
6929 if (oc != NULL) {
6930 unsigned req;
6931 int i;
6932
6933 if (!evaluate_option_cache(&packet_ero, packet,
6934 NULL, NULL,
6935 packet->options, NULL,
6936 &global_scope, oc, MDL) ||
6937 (packet_ero.len & 1)) {
6938 log_error("dhcp4o6_relay_forw: error evaluating ERO.");
6939 goto exit;
6940 }
6941
6942 /* Decode and apply the ERO. */
6943 for (i = 0; i < packet_ero.len; i += 2) {
6944 req = getUShort(packet_ero.data + i);
6945 /* Already in the reply? */
6946 oc = lookup_option(&dhcpv6_universe, opt_state, req);
6947 if (oc != NULL)
6948 continue;
6949 /* Get it from the packet if present. */
6950 oc = lookup_option(&dhcpv6_universe,
6951 packet->options,
6952 req);
6953 if (oc == NULL)
6954 continue;
6955 if (!evaluate_option_cache(&a_opt, packet,
6956 NULL, NULL,
6957 packet->options, NULL,
6958 &global_scope, oc, MDL)) {
6959 log_error("dhcp4o6_relay_forw: error "
6960 "evaluating option %u.", req);
6961 goto exit;
6962 }
6963 if (!save_option_buffer(&dhcpv6_universe,
6964 opt_state,
6965 NULL,
6966 (unsigned char *)a_opt.data,
6967 a_opt.len,
6968 req,
6969 0)) {
6970 log_error("dhcp4o6_relay_forw: error saving "
6971 "option %u.", req);
6972 goto exit;
6973 }
6974 data_string_forget(&a_opt, MDL);
6975 }
6976 }
6977
6978 reply_ofs += store_options6(reply_data + reply_ofs,
6979 sizeof(reply_data) - reply_ofs,
6980 opt_state, packet,
6981 required_opts_agent, &packet_ero);
6982
6983 /*
6984 * Return our reply to the caller.
6985 */
6986 reply_ret->len = reply_ofs;
6987 reply_ret->buffer = NULL;
6988 if (!buffer_allocate(&reply_ret->buffer, reply_ret->len, MDL)) {
6989 log_fatal("No memory to store reply.");
6990 }
6991 reply_ret->data = reply_ret->buffer->data;
6992 memcpy(reply_ret->buffer->data, reply_data, reply_ofs);
6993
6994 exit:
6995 if (opt_state != NULL)
6996 option_state_dereference(&opt_state, MDL);
6997 if (a_opt.data != NULL) {
6998 data_string_forget(&a_opt, MDL);
6999 }
7000 if (packet_ero.data != NULL) {
7001 data_string_forget(&packet_ero, MDL);
7002 }
7003 if (enc_reply.data != NULL) {
7004 data_string_forget(&enc_reply, MDL);
7005 }
7006 if (enc_opt_data.data != NULL) {
7007 data_string_forget(&enc_opt_data, MDL);
7008 }
7009 if (enc_packet != NULL) {
7010 packet_dereference(&enc_packet, MDL);
7011 }
7012 }
7013
7014 /*
7015 * \brief Internal processing of a DHCPv4-query
7016 * (DHCPv4 server function)
7017 *
7018 * Code copied from \ref do_packet().
7019 *
7020 * \param reply_ret pointer to the response
7021 * \param packet the query
7022 */
7023 static void
7024 dhcp4o6_dhcpv4_query(struct data_string *reply_ret, struct packet *packet) {
7025 struct option_cache *oc;
7026 struct data_string enc_opt_data;
7027 struct packet *enc_packet;
7028 struct data_string enc_response;
7029 struct option_state *opt_state;
7030 static char response_data[65536];
7031 struct dhcpv4_over_dhcpv6_packet *response;
7032 int response_ofs;
7033
7034 /*
7035 * Initialize variables for early exit.
7036 */
7037 opt_state = NULL;
7038 memset(&enc_response, 0, sizeof(enc_response));
7039 memset(&enc_opt_data, 0, sizeof(enc_opt_data));
7040 enc_packet = NULL;
7041
7042 /*
7043 * Get our encapsulated relay message.
7044 */
7045 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_DHCPV4_MSG);
7046 if (oc == NULL) {
7047 log_info("DHCPv4-query from %s missing DHCPv4 Message option.",
7048 piaddr(packet->client_addr));
7049 goto exit;
7050 }
7051
7052 if (!evaluate_option_cache(&enc_opt_data, NULL, NULL, NULL,
7053 NULL, NULL, &global_scope, oc, MDL)) {
7054 log_error("dhcp4o6_dhcpv4_query: error evaluating "
7055 "DHCPv4 message.");
7056 goto exit;
7057 }
7058
7059 if (enc_opt_data.len < DHCP_FIXED_NON_UDP) {
7060 log_error("dhcp4o6_dhcpv4_query: DHCPv4 packet too short.");
7061 goto exit;
7062 }
7063
7064 /*
7065 * Build a packet structure from this encapsulated packet.
7066 */
7067 if (!packet_allocate(&enc_packet, MDL)) {
7068 log_error("dhcp4o6_dhcpv4_query: "
7069 "no memory for encapsulated packet.");
7070 goto exit;
7071 }
7072
7073 enc_packet->raw = (struct dhcp_packet *)enc_opt_data.data;
7074 enc_packet->packet_length = enc_opt_data.len;
7075 enc_packet->dhcp4o6_response = &enc_response;
7076 enc_packet->client_port = packet->client_port;
7077 enc_packet->client_addr = packet->client_addr;
7078 interface_reference(&enc_packet->interface, packet->interface, MDL);
7079 enc_packet->dhcpv6_container_packet = packet;
7080 if (packet->dhcp4o6_flags[0] & DHCP4O6_QUERY_UNICAST)
7081 enc_packet->unicast = 1;
7082
7083 if (enc_packet->raw->hlen > sizeof(enc_packet->raw->chaddr)) {
7084 log_info("dhcp4o6_dhcpv4_query: "
7085 "discarding packet with bogus hlen.");
7086 goto exit;
7087 }
7088
7089 /* Allocate packet->options now so it is non-null for all packets */
7090 if (!option_state_allocate (&enc_packet->options, MDL)) {
7091 log_error("dhcp4o6_dhcpv4_query: no memory for options.");
7092 goto exit;
7093 }
7094
7095 /* If there's an option buffer, try to parse it. */
7096 if (enc_packet->packet_length >= DHCP_FIXED_NON_UDP + 4) {
7097 struct option_cache *op;
7098 if (!parse_options(enc_packet)) {
7099 if (enc_packet->options)
7100 option_state_dereference
7101 (&enc_packet->options, MDL);
7102 packet_dereference (&enc_packet, MDL);
7103 goto exit;
7104 }
7105
7106 if (enc_packet->options_valid &&
7107 (op = lookup_option(&dhcp_universe,
7108 enc_packet->options,
7109 DHO_DHCP_MESSAGE_TYPE))) {
7110 struct data_string dp;
7111 memset(&dp, 0, sizeof dp);
7112 evaluate_option_cache(&dp, enc_packet, NULL, NULL,
7113 enc_packet->options, NULL,
7114 NULL, op, MDL);
7115 if (dp.len > 0)
7116 enc_packet->packet_type = dp.data[0];
7117 else
7118 enc_packet->packet_type = 0;
7119 data_string_forget(&dp, MDL);
7120 }
7121 }
7122
7123 if (validate_packet(enc_packet) != 0) {
7124 if (enc_packet->packet_type)
7125 dhcp(enc_packet);
7126 else
7127 bootp(enc_packet);
7128 }
7129
7130 /* If the caller kept the packet, they'll have upped the refcnt. */
7131 packet_dereference(&enc_packet, MDL);
7132
7133 /*
7134 * If we got no response data, then it is discarded, and
7135 * our DHCPv4-response is also discarded.
7136 */
7137 if (enc_response.data == NULL) {
7138 goto exit;
7139 }
7140
7141 /*
7142 * Now we can use the response_data buffer.
7143 */
7144 response = (struct dhcpv4_over_dhcpv6_packet *)response_data;
7145 response->msg_type = DHCPV6_DHCPV4_RESPONSE;
7146 response->flags[0] = response->flags[1] = response->flags[2] = 0;
7147 response_ofs =
7148 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet, options));
7149
7150 /*
7151 * Get the response option state.
7152 */
7153 if (!option_state_allocate(&opt_state, MDL)) {
7154 log_error("dhcp4o6_dhcpv4_query: no memory for option state.");
7155 goto exit;
7156 }
7157
7158 /*
7159 * Append our encapsulated stuff for caller.
7160 */
7161 if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
7162 (unsigned char *)enc_response.data,
7163 enc_response.len,
7164 D6O_DHCPV4_MSG, 0)) {
7165 log_error("dhcp4o6_dhcpv4_query: error saving DHCPv4 MSG.");
7166 goto exit;
7167 }
7168
7169 response_ofs += store_options6(response_data + response_ofs,
7170 sizeof(response_data) - response_ofs,
7171 opt_state, packet,
7172 required_opts_4o6, NULL);
7173
7174 /*
7175 * Return our response to the caller.
7176 */
7177 reply_ret->len = response_ofs;
7178 reply_ret->buffer = NULL;
7179 if (!buffer_allocate(&reply_ret->buffer, reply_ret->len, MDL)) {
7180 log_fatal("dhcp4o6_dhcpv4_query: no memory to store reply.");
7181 }
7182 reply_ret->data = reply_ret->buffer->data;
7183 memcpy(reply_ret->buffer->data, response_data, response_ofs);
7184
7185 exit:
7186 if (opt_state != NULL)
7187 option_state_dereference(&opt_state, MDL);
7188 if (enc_response.data != NULL) {
7189 data_string_forget(&enc_response, MDL);
7190 }
7191 if (enc_opt_data.data != NULL) {
7192 data_string_forget(&enc_opt_data, MDL);
7193 }
7194 if (enc_packet != NULL) {
7195 packet_dereference(&enc_packet, MDL);
7196 }
7197 }
7198
7199 /*
7200 * \brief Forward a DHCPv4-query message to the DHCPv4 side
7201 * (DHCPv6 server function)
7202 *
7203 * Format: interface:16 + address:16 + DHCPv6 DHCPv4-query message
7204 *
7205 * \brief packet the DHCPv6 DHCPv4-query message
7206 */
7207 static void forw_dhcpv4_query(struct packet *packet) {
7208 struct data_string ds;
7209 unsigned len;
7210 int cc;
7211
7212 /* Get the initial message. */
7213 while (packet->dhcpv6_container_packet != NULL)
7214 packet = packet->dhcpv6_container_packet;
7215
7216 /* Check the initial message. */
7217 if ((packet->raw == NULL) ||
7218 (packet->client_addr.len != 16) ||
7219 (packet->interface == NULL)) {
7220 log_error("forw_dhcpv4_query: can't find initial message.");
7221 return;
7222 }
7223
7224 /* Get a buffer. */
7225 len = packet->packet_length + 32;
7226 memset(&ds, 0, sizeof(ds));
7227 if (!buffer_allocate(&ds.buffer, len, MDL)) {
7228 log_error("forw_dhcpv4_query: "
7229 "no memory for encapsulating packet.");
7230 return;
7231 }
7232 ds.data = ds.buffer->data;
7233 ds.len = len;
7234
7235 /* Fill the buffer. */
7236 strncpy((char *)ds.buffer->data, packet->interface->name, 16);
7237 memcpy(ds.buffer->data + 16,
7238 packet->client_addr.iabuf, 16);
7239 memcpy(ds.buffer->data + 32,
7240 (unsigned char *)packet->raw,
7241 packet->packet_length);
7242
7243 /* Forward to the DHCPv4 server. */
7244 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
7245 if (cc < 0)
7246 log_error("forw_dhcpv4_query: send(): %m");
7247 data_string_forget(&ds, MDL);
7248 }
7249 #endif
7250
7251 static void
7252 dhcpv6_discard(struct packet *packet) {
7253 /* INSIST(packet->msg_type > 0); */
7254 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
7255
7256 log_debug("Discarding %s from %s; message type not handled by server",
7257 dhcpv6_type_names[packet->dhcpv6_msg_type],
7258 piaddr(packet->client_addr));
7259 }
7260
7261 static void
7262 build_dhcpv6_reply(struct data_string *reply, struct packet *packet) {
7263 memset(reply, 0, sizeof(*reply));
7264
7265 /* I would like to classify the client once here, but
7266 * as I don't want to classify all of the incoming packets
7267 * I need to do it before handling specific types.
7268 * We don't need to classify if we are tossing the packet
7269 * or if it is a relay - the classification step will get
7270 * done when we process the inner client packet.
7271 */
7272
7273 switch (packet->dhcpv6_msg_type) {
7274 case DHCPV6_SOLICIT:
7275 classify_client(packet);
7276 dhcpv6_solicit(reply, packet);
7277 break;
7278 case DHCPV6_ADVERTISE:
7279 dhcpv6_discard(packet);
7280 break;
7281 case DHCPV6_REQUEST:
7282 classify_client(packet);
7283 dhcpv6_request(reply, packet);
7284 break;
7285 case DHCPV6_CONFIRM:
7286 classify_client(packet);
7287 dhcpv6_confirm(reply, packet);
7288 break;
7289 case DHCPV6_RENEW:
7290 classify_client(packet);
7291 dhcpv6_renew(reply, packet);
7292 break;
7293 case DHCPV6_REBIND:
7294 classify_client(packet);
7295 dhcpv6_rebind(reply, packet);
7296 break;
7297 case DHCPV6_REPLY:
7298 dhcpv6_discard(packet);
7299 break;
7300 case DHCPV6_RELEASE:
7301 classify_client(packet);
7302 dhcpv6_release(reply, packet);
7303 break;
7304 case DHCPV6_DECLINE:
7305 classify_client(packet);
7306 dhcpv6_decline(reply, packet);
7307 break;
7308 case DHCPV6_RECONFIGURE:
7309 dhcpv6_discard(packet);
7310 break;
7311 case DHCPV6_INFORMATION_REQUEST:
7312 classify_client(packet);
7313 dhcpv6_information_request(reply, packet);
7314 break;
7315 case DHCPV6_RELAY_FORW:
7316 #ifdef DHCP4o6
7317 if (dhcpv4_over_dhcpv6 && (local_family == AF_INET))
7318 dhcp4o6_relay_forw(reply, packet);
7319 else
7320 #endif /* DHCP4o6 */
7321 dhcpv6_relay_forw(reply, packet);
7322 break;
7323 case DHCPV6_RELAY_REPL:
7324 dhcpv6_discard(packet);
7325 break;
7326 case DHCPV6_LEASEQUERY:
7327 classify_client(packet);
7328 dhcpv6_leasequery(reply, packet);
7329 break;
7330 case DHCPV6_LEASEQUERY_REPLY:
7331 dhcpv6_discard(packet);
7332 break;
7333 case DHCPV6_DHCPV4_QUERY:
7334 #ifdef DHCP4o6
7335 if (dhcpv4_over_dhcpv6) {
7336 if (local_family == AF_INET6) {
7337 forw_dhcpv4_query(packet);
7338 } else {
7339 dhcp4o6_dhcpv4_query(reply, packet);
7340 }
7341 } else
7342 #endif /* DHCP4o6 */
7343 dhcpv6_discard(packet);
7344 break;
7345 case DHCPV6_DHCPV4_RESPONSE:
7346 dhcpv6_discard(packet);
7347 break;
7348 default:
7349 /* XXX: would be nice if we had "notice" level,
7350 as syslog, for this */
7351 log_info("Discarding unknown DHCPv6 message type %d "
7352 "from %s", packet->dhcpv6_msg_type,
7353 piaddr(packet->client_addr));
7354 }
7355 }
7356
7357 static void
7358 log_packet_in(const struct packet *packet) {
7359 struct data_string s;
7360 u_int32_t tid;
7361 char tmp_addr[INET6_ADDRSTRLEN];
7362 const void *addr;
7363
7364 memset(&s, 0, sizeof(s));
7365
7366 if (packet->dhcpv6_msg_type < dhcpv6_type_name_max) {
7367 data_string_sprintfa(&s, "%s message from %s port %d",
7368 dhcpv6_type_names[packet->dhcpv6_msg_type],
7369 piaddr(packet->client_addr),
7370 ntohs(packet->client_port));
7371 } else {
7372 data_string_sprintfa(&s,
7373 "Unknown message type %d from %s port %d",
7374 packet->dhcpv6_msg_type,
7375 piaddr(packet->client_addr),
7376 ntohs(packet->client_port));
7377 }
7378 if ((packet->dhcpv6_msg_type == DHCPV6_RELAY_FORW) ||
7379 (packet->dhcpv6_msg_type == DHCPV6_RELAY_REPL)) {
7380 addr = &packet->dhcpv6_link_address;
7381 data_string_sprintfa(&s, ", link address %s",
7382 inet_ntop(AF_INET6, addr,
7383 tmp_addr, sizeof(tmp_addr)));
7384 addr = &packet->dhcpv6_peer_address;
7385 data_string_sprintfa(&s, ", peer address %s",
7386 inet_ntop(AF_INET6, addr,
7387 tmp_addr, sizeof(tmp_addr)));
7388 } else if ((packet->dhcpv6_msg_type != DHCPV6_DHCPV4_QUERY) &&
7389 (packet->dhcpv6_msg_type != DHCPV6_DHCPV4_RESPONSE)) {
7390 tid = 0;
7391 memcpy(((char *)&tid)+1, packet->dhcpv6_transaction_id, 3);
7392 data_string_sprintfa(&s, ", transaction ID 0x%06X", tid);
7393
7394 /*
7395 oc = lookup_option(&dhcpv6_universe, packet->options,
7396 D6O_CLIENTID);
7397 if (oc != NULL) {
7398 memset(&tmp_ds, 0, sizeof(tmp_ds_));
7399 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
7400 packet->options, NULL,
7401 &global_scope, oc, MDL)) {
7402 log_error("Error evaluating Client Identifier");
7403 } else {
7404 data_strint_sprintf(&s, ", client ID %s",
7405
7406 data_string_forget(&tmp_ds, MDL);
7407 }
7408 }
7409 */
7410
7411 }
7412 log_info("%s", s.data);
7413
7414 data_string_forget(&s, MDL);
7415 }
7416
7417 void
7418 dhcpv6(struct packet *packet) {
7419 struct data_string reply;
7420 struct sockaddr_in6 to_addr;
7421 int send_ret;
7422
7423 /*
7424 * Log a message that we received this packet.
7425 */
7426 log_packet_in(packet);
7427
7428 /*
7429 * Build our reply packet.
7430 */
7431 build_dhcpv6_reply(&reply, packet);
7432
7433 if (reply.data != NULL) {
7434 /*
7435 * Send our reply, if we have one.
7436 */
7437 memset(&to_addr, 0, sizeof(to_addr));
7438 to_addr.sin6_family = AF_INET6;
7439 if ((packet->dhcpv6_msg_type == DHCPV6_RELAY_FORW) ||
7440 (packet->dhcpv6_msg_type == DHCPV6_RELAY_REPL)) {
7441 to_addr.sin6_port = local_port;
7442 } else {
7443 to_addr.sin6_port = remote_port;
7444 }
7445
7446 #if defined (REPLY_TO_SOURCE_PORT)
7447 /*
7448 * This appears to have been included for testing so we would
7449 * not need a root client, but was accidently left in the
7450 * final code. We continue to include it in case
7451 * some users have come to rely upon it, but leave
7452 * it off by default as it's a bad idea.
7453 */
7454 to_addr.sin6_port = packet->client_port;
7455 #endif
7456
7457 memcpy(&to_addr.sin6_addr, packet->client_addr.iabuf,
7458 sizeof(to_addr.sin6_addr));
7459
7460 log_info("Sending %s to %s port %d",
7461 dhcpv6_type_names[reply.data[0]],
7462 piaddr(packet->client_addr),
7463 ntohs(to_addr.sin6_port));
7464
7465 send_ret = send_packet6(packet->interface,
7466 reply.data, reply.len, &to_addr);
7467 if (send_ret != reply.len) {
7468 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
7469 send_ret, reply.len);
7470 }
7471 data_string_forget(&reply, MDL);
7472 }
7473 }
7474
7475 #ifdef DHCP4o6
7476 /*
7477 * \brief Receive a DHCPv4-query message from the DHCPv6 side
7478 * (DHCPv4 server function)
7479 *
7480 * Receive a message with a DHCPv4-query inside from the DHCPv6 server.
7481 * (code copied from \ref do_packet6() \ref and dhcpv6())
7482 *
7483 * Format: interface:16 + address:16 + DHCPv6 DHCPv4-query message
7484 *
7485 * \param raw the DHCPv6 DHCPv4-query message raw content
7486 */
7487 static void recv_dhcpv4_query(struct data_string *raw) {
7488 struct interface_info *ip;
7489 char name[16 + 1];
7490 struct iaddr iaddr;
7491 struct packet *packet;
7492 unsigned char msg_type;
7493 const struct dhcpv6_relay_packet *relay;
7494 const struct dhcpv4_over_dhcpv6_packet *msg;
7495 struct data_string reply;
7496 struct data_string ds;
7497 unsigned len;
7498 int cc;
7499
7500 memset(name, 0, sizeof(name));
7501 memcpy(name, raw->data, 16);
7502 for (ip = interfaces; ip != NULL; ip = ip->next) {
7503 if (!strcmp(name, ip->name))
7504 break;
7505 }
7506 if (ip == NULL) {
7507 log_error("recv_dhcpv4_query: can't find interface %s.",
7508 name);
7509 return;
7510 }
7511
7512 iaddr.len = 16;
7513 memcpy(iaddr.iabuf, raw->data + 16, 16);
7514
7515 /*
7516 * From do_packet6().
7517 */
7518
7519 if (!packet6_len_okay((char *)raw->data + 32, raw->len - 32)) {
7520 log_error("recv_dhcpv4_query: "
7521 "short packet from %s, len %d, dropped",
7522 piaddr(iaddr), raw->len - 32);
7523 return;
7524 }
7525
7526 /*
7527 * Build a packet structure.
7528 */
7529 packet = NULL;
7530 if (!packet_allocate(&packet, MDL)) {
7531 log_error("recv_dhcpv4_query: no memory for packet.");
7532 return;
7533 }
7534
7535 if (!option_state_allocate(&packet->options, MDL)) {
7536 log_error("recv_dhcpv4_query: no memory for options.");
7537 packet_dereference(&packet, MDL);
7538 return;
7539 }
7540
7541 packet->raw = (struct dhcp_packet *)(raw->data + 32);
7542 packet->packet_length = raw->len - 32;
7543 packet->client_port = remote_port;
7544 packet->client_addr = iaddr;
7545 interface_reference(&packet->interface, ip, MDL);
7546
7547 msg_type = raw->data[32];
7548 if ((msg_type == DHCPV6_RELAY_FORW) ||
7549 (msg_type == DHCPV6_RELAY_REPL)) {
7550 int relaylen =
7551 (int)(offsetof(struct dhcpv6_relay_packet, options));
7552 relay = (const struct dhcpv6_relay_packet *)(raw->data + 32);
7553 packet->dhcpv6_msg_type = relay->msg_type;
7554
7555 /* relay-specific data */
7556 packet->dhcpv6_hop_count = relay->hop_count;
7557 memcpy(&packet->dhcpv6_link_address,
7558 relay->link_address, sizeof(relay->link_address));
7559 memcpy(&packet->dhcpv6_peer_address,
7560 relay->peer_address, sizeof(relay->peer_address));
7561
7562 if (!parse_option_buffer(packet->options,
7563 relay->options,
7564 raw->len - 32 - relaylen,
7565 &dhcpv6_universe)) {
7566 /* no logging here, as parse_option_buffer() logs all
7567 cases where it fails */
7568 packet_dereference(&packet, MDL);
7569 return;
7570 }
7571 } else if ((msg_type == DHCPV6_DHCPV4_QUERY) ||
7572 (msg_type == DHCPV6_DHCPV4_RESPONSE)) {
7573 int msglen =
7574 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet, options));
7575 msg = (struct dhcpv4_over_dhcpv6_packet *)(raw->data + 32);
7576 packet->dhcpv6_msg_type = msg->msg_type;
7577
7578 /* message-specific data */
7579 memcpy(packet->dhcp4o6_flags, msg->flags,
7580 sizeof(packet->dhcp4o6_flags));
7581
7582 if (!parse_option_buffer(packet->options,
7583 msg->options,
7584 raw->len - 32 - msglen,
7585 &dhcpv6_universe)) {
7586 /* no logging here, as parse_option_buffer() logs all
7587 cases where it fails */
7588 packet_dereference(&packet, MDL);
7589 return;
7590 }
7591 } else {
7592 log_error("recv_dhcpv4_query: unexpected message of type %d.",
7593 (int)msg_type);
7594 packet_dereference(&packet, MDL);
7595 return;
7596 }
7597
7598 /*
7599 * From dhcpv6().
7600 */
7601
7602 /*
7603 * Log a message that we received this packet.
7604 */
7605 /* log_packet_in(packet); */
7606 memset(&ds, 0, sizeof(ds));
7607 if (packet->dhcpv6_msg_type < dhcpv6_type_name_max) {
7608 data_string_sprintfa(&ds, "%s message from %s",
7609 dhcpv6_type_names[packet->dhcpv6_msg_type],
7610 piaddr(packet->client_addr));
7611 } else {
7612 data_string_sprintfa(&ds,
7613 "Unknown message type %d from %s",
7614 packet->dhcpv6_msg_type,
7615 piaddr(packet->client_addr));
7616 }
7617 if ((packet->dhcpv6_msg_type == DHCPV6_RELAY_FORW) ||
7618 (packet->dhcpv6_msg_type == DHCPV6_RELAY_REPL)) {
7619 char tmp_addr[INET6_ADDRSTRLEN];
7620 const void *addr;
7621
7622 addr = &packet->dhcpv6_link_address;
7623 data_string_sprintfa(&ds, ", link address %s",
7624 inet_ntop(AF_INET6, addr,
7625 tmp_addr, sizeof(tmp_addr)));
7626 addr = &packet->dhcpv6_peer_address;
7627 data_string_sprintfa(&ds, ", peer address %s",
7628 inet_ntop(AF_INET6, addr,
7629 tmp_addr, sizeof(tmp_addr)));
7630 } else if ((packet->dhcpv6_msg_type != DHCPV6_DHCPV4_QUERY) &&
7631 (packet->dhcpv6_msg_type != DHCPV6_DHCPV4_RESPONSE)) {
7632 u_int32_t tid = 0;
7633
7634 memcpy(((char *)&tid)+1, packet->dhcpv6_transaction_id, 3);
7635 data_string_sprintfa(&ds, ", transaction ID 0x%06X", tid);
7636 }
7637 log_info("%s", ds.data);
7638 data_string_forget(&ds, MDL);
7639
7640 /*
7641 * Build our reply packet.
7642 */
7643 build_dhcpv6_reply(&reply, packet);
7644
7645 packet_dereference(&packet, MDL);
7646
7647 if (reply.data == NULL)
7648 return;
7649
7650 /*
7651 * Forward the response.
7652 */
7653 len = reply.len + 32;
7654 memset(&ds, 0, sizeof(ds));
7655 if (!buffer_allocate(&ds.buffer, len, MDL)) {
7656 log_error("recv_dhcpv4_query: no memory.");
7657 return;
7658 }
7659 ds.data = ds.buffer->data;
7660 ds.len = len;
7661
7662 memcpy(ds.buffer->data, name, 16);
7663 memcpy(ds.buffer->data + 16, iaddr.iabuf, 16);
7664 memcpy(ds.buffer->data + 32, reply.data, reply.len);
7665 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
7666 if (cc < 0)
7667 log_error("recv_dhcpv4_query: send(): %m");
7668 data_string_forget(&ds, MDL);
7669 }
7670 #endif /* DHCP4o6 */
7671
7672 static void
7673 seek_shared_host(struct host_decl **hp, struct shared_network *shared) {
7674 struct host_decl *nofixed = NULL;
7675 struct host_decl *seek, *hold = NULL;
7676
7677 /*
7678 * Seek forward through fixed addresses for the right link.
7679 *
7680 * Note: how to do this for fixed prefixes???
7681 */
7682 host_reference(&hold, *hp, MDL);
7683 host_dereference(hp, MDL);
7684 seek = hold;
7685 while (seek != NULL) {
7686 if (seek->fixed_addr == NULL)
7687 nofixed = seek;
7688 else if (fixed_matches_shared(seek, shared))
7689 break;
7690
7691 seek = seek->n_ipaddr;
7692 }
7693
7694 if ((seek == NULL) && (nofixed != NULL))
7695 seek = nofixed;
7696
7697 if (seek != NULL)
7698 host_reference(hp, seek, MDL);
7699 }
7700
7701 static isc_boolean_t
7702 fixed_matches_shared(struct host_decl *host, struct shared_network *shared) {
7703 struct subnet *subnet;
7704 struct data_string addr;
7705 isc_boolean_t matched;
7706 struct iaddr fixed;
7707
7708 if (host->fixed_addr == NULL)
7709 return ISC_FALSE;
7710
7711 memset(&addr, 0, sizeof(addr));
7712 if (!evaluate_option_cache(&addr, NULL, NULL, NULL, NULL, NULL,
7713 &global_scope, host->fixed_addr, MDL))
7714 return ISC_FALSE;
7715
7716 if (addr.len < 16) {
7717 data_string_forget(&addr, MDL);
7718 return ISC_FALSE;
7719 }
7720
7721 fixed.len = 16;
7722 memcpy(fixed.iabuf, addr.data, 16);
7723
7724 matched = ISC_FALSE;
7725 for (subnet = shared->subnets ; subnet != NULL ;
7726 subnet = subnet->next_sibling) {
7727 if (addr_eq(subnet_number(fixed, subnet->netmask),
7728 subnet->net)) {
7729 matched = ISC_TRUE;
7730 break;
7731 }
7732 }
7733
7734 data_string_forget(&addr, MDL);
7735 return matched;
7736 }
7737
7738 /*!
7739 *
7740 * \brief Constructs a REPLY with status of UseMulticast to a given packet
7741 *
7742 * Per RFC 3315 Secs 18.2.1,3,6 & 7, when a server rejects a client's
7743 * unicast-sent packet, the response must only contain the client id,
7744 * server id, and a status code option of 5 (UseMulticast). This function
7745 * constructs such a packet and returns it as a data_string.
7746 *
7747 * \param reply_ret = data_string which will receive the newly constructed
7748 * reply
7749 * \param packet = client request which is being rejected
7750 * \param client_id = data_string which contains the client id
7751 * \param server_id = data_string which which contains the server id
7752 *
7753 */
7754 void
7755 unicast_reject(struct data_string *reply_ret,
7756 struct packet *packet,
7757 const struct data_string *client_id,
7758 const struct data_string *server_id)
7759 {
7760 struct reply_state reply;
7761 memset(&reply, 0x0, sizeof(struct reply_state));
7762
7763 /* Locate the client. */
7764 if (shared_network_from_packet6(&reply.shared, packet)
7765 != ISC_R_SUCCESS) {
7766 log_error("unicast_reject: could not locate client.");
7767 return;
7768 }
7769
7770 /* Initialize the reply. */
7771 packet_reference(&reply.packet, packet, MDL);
7772 data_string_copy(&reply.client_id, client_id, MDL);
7773
7774 if (start_reply(packet, client_id, server_id, &reply.opt_state,
7775 &reply.buf.reply)) {
7776 /* Set the UseMulticast status code. */
7777 if (!set_status_code(STATUS_UseMulticast,
7778 "Unicast not allowed by server.",
7779 reply.opt_state)) {
7780 log_error("unicast_reject: Unable to set status code.");
7781 } else {
7782 /* Set write cursor to just past the reply header. */
7783 reply.cursor = REPLY_OPTIONS_INDEX;
7784 reply.cursor += store_options6(((char *)reply.buf.data
7785 + reply.cursor),
7786 (sizeof(reply.buf)
7787 - reply.cursor),
7788 reply.opt_state,
7789 reply.packet,
7790 unicast_reject_opts,
7791 NULL);
7792
7793 /* Return our reply to the caller. */
7794 reply_ret->len = reply.cursor;
7795 reply_ret->buffer = NULL;
7796 if (!buffer_allocate(&reply_ret->buffer,
7797 reply.cursor, MDL)) {
7798 log_fatal("unicast_reject:"
7799 "No memory to store Reply.");
7800 }
7801
7802 memcpy(reply_ret->buffer->data, reply.buf.data,
7803 reply.cursor);
7804 reply_ret->data = reply_ret->buffer->data;
7805 }
7806
7807 }
7808
7809 /* Cleanup. */
7810 if (reply.shared != NULL)
7811 shared_network_dereference(&reply.shared, MDL);
7812 if (reply.opt_state != NULL)
7813 option_state_dereference(&reply.opt_state, MDL);
7814 if (reply.packet != NULL)
7815 packet_dereference(&reply.packet, MDL);
7816 if (reply.client_id.data != NULL)
7817 data_string_forget(&reply.client_id, MDL);
7818 }
7819
7820 /*!
7821 *
7822 * \brief Checks if the dhcp6.unicast option has been defined
7823 *
7824 * Scans the option space for the presence of the dhcp6.unicast option. The
7825 * function attempts to map the inbound packet to a shared network first
7826 * by an ip address specified via an D6O_IA_XX option and if that fails then
7827 * by the packet's source information (e.g. relay link, link, or interace).
7828 * Once the packet is mapped to a shared network, the function executes all
7829 * statements from the network's group outward into a local option cache.
7830 * The option cache is then scanned for the presence of unicast option. If
7831 * the packet cannot be mapped to a shared network, the function returns
7832 * ISC_FALSE.
7833 * \param packet inbound packet from the client
7834 *
7835 * \return ISC_TRUE if the dhcp6.unicast option is defined, false otherwise.
7836 *
7837 */
7838 isc_boolean_t
7839 is_unicast_option_defined(struct packet *packet) {
7840 isc_boolean_t is_defined = ISC_FALSE;
7841 struct option_state *opt_state = NULL;
7842 struct option_cache *oc = NULL;
7843 struct shared_network *shared = NULL;
7844
7845 if (!option_state_allocate(&opt_state, MDL)) {
7846 log_fatal("is_unicast_option_defined:"
7847 "No memory for option state.");
7848 }
7849
7850 /* We try to map the packet to a network first by an IA_XX value.
7851 * If that fails, we try by packet source. */
7852 if (((shared_network_from_requested_addr(&shared, packet)
7853 != ISC_R_SUCCESS) &&
7854 (shared_network_from_packet6(&shared, packet) != ISC_R_SUCCESS))
7855 || (shared == NULL)) {
7856 /* @todo what would this really mean? I think wrong network
7857 * logic will catch it */
7858 log_error("is_unicast_option_defined:"
7859 "cannot attribute packet to a network.");
7860 return (ISC_FALSE);
7861 }
7862
7863 /* Now that we've mapped it to a network, execute statments to that
7864 * scope, looking for the unicast option. We don't care about the
7865 * value of the option, only whether or not it is defined. */
7866 execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL, opt_state,
7867 &global_scope, shared->group, NULL, NULL);
7868
7869 oc = lookup_option(&dhcpv6_universe, opt_state, D6O_UNICAST);
7870 is_defined = (oc != NULL ? ISC_TRUE : ISC_FALSE);
7871 log_debug("is_unicast_option_defined: option found : %d", is_defined);
7872
7873 if (shared != NULL) {
7874 shared_network_dereference(&shared, MDL);
7875 }
7876
7877 if (opt_state != NULL) {
7878 option_state_dereference(&opt_state, MDL);
7879 }
7880
7881 return (is_defined);
7882 }
7883
7884 /*!
7885 *
7886 * \brief Maps a packet to a shared network based on the requested IP address
7887 *
7888 * The function attempts to find a subnet that matches the first requested IP
7889 * address contained within the given packet. Note that it looks first for
7890 * D6O_IA_NAs, then D6O_IA_PDs and lastly D6O_IA_TAs. If a matching network is
7891 * found, a reference to it is returned in the parameter, shared.
7892 *
7893 * \param shared shared_network pointer which will receive the matching network
7894 * \param packet inbound packet from the client
7895 *
7896 * \return ISC_R_SUCCESS if the packet can be mapped to a shared_network.
7897 *
7898 */
7899 static isc_result_t
7900 shared_network_from_requested_addr (struct shared_network **shared,
7901 struct packet* packet) {
7902 struct iaddr iaddr;
7903 struct subnet* subnet = NULL;
7904 isc_result_t status = ISC_R_FAILURE;
7905
7906 /* Try to match first IA_ address or prefix we find to a subnet. In
7907 * theory all IA_ values in a given request are supposed to be in the
7908 * same subnet so we only need to try one right? */
7909 if ((get_first_ia_addr_val(packet, D6O_IA_NA, &iaddr) != ISC_R_SUCCESS)
7910 && (get_first_ia_addr_val(packet, D6O_IA_PD, &iaddr)
7911 != ISC_R_SUCCESS)
7912 && (get_first_ia_addr_val(packet, D6O_IA_TA, &iaddr)
7913 != ISC_R_SUCCESS)) {
7914 /* we found nothing to match against */
7915 log_debug("share_network_from_request_addr: nothing to match");
7916 return (ISC_R_FAILURE);
7917 }
7918
7919 if (!find_subnet(&subnet, iaddr, MDL)) {
7920 log_debug("shared_network_from_requested_addr:"
7921 "No subnet found for addr %s.", piaddr(iaddr));
7922 } else {
7923 status = shared_network_reference(shared,
7924 subnet->shared_network, MDL);
7925 subnet_dereference(&subnet, MDL);
7926 log_debug("shared_network_from_requested_addr:"
7927 " found shared network %s for address %s.",
7928 ((*shared)->name ? (*shared)->name : "unnamed"),
7929 piaddr(iaddr));
7930 return (status);
7931 }
7932
7933 return (ISC_R_FAILURE);
7934 }
7935
7936 /*!
7937 *
7938 * \brief Retrieves the first IP address from a given packet of a given type
7939 *
7940 * Search a packet for options of a given type (D6O_IA_AN, D6O_IA_PD, or
7941 * D6O_IA_TA) for the first non-blank IA_XX value and return its IP address
7942 * component.
7943 *
7944 * \param packet packet received from the client
7945 * \param addr_type the address option type (D6O_IA_NA , D6O_IA_PD, or
7946 * D6O_IP_TA) to look for within the packet.
7947 * \param iaddr pointer to the iaddr structure which will receive the extracted
7948 * address.
7949 *
7950 * \return ISC_R_SUCCESS if an address was succesfully extracted, ISC_R_FALURE
7951 * otherwise.
7952 *
7953 */
7954 static isc_result_t
7955 get_first_ia_addr_val (struct packet* packet, int addr_type,
7956 struct iaddr* iaddr) {
7957 struct option_cache *ia;
7958 struct option_cache *oc = NULL;
7959 struct data_string cli_enc_opt_data;
7960 struct option_state *cli_enc_opt_state;
7961 int addr_opt_offset;
7962 int addr_opt;
7963 int addr_opt_data_len;
7964 int ip_addr_offset;
7965
7966 isc_result_t status = ISC_R_FAILURE;
7967 memset(iaddr, 0, sizeof(struct iaddr));
7968
7969 /* Set up address type specifics */
7970 switch (addr_type) {
7971 case D6O_IA_NA:
7972 addr_opt_offset = IA_NA_OFFSET;
7973 addr_opt = D6O_IAADDR;
7974 addr_opt_data_len = 24;
7975 ip_addr_offset = 0;
7976 break;
7977 case D6O_IA_TA:
7978 addr_opt_offset = IA_TA_OFFSET;
7979 addr_opt = D6O_IAADDR;
7980 addr_opt_data_len = 24;
7981 ip_addr_offset = 0;
7982 break;
7983 case D6O_IA_PD:
7984 addr_opt_offset = IA_PD_OFFSET;
7985 addr_opt = D6O_IAPREFIX;
7986 addr_opt_data_len = 25;
7987 ip_addr_offset = 9;
7988 break;
7989 default:
7990 /* shouldn't be here */
7991 log_error ("get_first_ia_addr_val: invalid opt type %d",
7992 addr_type);
7993 return (ISC_R_FAILURE);
7994 }
7995
7996 /* Find the first, non-blank IA_XX value within an D6O_IA_XX option. */
7997 for (ia = lookup_option(&dhcpv6_universe, packet->options, addr_type);
7998 ia != NULL && oc == NULL; ia = ia->next) {
7999 if (!get_encapsulated_IA_state(&cli_enc_opt_state,
8000 &cli_enc_opt_data,
8001 packet, ia, addr_opt_offset)) {
8002 log_debug ("get_first_ia_addr_val:"
8003 " couldn't unroll enclosing option");
8004 return (ISC_R_FAILURE);
8005 }
8006
8007 oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
8008 addr_opt);
8009 if (oc == NULL) {
8010 /* no address given for this IA, ignore */
8011 option_state_dereference(&cli_enc_opt_state, MDL);
8012 data_string_forget(&cli_enc_opt_data, MDL);
8013 }
8014 }
8015
8016 /* If we found a non-blank IA_XX then extract its ip address. */
8017 if (oc != NULL) {
8018 struct data_string iaddr_str;
8019
8020 memset(&iaddr_str, 0, sizeof(iaddr_str));
8021 if (!evaluate_option_cache(&iaddr_str, packet, NULL, NULL,
8022 packet->options, NULL, &global_scope,
8023 oc, MDL)) {
8024 log_error("get_first_ia_addr_val: "
8025 "error evaluating IA_XX option.");
8026 } else {
8027 if (iaddr_str.len != addr_opt_data_len) {
8028 log_error("shared_network_from_requested_addr:"
8029 " invalid length %d, expected %d",
8030 iaddr_str.len, addr_opt_data_len);
8031 } else {
8032 iaddr->len = 16;
8033 memcpy (iaddr->iabuf,
8034 iaddr_str.data + ip_addr_offset, 16);
8035 status = ISC_R_SUCCESS;
8036 }
8037 data_string_forget(&iaddr_str, MDL);
8038 }
8039
8040 option_state_dereference(&cli_enc_opt_state, MDL);
8041 data_string_forget(&cli_enc_opt_data, MDL);
8042 }
8043
8044 return (status);
8045 }
8046
8047 /*
8048 * \brief Calculates the reply T1/T2 times and stuffs them in outbound buffer
8049 *
8050 * T1/T2 time selection is kind of weird. We actually use DHCP * (v4) scoped
8051 * options, dhcp-renewal-time and dhcp-rebinding-time, as handy existing places
8052 * where these can be configured by an administrator. A value of zero tells the
8053 * client it may choose its own value.
8054 *
8055 * When those options are not defined, the values will be set to zero unless
8056 * the global option, dhcpv6-set-tee-times is enabled. When this option is
8057 * enabled the values are calculated as recommended by RFC 3315, Section 22.4:
8058 *
8059 * T1 will be set to 0.5 times the shortest preferred lifetime
8060 * in the IA_XX option. If the "shortest" preferred lifetime is
8061 * 0xFFFFFFFF, T1 will set to 0xFFFFFFFF.
8062 *
8063 * T2 will be set to 0.8 times the shortest preferred lifetime
8064 * in the IA_XX option. If the "shortest" preferred lifetime is
8065 * 0xFFFFFFFF, T2 will set to 0xFFFFFFFF.
8066 *
8067 * Note that dhcpv6-set-tee-times is intended to be transitional and will
8068 * likely be removed in 4.4.0, leaving the behavior as getting the values
8069 * either from the configured parameters (if you want zeros, define them as
8070 * zeros) or by calculating them per the RFC.
8071 *
8072 * \param reply - pointer to the reply_state structure
8073 * \param ia_cursor - offset of the beginning of the IA_XX option within the
8074 * reply's outbound data buffer
8075 */
8076 static void
8077 set_reply_tee_times(struct reply_state* reply, unsigned ia_cursor)
8078 {
8079 struct option_cache *oc;
8080 int set_tee_times;
8081
8082 /* Found out if calculated values are enabled. */
8083 oc = lookup_option(&server_universe, reply->opt_state,
8084 SV_DHCPV6_SET_TEE_TIMES);
8085 set_tee_times = (oc &&
8086 evaluate_boolean_option_cache(NULL, reply->packet,
8087 NULL, NULL,
8088 reply->packet->options,
8089 reply->opt_state,
8090 &global_scope, oc, MDL));
8091
8092 oc = lookup_option(&dhcp_universe, reply->opt_state,
8093 DHO_DHCP_RENEWAL_TIME);
8094 if (oc != NULL) {
8095 /* dhcp-renewal-time is defined, use it */
8096 struct data_string data;
8097 memset(&data, 0x00, sizeof(data));
8098
8099 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
8100 reply->packet->options,
8101 reply->opt_state, &global_scope,
8102 oc, MDL) ||
8103 (data.len != 4)) {
8104 log_error("Invalid renewal time.");
8105 reply->renew = 0;
8106 } else {
8107 reply->renew = getULong(data.data);
8108 }
8109
8110 if (data.data != NULL)
8111 data_string_forget(&data, MDL);
8112 } else if (set_tee_times) {
8113 /* Setting them is enabled so T1 is either infinite or
8114 * 0.5 * the shortest preferred lifetime in the IA_XX */
8115 if (reply->min_prefer == INFINITE_TIME)
8116 reply->renew = INFINITE_TIME;
8117 else
8118 reply->renew = reply->min_prefer / 2;
8119 } else {
8120 /* Default is to let the client choose */
8121 reply->renew = 0;
8122 }
8123
8124 putULong(reply->buf.data + ia_cursor + 8, reply->renew);
8125
8126 /* Now T2. */
8127 oc = lookup_option(&dhcp_universe, reply->opt_state,
8128 DHO_DHCP_REBINDING_TIME);
8129 if (oc != NULL) {
8130 /* dhcp-rebinding-time is defined, use it */
8131 struct data_string data;
8132 memset(&data, 0x00, sizeof(data));
8133
8134 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
8135 reply->packet->options,
8136 reply->opt_state, &global_scope,
8137 oc, MDL) ||
8138 (data.len != 4)) {
8139 log_error("Invalid rebinding time.");
8140 reply->rebind = 0;
8141 } else {
8142 reply->rebind = getULong(data.data);
8143 }
8144
8145 if (data.data != NULL)
8146 data_string_forget(&data, MDL);
8147 } else if (set_tee_times) {
8148 /* Setting them is enabled so T2 is either infinite or
8149 * 0.8 * the shortest preferred lifetime in the reply */
8150 if (reply->min_prefer == INFINITE_TIME)
8151 reply->rebind = INFINITE_TIME;
8152 else
8153 reply->rebind = (reply->min_prefer / 5) * 4;
8154 } else {
8155 /* Default is to let the client choose */
8156 reply->rebind = 0;
8157 }
8158
8159 putULong(reply->buf.data + ia_cursor + 12, reply->rebind);
8160 }
8161
8162 /*
8163 * Releases the iasubopts in the pre-existing IA, if they are not in
8164 * the same shared-network as the new IA.
8165 *
8166 * returns 1 if the release was done, 0 otherwise
8167 */
8168 int
8169 release_on_roam(struct reply_state* reply) {
8170 struct ia_xx* old_ia = reply->old_ia;
8171 struct iasubopt *lease = NULL;
8172 int i;
8173
8174 if (old_ia == NULL || old_ia->num_iasubopt <= 0) {
8175 return(0);
8176 }
8177
8178 /* If the old shared-network and new are the same, client hasn't
8179 * roamed, nothing to do. We only check the first one because you
8180 * cannot have iasubopts on different shared-networks within a
8181 * single ia. */
8182 lease = old_ia->iasubopt[0];
8183 if (lease->ipv6_pool->shared_network == reply->shared) {
8184 return (0);
8185 }
8186
8187 /* Old and new are on different shared networks so the client must
8188 * roamed. Release the old leases. */
8189 for (i = 0; i < old_ia->num_iasubopt; i++) {
8190 lease = old_ia->iasubopt[i];
8191
8192 log_info("Client: %s roamed to new network,"
8193 " releasing lease: %s%s",
8194 print_hex_1(reply->client_id.len,
8195 reply->client_id.data, 60),
8196 pin6_addr(&lease->addr), iasubopt_plen_str(lease));
8197
8198 release_lease6(lease->ipv6_pool, lease);
8199 lease->ia->cltt = cur_time;
8200 write_ia(lease->ia);
8201 }
8202
8203 return (1);
8204 }
8205
8206 /*
8207 * Convenience function which returns a string (static buffer)
8208 * containing either a "/" followed by the prefix length or an
8209 * empty string depending on the lease type
8210 */
8211 const char *iasubopt_plen_str(struct iasubopt *lease) {
8212 static char prefix_buf[16];
8213 *prefix_buf = 0;
8214 if ((lease->ia) && (lease->ia->ia_type == D6O_IA_PD)) {
8215 sprintf(prefix_buf, "/%-d", lease->plen);
8216 }
8217
8218 return (prefix_buf);
8219 }
8220
8221 #endif /* DHCPv6 */