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