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