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