]> git.ipfire.org Git - thirdparty/dhcp.git/blob - server/dhcpv6.c
[master] Fixed mispelling of abandon-lease-time in dhcpd.conf.5
[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 /* Try to pick a new prefix if we didn't find one, or if we found an
4670 * abandoned prefix.
4671 */
4672 if ((best_prefix == NULL) || (best_prefix->state == FTS_ABANDONED)) {
4673 status = pick_v6_prefix(reply);
4674 } else if (best_prefix != NULL) {
4675 iasubopt_reference(&reply->lease, best_prefix, MDL);
4676 status = ISC_R_SUCCESS;
4677 }
4678
4679 /* Pick the abandoned prefix as a last resort. */
4680 if ((status == ISC_R_NORESOURCES) && (best_prefix != NULL)) {
4681 /* I don't see how this is supposed to be done right now. */
4682 log_error("Reclaiming abandoned prefixes is not yet "
4683 "supported. Treating this as an out of space "
4684 "condition.");
4685 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
4686 }
4687
4688 /* Give up now if we didn't find a prefix. */
4689 if (status != ISC_R_SUCCESS)
4690 return status;
4691
4692 if (reply->lease == NULL)
4693 log_fatal("Impossible condition at %s:%d.", MDL);
4694
4695 scope = &reply->lease->scope;
4696 group = reply->lease->ipv6_pool->ipv6_pond->group;
4697
4698 send_pref.lo_addr.len = 16;
4699 memcpy(send_pref.lo_addr.iabuf, &reply->lease->addr, 16);
4700 send_pref.bits = (int) reply->lease->plen;
4701
4702 send_pref:
4703 status = reply_process_is_prefixed(reply, scope, group);
4704 if (status != ISC_R_SUCCESS)
4705 return status;
4706
4707 status = reply_process_send_prefix(reply, &send_pref);
4708 return status;
4709 }
4710
4711 /* Once a prefix is found for a client, perform several common functions;
4712 * Calculate and store valid and preferred prefix times, draw client options
4713 * into the option state.
4714 */
4715 static isc_result_t
4716 reply_process_is_prefixed(struct reply_state *reply,
4717 struct binding_scope **scope, struct group *group)
4718 {
4719 isc_result_t status = ISC_R_SUCCESS;
4720 struct data_string data;
4721 struct option_cache *oc;
4722 struct option_state *tmp_options = NULL;
4723 struct on_star *on_star;
4724 int i;
4725
4726 /* Initialize values we will cleanup. */
4727 memset(&data, 0, sizeof(data));
4728
4729 /*
4730 * Find the proper on_star block to use. We use the
4731 * one in the lease if we have a lease or the one in
4732 * the reply if we don't have a lease because this is
4733 * a static instance
4734 */
4735 if (reply->lease) {
4736 on_star = &reply->lease->on_star;
4737 } else {
4738 on_star = &reply->on_star;
4739 }
4740
4741 /*
4742 * Bring in the root configuration. We only do this to bring
4743 * in the on * statements, as we didn't have the lease available
4744 * we we did it the first time.
4745 */
4746 option_state_allocate(&tmp_options, MDL);
4747 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4748 reply->packet->options, tmp_options,
4749 &global_scope, root_group, NULL,
4750 on_star);
4751 if (tmp_options != NULL) {
4752 option_state_dereference(&tmp_options, MDL);
4753 }
4754
4755 /*
4756 * Bring configured options into the root packet level cache - start
4757 * with the lease's closest enclosing group (passed in by the caller
4758 * as 'group').
4759 */
4760 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4761 reply->packet->options, reply->opt_state,
4762 scope, group, root_group, on_star);
4763
4764 /* Execute statements from class scopes. */
4765 for (i = reply->packet->class_count; i > 0; i--) {
4766 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4767 reply->packet->options,
4768 reply->opt_state, scope,
4769 reply->packet->classes[i - 1]->group,
4770 group, on_star);
4771 }
4772
4773 /*
4774 * If there is a host record, over-ride with values configured there,
4775 * without re-evaluating configuration from the previously executed
4776 * group or its common enclosers.
4777 */
4778 if (reply->host != NULL)
4779 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4780 reply->packet->options,
4781 reply->opt_state, scope,
4782 reply->host->group, group,
4783 on_star);
4784
4785 /* Determine valid lifetime. */
4786 if (reply->client_valid == 0)
4787 reply->send_valid = DEFAULT_DEFAULT_LEASE_TIME;
4788 else
4789 reply->send_valid = reply->client_valid;
4790
4791 oc = lookup_option(&server_universe, reply->opt_state,
4792 SV_DEFAULT_LEASE_TIME);
4793 if (oc != NULL) {
4794 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
4795 reply->packet->options,
4796 reply->opt_state,
4797 scope, oc, MDL) ||
4798 (data.len != 4)) {
4799 log_error("reply_process_is_prefixed: unable to "
4800 "evaluate default prefix time");
4801 status = ISC_R_FAILURE;
4802 goto cleanup;
4803 }
4804
4805 reply->send_valid = getULong(data.data);
4806 data_string_forget(&data, MDL);
4807 }
4808
4809 /* Check to see if the lease time would cause us to wrap
4810 * in which case we make it infinite.
4811 * The following doesn't work on at least some systems:
4812 * (cur_time + reply->send_valid < cur_time)
4813 */
4814 if (reply->send_valid != INFINITE_TIME) {
4815 time_t test_time = cur_time + reply->send_valid;
4816 if (test_time < cur_time)
4817 reply->send_valid = INFINITE_TIME;
4818 }
4819
4820 if (reply->client_prefer == 0)
4821 reply->send_prefer = reply->send_valid;
4822 else
4823 reply->send_prefer = reply->client_prefer;
4824
4825 if ((reply->send_prefer >= reply->send_valid) &&
4826 (reply->send_valid != INFINITE_TIME))
4827 reply->send_prefer = (reply->send_valid / 2) +
4828 (reply->send_valid / 8);
4829
4830 oc = lookup_option(&server_universe, reply->opt_state,
4831 SV_PREFER_LIFETIME);
4832 if (oc != NULL) {
4833 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
4834 reply->packet->options,
4835 reply->opt_state,
4836 scope, oc, MDL) ||
4837 (data.len != 4)) {
4838 log_error("reply_process_is_prefixed: unable to "
4839 "evaluate preferred prefix time");
4840 status = ISC_R_FAILURE;
4841 goto cleanup;
4842 }
4843
4844 reply->send_prefer = getULong(data.data);
4845 data_string_forget(&data, MDL);
4846 }
4847
4848 /* Note lowest values for later calculation of renew/rebind times. */
4849 if (reply->min_prefer > reply->send_prefer)
4850 reply->min_prefer = reply->send_prefer;
4851
4852 if (reply->min_valid > reply->send_valid)
4853 reply->min_valid = reply->send_valid;
4854
4855 /* Perform dynamic prefix related update work. */
4856 if (reply->lease != NULL) {
4857 /* Cached lifetimes */
4858 reply->lease->prefer = reply->send_prefer;
4859 reply->lease->valid = reply->send_valid;
4860
4861 /* Advance (or rewind) the valid lifetime.
4862 * In the protocol 0xFFFFFFFF is infinite
4863 * when connecting to the lease file MAX_TIME is
4864 */
4865 if (reply->buf.reply.msg_type == DHCPV6_REPLY) {
4866 if (reply->send_valid == INFINITE_TIME) {
4867 reply->lease->soft_lifetime_end_time = MAX_TIME;
4868 } else {
4869 reply->lease->soft_lifetime_end_time =
4870 cur_time + reply->send_valid;
4871 }
4872 /* Wait before renew! */
4873 }
4874
4875 status = ia_add_iasubopt(reply->ia, reply->lease, MDL);
4876 if (status != ISC_R_SUCCESS) {
4877 log_fatal("reply_process_is_prefixed: Unable to "
4878 "attach prefix to new IA_PD: %s",
4879 isc_result_totext(status));
4880 }
4881
4882 /*
4883 * If this is a new prefix, make sure it is attached somewhere.
4884 */
4885 if (reply->lease->ia == NULL) {
4886 ia_reference(&reply->lease->ia, reply->ia, MDL);
4887 }
4888 }
4889
4890 /* Bring a copy of the relevant options into the IA_PD scope. */
4891 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4892 reply->packet->options, reply->reply_ia,
4893 scope, group, root_group, NULL);
4894
4895 /* Execute statements from class scopes. */
4896 for (i = reply->packet->class_count; i > 0; i--) {
4897 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4898 reply->packet->options,
4899 reply->reply_ia, scope,
4900 reply->packet->classes[i - 1]->group,
4901 group, NULL);
4902 }
4903
4904 /*
4905 * And bring in host record configuration, if any, but not to overlap
4906 * the previous group or its common enclosers.
4907 */
4908 if (reply->host != NULL)
4909 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
4910 reply->packet->options,
4911 reply->reply_ia, scope,
4912 reply->host->group, group, NULL);
4913
4914 cleanup:
4915 if (data.data != NULL)
4916 data_string_forget(&data, MDL);
4917
4918 if (status == ISC_R_SUCCESS)
4919 reply->client_resources++;
4920
4921 return status;
4922 }
4923
4924 /* Simply send an IAPREFIX within the IA_PD scope as described. */
4925 static isc_result_t
4926 reply_process_send_prefix(struct reply_state *reply,
4927 struct iaddrcidrnet *pref) {
4928 isc_result_t status = ISC_R_SUCCESS;
4929 struct data_string data;
4930
4931 memset(&data, 0, sizeof(data));
4932
4933 /* Now append the prefix. */
4934 data.len = IAPREFIX_OFFSET;
4935 if (!buffer_allocate(&data.buffer, data.len, MDL)) {
4936 log_error("reply_process_send_prefix: out of memory"
4937 "allocating new IAPREFIX buffer.");
4938 status = ISC_R_NOMEMORY;
4939 goto cleanup;
4940 }
4941 data.data = data.buffer->data;
4942
4943 putULong(data.buffer->data, reply->send_prefer);
4944 putULong(data.buffer->data + 4, reply->send_valid);
4945 data.buffer->data[8] = pref->bits;
4946 memcpy(data.buffer->data + 9, pref->lo_addr.iabuf, 16);
4947
4948 if (!append_option_buffer(&dhcpv6_universe, reply->reply_ia,
4949 data.buffer, data.buffer->data,
4950 data.len, D6O_IAPREFIX, 0)) {
4951 log_error("reply_process_send_prefix: unable "
4952 "to save IAPREFIX option");
4953 status = ISC_R_FAILURE;
4954 goto cleanup;
4955 }
4956
4957 reply->resources_included = ISC_TRUE;
4958
4959 cleanup:
4960 if (data.data != NULL)
4961 data_string_forget(&data, MDL);
4962
4963 return status;
4964 }
4965
4966 /* Choose the better of two prefixes. */
4967 static struct iasubopt *
4968 prefix_compare(struct reply_state *reply,
4969 struct iasubopt *alpha, struct iasubopt *beta) {
4970 if (alpha == NULL)
4971 return beta;
4972 if (beta == NULL)
4973 return alpha;
4974
4975 if (reply->preflen >= 0) {
4976 if ((alpha->plen == reply->preflen) &&
4977 (beta->plen != reply->preflen))
4978 return alpha;
4979 if ((beta->plen == reply->preflen) &&
4980 (alpha->plen != reply->preflen))
4981 return beta;
4982 }
4983
4984 switch(alpha->state) {
4985 case FTS_ACTIVE:
4986 switch(beta->state) {
4987 case FTS_ACTIVE:
4988 /* Choose the prefix with the longest lifetime (most
4989 * likely the most recently allocated).
4990 */
4991 if (alpha->hard_lifetime_end_time <
4992 beta->hard_lifetime_end_time)
4993 return beta;
4994 else
4995 return alpha;
4996
4997 case FTS_EXPIRED:
4998 case FTS_ABANDONED:
4999 return alpha;
5000
5001 default:
5002 log_fatal("Impossible condition at %s:%d.", MDL);
5003 }
5004 break;
5005
5006 case FTS_EXPIRED:
5007 switch (beta->state) {
5008 case FTS_ACTIVE:
5009 return beta;
5010
5011 case FTS_EXPIRED:
5012 /* Choose the most recently expired prefix. */
5013 if (alpha->hard_lifetime_end_time <
5014 beta->hard_lifetime_end_time)
5015 return beta;
5016 else if ((alpha->hard_lifetime_end_time ==
5017 beta->hard_lifetime_end_time) &&
5018 (alpha->soft_lifetime_end_time <
5019 beta->soft_lifetime_end_time))
5020 return beta;
5021 else
5022 return alpha;
5023
5024 case FTS_ABANDONED:
5025 return alpha;
5026
5027 default:
5028 log_fatal("Impossible condition at %s:%d.", MDL);
5029 }
5030 break;
5031
5032 case FTS_ABANDONED:
5033 switch (beta->state) {
5034 case FTS_ACTIVE:
5035 case FTS_EXPIRED:
5036 return alpha;
5037
5038 case FTS_ABANDONED:
5039 /* Choose the prefix that was abandoned longest ago. */
5040 if (alpha->hard_lifetime_end_time <
5041 beta->hard_lifetime_end_time)
5042 return alpha;
5043 else
5044 return beta;
5045
5046 default:
5047 log_fatal("Impossible condition at %s:%d.", MDL);
5048 }
5049 break;
5050
5051 default:
5052 log_fatal("Impossible condition at %s:%d.", MDL);
5053 }
5054
5055 log_fatal("Triple impossible condition at %s:%d.", MDL);
5056 return NULL;
5057 }
5058
5059 /*
5060 * Solicit is how a client starts requesting addresses.
5061 *
5062 * If the client asks for rapid commit, and we support it, we will
5063 * allocate the addresses and reply.
5064 *
5065 * Otherwise we will send an advertise message.
5066 */
5067
5068 static void
5069 dhcpv6_solicit(struct data_string *reply_ret, struct packet *packet) {
5070 struct data_string client_id;
5071
5072 /*
5073 * Validate our input.
5074 */
5075 if (!valid_client_msg(packet, &client_id)) {
5076 return;
5077 }
5078
5079 lease_to_client(reply_ret, packet, &client_id, NULL);
5080
5081 /*
5082 * Clean up.
5083 */
5084 data_string_forget(&client_id, MDL);
5085 }
5086
5087 /*
5088 * Request is how a client actually requests addresses.
5089 *
5090 * Very similar to Solicit handling, except the server DUID is required.
5091 */
5092
5093 static void
5094 dhcpv6_request(struct data_string *reply_ret, struct packet *packet) {
5095 struct data_string client_id;
5096 struct data_string server_id;
5097
5098 /*
5099 * Validate our input.
5100 */
5101 if (!valid_client_resp(packet, &client_id, &server_id)) {
5102 return;
5103 }
5104
5105 /* If the REQUEST arrived via unicast and unicast option isn't set,
5106 * reject it per RFC 3315, Sec 18.2.1 */
5107 if (packet->unicast == ISC_TRUE &&
5108 is_unicast_option_defined(packet) == ISC_FALSE) {
5109 unicast_reject(reply_ret, packet, &client_id, &server_id);
5110 } else {
5111 /*
5112 * Issue our lease.
5113 */
5114 lease_to_client(reply_ret, packet, &client_id, &server_id);
5115 }
5116
5117 /*
5118 * Cleanup.
5119 */
5120 data_string_forget(&client_id, MDL);
5121 data_string_forget(&server_id, MDL);
5122 }
5123
5124 /* Find a DHCPv6 packet's shared network from hints in the packet.
5125 */
5126 static isc_result_t
5127 shared_network_from_packet6(struct shared_network **shared,
5128 struct packet *packet)
5129 {
5130 const struct packet *chk_packet;
5131 const struct in6_addr *link_addr, *first_link_addr;
5132 struct iaddr tmp_addr;
5133 struct subnet *subnet;
5134 isc_result_t status;
5135
5136 if ((shared == NULL) || (*shared != NULL) || (packet == NULL))
5137 return DHCP_R_INVALIDARG;
5138
5139 /*
5140 * First, find the link address where the packet from the client
5141 * first appeared (if this packet was relayed).
5142 */
5143 first_link_addr = NULL;
5144 chk_packet = packet->dhcpv6_container_packet;
5145 while (chk_packet != NULL) {
5146 link_addr = &chk_packet->dhcpv6_link_address;
5147 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr) &&
5148 !IN6_IS_ADDR_LINKLOCAL(link_addr)) {
5149 first_link_addr = link_addr;
5150 break;
5151 }
5152 chk_packet = chk_packet->dhcpv6_container_packet;
5153 }
5154
5155 /*
5156 * If there is a relayed link address, find the subnet associated
5157 * with that, and use that to get the appropriate
5158 * shared_network.
5159 */
5160 if (first_link_addr != NULL) {
5161 tmp_addr.len = sizeof(*first_link_addr);
5162 memcpy(tmp_addr.iabuf,
5163 first_link_addr, sizeof(*first_link_addr));
5164 subnet = NULL;
5165 if (!find_subnet(&subnet, tmp_addr, MDL)) {
5166 log_debug("No subnet found for link-address %s.",
5167 piaddr(tmp_addr));
5168 return ISC_R_NOTFOUND;
5169 }
5170 status = shared_network_reference(shared,
5171 subnet->shared_network, MDL);
5172 subnet_dereference(&subnet, MDL);
5173
5174 /*
5175 * If there is no link address, we will use the interface
5176 * that this packet came in on to pick the shared_network.
5177 */
5178 } else if (packet->interface != NULL) {
5179 status = shared_network_reference(shared,
5180 packet->interface->shared_network,
5181 MDL);
5182 if (packet->dhcpv6_container_packet != NULL) {
5183 log_info("[L2 Relay] No link address in relay packet "
5184 "assuming L2 relay and using receiving "
5185 "interface");
5186 }
5187
5188 } else {
5189 /*
5190 * We shouldn't be able to get here but if there is no link
5191 * address and no interface we don't know where to get the
5192 * pool from log an error and return an error.
5193 */
5194 log_error("No interface and no link address "
5195 "can't determine pool");
5196 status = DHCP_R_INVALIDARG;
5197 }
5198
5199 return status;
5200 }
5201
5202 /*
5203 * When a client thinks it might be on a new link, it sends a
5204 * Confirm message.
5205 *
5206 * From RFC3315 section 18.2.2:
5207 *
5208 * When the server receives a Confirm message, the server determines
5209 * whether the addresses in the Confirm message are appropriate for the
5210 * link to which the client is attached. If all of the addresses in the
5211 * Confirm message pass this test, the server returns a status of
5212 * Success. If any of the addresses do not pass this test, the server
5213 * returns a status of NotOnLink. If the server is unable to perform
5214 * this test (for example, the server does not have information about
5215 * prefixes on the link to which the client is connected), or there were
5216 * no addresses in any of the IAs sent by the client, the server MUST
5217 * NOT send a reply to the client.
5218 */
5219
5220 static void
5221 dhcpv6_confirm(struct data_string *reply_ret, struct packet *packet) {
5222 struct shared_network *shared;
5223 struct subnet *subnet;
5224 struct option_cache *ia, *ta, *oc;
5225 struct data_string cli_enc_opt_data, iaaddr, client_id, packet_oro;
5226 struct option_state *cli_enc_opt_state, *opt_state;
5227 struct iaddr cli_addr;
5228 int pass;
5229 isc_boolean_t inappropriate, has_addrs;
5230 char reply_data[65536];
5231 struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data;
5232 int reply_ofs = (int)(offsetof(struct dhcpv6_packet, options));
5233
5234 /*
5235 * Basic client message validation.
5236 */
5237 memset(&client_id, 0, sizeof(client_id));
5238 if (!valid_client_msg(packet, &client_id)) {
5239 return;
5240 }
5241
5242 /*
5243 * Do not process Confirms that do not have IA's we do not recognize.
5244 */
5245 ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
5246 ta = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_TA);
5247 if ((ia == NULL) && (ta == NULL))
5248 return;
5249
5250 /*
5251 * IA_PD's are simply ignored.
5252 */
5253 delete_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
5254
5255 /*
5256 * Bit of variable initialization.
5257 */
5258 opt_state = cli_enc_opt_state = NULL;
5259 memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
5260 memset(&iaaddr, 0, sizeof(iaaddr));
5261 memset(&packet_oro, 0, sizeof(packet_oro));
5262
5263 /* Determine what shared network the client is connected to. We
5264 * must not respond if we don't have any information about the
5265 * network the client is on.
5266 */
5267 shared = NULL;
5268 if ((shared_network_from_packet6(&shared, packet) != ISC_R_SUCCESS) ||
5269 (shared == NULL))
5270 goto exit;
5271
5272 /* If there are no recorded subnets, then we have no
5273 * information about this subnet - ignore Confirms.
5274 */
5275 subnet = shared->subnets;
5276 if (subnet == NULL)
5277 goto exit;
5278
5279 /* Are the addresses in all the IA's appropriate for that link? */
5280 has_addrs = inappropriate = ISC_FALSE;
5281 pass = D6O_IA_NA;
5282 while(!inappropriate) {
5283 /* If we've reached the end of the IA_NA pass, move to the
5284 * IA_TA pass.
5285 */
5286 if ((pass == D6O_IA_NA) && (ia == NULL)) {
5287 pass = D6O_IA_TA;
5288 ia = ta;
5289 }
5290
5291 /* If we've reached the end of all passes, we're done. */
5292 if (ia == NULL)
5293 break;
5294
5295 if (((pass == D6O_IA_NA) &&
5296 !get_encapsulated_IA_state(&cli_enc_opt_state,
5297 &cli_enc_opt_data,
5298 packet, ia, IA_NA_OFFSET)) ||
5299 ((pass == D6O_IA_TA) &&
5300 !get_encapsulated_IA_state(&cli_enc_opt_state,
5301 &cli_enc_opt_data,
5302 packet, ia, IA_TA_OFFSET))) {
5303 goto exit;
5304 }
5305
5306 oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
5307 D6O_IAADDR);
5308
5309 for ( ; oc != NULL ; oc = oc->next) {
5310 if (!evaluate_option_cache(&iaaddr, packet, NULL, NULL,
5311 packet->options, NULL,
5312 &global_scope, oc, MDL) ||
5313 (iaaddr.len < IAADDR_OFFSET)) {
5314 log_error("dhcpv6_confirm: "
5315 "error evaluating IAADDR.");
5316 goto exit;
5317 }
5318
5319 /* Copy out the IPv6 address for processing. */
5320 cli_addr.len = 16;
5321 memcpy(cli_addr.iabuf, iaaddr.data, 16);
5322
5323 data_string_forget(&iaaddr, MDL);
5324
5325 /* Record that we've processed at least one address. */
5326 has_addrs = ISC_TRUE;
5327
5328 /* Find out if any subnets cover this address. */
5329 for (subnet = shared->subnets ; subnet != NULL ;
5330 subnet = subnet->next_sibling) {
5331 if (addr_eq(subnet_number(cli_addr,
5332 subnet->netmask),
5333 subnet->net))
5334 break;
5335 }
5336
5337 /* If we reach the end of the subnet list, and no
5338 * subnet matches the client address, then it must
5339 * be inappropriate to the link (so far as our
5340 * configuration says). Once we've found one
5341 * inappropriate address, there is no reason to
5342 * continue searching.
5343 */
5344 if (subnet == NULL) {
5345 inappropriate = ISC_TRUE;
5346 break;
5347 }
5348 }
5349
5350 option_state_dereference(&cli_enc_opt_state, MDL);
5351 data_string_forget(&cli_enc_opt_data, MDL);
5352
5353 /* Advance to the next IA_*. */
5354 ia = ia->next;
5355 }
5356
5357 /* If the client supplied no addresses, do not reply. */
5358 if (!has_addrs)
5359 goto exit;
5360
5361 /*
5362 * Set up reply.
5363 */
5364 if (!start_reply(packet, &client_id, NULL, &opt_state, reply)) {
5365 goto exit;
5366 }
5367
5368 /*
5369 * Set our status.
5370 */
5371 if (inappropriate) {
5372 if (!set_status_code(STATUS_NotOnLink,
5373 "Some of the addresses are not on link.",
5374 opt_state)) {
5375 goto exit;
5376 }
5377 } else {
5378 if (!set_status_code(STATUS_Success,
5379 "All addresses still on link.",
5380 opt_state)) {
5381 goto exit;
5382 }
5383 }
5384
5385 /*
5386 * Only one option: add it.
5387 */
5388 reply_ofs += store_options6(reply_data+reply_ofs,
5389 sizeof(reply_data)-reply_ofs,
5390 opt_state, packet,
5391 required_opts, &packet_oro);
5392
5393 /*
5394 * Return our reply to the caller.
5395 */
5396 reply_ret->len = reply_ofs;
5397 reply_ret->buffer = NULL;
5398 if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) {
5399 log_fatal("No memory to store reply.");
5400 }
5401 reply_ret->data = reply_ret->buffer->data;
5402 memcpy(reply_ret->buffer->data, reply, reply_ofs);
5403
5404 exit:
5405 /* Cleanup any stale data strings. */
5406 if (cli_enc_opt_data.buffer != NULL)
5407 data_string_forget(&cli_enc_opt_data, MDL);
5408 if (iaaddr.buffer != NULL)
5409 data_string_forget(&iaaddr, MDL);
5410 if (client_id.buffer != NULL)
5411 data_string_forget(&client_id, MDL);
5412 if (packet_oro.buffer != NULL)
5413 data_string_forget(&packet_oro, MDL);
5414
5415 /* Release any stale option states. */
5416 if (cli_enc_opt_state != NULL)
5417 option_state_dereference(&cli_enc_opt_state, MDL);
5418 if (opt_state != NULL)
5419 option_state_dereference(&opt_state, MDL);
5420 }
5421
5422 /*
5423 * Renew is when a client wants to extend its lease/prefix, at time T1.
5424 *
5425 * We handle this the same as if the client wants a new lease/prefix,
5426 * except for the error code of when addresses don't match.
5427 */
5428
5429 static void
5430 dhcpv6_renew(struct data_string *reply, struct packet *packet) {
5431 struct data_string client_id;
5432 struct data_string server_id;
5433
5434 /*
5435 * Validate the request.
5436 */
5437 if (!valid_client_resp(packet, &client_id, &server_id)) {
5438 return;
5439 }
5440
5441 /* If the RENEW arrived via unicast and unicast option isn't set,
5442 * reject it per RFC 3315, Sec 18.2.3 */
5443 if (packet->unicast == ISC_TRUE &&
5444 is_unicast_option_defined(packet) == ISC_FALSE) {
5445 unicast_reject(reply, packet, &client_id, &server_id);
5446 } else {
5447 /*
5448 * Renew our lease.
5449 */
5450 lease_to_client(reply, packet, &client_id, &server_id);
5451 }
5452
5453 /*
5454 * Cleanup.
5455 */
5456 data_string_forget(&server_id, MDL);
5457 data_string_forget(&client_id, MDL);
5458 }
5459
5460 /*
5461 * Rebind is when a client wants to extend its lease, at time T2.
5462 *
5463 * We handle this the same as if the client wants a new lease, except
5464 * for the error code of when addresses don't match.
5465 */
5466
5467 static void
5468 dhcpv6_rebind(struct data_string *reply, struct packet *packet) {
5469 struct data_string client_id;
5470
5471 if (!valid_client_msg(packet, &client_id)) {
5472 return;
5473 }
5474
5475 lease_to_client(reply, packet, &client_id, NULL);
5476
5477 data_string_forget(&client_id, MDL);
5478 }
5479
5480 static void
5481 ia_na_match_decline(const struct data_string *client_id,
5482 const struct data_string *iaaddr,
5483 struct iasubopt *lease)
5484 {
5485 char tmp_addr[INET6_ADDRSTRLEN];
5486
5487 log_error("Client %s reports address %s is "
5488 "already in use by another host!",
5489 print_hex_1(client_id->len, client_id->data, 60),
5490 inet_ntop(AF_INET6, iaaddr->data,
5491 tmp_addr, sizeof(tmp_addr)));
5492 if (lease != NULL) {
5493 decline_lease6(lease->ipv6_pool, lease);
5494 lease->ia->cltt = cur_time;
5495 write_ia(lease->ia);
5496 }
5497 }
5498
5499 static void
5500 ia_na_nomatch_decline(const struct data_string *client_id,
5501 const struct data_string *iaaddr,
5502 u_int32_t *ia_na_id,
5503 struct packet *packet,
5504 char *reply_data,
5505 int *reply_ofs,
5506 int reply_len)
5507 {
5508 char tmp_addr[INET6_ADDRSTRLEN];
5509 struct option_state *host_opt_state;
5510 int len;
5511
5512 log_info("Client %s declines address %s, which is not offered to it.",
5513 print_hex_1(client_id->len, client_id->data, 60),
5514 inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
5515
5516 /*
5517 * Create state for this IA_NA.
5518 */
5519 host_opt_state = NULL;
5520 if (!option_state_allocate(&host_opt_state, MDL)) {
5521 log_error("ia_na_nomatch_decline: out of memory "
5522 "allocating option_state.");
5523 goto exit;
5524 }
5525
5526 if (!set_status_code(STATUS_NoBinding, "Decline for unknown address.",
5527 host_opt_state)) {
5528 goto exit;
5529 }
5530
5531 /*
5532 * Insure we have enough space
5533 */
5534 if (reply_len < (*reply_ofs + 16)) {
5535 log_error("ia_na_nomatch_decline: "
5536 "out of space for reply packet.");
5537 goto exit;
5538 }
5539
5540 /*
5541 * Put our status code into the reply packet.
5542 */
5543 len = store_options6(reply_data+(*reply_ofs)+16,
5544 reply_len-(*reply_ofs)-16,
5545 host_opt_state, packet,
5546 required_opts_STATUS_CODE, NULL);
5547
5548 /*
5549 * Store the non-encapsulated option data for this
5550 * IA_NA into our reply packet. Defined in RFC 3315,
5551 * section 22.4.
5552 */
5553 /* option number */
5554 putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_NA);
5555 /* option length */
5556 putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
5557 /* IA_NA, copied from the client */
5558 memcpy(reply_data+(*reply_ofs)+4, ia_na_id, 4);
5559 /* t1 and t2, odd that we need them, but here it is */
5560 putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
5561 putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
5562
5563 /*
5564 * Get ready for next IA_NA.
5565 */
5566 *reply_ofs += (len + 16);
5567
5568 exit:
5569 option_state_dereference(&host_opt_state, MDL);
5570 }
5571
5572 static void
5573 iterate_over_ia_na(struct data_string *reply_ret,
5574 struct packet *packet,
5575 const struct data_string *client_id,
5576 const struct data_string *server_id,
5577 const char *packet_type,
5578 void (*ia_na_match)(),
5579 void (*ia_na_nomatch)())
5580 {
5581 struct option_state *opt_state;
5582 struct host_decl *packet_host;
5583 struct option_cache *ia;
5584 struct option_cache *oc;
5585 /* cli_enc_... variables come from the IA_NA/IA_TA options */
5586 struct data_string cli_enc_opt_data;
5587 struct option_state *cli_enc_opt_state;
5588 struct host_decl *host;
5589 struct data_string iaaddr;
5590 struct data_string fixed_addr;
5591 char reply_data[65536];
5592 struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data;
5593 int reply_ofs = (int)(offsetof(struct dhcpv6_packet, options));
5594 char status_msg[32];
5595 struct iasubopt *lease;
5596 struct ia_xx *existing_ia_na;
5597 int i;
5598 struct data_string key;
5599 u_int32_t iaid;
5600
5601 /*
5602 * Initialize to empty values, in case we have to exit early.
5603 */
5604 opt_state = NULL;
5605 memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
5606 cli_enc_opt_state = NULL;
5607 memset(&iaaddr, 0, sizeof(iaaddr));
5608 memset(&fixed_addr, 0, sizeof(fixed_addr));
5609 lease = NULL;
5610
5611 /*
5612 * Find the host record that matches from the packet, if any.
5613 */
5614 packet_host = NULL;
5615 find_hosts6(&packet_host, packet, client_id, MDL);
5616
5617 /*
5618 * Set our reply information.
5619 */
5620 reply->msg_type = DHCPV6_REPLY;
5621 memcpy(reply->transaction_id, packet->dhcpv6_transaction_id,
5622 sizeof(reply->transaction_id));
5623
5624 /*
5625 * Build our option state for reply.
5626 */
5627 opt_state = NULL;
5628 if (!option_state_allocate(&opt_state, MDL)) {
5629 log_error("iterate_over_ia_na: no memory for option_state.");
5630 goto exit;
5631 }
5632 execute_statements_in_scope(NULL, packet, NULL, NULL,
5633 packet->options, opt_state,
5634 &global_scope, root_group, NULL, NULL);
5635
5636 /*
5637 * RFC 3315, section 18.2.7 tells us which options to include.
5638 */
5639 oc = lookup_option(&dhcpv6_universe, opt_state, D6O_SERVERID);
5640 if (oc == NULL) {
5641 if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
5642 (unsigned char *)server_duid.data,
5643 server_duid.len, D6O_SERVERID, 0)) {
5644 log_error("iterate_over_ia_na: "
5645 "error saving server identifier.");
5646 goto exit;
5647 }
5648 }
5649
5650 if (!save_option_buffer(&dhcpv6_universe, opt_state,
5651 client_id->buffer,
5652 (unsigned char *)client_id->data,
5653 client_id->len,
5654 D6O_CLIENTID, 0)) {
5655 log_error("iterate_over_ia_na: "
5656 "error saving client identifier.");
5657 goto exit;
5658 }
5659
5660 snprintf(status_msg, sizeof(status_msg), "%s received.", packet_type);
5661 if (!set_status_code(STATUS_Success, status_msg, opt_state)) {
5662 goto exit;
5663 }
5664
5665 /*
5666 * Add our options that are not associated with any IA_NA or IA_TA.
5667 */
5668 reply_ofs += store_options6(reply_data+reply_ofs,
5669 sizeof(reply_data)-reply_ofs,
5670 opt_state, packet,
5671 required_opts, NULL);
5672
5673 /*
5674 * Loop through the IA_NA reported by the client, and deal with
5675 * addresses reported as already in use.
5676 */
5677 for (ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
5678 ia != NULL; ia = ia->next) {
5679
5680 if (!get_encapsulated_IA_state(&cli_enc_opt_state,
5681 &cli_enc_opt_data,
5682 packet, ia, IA_NA_OFFSET)) {
5683 goto exit;
5684 }
5685
5686 iaid = getULong(cli_enc_opt_data.data);
5687
5688 /*
5689 * XXX: It is possible that we can get multiple addresses
5690 * sent by the client. We don't send multiple
5691 * addresses, so this indicates a client error.
5692 * We should check for multiple IAADDR options, log
5693 * if found, and set as an error.
5694 */
5695 oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
5696 D6O_IAADDR);
5697 if (oc == NULL) {
5698 /* no address given for this IA, ignore */
5699 option_state_dereference(&cli_enc_opt_state, MDL);
5700 data_string_forget(&cli_enc_opt_data, MDL);
5701 continue;
5702 }
5703
5704 memset(&iaaddr, 0, sizeof(iaaddr));
5705 if (!evaluate_option_cache(&iaaddr, packet, NULL, NULL,
5706 packet->options, NULL,
5707 &global_scope, oc, MDL)) {
5708 log_error("iterate_over_ia_na: "
5709 "error evaluating IAADDR.");
5710 goto exit;
5711 }
5712
5713 /*
5714 * Now we need to figure out which host record matches
5715 * this IA_NA and IAADDR (encapsulated option contents
5716 * matching a host record by option).
5717 *
5718 * XXX: We don't currently track IA_NA separately, but
5719 * we will need to do this!
5720 */
5721 host = NULL;
5722 if (!find_hosts_by_option(&host, packet,
5723 cli_enc_opt_state, MDL)) {
5724 if (packet_host != NULL) {
5725 host = packet_host;
5726 } else {
5727 host = NULL;
5728 }
5729 }
5730 while (host != NULL) {
5731 if (host->fixed_addr != NULL) {
5732 if (!evaluate_option_cache(&fixed_addr, NULL,
5733 NULL, NULL, NULL,
5734 NULL, &global_scope,
5735 host->fixed_addr,
5736 MDL)) {
5737 log_error("iterate_over_ia_na: error "
5738 "evaluating host address.");
5739 goto exit;
5740 }
5741 if ((iaaddr.len >= 16) &&
5742 !memcmp(fixed_addr.data, iaaddr.data, 16)) {
5743 data_string_forget(&fixed_addr, MDL);
5744 break;
5745 }
5746 data_string_forget(&fixed_addr, MDL);
5747 }
5748 host = host->n_ipaddr;
5749 }
5750
5751 if ((host == NULL) && (iaaddr.len >= IAADDR_OFFSET)) {
5752 /*
5753 * Find existing IA_NA.
5754 */
5755 if (ia_make_key(&key, iaid,
5756 (char *)client_id->data,
5757 client_id->len,
5758 MDL) != ISC_R_SUCCESS) {
5759 log_fatal("iterate_over_ia_na: no memory for "
5760 "key.");
5761 }
5762
5763 existing_ia_na = NULL;
5764 if (ia_hash_lookup(&existing_ia_na, ia_na_active,
5765 (unsigned char *)key.data,
5766 key.len, MDL)) {
5767 /*
5768 * Make sure this address is in the IA_NA.
5769 */
5770 for (i=0; i<existing_ia_na->num_iasubopt; i++) {
5771 struct iasubopt *tmp;
5772 struct in6_addr *in6_addr;
5773
5774 tmp = existing_ia_na->iasubopt[i];
5775 in6_addr = &tmp->addr;
5776 if (memcmp(in6_addr,
5777 iaaddr.data, 16) == 0) {
5778 iasubopt_reference(&lease,
5779 tmp, MDL);
5780 break;
5781 }
5782 }
5783 }
5784
5785 data_string_forget(&key, MDL);
5786 }
5787
5788 if ((host != NULL) || (lease != NULL)) {
5789 ia_na_match(client_id, &iaaddr, lease);
5790 } else {
5791 ia_na_nomatch(client_id, &iaaddr,
5792 (u_int32_t *)cli_enc_opt_data.data,
5793 packet, reply_data, &reply_ofs,
5794 sizeof(reply_data));
5795 }
5796
5797 if (lease != NULL) {
5798 iasubopt_dereference(&lease, MDL);
5799 }
5800
5801 data_string_forget(&iaaddr, MDL);
5802 option_state_dereference(&cli_enc_opt_state, MDL);
5803 data_string_forget(&cli_enc_opt_data, MDL);
5804 }
5805
5806 /*
5807 * Return our reply to the caller.
5808 */
5809 reply_ret->len = reply_ofs;
5810 reply_ret->buffer = NULL;
5811 if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) {
5812 log_fatal("No memory to store reply.");
5813 }
5814 reply_ret->data = reply_ret->buffer->data;
5815 memcpy(reply_ret->buffer->data, reply, reply_ofs);
5816
5817 exit:
5818 if (lease != NULL) {
5819 iasubopt_dereference(&lease, MDL);
5820 }
5821 if (fixed_addr.buffer != NULL) {
5822 data_string_forget(&fixed_addr, MDL);
5823 }
5824 if (iaaddr.buffer != NULL) {
5825 data_string_forget(&iaaddr, MDL);
5826 }
5827 if (cli_enc_opt_state != NULL) {
5828 option_state_dereference(&cli_enc_opt_state, MDL);
5829 }
5830 if (cli_enc_opt_data.buffer != NULL) {
5831 data_string_forget(&cli_enc_opt_data, MDL);
5832 }
5833 if (opt_state != NULL) {
5834 option_state_dereference(&opt_state, MDL);
5835 }
5836 }
5837
5838 /*
5839 * Decline means a client has detected that something else is using an
5840 * address we gave it.
5841 *
5842 * Since we're only dealing with fixed leases for now, there's not
5843 * much we can do, other that log the occurrence.
5844 *
5845 * When we start issuing addresses from pools, then we will have to
5846 * record our declined addresses and issue another. In general with
5847 * IPv6 there is no worry about DoS by clients exhausting space, but
5848 * we still need to be aware of this possibility.
5849 */
5850
5851 /* TODO: IA_TA */
5852 static void
5853 dhcpv6_decline(struct data_string *reply, struct packet *packet) {
5854 struct data_string client_id;
5855 struct data_string server_id;
5856
5857 /*
5858 * Validate our input.
5859 */
5860 if (!valid_client_resp(packet, &client_id, &server_id)) {
5861 return;
5862 }
5863
5864 /* If the DECLINE arrived via unicast and unicast option isn't set,
5865 * reject it per RFC 3315, Sec 18.2.7 */
5866 if (packet->unicast == ISC_TRUE &&
5867 is_unicast_option_defined(packet) == ISC_FALSE) {
5868 unicast_reject(reply, packet, &client_id, &server_id);
5869 } else {
5870 /*
5871 * Undefined for IA_PD.
5872 */
5873 delete_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
5874
5875 /*
5876 * And operate on each IA_NA in this packet.
5877 */
5878 iterate_over_ia_na(reply, packet, &client_id, &server_id,
5879 "Decline", ia_na_match_decline,
5880 ia_na_nomatch_decline);
5881
5882 }
5883
5884 data_string_forget(&server_id, MDL);
5885 data_string_forget(&client_id, MDL);
5886 }
5887
5888 static void
5889 ia_na_match_release(const struct data_string *client_id,
5890 const struct data_string *iaaddr,
5891 struct iasubopt *lease)
5892 {
5893 char tmp_addr[INET6_ADDRSTRLEN];
5894
5895 log_info("Client %s releases address %s",
5896 print_hex_1(client_id->len, client_id->data, 60),
5897 inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
5898 if (lease != NULL) {
5899 release_lease6(lease->ipv6_pool, lease);
5900 lease->ia->cltt = cur_time;
5901 write_ia(lease->ia);
5902 }
5903 }
5904
5905 static void
5906 ia_na_nomatch_release(const struct data_string *client_id,
5907 const struct data_string *iaaddr,
5908 u_int32_t *ia_na_id,
5909 struct packet *packet,
5910 char *reply_data,
5911 int *reply_ofs,
5912 int reply_len)
5913 {
5914 char tmp_addr[INET6_ADDRSTRLEN];
5915 struct option_state *host_opt_state;
5916 int len;
5917
5918 log_info("Client %s releases address %s, which is not leased to it.",
5919 print_hex_1(client_id->len, client_id->data, 60),
5920 inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
5921
5922 /*
5923 * Create state for this IA_NA.
5924 */
5925 host_opt_state = NULL;
5926 if (!option_state_allocate(&host_opt_state, MDL)) {
5927 log_error("ia_na_nomatch_release: out of memory "
5928 "allocating option_state.");
5929 goto exit;
5930 }
5931
5932 if (!set_status_code(STATUS_NoBinding,
5933 "Release for non-leased address.",
5934 host_opt_state)) {
5935 goto exit;
5936 }
5937
5938 /*
5939 * Insure we have enough space
5940 */
5941 if (reply_len < (*reply_ofs + 16)) {
5942 log_error("ia_na_nomatch_release: "
5943 "out of space for reply packet.");
5944 goto exit;
5945 }
5946
5947 /*
5948 * Put our status code into the reply packet.
5949 */
5950 len = store_options6(reply_data+(*reply_ofs)+16,
5951 reply_len-(*reply_ofs)-16,
5952 host_opt_state, packet,
5953 required_opts_STATUS_CODE, NULL);
5954
5955 /*
5956 * Store the non-encapsulated option data for this
5957 * IA_NA into our reply packet. Defined in RFC 3315,
5958 * section 22.4.
5959 */
5960 /* option number */
5961 putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_NA);
5962 /* option length */
5963 putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
5964 /* IA_NA, copied from the client */
5965 memcpy(reply_data+(*reply_ofs)+4, ia_na_id, 4);
5966 /* t1 and t2, odd that we need them, but here it is */
5967 putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
5968 putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
5969
5970 /*
5971 * Get ready for next IA_NA.
5972 */
5973 *reply_ofs += (len + 16);
5974
5975 exit:
5976 option_state_dereference(&host_opt_state, MDL);
5977 }
5978
5979 static void
5980 ia_pd_match_release(const struct data_string *client_id,
5981 const struct data_string *iapref,
5982 struct iasubopt *prefix)
5983 {
5984 char tmp_addr[INET6_ADDRSTRLEN];
5985
5986 log_info("Client %s releases prefix %s/%u",
5987 print_hex_1(client_id->len, client_id->data, 60),
5988 inet_ntop(AF_INET6, iapref->data + 9,
5989 tmp_addr, sizeof(tmp_addr)),
5990 (unsigned) getUChar(iapref->data + 8));
5991 if (prefix != NULL) {
5992 release_lease6(prefix->ipv6_pool, prefix);
5993 prefix->ia->cltt = cur_time;
5994 write_ia(prefix->ia);
5995 }
5996 }
5997
5998 static void
5999 ia_pd_nomatch_release(const struct data_string *client_id,
6000 const struct data_string *iapref,
6001 u_int32_t *ia_pd_id,
6002 struct packet *packet,
6003 char *reply_data,
6004 int *reply_ofs,
6005 int reply_len)
6006 {
6007 char tmp_addr[INET6_ADDRSTRLEN];
6008 struct option_state *host_opt_state;
6009 int len;
6010
6011 log_info("Client %s releases prefix %s/%u, which is not leased to it.",
6012 print_hex_1(client_id->len, client_id->data, 60),
6013 inet_ntop(AF_INET6, iapref->data + 9,
6014 tmp_addr, sizeof(tmp_addr)),
6015 (unsigned) getUChar(iapref->data + 8));
6016
6017 /*
6018 * Create state for this IA_PD.
6019 */
6020 host_opt_state = NULL;
6021 if (!option_state_allocate(&host_opt_state, MDL)) {
6022 log_error("ia_pd_nomatch_release: out of memory "
6023 "allocating option_state.");
6024 goto exit;
6025 }
6026
6027 if (!set_status_code(STATUS_NoBinding,
6028 "Release for non-leased prefix.",
6029 host_opt_state)) {
6030 goto exit;
6031 }
6032
6033 /*
6034 * Insure we have enough space
6035 */
6036 if (reply_len < (*reply_ofs + 16)) {
6037 log_error("ia_pd_nomatch_release: "
6038 "out of space for reply packet.");
6039 goto exit;
6040 }
6041
6042 /*
6043 * Put our status code into the reply packet.
6044 */
6045 len = store_options6(reply_data+(*reply_ofs)+16,
6046 reply_len-(*reply_ofs)-16,
6047 host_opt_state, packet,
6048 required_opts_STATUS_CODE, NULL);
6049
6050 /*
6051 * Store the non-encapsulated option data for this
6052 * IA_PD into our reply packet. Defined in RFC 3315,
6053 * section 22.4.
6054 */
6055 /* option number */
6056 putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_PD);
6057 /* option length */
6058 putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
6059 /* IA_PD, copied from the client */
6060 memcpy(reply_data+(*reply_ofs)+4, ia_pd_id, 4);
6061 /* t1 and t2, odd that we need them, but here it is */
6062 putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
6063 putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
6064
6065 /*
6066 * Get ready for next IA_PD.
6067 */
6068 *reply_ofs += (len + 16);
6069
6070 exit:
6071 option_state_dereference(&host_opt_state, MDL);
6072 }
6073
6074 static void
6075 iterate_over_ia_pd(struct data_string *reply_ret,
6076 struct packet *packet,
6077 const struct data_string *client_id,
6078 const struct data_string *server_id,
6079 const char *packet_type,
6080 void (*ia_pd_match)(),
6081 void (*ia_pd_nomatch)())
6082 {
6083 struct data_string reply_new;
6084 int reply_len;
6085 struct option_state *opt_state;
6086 struct host_decl *packet_host;
6087 struct option_cache *ia;
6088 struct option_cache *oc;
6089 /* cli_enc_... variables come from the IA_PD options */
6090 struct data_string cli_enc_opt_data;
6091 struct option_state *cli_enc_opt_state;
6092 struct host_decl *host;
6093 struct data_string iaprefix;
6094 char reply_data[65536];
6095 int reply_ofs;
6096 struct iasubopt *prefix;
6097 struct ia_xx *existing_ia_pd;
6098 int i;
6099 struct data_string key;
6100 u_int32_t iaid;
6101
6102 /*
6103 * Initialize to empty values, in case we have to exit early.
6104 */
6105 memset(&reply_new, 0, sizeof(reply_new));
6106 opt_state = NULL;
6107 memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
6108 cli_enc_opt_state = NULL;
6109 memset(&iaprefix, 0, sizeof(iaprefix));
6110 prefix = NULL;
6111
6112 /*
6113 * Compute the available length for the reply.
6114 */
6115 reply_len = sizeof(reply_data) - reply_ret->len;
6116 reply_ofs = 0;
6117
6118 /*
6119 * Find the host record that matches from the packet, if any.
6120 */
6121 packet_host = NULL;
6122 find_hosts6(&packet_host, packet, client_id, MDL);
6123
6124 /*
6125 * Build our option state for reply.
6126 */
6127 opt_state = NULL;
6128 if (!option_state_allocate(&opt_state, MDL)) {
6129 log_error("iterate_over_ia_pd: no memory for option_state.");
6130 goto exit;
6131 }
6132 execute_statements_in_scope(NULL, packet, NULL, NULL,
6133 packet->options, opt_state,
6134 &global_scope, root_group, NULL, NULL);
6135
6136 /*
6137 * Loop through the IA_PD reported by the client, and deal with
6138 * prefixes reported as already in use.
6139 */
6140 for (ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
6141 ia != NULL; ia = ia->next) {
6142
6143 if (!get_encapsulated_IA_state(&cli_enc_opt_state,
6144 &cli_enc_opt_data,
6145 packet, ia, IA_PD_OFFSET)) {
6146 goto exit;
6147 }
6148
6149 iaid = getULong(cli_enc_opt_data.data);
6150
6151 oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
6152 D6O_IAPREFIX);
6153 if (oc == NULL) {
6154 /* no prefix given for this IA_PD, ignore */
6155 option_state_dereference(&cli_enc_opt_state, MDL);
6156 data_string_forget(&cli_enc_opt_data, MDL);
6157 continue;
6158 }
6159
6160 for (; oc != NULL; oc = oc->next) {
6161 memset(&iaprefix, 0, sizeof(iaprefix));
6162 if (!evaluate_option_cache(&iaprefix, packet, NULL, NULL,
6163 packet->options, NULL,
6164 &global_scope, oc, MDL)) {
6165 log_error("iterate_over_ia_pd: "
6166 "error evaluating IAPREFIX.");
6167 goto exit;
6168 }
6169
6170 /*
6171 * Now we need to figure out which host record matches
6172 * this IA_PD and IAPREFIX (encapsulated option contents
6173 * matching a host record by option).
6174 *
6175 * XXX: We don't currently track IA_PD separately, but
6176 * we will need to do this!
6177 */
6178 host = NULL;
6179 if (!find_hosts_by_option(&host, packet,
6180 cli_enc_opt_state, MDL)) {
6181 if (packet_host != NULL) {
6182 host = packet_host;
6183 } else {
6184 host = NULL;
6185 }
6186 }
6187 while (host != NULL) {
6188 if (host->fixed_prefix != NULL) {
6189 struct iaddrcidrnetlist *l;
6190 int plen = (int) getUChar(iaprefix.data + 8);
6191
6192 for (l = host->fixed_prefix; l != NULL;
6193 l = l->next) {
6194 if (plen != l->cidrnet.bits)
6195 continue;
6196 if (memcmp(iaprefix.data + 9,
6197 l->cidrnet.lo_addr.iabuf,
6198 16) == 0)
6199 break;
6200 }
6201 if ((l != NULL) && (iaprefix.len >= 17))
6202 break;
6203 }
6204 host = host->n_ipaddr;
6205 }
6206
6207 if ((host == NULL) && (iaprefix.len >= IAPREFIX_OFFSET)) {
6208 /*
6209 * Find existing IA_PD.
6210 */
6211 if (ia_make_key(&key, iaid,
6212 (char *)client_id->data,
6213 client_id->len,
6214 MDL) != ISC_R_SUCCESS) {
6215 log_fatal("iterate_over_ia_pd: no memory for "
6216 "key.");
6217 }
6218
6219 existing_ia_pd = NULL;
6220 if (ia_hash_lookup(&existing_ia_pd, ia_pd_active,
6221 (unsigned char *)key.data,
6222 key.len, MDL)) {
6223 /*
6224 * Make sure this prefix is in the IA_PD.
6225 */
6226 for (i = 0;
6227 i < existing_ia_pd->num_iasubopt;
6228 i++) {
6229 struct iasubopt *tmp;
6230 u_int8_t plen;
6231
6232 plen = getUChar(iaprefix.data + 8);
6233 tmp = existing_ia_pd->iasubopt[i];
6234 if ((tmp->plen == plen) &&
6235 (memcmp(&tmp->addr,
6236 iaprefix.data + 9,
6237 16) == 0)) {
6238 iasubopt_reference(&prefix,
6239 tmp, MDL);
6240 break;
6241 }
6242 }
6243 }
6244
6245 data_string_forget(&key, MDL);
6246 }
6247
6248 if ((host != NULL) || (prefix != NULL)) {
6249 ia_pd_match(client_id, &iaprefix, prefix);
6250 } else {
6251 ia_pd_nomatch(client_id, &iaprefix,
6252 (u_int32_t *)cli_enc_opt_data.data,
6253 packet, reply_data, &reply_ofs,
6254 reply_len - reply_ofs);
6255 }
6256
6257 if (prefix != NULL) {
6258 iasubopt_dereference(&prefix, MDL);
6259 }
6260
6261 data_string_forget(&iaprefix, MDL);
6262 }
6263
6264 option_state_dereference(&cli_enc_opt_state, MDL);
6265 data_string_forget(&cli_enc_opt_data, MDL);
6266 }
6267
6268 /*
6269 * Return our reply to the caller.
6270 * The IA_NA routine has already filled at least the header.
6271 */
6272 reply_new.len = reply_ret->len + reply_ofs;
6273 if (!buffer_allocate(&reply_new.buffer, reply_new.len, MDL)) {
6274 log_fatal("No memory to store reply.");
6275 }
6276 reply_new.data = reply_new.buffer->data;
6277 memcpy(reply_new.buffer->data,
6278 reply_ret->buffer->data, reply_ret->len);
6279 memcpy(reply_new.buffer->data + reply_ret->len,
6280 reply_data, reply_ofs);
6281 data_string_forget(reply_ret, MDL);
6282 data_string_copy(reply_ret, &reply_new, MDL);
6283 data_string_forget(&reply_new, MDL);
6284
6285 exit:
6286 if (prefix != NULL) {
6287 iasubopt_dereference(&prefix, MDL);
6288 }
6289 if (iaprefix.buffer != NULL) {
6290 data_string_forget(&iaprefix, MDL);
6291 }
6292 if (cli_enc_opt_state != NULL) {
6293 option_state_dereference(&cli_enc_opt_state, MDL);
6294 }
6295 if (cli_enc_opt_data.buffer != NULL) {
6296 data_string_forget(&cli_enc_opt_data, MDL);
6297 }
6298 if (opt_state != NULL) {
6299 option_state_dereference(&opt_state, MDL);
6300 }
6301 }
6302
6303 /*
6304 * Release means a client is done with the leases.
6305 */
6306
6307 static void
6308 dhcpv6_release(struct data_string *reply, struct packet *packet) {
6309 struct data_string client_id;
6310 struct data_string server_id;
6311
6312 /*
6313 * Validate our input.
6314 */
6315 if (!valid_client_resp(packet, &client_id, &server_id)) {
6316 return;
6317 }
6318
6319 /* If the RELEASE arrived via unicast and unicast option isn't set,
6320 * reject it per RFC 3315, Sec 18.2.6 */
6321 if (packet->unicast == ISC_TRUE &&
6322 is_unicast_option_defined(packet) == ISC_FALSE) {
6323 unicast_reject(reply, packet, &client_id, &server_id);
6324 } else {
6325 /*
6326 * And operate on each IA_NA in this packet.
6327 */
6328 iterate_over_ia_na(reply, packet, &client_id, &server_id,
6329 "Release", ia_na_match_release,
6330 ia_na_nomatch_release);
6331
6332 /*
6333 * And operate on each IA_PD in this packet.
6334 */
6335 iterate_over_ia_pd(reply, packet, &client_id, &server_id,
6336 "Release", ia_pd_match_release,
6337 ia_pd_nomatch_release);
6338 }
6339
6340 data_string_forget(&server_id, MDL);
6341 data_string_forget(&client_id, MDL);
6342 }
6343
6344 /*
6345 * Information-Request is used by clients who have obtained an address
6346 * from other means, but want configuration information from the server.
6347 */
6348
6349 static void
6350 dhcpv6_information_request(struct data_string *reply, struct packet *packet) {
6351 struct data_string client_id;
6352 struct data_string server_id;
6353
6354 /*
6355 * Validate our input.
6356 */
6357 if (!valid_client_info_req(packet, &server_id)) {
6358 return;
6359 }
6360
6361 /*
6362 * Get our client ID, if there is one.
6363 */
6364 memset(&client_id, 0, sizeof(client_id));
6365 if (get_client_id(packet, &client_id) != ISC_R_SUCCESS) {
6366 data_string_forget(&client_id, MDL);
6367 }
6368
6369 /*
6370 * Use the lease_to_client() function. This will work fine,
6371 * because the valid_client_info_req() insures that we
6372 * don't have any IA that would cause us to allocate
6373 * resources to the client.
6374 */
6375 lease_to_client(reply, packet, &client_id,
6376 server_id.data != NULL ? &server_id : NULL);
6377
6378 /*
6379 * Cleanup.
6380 */
6381 if (client_id.data != NULL) {
6382 data_string_forget(&client_id, MDL);
6383 }
6384 data_string_forget(&server_id, MDL);
6385 }
6386
6387 /*
6388 * The Relay-forw message is sent by relays. It typically contains a
6389 * single option, which encapsulates an entire packet.
6390 *
6391 * We need to build an encapsulated reply.
6392 */
6393
6394 /* XXX: this is very, very similar to do_packet6(), and should probably
6395 be combined in a clever way */
6396 /* DHCPv6 server side */
6397 static void
6398 dhcpv6_relay_forw(struct data_string *reply_ret, struct packet *packet) {
6399 struct option_cache *oc;
6400 struct data_string enc_opt_data;
6401 struct packet *enc_packet;
6402 unsigned char msg_type;
6403 const struct dhcpv6_packet *msg;
6404 const struct dhcpv6_relay_packet *relay;
6405 struct data_string enc_reply;
6406 char link_addr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6407 char peer_addr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6408 struct data_string a_opt, packet_ero;
6409 struct option_state *opt_state;
6410 static char reply_data[65536];
6411 struct dhcpv6_relay_packet *reply;
6412 int reply_ofs;
6413
6414 /*
6415 * Initialize variables for early exit.
6416 */
6417 opt_state = NULL;
6418 memset(&a_opt, 0, sizeof(a_opt));
6419 memset(&packet_ero, 0, sizeof(packet_ero));
6420 memset(&enc_reply, 0, sizeof(enc_reply));
6421 memset(&enc_opt_data, 0, sizeof(enc_opt_data));
6422 enc_packet = NULL;
6423
6424 /*
6425 * Get our encapsulated relay message.
6426 */
6427 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_RELAY_MSG);
6428 if (oc == NULL) {
6429 inet_ntop(AF_INET6, &packet->dhcpv6_link_address,
6430 link_addr, sizeof(link_addr));
6431 inet_ntop(AF_INET6, &packet->dhcpv6_peer_address,
6432 peer_addr, sizeof(peer_addr));
6433 log_info("Relay-forward from %s with link address=%s and "
6434 "peer address=%s missing Relay Message option.",
6435 piaddr(packet->client_addr), link_addr, peer_addr);
6436 goto exit;
6437 }
6438
6439 if (!evaluate_option_cache(&enc_opt_data, NULL, NULL, NULL,
6440 NULL, NULL, &global_scope, oc, MDL)) {
6441 /* should be dhcpv6_relay_forw */
6442 log_error("dhcpv6_forw_relay: error evaluating "
6443 "relayed message.");
6444 goto exit;
6445 }
6446
6447 if (!packet6_len_okay((char *)enc_opt_data.data, enc_opt_data.len)) {
6448 /* should be dhcpv6_relay_forw */
6449 log_error("dhcpv6_forw_relay: encapsulated packet too short.");
6450 goto exit;
6451 }
6452
6453 /*
6454 * Build a packet structure from this encapsulated packet.
6455 */
6456 enc_packet = NULL;
6457 if (!packet_allocate(&enc_packet, MDL)) {
6458 /* should be dhcpv6_relay_forw */
6459 log_error("dhcpv6_forw_relay: "
6460 "no memory for encapsulated packet.");
6461 goto exit;
6462 }
6463
6464 if (!option_state_allocate(&enc_packet->options, MDL)) {
6465 /* should be dhcpv6_relay_forw */
6466 log_error("dhcpv6_forw_relay: "
6467 "no memory for encapsulated packet's options.");
6468 goto exit;
6469 }
6470
6471 enc_packet->client_port = packet->client_port;
6472 enc_packet->client_addr = packet->client_addr;
6473 interface_reference(&enc_packet->interface, packet->interface, MDL);
6474 enc_packet->dhcpv6_container_packet = packet;
6475
6476 msg_type = enc_opt_data.data[0];
6477 if ((msg_type == DHCPV6_RELAY_FORW) ||
6478 (msg_type == DHCPV6_RELAY_REPL)) {
6479 int relaylen = (int)(offsetof(struct dhcpv6_relay_packet, options));
6480 relay = (struct dhcpv6_relay_packet *)enc_opt_data.data;
6481 enc_packet->dhcpv6_msg_type = relay->msg_type;
6482
6483 /* relay-specific data */
6484 enc_packet->dhcpv6_hop_count = relay->hop_count;
6485 memcpy(&enc_packet->dhcpv6_link_address,
6486 relay->link_address, sizeof(relay->link_address));
6487 memcpy(&enc_packet->dhcpv6_peer_address,
6488 relay->peer_address, sizeof(relay->peer_address));
6489
6490 if (!parse_option_buffer(enc_packet->options,
6491 relay->options,
6492 enc_opt_data.len - relaylen,
6493 &dhcpv6_universe)) {
6494 /* no logging here, as parse_option_buffer() logs all
6495 cases where it fails */
6496 goto exit;
6497 }
6498 } else if ((msg_type == DHCPV6_DHCPV4_QUERY) ||
6499 (msg_type == DHCPV6_DHCPV4_RESPONSE)) {
6500 #ifdef DHCP4o6
6501 if (!dhcpv4_over_dhcpv6 ||
6502 (msg_type == DHCPV6_DHCPV4_RESPONSE)) {
6503 log_error("dhcpv6_relay_forw: "
6504 "unsupported %s message type.",
6505 dhcpv6_type_names[msg_type]);
6506 goto exit;
6507 }
6508 forw_dhcpv4_query(packet);
6509 goto exit;
6510 #else /* DHCP4o6 */
6511 log_error("dhcpv6_relay_forw: unsupported %s message type.",
6512 dhcpv6_type_names[msg_type]);
6513 goto exit;
6514 #endif /* DHCP4o6 */
6515 } else {
6516 int msglen = (int)(offsetof(struct dhcpv6_packet, options));
6517 msg = (struct dhcpv6_packet *)enc_opt_data.data;
6518 enc_packet->dhcpv6_msg_type = msg->msg_type;
6519
6520 /* message-specific data */
6521 memcpy(enc_packet->dhcpv6_transaction_id,
6522 msg->transaction_id,
6523 sizeof(enc_packet->dhcpv6_transaction_id));
6524
6525 if (!parse_option_buffer(enc_packet->options,
6526 msg->options,
6527 enc_opt_data.len - msglen,
6528 &dhcpv6_universe)) {
6529 /* no logging here, as parse_option_buffer() logs all
6530 cases where it fails */
6531 goto exit;
6532 }
6533 }
6534
6535 /*
6536 * This is recursive. It is possible to exceed maximum packet size.
6537 * XXX: This will cause the packet send to fail.
6538 */
6539 build_dhcpv6_reply(&enc_reply, enc_packet);
6540
6541 /*
6542 * If we got no encapsulated data, then it is discarded, and
6543 * our reply-forw is also discarded.
6544 */
6545 if (enc_reply.data == NULL) {
6546 goto exit;
6547 }
6548
6549 /*
6550 * Now we can use the reply_data buffer.
6551 * Packet header stuff all comes from the forward message.
6552 */
6553 reply = (struct dhcpv6_relay_packet *)reply_data;
6554 reply->msg_type = DHCPV6_RELAY_REPL;
6555 reply->hop_count = packet->dhcpv6_hop_count;
6556 memcpy(reply->link_address, &packet->dhcpv6_link_address,
6557 sizeof(reply->link_address));
6558 memcpy(reply->peer_address, &packet->dhcpv6_peer_address,
6559 sizeof(reply->peer_address));
6560 reply_ofs = (int)(offsetof(struct dhcpv6_relay_packet, options));
6561
6562 /*
6563 * Get the reply option state.
6564 */
6565 opt_state = NULL;
6566 if (!option_state_allocate(&opt_state, MDL)) {
6567 log_error("dhcpv6_relay_forw: no memory for option state.");
6568 goto exit;
6569 }
6570
6571 /*
6572 * Append the interface-id if present.
6573 */
6574 oc = lookup_option(&dhcpv6_universe, packet->options,
6575 D6O_INTERFACE_ID);
6576 if (oc != NULL) {
6577 if (!evaluate_option_cache(&a_opt, packet,
6578 NULL, NULL,
6579 packet->options, NULL,
6580 &global_scope, oc, MDL)) {
6581 log_error("dhcpv6_relay_forw: error evaluating "
6582 "Interface ID.");
6583 goto exit;
6584 }
6585 if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
6586 (unsigned char *)a_opt.data,
6587 a_opt.len,
6588 D6O_INTERFACE_ID, 0)) {
6589 log_error("dhcpv6_relay_forw: error saving "
6590 "Interface ID.");
6591 goto exit;
6592 }
6593 data_string_forget(&a_opt, MDL);
6594 }
6595
6596 /*
6597 * Append our encapsulated stuff for caller.
6598 */
6599 if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
6600 (unsigned char *)enc_reply.data,
6601 enc_reply.len,
6602 D6O_RELAY_MSG, 0)) {
6603 log_error("dhcpv6_relay_forw: error saving Relay MSG.");
6604 goto exit;
6605 }
6606
6607 /*
6608 * Get the ERO if any.
6609 */
6610 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_ERO);
6611 if (oc != NULL) {
6612 unsigned req;
6613 int i;
6614
6615 if (!evaluate_option_cache(&packet_ero, packet,
6616 NULL, NULL,
6617 packet->options, NULL,
6618 &global_scope, oc, MDL) ||
6619 (packet_ero.len & 1)) {
6620 log_error("dhcpv6_relay_forw: error evaluating ERO.");
6621 goto exit;
6622 }
6623
6624 /* Decode and apply the ERO. */
6625 for (i = 0; i < packet_ero.len; i += 2) {
6626 req = getUShort(packet_ero.data + i);
6627 /* Already in the reply? */
6628 oc = lookup_option(&dhcpv6_universe, opt_state, req);
6629 if (oc != NULL)
6630 continue;
6631 /* Get it from the packet if present. */
6632 oc = lookup_option(&dhcpv6_universe,
6633 packet->options,
6634 req);
6635 if (oc == NULL)
6636 continue;
6637 if (!evaluate_option_cache(&a_opt, packet,
6638 NULL, NULL,
6639 packet->options, NULL,
6640 &global_scope, oc, MDL)) {
6641 log_error("dhcpv6_relay_forw: error "
6642 "evaluating option %u.", req);
6643 goto exit;
6644 }
6645 if (!save_option_buffer(&dhcpv6_universe,
6646 opt_state,
6647 NULL,
6648 (unsigned char *)a_opt.data,
6649 a_opt.len,
6650 req,
6651 0)) {
6652 log_error("dhcpv6_relay_forw: error saving "
6653 "option %u.", req);
6654 goto exit;
6655 }
6656 data_string_forget(&a_opt, MDL);
6657 }
6658 }
6659
6660 reply_ofs += store_options6(reply_data + reply_ofs,
6661 sizeof(reply_data) - reply_ofs,
6662 opt_state, packet,
6663 required_opts_agent, &packet_ero);
6664
6665 /*
6666 * Return our reply to the caller.
6667 */
6668 reply_ret->len = reply_ofs;
6669 reply_ret->buffer = NULL;
6670 if (!buffer_allocate(&reply_ret->buffer, reply_ret->len, MDL)) {
6671 log_fatal("No memory to store reply.");
6672 }
6673 reply_ret->data = reply_ret->buffer->data;
6674 memcpy(reply_ret->buffer->data, reply_data, reply_ofs);
6675
6676 exit:
6677 if (opt_state != NULL)
6678 option_state_dereference(&opt_state, MDL);
6679 if (a_opt.data != NULL) {
6680 data_string_forget(&a_opt, MDL);
6681 }
6682 if (packet_ero.data != NULL) {
6683 data_string_forget(&packet_ero, MDL);
6684 }
6685 if (enc_reply.data != NULL) {
6686 data_string_forget(&enc_reply, MDL);
6687 }
6688 if (enc_opt_data.data != NULL) {
6689 data_string_forget(&enc_opt_data, MDL);
6690 }
6691 if (enc_packet != NULL) {
6692 packet_dereference(&enc_packet, MDL);
6693 }
6694 }
6695
6696 #ifdef DHCP4o6
6697 /* \brief Internal processing of a relayed DHCPv4-query
6698 * (DHCPv4 server side)
6699 *
6700 * Code copied from \ref dhcpv6_relay_forw() which itself is
6701 * from \ref do_packet6().
6702 *
6703 * \param reply_ret pointer to the response
6704 * \param packet the query
6705 */
6706 static void
6707 dhcp4o6_relay_forw(struct data_string *reply_ret, struct packet *packet) {
6708 struct option_cache *oc;
6709 struct data_string enc_opt_data;
6710 struct packet *enc_packet;
6711 unsigned char msg_type;
6712 const struct dhcpv6_relay_packet *relay;
6713 const struct dhcpv4_over_dhcpv6_packet *msg;
6714 struct data_string enc_reply;
6715 char link_addr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6716 char peer_addr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6717 struct data_string a_opt, packet_ero;
6718 struct option_state *opt_state;
6719 static char reply_data[65536];
6720 struct dhcpv6_relay_packet *reply;
6721 int reply_ofs;
6722
6723 /*
6724 * Initialize variables for early exit.
6725 */
6726 opt_state = NULL;
6727 memset(&a_opt, 0, sizeof(a_opt));
6728 memset(&packet_ero, 0, sizeof(packet_ero));
6729 memset(&enc_reply, 0, sizeof(enc_reply));
6730 memset(&enc_opt_data, 0, sizeof(enc_opt_data));
6731 enc_packet = NULL;
6732
6733 /*
6734 * Get our encapsulated relay message.
6735 */
6736 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_RELAY_MSG);
6737 if (oc == NULL) {
6738 inet_ntop(AF_INET6, &packet->dhcpv6_link_address,
6739 link_addr, sizeof(link_addr));
6740 inet_ntop(AF_INET6, &packet->dhcpv6_peer_address,
6741 peer_addr, sizeof(peer_addr));
6742 log_info("Relay-forward from %s with link address=%s and "
6743 "peer address=%s missing Relay Message option.",
6744 piaddr(packet->client_addr), link_addr, peer_addr);
6745 goto exit;
6746 }
6747
6748 if (!evaluate_option_cache(&enc_opt_data, NULL, NULL, NULL,
6749 NULL, NULL, &global_scope, oc, MDL)) {
6750 log_error("dhcp4o6_relay_forw: error evaluating "
6751 "relayed message.");
6752 goto exit;
6753 }
6754
6755 if (!packet6_len_okay((char *)enc_opt_data.data, enc_opt_data.len)) {
6756 log_error("dhcp4o6_relay_forw: "
6757 "encapsulated packet too short.");
6758 goto exit;
6759 }
6760
6761 /*
6762 * Build a packet structure from this encapsulated packet.
6763 */
6764 if (!packet_allocate(&enc_packet, MDL)) {
6765 log_error("dhcp4o6_relay_forw: "
6766 "no memory for encapsulated packet.");
6767 goto exit;
6768 }
6769
6770 if (!option_state_allocate(&enc_packet->options, MDL)) {
6771 log_error("dhcp4o6_relay_forw: "
6772 "no memory for encapsulated packet's options.");
6773 goto exit;
6774 }
6775
6776 enc_packet->client_port = packet->client_port;
6777 enc_packet->client_addr = packet->client_addr;
6778 interface_reference(&enc_packet->interface, packet->interface, MDL);
6779 enc_packet->dhcpv6_container_packet = packet;
6780
6781 msg_type = enc_opt_data.data[0];
6782 if ((msg_type == DHCPV6_RELAY_FORW) ||
6783 (msg_type == DHCPV6_RELAY_REPL)) {
6784 int relaylen = (int)(offsetof(struct dhcpv6_relay_packet, options));
6785 relay = (struct dhcpv6_relay_packet *)enc_opt_data.data;
6786 enc_packet->dhcpv6_msg_type = relay->msg_type;
6787
6788 /* relay-specific data */
6789 enc_packet->dhcpv6_hop_count = relay->hop_count;
6790 memcpy(&enc_packet->dhcpv6_link_address,
6791 relay->link_address, sizeof(relay->link_address));
6792 memcpy(&enc_packet->dhcpv6_peer_address,
6793 relay->peer_address, sizeof(relay->peer_address));
6794
6795 if (!parse_option_buffer(enc_packet->options,
6796 relay->options,
6797 enc_opt_data.len - relaylen,
6798 &dhcpv6_universe)) {
6799 /* no logging here, as parse_option_buffer() logs all
6800 cases where it fails */
6801 goto exit;
6802 }
6803 } else if ((msg_type == DHCPV6_DHCPV4_QUERY) ||
6804 (msg_type == DHCPV6_DHCPV4_RESPONSE)) {
6805 int msglen =
6806 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet, options));
6807 msg = (struct dhcpv4_over_dhcpv6_packet *)enc_opt_data.data;
6808 enc_packet->dhcpv6_msg_type = msg->msg_type;
6809
6810 /* message-specific data */
6811 memcpy(enc_packet->dhcp4o6_flags,
6812 msg->flags,
6813 sizeof(enc_packet->dhcp4o6_flags));
6814
6815 if (!parse_option_buffer(enc_packet->options,
6816 msg->options,
6817 enc_opt_data.len - msglen,
6818 &dhcpv6_universe)) {
6819 /* no logging here, as parse_option_buffer() logs all
6820 cases where it fails */
6821 goto exit;
6822 }
6823 } else {
6824 log_error("dhcp4o6_relay_forw: unexpected message of type %d.",
6825 (int)msg_type);
6826 goto exit;
6827 }
6828
6829 /*
6830 * This is recursive. It is possible to exceed maximum packet size.
6831 * XXX: This will cause the packet send to fail.
6832 */
6833 build_dhcpv6_reply(&enc_reply, enc_packet);
6834
6835 /*
6836 * If we got no encapsulated data, then it is discarded, and
6837 * our reply-forw is also discarded.
6838 */
6839 if (enc_reply.data == NULL) {
6840 goto exit;
6841 }
6842
6843 /*
6844 * Now we can use the reply_data buffer.
6845 * Packet header stuff all comes from the forward message.
6846 */
6847 reply = (struct dhcpv6_relay_packet *)reply_data;
6848 reply->msg_type = DHCPV6_RELAY_REPL;
6849 reply->hop_count = packet->dhcpv6_hop_count;
6850 memcpy(reply->link_address, &packet->dhcpv6_link_address,
6851 sizeof(reply->link_address));
6852 memcpy(reply->peer_address, &packet->dhcpv6_peer_address,
6853 sizeof(reply->peer_address));
6854 reply_ofs = (int)(offsetof(struct dhcpv6_relay_packet, options));
6855
6856 /*
6857 * Get the reply option state.
6858 */
6859 if (!option_state_allocate(&opt_state, MDL)) {
6860 log_error("dhcp4o6_relay_forw: no memory for option state.");
6861 goto exit;
6862 }
6863
6864 /*
6865 * Append the interface-id if present.
6866 */
6867 oc = lookup_option(&dhcpv6_universe, packet->options,
6868 D6O_INTERFACE_ID);
6869 if (oc != NULL) {
6870 if (!evaluate_option_cache(&a_opt, packet,
6871 NULL, NULL,
6872 packet->options, NULL,
6873 &global_scope, oc, MDL)) {
6874 log_error("dhcp4o6_relay_forw: error evaluating "
6875 "Interface ID.");
6876 goto exit;
6877 }
6878 if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
6879 (unsigned char *)a_opt.data,
6880 a_opt.len,
6881 D6O_INTERFACE_ID, 0)) {
6882 log_error("dhcp4o6_relay_forw: error saving "
6883 "Interface ID.");
6884 goto exit;
6885 }
6886 data_string_forget(&a_opt, MDL);
6887 }
6888
6889 /*
6890 * Append our encapsulated stuff for caller.
6891 */
6892 if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
6893 (unsigned char *)enc_reply.data,
6894 enc_reply.len,
6895 D6O_RELAY_MSG, 0)) {
6896 log_error("dhcp4o6_relay_forw: error saving Relay MSG.");
6897 goto exit;
6898 }
6899
6900 /*
6901 * Get the ERO if any.
6902 */
6903 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_ERO);
6904 if (oc != NULL) {
6905 unsigned req;
6906 int i;
6907
6908 if (!evaluate_option_cache(&packet_ero, packet,
6909 NULL, NULL,
6910 packet->options, NULL,
6911 &global_scope, oc, MDL) ||
6912 (packet_ero.len & 1)) {
6913 log_error("dhcp4o6_relay_forw: error evaluating ERO.");
6914 goto exit;
6915 }
6916
6917 /* Decode and apply the ERO. */
6918 for (i = 0; i < packet_ero.len; i += 2) {
6919 req = getUShort(packet_ero.data + i);
6920 /* Already in the reply? */
6921 oc = lookup_option(&dhcpv6_universe, opt_state, req);
6922 if (oc != NULL)
6923 continue;
6924 /* Get it from the packet if present. */
6925 oc = lookup_option(&dhcpv6_universe,
6926 packet->options,
6927 req);
6928 if (oc == NULL)
6929 continue;
6930 if (!evaluate_option_cache(&a_opt, packet,
6931 NULL, NULL,
6932 packet->options, NULL,
6933 &global_scope, oc, MDL)) {
6934 log_error("dhcp4o6_relay_forw: error "
6935 "evaluating option %u.", req);
6936 goto exit;
6937 }
6938 if (!save_option_buffer(&dhcpv6_universe,
6939 opt_state,
6940 NULL,
6941 (unsigned char *)a_opt.data,
6942 a_opt.len,
6943 req,
6944 0)) {
6945 log_error("dhcp4o6_relay_forw: error saving "
6946 "option %u.", req);
6947 goto exit;
6948 }
6949 data_string_forget(&a_opt, MDL);
6950 }
6951 }
6952
6953 reply_ofs += store_options6(reply_data + reply_ofs,
6954 sizeof(reply_data) - reply_ofs,
6955 opt_state, packet,
6956 required_opts_agent, &packet_ero);
6957
6958 /*
6959 * Return our reply to the caller.
6960 */
6961 reply_ret->len = reply_ofs;
6962 reply_ret->buffer = NULL;
6963 if (!buffer_allocate(&reply_ret->buffer, reply_ret->len, MDL)) {
6964 log_fatal("No memory to store reply.");
6965 }
6966 reply_ret->data = reply_ret->buffer->data;
6967 memcpy(reply_ret->buffer->data, reply_data, reply_ofs);
6968
6969 exit:
6970 if (opt_state != NULL)
6971 option_state_dereference(&opt_state, MDL);
6972 if (a_opt.data != NULL) {
6973 data_string_forget(&a_opt, MDL);
6974 }
6975 if (packet_ero.data != NULL) {
6976 data_string_forget(&packet_ero, MDL);
6977 }
6978 if (enc_reply.data != NULL) {
6979 data_string_forget(&enc_reply, MDL);
6980 }
6981 if (enc_opt_data.data != NULL) {
6982 data_string_forget(&enc_opt_data, MDL);
6983 }
6984 if (enc_packet != NULL) {
6985 packet_dereference(&enc_packet, MDL);
6986 }
6987 }
6988
6989 /*
6990 * \brief Internal processing of a DHCPv4-query
6991 * (DHCPv4 server function)
6992 *
6993 * Code copied from \ref do_packet().
6994 *
6995 * \param reply_ret pointer to the response
6996 * \param packet the query
6997 */
6998 static void
6999 dhcp4o6_dhcpv4_query(struct data_string *reply_ret, struct packet *packet) {
7000 struct option_cache *oc;
7001 struct data_string enc_opt_data;
7002 struct packet *enc_packet;
7003 struct data_string enc_response;
7004 struct option_state *opt_state;
7005 static char response_data[65536];
7006 struct dhcpv4_over_dhcpv6_packet *response;
7007 int response_ofs;
7008
7009 /*
7010 * Initialize variables for early exit.
7011 */
7012 opt_state = NULL;
7013 memset(&enc_response, 0, sizeof(enc_response));
7014 memset(&enc_opt_data, 0, sizeof(enc_opt_data));
7015 enc_packet = NULL;
7016
7017 /*
7018 * Get our encapsulated relay message.
7019 */
7020 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_DHCPV4_MSG);
7021 if (oc == NULL) {
7022 log_info("DHCPv4-query from %s missing DHCPv4 Message option.",
7023 piaddr(packet->client_addr));
7024 goto exit;
7025 }
7026
7027 if (!evaluate_option_cache(&enc_opt_data, NULL, NULL, NULL,
7028 NULL, NULL, &global_scope, oc, MDL)) {
7029 log_error("dhcp4o6_dhcpv4_query: error evaluating "
7030 "DHCPv4 message.");
7031 goto exit;
7032 }
7033
7034 if (enc_opt_data.len < DHCP_FIXED_NON_UDP) {
7035 log_error("dhcp4o6_dhcpv4_query: DHCPv4 packet too short.");
7036 goto exit;
7037 }
7038
7039 /*
7040 * Build a packet structure from this encapsulated packet.
7041 */
7042 if (!packet_allocate(&enc_packet, MDL)) {
7043 log_error("dhcp4o6_dhcpv4_query: "
7044 "no memory for encapsulated packet.");
7045 goto exit;
7046 }
7047
7048 enc_packet->raw = (struct dhcp_packet *)enc_opt_data.data;
7049 enc_packet->packet_length = enc_opt_data.len;
7050 enc_packet->dhcp4o6_response = &enc_response;
7051 enc_packet->client_port = packet->client_port;
7052 enc_packet->client_addr = packet->client_addr;
7053 interface_reference(&enc_packet->interface, packet->interface, MDL);
7054 enc_packet->dhcpv6_container_packet = packet;
7055 if (packet->dhcp4o6_flags[0] & DHCP4O6_QUERY_UNICAST)
7056 enc_packet->unicast = 1;
7057
7058 if (enc_packet->raw->hlen > sizeof(enc_packet->raw->chaddr)) {
7059 log_info("dhcp4o6_dhcpv4_query: "
7060 "discarding packet with bogus hlen.");
7061 goto exit;
7062 }
7063
7064 /* Allocate packet->options now so it is non-null for all packets */
7065 if (!option_state_allocate (&enc_packet->options, MDL)) {
7066 log_error("dhcp4o6_dhcpv4_query: no memory for options.");
7067 goto exit;
7068 }
7069
7070 /* If there's an option buffer, try to parse it. */
7071 if (enc_packet->packet_length >= DHCP_FIXED_NON_UDP + 4) {
7072 struct option_cache *op;
7073 if (!parse_options(enc_packet)) {
7074 if (enc_packet->options)
7075 option_state_dereference
7076 (&enc_packet->options, MDL);
7077 packet_dereference (&enc_packet, MDL);
7078 goto exit;
7079 }
7080
7081 if (enc_packet->options_valid &&
7082 (op = lookup_option(&dhcp_universe,
7083 enc_packet->options,
7084 DHO_DHCP_MESSAGE_TYPE))) {
7085 struct data_string dp;
7086 memset(&dp, 0, sizeof dp);
7087 evaluate_option_cache(&dp, enc_packet, NULL, NULL,
7088 enc_packet->options, NULL,
7089 NULL, op, MDL);
7090 if (dp.len > 0)
7091 enc_packet->packet_type = dp.data[0];
7092 else
7093 enc_packet->packet_type = 0;
7094 data_string_forget(&dp, MDL);
7095 }
7096 }
7097
7098 if (validate_packet(enc_packet) != 0) {
7099 if (enc_packet->packet_type)
7100 dhcp(enc_packet);
7101 else
7102 bootp(enc_packet);
7103 }
7104
7105 /* If the caller kept the packet, they'll have upped the refcnt. */
7106 packet_dereference(&enc_packet, MDL);
7107
7108 /*
7109 * If we got no response data, then it is discarded, and
7110 * our DHCPv4-response is also discarded.
7111 */
7112 if (enc_response.data == NULL) {
7113 goto exit;
7114 }
7115
7116 /*
7117 * Now we can use the response_data buffer.
7118 */
7119 response = (struct dhcpv4_over_dhcpv6_packet *)response_data;
7120 response->msg_type = DHCPV6_DHCPV4_RESPONSE;
7121 response->flags[0] = response->flags[1] = response->flags[2] = 0;
7122 response_ofs =
7123 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet, options));
7124
7125 /*
7126 * Get the response option state.
7127 */
7128 if (!option_state_allocate(&opt_state, MDL)) {
7129 log_error("dhcp4o6_dhcpv4_query: no memory for option state.");
7130 goto exit;
7131 }
7132
7133 /*
7134 * Append our encapsulated stuff for caller.
7135 */
7136 if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
7137 (unsigned char *)enc_response.data,
7138 enc_response.len,
7139 D6O_DHCPV4_MSG, 0)) {
7140 log_error("dhcp4o6_dhcpv4_query: error saving DHCPv4 MSG.");
7141 goto exit;
7142 }
7143
7144 response_ofs += store_options6(response_data + response_ofs,
7145 sizeof(response_data) - response_ofs,
7146 opt_state, packet,
7147 required_opts_4o6, NULL);
7148
7149 /*
7150 * Return our response to the caller.
7151 */
7152 reply_ret->len = response_ofs;
7153 reply_ret->buffer = NULL;
7154 if (!buffer_allocate(&reply_ret->buffer, reply_ret->len, MDL)) {
7155 log_fatal("dhcp4o6_dhcpv4_query: no memory to store reply.");
7156 }
7157 reply_ret->data = reply_ret->buffer->data;
7158 memcpy(reply_ret->buffer->data, response_data, response_ofs);
7159
7160 exit:
7161 if (opt_state != NULL)
7162 option_state_dereference(&opt_state, MDL);
7163 if (enc_response.data != NULL) {
7164 data_string_forget(&enc_response, MDL);
7165 }
7166 if (enc_opt_data.data != NULL) {
7167 data_string_forget(&enc_opt_data, MDL);
7168 }
7169 if (enc_packet != NULL) {
7170 packet_dereference(&enc_packet, MDL);
7171 }
7172 }
7173
7174 /*
7175 * \brief Forward a DHCPv4-query message to the DHCPv4 side
7176 * (DHCPv6 server function)
7177 *
7178 * Format: interface:16 + address:16 + DHCPv6 DHCPv4-query message
7179 *
7180 * \brief packet the DHCPv6 DHCPv4-query message
7181 */
7182 static void forw_dhcpv4_query(struct packet *packet) {
7183 struct data_string ds;
7184 unsigned len;
7185 int cc;
7186
7187 /* Get the initial message. */
7188 while (packet->dhcpv6_container_packet != NULL)
7189 packet = packet->dhcpv6_container_packet;
7190
7191 /* Check the initial message. */
7192 if ((packet->raw == NULL) ||
7193 (packet->client_addr.len != 16) ||
7194 (packet->interface == NULL)) {
7195 log_error("forw_dhcpv4_query: can't find initial message.");
7196 return;
7197 }
7198
7199 /* Get a buffer. */
7200 len = packet->packet_length + 32;
7201 memset(&ds, 0, sizeof(ds));
7202 if (!buffer_allocate(&ds.buffer, len, MDL)) {
7203 log_error("forw_dhcpv4_query: "
7204 "no memory for encapsulating packet.");
7205 return;
7206 }
7207 ds.data = ds.buffer->data;
7208 ds.len = len;
7209
7210 /* Fill the buffer. */
7211 strncpy((char *)ds.buffer->data, packet->interface->name, 16);
7212 memcpy(ds.buffer->data + 16,
7213 packet->client_addr.iabuf, 16);
7214 memcpy(ds.buffer->data + 32,
7215 (unsigned char *)packet->raw,
7216 packet->packet_length);
7217
7218 /* Forward to the DHCPv4 server. */
7219 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
7220 if (cc < 0)
7221 log_error("forw_dhcpv4_query: send(): %m");
7222 data_string_forget(&ds, MDL);
7223 }
7224 #endif
7225
7226 static void
7227 dhcpv6_discard(struct packet *packet) {
7228 /* INSIST(packet->msg_type > 0); */
7229 /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
7230
7231 log_debug("Discarding %s from %s; message type not handled by server",
7232 dhcpv6_type_names[packet->dhcpv6_msg_type],
7233 piaddr(packet->client_addr));
7234 }
7235
7236 static void
7237 build_dhcpv6_reply(struct data_string *reply, struct packet *packet) {
7238 memset(reply, 0, sizeof(*reply));
7239
7240 /* I would like to classify the client once here, but
7241 * as I don't want to classify all of the incoming packets
7242 * I need to do it before handling specific types.
7243 * We don't need to classify if we are tossing the packet
7244 * or if it is a relay - the classification step will get
7245 * done when we process the inner client packet.
7246 */
7247
7248 switch (packet->dhcpv6_msg_type) {
7249 case DHCPV6_SOLICIT:
7250 classify_client(packet);
7251 dhcpv6_solicit(reply, packet);
7252 break;
7253 case DHCPV6_ADVERTISE:
7254 dhcpv6_discard(packet);
7255 break;
7256 case DHCPV6_REQUEST:
7257 classify_client(packet);
7258 dhcpv6_request(reply, packet);
7259 break;
7260 case DHCPV6_CONFIRM:
7261 classify_client(packet);
7262 dhcpv6_confirm(reply, packet);
7263 break;
7264 case DHCPV6_RENEW:
7265 classify_client(packet);
7266 dhcpv6_renew(reply, packet);
7267 break;
7268 case DHCPV6_REBIND:
7269 classify_client(packet);
7270 dhcpv6_rebind(reply, packet);
7271 break;
7272 case DHCPV6_REPLY:
7273 dhcpv6_discard(packet);
7274 break;
7275 case DHCPV6_RELEASE:
7276 classify_client(packet);
7277 dhcpv6_release(reply, packet);
7278 break;
7279 case DHCPV6_DECLINE:
7280 classify_client(packet);
7281 dhcpv6_decline(reply, packet);
7282 break;
7283 case DHCPV6_RECONFIGURE:
7284 dhcpv6_discard(packet);
7285 break;
7286 case DHCPV6_INFORMATION_REQUEST:
7287 classify_client(packet);
7288 dhcpv6_information_request(reply, packet);
7289 break;
7290 case DHCPV6_RELAY_FORW:
7291 #ifdef DHCP4o6
7292 if (dhcpv4_over_dhcpv6 && (local_family == AF_INET))
7293 dhcp4o6_relay_forw(reply, packet);
7294 else
7295 #endif /* DHCP4o6 */
7296 dhcpv6_relay_forw(reply, packet);
7297 break;
7298 case DHCPV6_RELAY_REPL:
7299 dhcpv6_discard(packet);
7300 break;
7301 case DHCPV6_LEASEQUERY:
7302 classify_client(packet);
7303 dhcpv6_leasequery(reply, packet);
7304 break;
7305 case DHCPV6_LEASEQUERY_REPLY:
7306 dhcpv6_discard(packet);
7307 break;
7308 case DHCPV6_DHCPV4_QUERY:
7309 #ifdef DHCP4o6
7310 if (dhcpv4_over_dhcpv6) {
7311 if (local_family == AF_INET6) {
7312 forw_dhcpv4_query(packet);
7313 } else {
7314 dhcp4o6_dhcpv4_query(reply, packet);
7315 }
7316 } else
7317 #endif /* DHCP4o6 */
7318 dhcpv6_discard(packet);
7319 break;
7320 case DHCPV6_DHCPV4_RESPONSE:
7321 dhcpv6_discard(packet);
7322 break;
7323 default:
7324 /* XXX: would be nice if we had "notice" level,
7325 as syslog, for this */
7326 log_info("Discarding unknown DHCPv6 message type %d "
7327 "from %s", packet->dhcpv6_msg_type,
7328 piaddr(packet->client_addr));
7329 }
7330 }
7331
7332 static void
7333 log_packet_in(const struct packet *packet) {
7334 struct data_string s;
7335 u_int32_t tid;
7336 char tmp_addr[INET6_ADDRSTRLEN];
7337 const void *addr;
7338
7339 memset(&s, 0, sizeof(s));
7340
7341 if (packet->dhcpv6_msg_type < dhcpv6_type_name_max) {
7342 data_string_sprintfa(&s, "%s message from %s port %d",
7343 dhcpv6_type_names[packet->dhcpv6_msg_type],
7344 piaddr(packet->client_addr),
7345 ntohs(packet->client_port));
7346 } else {
7347 data_string_sprintfa(&s,
7348 "Unknown message type %d from %s port %d",
7349 packet->dhcpv6_msg_type,
7350 piaddr(packet->client_addr),
7351 ntohs(packet->client_port));
7352 }
7353 if ((packet->dhcpv6_msg_type == DHCPV6_RELAY_FORW) ||
7354 (packet->dhcpv6_msg_type == DHCPV6_RELAY_REPL)) {
7355 addr = &packet->dhcpv6_link_address;
7356 data_string_sprintfa(&s, ", link address %s",
7357 inet_ntop(AF_INET6, addr,
7358 tmp_addr, sizeof(tmp_addr)));
7359 addr = &packet->dhcpv6_peer_address;
7360 data_string_sprintfa(&s, ", peer address %s",
7361 inet_ntop(AF_INET6, addr,
7362 tmp_addr, sizeof(tmp_addr)));
7363 } else if ((packet->dhcpv6_msg_type != DHCPV6_DHCPV4_QUERY) &&
7364 (packet->dhcpv6_msg_type != DHCPV6_DHCPV4_RESPONSE)) {
7365 tid = 0;
7366 memcpy(((char *)&tid)+1, packet->dhcpv6_transaction_id, 3);
7367 data_string_sprintfa(&s, ", transaction ID 0x%06X", tid);
7368
7369 /*
7370 oc = lookup_option(&dhcpv6_universe, packet->options,
7371 D6O_CLIENTID);
7372 if (oc != NULL) {
7373 memset(&tmp_ds, 0, sizeof(tmp_ds_));
7374 if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL,
7375 packet->options, NULL,
7376 &global_scope, oc, MDL)) {
7377 log_error("Error evaluating Client Identifier");
7378 } else {
7379 data_strint_sprintf(&s, ", client ID %s",
7380
7381 data_string_forget(&tmp_ds, MDL);
7382 }
7383 }
7384 */
7385
7386 }
7387 log_info("%s", s.data);
7388
7389 data_string_forget(&s, MDL);
7390 }
7391
7392 void
7393 dhcpv6(struct packet *packet) {
7394 struct data_string reply;
7395 struct sockaddr_in6 to_addr;
7396 int send_ret;
7397
7398 /*
7399 * Log a message that we received this packet.
7400 */
7401 log_packet_in(packet);
7402
7403 /*
7404 * Build our reply packet.
7405 */
7406 build_dhcpv6_reply(&reply, packet);
7407
7408 if (reply.data != NULL) {
7409 /*
7410 * Send our reply, if we have one.
7411 */
7412 memset(&to_addr, 0, sizeof(to_addr));
7413 to_addr.sin6_family = AF_INET6;
7414 if ((packet->dhcpv6_msg_type == DHCPV6_RELAY_FORW) ||
7415 (packet->dhcpv6_msg_type == DHCPV6_RELAY_REPL)) {
7416 to_addr.sin6_port = local_port;
7417 } else {
7418 to_addr.sin6_port = remote_port;
7419 }
7420
7421 #if defined (REPLY_TO_SOURCE_PORT)
7422 /*
7423 * This appears to have been included for testing so we would
7424 * not need a root client, but was accidently left in the
7425 * final code. We continue to include it in case
7426 * some users have come to rely upon it, but leave
7427 * it off by default as it's a bad idea.
7428 */
7429 to_addr.sin6_port = packet->client_port;
7430 #endif
7431
7432 memcpy(&to_addr.sin6_addr, packet->client_addr.iabuf,
7433 sizeof(to_addr.sin6_addr));
7434
7435 log_info("Sending %s to %s port %d",
7436 dhcpv6_type_names[reply.data[0]],
7437 piaddr(packet->client_addr),
7438 ntohs(to_addr.sin6_port));
7439
7440 send_ret = send_packet6(packet->interface,
7441 reply.data, reply.len, &to_addr);
7442 if (send_ret != reply.len) {
7443 log_error("dhcpv6: send_packet6() sent %d of %d bytes",
7444 send_ret, reply.len);
7445 }
7446 data_string_forget(&reply, MDL);
7447 }
7448 }
7449
7450 #ifdef DHCP4o6
7451 /*
7452 * \brief Receive a DHCPv4-query message from the DHCPv6 side
7453 * (DHCPv4 server function)
7454 *
7455 * Receive a message with a DHCPv4-query inside from the DHCPv6 server.
7456 * (code copied from \ref do_packet6() \ref and dhcpv6())
7457 *
7458 * Format: interface:16 + address:16 + DHCPv6 DHCPv4-query message
7459 *
7460 * \param raw the DHCPv6 DHCPv4-query message raw content
7461 */
7462 static void recv_dhcpv4_query(struct data_string *raw) {
7463 struct interface_info *ip;
7464 char name[16 + 1];
7465 struct iaddr iaddr;
7466 struct packet *packet;
7467 unsigned char msg_type;
7468 const struct dhcpv6_relay_packet *relay;
7469 const struct dhcpv4_over_dhcpv6_packet *msg;
7470 struct data_string reply;
7471 struct data_string ds;
7472 unsigned len;
7473 int cc;
7474
7475 memset(name, 0, sizeof(name));
7476 memcpy(name, raw->data, 16);
7477 for (ip = interfaces; ip != NULL; ip = ip->next) {
7478 if (!strcmp(name, ip->name))
7479 break;
7480 }
7481 if (ip == NULL) {
7482 log_error("recv_dhcpv4_query: can't find interface %s.",
7483 name);
7484 return;
7485 }
7486
7487 iaddr.len = 16;
7488 memcpy(iaddr.iabuf, raw->data + 16, 16);
7489
7490 /*
7491 * From do_packet6().
7492 */
7493
7494 if (!packet6_len_okay((char *)raw->data + 32, raw->len - 32)) {
7495 log_error("recv_dhcpv4_query: "
7496 "short packet from %s, len %d, dropped",
7497 piaddr(iaddr), raw->len - 32);
7498 return;
7499 }
7500
7501 /*
7502 * Build a packet structure.
7503 */
7504 packet = NULL;
7505 if (!packet_allocate(&packet, MDL)) {
7506 log_error("recv_dhcpv4_query: no memory for packet.");
7507 return;
7508 }
7509
7510 if (!option_state_allocate(&packet->options, MDL)) {
7511 log_error("recv_dhcpv4_query: no memory for options.");
7512 packet_dereference(&packet, MDL);
7513 return;
7514 }
7515
7516 packet->raw = (struct dhcp_packet *)(raw->data + 32);
7517 packet->packet_length = raw->len - 32;
7518 packet->client_port = remote_port;
7519 packet->client_addr = iaddr;
7520 interface_reference(&packet->interface, ip, MDL);
7521
7522 msg_type = raw->data[32];
7523 if ((msg_type == DHCPV6_RELAY_FORW) ||
7524 (msg_type == DHCPV6_RELAY_REPL)) {
7525 int relaylen =
7526 (int)(offsetof(struct dhcpv6_relay_packet, options));
7527 relay = (const struct dhcpv6_relay_packet *)(raw->data + 32);
7528 packet->dhcpv6_msg_type = relay->msg_type;
7529
7530 /* relay-specific data */
7531 packet->dhcpv6_hop_count = relay->hop_count;
7532 memcpy(&packet->dhcpv6_link_address,
7533 relay->link_address, sizeof(relay->link_address));
7534 memcpy(&packet->dhcpv6_peer_address,
7535 relay->peer_address, sizeof(relay->peer_address));
7536
7537 if (!parse_option_buffer(packet->options,
7538 relay->options,
7539 raw->len - 32 - relaylen,
7540 &dhcpv6_universe)) {
7541 /* no logging here, as parse_option_buffer() logs all
7542 cases where it fails */
7543 packet_dereference(&packet, MDL);
7544 return;
7545 }
7546 } else if ((msg_type == DHCPV6_DHCPV4_QUERY) ||
7547 (msg_type == DHCPV6_DHCPV4_RESPONSE)) {
7548 int msglen =
7549 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet, options));
7550 msg = (struct dhcpv4_over_dhcpv6_packet *)(raw->data + 32);
7551 packet->dhcpv6_msg_type = msg->msg_type;
7552
7553 /* message-specific data */
7554 memcpy(packet->dhcp4o6_flags, msg->flags,
7555 sizeof(packet->dhcp4o6_flags));
7556
7557 if (!parse_option_buffer(packet->options,
7558 msg->options,
7559 raw->len - 32 - msglen,
7560 &dhcpv6_universe)) {
7561 /* no logging here, as parse_option_buffer() logs all
7562 cases where it fails */
7563 packet_dereference(&packet, MDL);
7564 return;
7565 }
7566 } else {
7567 log_error("recv_dhcpv4_query: unexpected message of type %d.",
7568 (int)msg_type);
7569 packet_dereference(&packet, MDL);
7570 return;
7571 }
7572
7573 /*
7574 * From dhcpv6().
7575 */
7576
7577 /*
7578 * Log a message that we received this packet.
7579 */
7580 /* log_packet_in(packet); */
7581 memset(&ds, 0, sizeof(ds));
7582 if (packet->dhcpv6_msg_type < dhcpv6_type_name_max) {
7583 data_string_sprintfa(&ds, "%s message from %s",
7584 dhcpv6_type_names[packet->dhcpv6_msg_type],
7585 piaddr(packet->client_addr));
7586 } else {
7587 data_string_sprintfa(&ds,
7588 "Unknown message type %d from %s",
7589 packet->dhcpv6_msg_type,
7590 piaddr(packet->client_addr));
7591 }
7592 if ((packet->dhcpv6_msg_type == DHCPV6_RELAY_FORW) ||
7593 (packet->dhcpv6_msg_type == DHCPV6_RELAY_REPL)) {
7594 char tmp_addr[INET6_ADDRSTRLEN];
7595 const void *addr;
7596
7597 addr = &packet->dhcpv6_link_address;
7598 data_string_sprintfa(&ds, ", link address %s",
7599 inet_ntop(AF_INET6, addr,
7600 tmp_addr, sizeof(tmp_addr)));
7601 addr = &packet->dhcpv6_peer_address;
7602 data_string_sprintfa(&ds, ", peer address %s",
7603 inet_ntop(AF_INET6, addr,
7604 tmp_addr, sizeof(tmp_addr)));
7605 } else if ((packet->dhcpv6_msg_type != DHCPV6_DHCPV4_QUERY) &&
7606 (packet->dhcpv6_msg_type != DHCPV6_DHCPV4_RESPONSE)) {
7607 u_int32_t tid = 0;
7608
7609 memcpy(((char *)&tid)+1, packet->dhcpv6_transaction_id, 3);
7610 data_string_sprintfa(&ds, ", transaction ID 0x%06X", tid);
7611 }
7612 log_info("%s", ds.data);
7613 data_string_forget(&ds, MDL);
7614
7615 /*
7616 * Build our reply packet.
7617 */
7618 build_dhcpv6_reply(&reply, packet);
7619
7620 packet_dereference(&packet, MDL);
7621
7622 if (reply.data == NULL)
7623 return;
7624
7625 /*
7626 * Forward the response.
7627 */
7628 len = reply.len + 32;
7629 memset(&ds, 0, sizeof(ds));
7630 if (!buffer_allocate(&ds.buffer, len, MDL)) {
7631 log_error("recv_dhcpv4_query: no memory.");
7632 return;
7633 }
7634 ds.data = ds.buffer->data;
7635 ds.len = len;
7636
7637 memcpy(ds.buffer->data, name, 16);
7638 memcpy(ds.buffer->data + 16, iaddr.iabuf, 16);
7639 memcpy(ds.buffer->data + 32, reply.data, reply.len);
7640 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
7641 if (cc < 0)
7642 log_error("recv_dhcpv4_query: send(): %m");
7643 data_string_forget(&ds, MDL);
7644 }
7645 #endif /* DHCP4o6 */
7646
7647 static void
7648 seek_shared_host(struct host_decl **hp, struct shared_network *shared) {
7649 struct host_decl *nofixed = NULL;
7650 struct host_decl *seek, *hold = NULL;
7651
7652 /*
7653 * Seek forward through fixed addresses for the right link.
7654 *
7655 * Note: how to do this for fixed prefixes???
7656 */
7657 host_reference(&hold, *hp, MDL);
7658 host_dereference(hp, MDL);
7659 seek = hold;
7660 while (seek != NULL) {
7661 if (seek->fixed_addr == NULL)
7662 nofixed = seek;
7663 else if (fixed_matches_shared(seek, shared))
7664 break;
7665
7666 seek = seek->n_ipaddr;
7667 }
7668
7669 if ((seek == NULL) && (nofixed != NULL))
7670 seek = nofixed;
7671
7672 if (seek != NULL)
7673 host_reference(hp, seek, MDL);
7674 }
7675
7676 static isc_boolean_t
7677 fixed_matches_shared(struct host_decl *host, struct shared_network *shared) {
7678 struct subnet *subnet;
7679 struct data_string addr;
7680 isc_boolean_t matched;
7681 struct iaddr fixed;
7682
7683 if (host->fixed_addr == NULL)
7684 return ISC_FALSE;
7685
7686 memset(&addr, 0, sizeof(addr));
7687 if (!evaluate_option_cache(&addr, NULL, NULL, NULL, NULL, NULL,
7688 &global_scope, host->fixed_addr, MDL))
7689 return ISC_FALSE;
7690
7691 if (addr.len < 16) {
7692 data_string_forget(&addr, MDL);
7693 return ISC_FALSE;
7694 }
7695
7696 fixed.len = 16;
7697 memcpy(fixed.iabuf, addr.data, 16);
7698
7699 matched = ISC_FALSE;
7700 for (subnet = shared->subnets ; subnet != NULL ;
7701 subnet = subnet->next_sibling) {
7702 if (addr_eq(subnet_number(fixed, subnet->netmask),
7703 subnet->net)) {
7704 matched = ISC_TRUE;
7705 break;
7706 }
7707 }
7708
7709 data_string_forget(&addr, MDL);
7710 return matched;
7711 }
7712
7713 /*!
7714 *
7715 * \brief Constructs a REPLY with status of UseMulticast to a given packet
7716 *
7717 * Per RFC 3315 Secs 18.2.1,3,6 & 7, when a server rejects a client's
7718 * unicast-sent packet, the response must only contain the client id,
7719 * server id, and a status code option of 5 (UseMulticast). This function
7720 * constructs such a packet and returns it as a data_string.
7721 *
7722 * \param reply_ret = data_string which will receive the newly constructed
7723 * reply
7724 * \param packet = client request which is being rejected
7725 * \param client_id = data_string which contains the client id
7726 * \param server_id = data_string which which contains the server id
7727 *
7728 */
7729 void
7730 unicast_reject(struct data_string *reply_ret,
7731 struct packet *packet,
7732 const struct data_string *client_id,
7733 const struct data_string *server_id)
7734 {
7735 struct reply_state reply;
7736 memset(&reply, 0x0, sizeof(struct reply_state));
7737
7738 /* Locate the client. */
7739 if (shared_network_from_packet6(&reply.shared, packet)
7740 != ISC_R_SUCCESS) {
7741 log_error("unicast_reject: could not locate client.");
7742 return;
7743 }
7744
7745 /* Initialize the reply. */
7746 packet_reference(&reply.packet, packet, MDL);
7747 data_string_copy(&reply.client_id, client_id, MDL);
7748
7749 if (start_reply(packet, client_id, server_id, &reply.opt_state,
7750 &reply.buf.reply)) {
7751 /* Set the UseMulticast status code. */
7752 if (!set_status_code(STATUS_UseMulticast,
7753 "Unicast not allowed by server.",
7754 reply.opt_state)) {
7755 log_error("unicast_reject: Unable to set status code.");
7756 } else {
7757 /* Set write cursor to just past the reply header. */
7758 reply.cursor = REPLY_OPTIONS_INDEX;
7759 reply.cursor += store_options6(((char *)reply.buf.data
7760 + reply.cursor),
7761 (sizeof(reply.buf)
7762 - reply.cursor),
7763 reply.opt_state,
7764 reply.packet,
7765 unicast_reject_opts,
7766 NULL);
7767
7768 /* Return our reply to the caller. */
7769 reply_ret->len = reply.cursor;
7770 reply_ret->buffer = NULL;
7771 if (!buffer_allocate(&reply_ret->buffer,
7772 reply.cursor, MDL)) {
7773 log_fatal("unicast_reject:"
7774 "No memory to store Reply.");
7775 }
7776
7777 memcpy(reply_ret->buffer->data, reply.buf.data,
7778 reply.cursor);
7779 reply_ret->data = reply_ret->buffer->data;
7780 }
7781
7782 }
7783
7784 /* Cleanup. */
7785 if (reply.shared != NULL)
7786 shared_network_dereference(&reply.shared, MDL);
7787 if (reply.opt_state != NULL)
7788 option_state_dereference(&reply.opt_state, MDL);
7789 if (reply.packet != NULL)
7790 packet_dereference(&reply.packet, MDL);
7791 if (reply.client_id.data != NULL)
7792 data_string_forget(&reply.client_id, MDL);
7793 }
7794
7795 /*!
7796 *
7797 * \brief Checks if the dhcp6.unicast option has been defined
7798 *
7799 * Scans the option space for the presence of the dhcp6.unicast option. The
7800 * function attempts to map the inbound packet to a shared network first
7801 * by an ip address specified via an D6O_IA_XX option and if that fails then
7802 * by the packet's source information (e.g. relay link, link, or interace).
7803 * Once the packet is mapped to a shared network, the function executes all
7804 * statements from the network's group outward into a local option cache.
7805 * The option cache is then scanned for the presence of unicast option. If
7806 * the packet cannot be mapped to a shared network, the function returns
7807 * ISC_FALSE.
7808 * \param packet inbound packet from the client
7809 *
7810 * \return ISC_TRUE if the dhcp6.unicast option is defined, false otherwise.
7811 *
7812 */
7813 isc_boolean_t
7814 is_unicast_option_defined(struct packet *packet) {
7815 isc_boolean_t is_defined = ISC_FALSE;
7816 struct option_state *opt_state = NULL;
7817 struct option_cache *oc = NULL;
7818 struct shared_network *shared = NULL;
7819
7820 if (!option_state_allocate(&opt_state, MDL)) {
7821 log_fatal("is_unicast_option_defined:"
7822 "No memory for option state.");
7823 }
7824
7825 /* We try to map the packet to a network first by an IA_XX value.
7826 * If that fails, we try by packet source. */
7827 if (((shared_network_from_requested_addr(&shared, packet)
7828 != ISC_R_SUCCESS) &&
7829 (shared_network_from_packet6(&shared, packet) != ISC_R_SUCCESS))
7830 || (shared == NULL)) {
7831 /* @todo what would this really mean? I think wrong network
7832 * logic will catch it */
7833 log_error("is_unicast_option_defined:"
7834 "cannot attribute packet to a network.");
7835 return (ISC_FALSE);
7836 }
7837
7838 /* Now that we've mapped it to a network, execute statments to that
7839 * scope, looking for the unicast option. We don't care about the
7840 * value of the option, only whether or not it is defined. */
7841 execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL, opt_state,
7842 &global_scope, shared->group, NULL, NULL);
7843
7844 oc = lookup_option(&dhcpv6_universe, opt_state, D6O_UNICAST);
7845 is_defined = (oc != NULL ? ISC_TRUE : ISC_FALSE);
7846 log_debug("is_unicast_option_defined: option found : %d", is_defined);
7847
7848 if (shared != NULL) {
7849 shared_network_dereference(&shared, MDL);
7850 }
7851
7852 if (opt_state != NULL) {
7853 option_state_dereference(&opt_state, MDL);
7854 }
7855
7856 return (is_defined);
7857 }
7858
7859 /*!
7860 *
7861 * \brief Maps a packet to a shared network based on the requested IP address
7862 *
7863 * The function attempts to find a subnet that matches the first requested IP
7864 * address contained within the given packet. Note that it looks first for
7865 * D6O_IA_NAs, then D6O_IA_PDs and lastly D6O_IA_TAs. If a matching network is
7866 * found, a reference to it is returned in the parameter, shared.
7867 *
7868 * \param shared shared_network pointer which will receive the matching network
7869 * \param packet inbound packet from the client
7870 *
7871 * \return ISC_R_SUCCESS if the packet can be mapped to a shared_network.
7872 *
7873 */
7874 static isc_result_t
7875 shared_network_from_requested_addr (struct shared_network **shared,
7876 struct packet* packet) {
7877 struct iaddr iaddr;
7878 struct subnet* subnet = NULL;
7879 isc_result_t status = ISC_R_FAILURE;
7880
7881 /* Try to match first IA_ address or prefix we find to a subnet. In
7882 * theory all IA_ values in a given request are supposed to be in the
7883 * same subnet so we only need to try one right? */
7884 if ((get_first_ia_addr_val(packet, D6O_IA_NA, &iaddr) != ISC_R_SUCCESS)
7885 && (get_first_ia_addr_val(packet, D6O_IA_PD, &iaddr)
7886 != ISC_R_SUCCESS)
7887 && (get_first_ia_addr_val(packet, D6O_IA_TA, &iaddr)
7888 != ISC_R_SUCCESS)) {
7889 /* we found nothing to match against */
7890 log_debug("share_network_from_request_addr: nothing to match");
7891 return (ISC_R_FAILURE);
7892 }
7893
7894 if (!find_subnet(&subnet, iaddr, MDL)) {
7895 log_debug("shared_network_from_requested_addr:"
7896 "No subnet found for addr %s.", piaddr(iaddr));
7897 } else {
7898 status = shared_network_reference(shared,
7899 subnet->shared_network, MDL);
7900 subnet_dereference(&subnet, MDL);
7901 log_debug("shared_network_from_requested_addr:"
7902 " found shared network %s for address %s.",
7903 ((*shared)->name ? (*shared)->name : "unnamed"),
7904 piaddr(iaddr));
7905 return (status);
7906 }
7907
7908 return (ISC_R_FAILURE);
7909 }
7910
7911 /*!
7912 *
7913 * \brief Retrieves the first IP address from a given packet of a given type
7914 *
7915 * Search a packet for options of a given type (D6O_IA_AN, D6O_IA_PD, or
7916 * D6O_IA_TA) for the first non-blank IA_XX value and return its IP address
7917 * component.
7918 *
7919 * \param packet packet received from the client
7920 * \param addr_type the address option type (D6O_IA_NA , D6O_IA_PD, or
7921 * D6O_IP_TA) to look for within the packet.
7922 * \param iaddr pointer to the iaddr structure which will receive the extracted
7923 * address.
7924 *
7925 * \return ISC_R_SUCCESS if an address was succesfully extracted, ISC_R_FALURE
7926 * otherwise.
7927 *
7928 */
7929 static isc_result_t
7930 get_first_ia_addr_val (struct packet* packet, int addr_type,
7931 struct iaddr* iaddr) {
7932 struct option_cache *ia;
7933 struct option_cache *oc = NULL;
7934 struct data_string cli_enc_opt_data;
7935 struct option_state *cli_enc_opt_state;
7936 int addr_opt_offset;
7937 int addr_opt;
7938 int addr_opt_data_len;
7939 int ip_addr_offset;
7940
7941 isc_result_t status = ISC_R_FAILURE;
7942 memset(iaddr, 0, sizeof(struct iaddr));
7943
7944 /* Set up address type specifics */
7945 switch (addr_type) {
7946 case D6O_IA_NA:
7947 addr_opt_offset = IA_NA_OFFSET;
7948 addr_opt = D6O_IAADDR;
7949 addr_opt_data_len = 24;
7950 ip_addr_offset = 0;
7951 break;
7952 case D6O_IA_TA:
7953 addr_opt_offset = IA_TA_OFFSET;
7954 addr_opt = D6O_IAADDR;
7955 addr_opt_data_len = 24;
7956 ip_addr_offset = 0;
7957 break;
7958 case D6O_IA_PD:
7959 addr_opt_offset = IA_PD_OFFSET;
7960 addr_opt = D6O_IAPREFIX;
7961 addr_opt_data_len = 25;
7962 ip_addr_offset = 9;
7963 break;
7964 default:
7965 /* shouldn't be here */
7966 log_error ("get_first_ia_addr_val: invalid opt type %d",
7967 addr_type);
7968 return (ISC_R_FAILURE);
7969 }
7970
7971 /* Find the first, non-blank IA_XX value within an D6O_IA_XX option. */
7972 for (ia = lookup_option(&dhcpv6_universe, packet->options, addr_type);
7973 ia != NULL && oc == NULL; ia = ia->next) {
7974 if (!get_encapsulated_IA_state(&cli_enc_opt_state,
7975 &cli_enc_opt_data,
7976 packet, ia, addr_opt_offset)) {
7977 log_debug ("get_first_ia_addr_val:"
7978 " couldn't unroll enclosing option");
7979 return (ISC_R_FAILURE);
7980 }
7981
7982 oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
7983 addr_opt);
7984 if (oc == NULL) {
7985 /* no address given for this IA, ignore */
7986 option_state_dereference(&cli_enc_opt_state, MDL);
7987 data_string_forget(&cli_enc_opt_data, MDL);
7988 }
7989 }
7990
7991 /* If we found a non-blank IA_XX then extract its ip address. */
7992 if (oc != NULL) {
7993 struct data_string iaddr_str;
7994
7995 memset(&iaddr_str, 0, sizeof(iaddr_str));
7996 if (!evaluate_option_cache(&iaddr_str, packet, NULL, NULL,
7997 packet->options, NULL, &global_scope,
7998 oc, MDL)) {
7999 log_error("get_first_ia_addr_val: "
8000 "error evaluating IA_XX option.");
8001 } else {
8002 if (iaddr_str.len != addr_opt_data_len) {
8003 log_error("shared_network_from_requested_addr:"
8004 " invalid length %d, expected %d",
8005 iaddr_str.len, addr_opt_data_len);
8006 } else {
8007 iaddr->len = 16;
8008 memcpy (iaddr->iabuf,
8009 iaddr_str.data + ip_addr_offset, 16);
8010 status = ISC_R_SUCCESS;
8011 }
8012 data_string_forget(&iaddr_str, MDL);
8013 }
8014
8015 option_state_dereference(&cli_enc_opt_state, MDL);
8016 data_string_forget(&cli_enc_opt_data, MDL);
8017 }
8018
8019 return (status);
8020 }
8021
8022 /*
8023 * \brief Calculates the reply T1/T2 times and stuffs them in outbound buffer
8024 *
8025 * T1/T2 time selection is kind of weird. We actually use DHCP * (v4) scoped
8026 * options, dhcp-renewal-time and dhcp-rebinding-time, as handy existing places
8027 * where these can be configured by an administrator. A value of zero tells the
8028 * client it may choose its own value.
8029 *
8030 * When those options are not defined, the values will be set to zero unless
8031 * the global option, dhcpv6-set-tee-times is enabled. When this option is
8032 * enabled the values are calculated as recommended by RFC 3315, Section 22.4:
8033 *
8034 * T1 will be set to 0.5 times the shortest preferred lifetime
8035 * in the IA_XX option. If the "shortest" preferred lifetime is
8036 * 0xFFFFFFFF, T1 will set to 0xFFFFFFFF.
8037 *
8038 * T2 will be set to 0.8 times the shortest preferred lifetime
8039 * in the IA_XX option. If the "shortest" preferred lifetime is
8040 * 0xFFFFFFFF, T2 will set to 0xFFFFFFFF.
8041 *
8042 * Note that dhcpv6-set-tee-times is intended to be transitional and will
8043 * likely be removed in 4.4.0, leaving the behavior as getting the values
8044 * either from the configured parameters (if you want zeros, define them as
8045 * zeros) or by calculating them per the RFC.
8046 *
8047 * \param reply - pointer to the reply_state structure
8048 * \param ia_cursor - offset of the beginning of the IA_XX option within the
8049 * reply's outbound data buffer
8050 */
8051 static void
8052 set_reply_tee_times(struct reply_state* reply, unsigned ia_cursor)
8053 {
8054 struct option_cache *oc;
8055 int set_tee_times;
8056
8057 /* Found out if calculated values are enabled. */
8058 oc = lookup_option(&server_universe, reply->opt_state,
8059 SV_DHCPV6_SET_TEE_TIMES);
8060 set_tee_times = (oc &&
8061 evaluate_boolean_option_cache(NULL, reply->packet,
8062 NULL, NULL,
8063 reply->packet->options,
8064 reply->opt_state,
8065 &global_scope, oc, MDL));
8066
8067 oc = lookup_option(&dhcp_universe, reply->opt_state,
8068 DHO_DHCP_RENEWAL_TIME);
8069 if (oc != NULL) {
8070 /* dhcp-renewal-time is defined, use it */
8071 struct data_string data;
8072 memset(&data, 0x00, sizeof(data));
8073
8074 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
8075 reply->packet->options,
8076 reply->opt_state, &global_scope,
8077 oc, MDL) ||
8078 (data.len != 4)) {
8079 log_error("Invalid renewal time.");
8080 reply->renew = 0;
8081 } else {
8082 reply->renew = getULong(data.data);
8083 }
8084
8085 if (data.data != NULL)
8086 data_string_forget(&data, MDL);
8087 } else if (set_tee_times) {
8088 /* Setting them is enabled so T1 is either infinite or
8089 * 0.5 * the shortest preferred lifetime in the IA_XX */
8090 if (reply->min_prefer == INFINITE_TIME)
8091 reply->renew = INFINITE_TIME;
8092 else
8093 reply->renew = reply->min_prefer / 2;
8094 } else {
8095 /* Default is to let the client choose */
8096 reply->renew = 0;
8097 }
8098
8099 putULong(reply->buf.data + ia_cursor + 8, reply->renew);
8100
8101 /* Now T2. */
8102 oc = lookup_option(&dhcp_universe, reply->opt_state,
8103 DHO_DHCP_REBINDING_TIME);
8104 if (oc != NULL) {
8105 /* dhcp-rebinding-time is defined, use it */
8106 struct data_string data;
8107 memset(&data, 0x00, sizeof(data));
8108
8109 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
8110 reply->packet->options,
8111 reply->opt_state, &global_scope,
8112 oc, MDL) ||
8113 (data.len != 4)) {
8114 log_error("Invalid rebinding time.");
8115 reply->rebind = 0;
8116 } else {
8117 reply->rebind = getULong(data.data);
8118 }
8119
8120 if (data.data != NULL)
8121 data_string_forget(&data, MDL);
8122 } else if (set_tee_times) {
8123 /* Setting them is enabled so T2 is either infinite or
8124 * 0.8 * the shortest preferred lifetime in the reply */
8125 if (reply->min_prefer == INFINITE_TIME)
8126 reply->rebind = INFINITE_TIME;
8127 else
8128 reply->rebind = (reply->min_prefer / 5) * 4;
8129 } else {
8130 /* Default is to let the client choose */
8131 reply->rebind = 0;
8132 }
8133
8134 putULong(reply->buf.data + ia_cursor + 12, reply->rebind);
8135 }
8136
8137
8138 #endif /* DHCPv6 */