xref: /netbsd/external/mpl/dhcp/dist/client/dhc6.c (revision 13df4856)
1 /*	$NetBSD: dhc6.c,v 1.4 2022/04/03 01:10:57 christos Exp $	*/
2 
3 /* dhc6.c - DHCPv6 client routines. */
4 
5 /*
6  * Copyright (C) 2012-2022 Internet Systems Consortium, Inc. ("ISC")
7  * Copyright (c) 2006-2010 by Internet Systems Consortium, Inc. ("ISC")
8  *
9  * This Source Code Form is subject to the terms of the Mozilla Public
10  * License, v. 2.0. If a copy of the MPL was not distributed with this
11  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  *
21  *   Internet Systems Consortium, Inc.
22  *   PO Box 360
23  *   Newmarket, NH 03857 USA
24  *   <info@isc.org>
25  *   https://www.isc.org/
26  */
27 
28 #include <sys/cdefs.h>
29 __RCSID("$NetBSD: dhc6.c,v 1.4 2022/04/03 01:10:57 christos Exp $");
30 
31 #include "dhcpd.h"
32 
33 #ifdef DHCPv6
34 
35 struct sockaddr_in6 DHCPv6DestAddr;
36 
37 /*
38  * Option definition structures that are used by the software - declared
39  * here once and assigned at startup to save lookups.
40  */
41 struct option *clientid_option = NULL;
42 struct option *elapsed_option = NULL;
43 struct option *ia_na_option = NULL;
44 struct option *ia_ta_option = NULL;
45 struct option *ia_pd_option = NULL;
46 struct option *iaaddr_option = NULL;
47 struct option *iaprefix_option = NULL;
48 struct option *oro_option = NULL;
49 struct option *irt_option = NULL;
50 
51 static struct dhc6_lease *dhc6_dup_lease(struct dhc6_lease *lease,
52 					 const char *file, int line);
53 static struct dhc6_ia *dhc6_dup_ia(struct dhc6_ia *ia,
54 				   const char *file, int line);
55 static struct dhc6_addr *dhc6_dup_addr(struct dhc6_addr *addr,
56 				       const char *file, int line);
57 static void dhc6_ia_destroy(struct dhc6_ia **src, const char *file, int line);
58 static isc_result_t dhc6_parse_ia_na(struct dhc6_ia **pia,
59 				     struct packet *packet,
60 				     struct option_state *options,
61 				     unsigned code);
62 static isc_result_t dhc6_parse_ia_ta(struct dhc6_ia **pia,
63 				     struct packet *packet,
64 				     struct option_state *options,
65 				     unsigned code);
66 static isc_result_t dhc6_parse_ia_pd(struct dhc6_ia **pia,
67 				     struct packet *packet,
68 				     struct option_state *options,
69 				     unsigned code);
70 static isc_result_t dhc6_parse_addrs(struct dhc6_addr **paddr,
71 				     struct packet *packet,
72 				     struct option_state *options);
73 static isc_result_t dhc6_parse_prefixes(struct dhc6_addr **ppref,
74 					struct packet *packet,
75 					struct option_state *options);
76 static struct dhc6_ia *find_ia(struct dhc6_ia *head,
77 			       u_int16_t type, const char *id);
78 static struct dhc6_addr *find_addr(struct dhc6_addr *head,
79 				   struct iaddr *address);
80 static struct dhc6_addr *find_pref(struct dhc6_addr *head,
81 				   struct iaddr *prefix, u_int8_t plen);
82 void init_handler(struct packet *packet, struct client_state *client);
83 void info_request_handler(struct packet *packet, struct client_state *client);
84 void rapid_commit_handler(struct packet *packet, struct client_state *client);
85 void do_init6(void *input);
86 void do_info_request6(void *input);
87 void do_confirm6(void *input);
88 void reply_handler(struct packet *packet, struct client_state *client);
89 static isc_result_t dhc6_create_iaid(struct client_state *client,
90 				     struct data_string *ia,
91 				     int idx,
92 				     unsigned len);
93 static int dhc6_count_ia(struct dhc6_lease *lease,
94 			 u_int16_t ia_type);
95 static isc_result_t dhc6_bare_ia_xx(struct client_state *client,
96 				    struct data_string *packet,
97 				    int wanted,
98 				    u_int16_t ia_type);
99 static isc_result_t dhc6_add_ia_na(struct client_state *client,
100 				   struct data_string *packet,
101 				   struct dhc6_lease *lease,
102 				   u_int8_t message,
103 				   int wanted,
104 				   int *added);
105 static isc_result_t dhc6_add_ia_ta(struct client_state *client,
106 				   struct data_string *packet,
107 				   struct dhc6_lease *lease,
108 				   u_int8_t message,
109 				   int wanted,
110 				   int *added);
111 static isc_result_t dhc6_add_ia_pd(struct client_state *client,
112 				   struct data_string *packet,
113 				   struct dhc6_lease *lease,
114 				   u_int8_t message,
115 				   int wanted,
116 				   int *added);
117 static isc_boolean_t stopping_finished(void);
118 static void dhc6_merge_lease(struct dhc6_lease *src, struct dhc6_lease *dst);
119 void do_select6(void *input);
120 void do_refresh6(void *input);
121 static void do_release6(void *input);
122 static void start_bound(struct client_state *client);
123 static void start_decline6(struct client_state *client);
124 static void do_decline6(void *input);
125 static void start_informed(struct client_state *client);
126 void informed_handler(struct packet *packet, struct client_state *client);
127 void bound_handler(struct packet *packet, struct client_state *client);
128 void start_renew6(void *input);
129 void start_rebind6(void *input);
130 void do_depref(void *input);
131 void do_expire(void *input);
132 static void make_client6_options(struct client_state *client,
133 				 struct option_state **op,
134 				 struct dhc6_lease *lease, u_int8_t message);
135 static void script_write_params6(struct client_state *client,
136 				 const char *prefix,
137 				 struct option_state *options);
138 static void script_write_requested6(struct client_state *client);
139 static isc_boolean_t active_prefix(struct client_state *client);
140 
141 static int check_timing6(struct client_state *client, u_int8_t msg_type,
142 			 char *msg_str, struct dhc6_lease *lease,
143 			 struct data_string *ds);
144 static isc_result_t dhc6_get_status_code(struct option_state *options,
145 					 unsigned *code,
146 					 struct data_string *msg);
147 static isc_result_t dhc6_check_status(isc_result_t rval,
148 				      struct option_state *options,
149 				      const char *scope,
150 				      unsigned *code);
151 static int dhc6_score_lease(struct client_state *client,
152 			    struct dhc6_lease *lease);
153 static isc_result_t dhc6_add_ia_na_decline(struct client_state *client,
154 					   struct data_string *packet,
155 					   struct dhc6_lease *lease);
156 static int drop_declined_addrs(struct dhc6_lease *lease);
157 static isc_boolean_t unexpired_address_in_lease(struct dhc6_lease *lease);
158 
159 extern int onetry;
160 extern int stateless;
161 extern int prefix_len_hint;
162 extern int address_prefix_len;
163 
164 /*
165  * Assign DHCPv6 port numbers as a client.
166  */
167 void
dhcpv6_client_assignments(void)168 dhcpv6_client_assignments(void)
169 {
170 	struct servent *ent;
171 	unsigned code;
172 
173 	if (path_dhclient_pid == NULL)
174 		path_dhclient_pid = _PATH_DHCLIENT6_PID;
175 	if (path_dhclient_db == NULL)
176 		path_dhclient_db = _PATH_DHCLIENT6_DB;
177 
178 	if (local_port == 0) {
179 		ent = getservbyname("dhcpv6-client", "udp");
180 		if (ent == NULL)
181 			local_port = htons(546);
182 		else
183 			local_port = ent->s_port;
184 	}
185 
186 	if (remote_port == 0) {
187 		ent = getservbyname("dhcpv6-server", "udp");
188 		if (ent == NULL)
189 			remote_port = htons(547);
190 		else
191 			remote_port = ent->s_port;
192 	}
193 
194 	memset(&DHCPv6DestAddr, 0, sizeof(DHCPv6DestAddr));
195 	DHCPv6DestAddr.sin6_family = AF_INET6;
196 	DHCPv6DestAddr.sin6_port = remote_port;
197 	if (inet_pton(AF_INET6, All_DHCP_Relay_Agents_and_Servers,
198 		      &DHCPv6DestAddr.sin6_addr) <= 0) {
199 		log_fatal("Bad address %s", All_DHCP_Relay_Agents_and_Servers);
200 	}
201 
202 	code = D6O_CLIENTID;
203 	if (!option_code_hash_lookup(&clientid_option,
204 				     dhcpv6_universe.code_hash, &code, 0, MDL))
205 		log_fatal("Unable to find the CLIENTID option definition.");
206 
207 	code = D6O_ELAPSED_TIME;
208 	if (!option_code_hash_lookup(&elapsed_option,
209 				     dhcpv6_universe.code_hash, &code, 0, MDL))
210 		log_fatal("Unable to find the ELAPSED_TIME option definition.");
211 
212 	code = D6O_IA_NA;
213 	if (!option_code_hash_lookup(&ia_na_option, dhcpv6_universe.code_hash,
214 				     &code, 0, MDL))
215 		log_fatal("Unable to find the IA_NA option definition.");
216 
217 	code = D6O_IA_TA;
218 	if (!option_code_hash_lookup(&ia_ta_option, dhcpv6_universe.code_hash,
219 				     &code, 0, MDL))
220 		log_fatal("Unable to find the IA_TA option definition.");
221 
222 	code = D6O_IA_PD;
223 	if (!option_code_hash_lookup(&ia_pd_option, dhcpv6_universe.code_hash,
224 				     &code, 0, MDL))
225 		log_fatal("Unable to find the IA_PD option definition.");
226 
227 	code = D6O_IAADDR;
228 	if (!option_code_hash_lookup(&iaaddr_option, dhcpv6_universe.code_hash,
229 				     &code, 0, MDL))
230 		log_fatal("Unable to find the IAADDR option definition.");
231 
232 	code = D6O_IAPREFIX;
233 	if (!option_code_hash_lookup(&iaprefix_option,
234 				     dhcpv6_universe.code_hash,
235 				     &code, 0, MDL))
236 		log_fatal("Unable to find the IAPREFIX option definition.");
237 
238 	code = D6O_ORO;
239 	if (!option_code_hash_lookup(&oro_option, dhcpv6_universe.code_hash,
240 				     &code, 0, MDL))
241 		log_fatal("Unable to find the ORO option definition.");
242 
243 	code = D6O_INFORMATION_REFRESH_TIME;
244 	if (!option_code_hash_lookup(&irt_option, dhcpv6_universe.code_hash,
245 				     &code, 0, MDL))
246 		log_fatal("Unable to find the IRT option definition.");
247 
248 #ifndef __CYGWIN32__ /* XXX */
249 	endservent();
250 #endif
251 }
252 
253 /*
254  * Instead of implementing RFC3315 RAND (section 14) as a float "between"
255  * -0.1 and 0.1 non-inclusive, we implement it as an integer.
256  *
257  * The result is expected to follow this table:
258  *
259  *		split range answer
260  *		    - ERROR -		      base <= 0
261  *		0	1   0..0	 1 <= base <= 10
262  *		1	3  -1..1	11 <= base <= 20
263  *		2	5  -2..2	21 <= base <= 30
264  *		3	7  -3..3	31 <= base <= 40
265  *		...
266  *
267  * XXX: For this to make sense, we really need to do timing on a
268  * XXX: usec scale...we currently can assume zero for any value less than
269  * XXX: 11, which are very common in early stages of transmission for most
270  * XXX: messages.
271  */
272 static TIME
dhc6_rand(TIME base)273 dhc6_rand(TIME base)
274 {
275 	TIME rval;
276 	TIME range;
277 	TIME split;
278 
279 	/*
280 	 * A zero or less timeout is a bad thing...we don't want to
281 	 * DHCP-flood anyone.
282 	 */
283 	if (base <= 0)
284 		log_fatal("Impossible condition at %s:%d.", MDL);
285 
286 	/*
287 	 * The first thing we do is count how many random integers we want
288 	 * in either direction (best thought of as the maximum negative
289 	 * integer, as we will subtract this potentially from a random 0).
290 	 */
291 	split = (base - 1) / 10;
292 
293 	/* Don't bother with the rest of the math if we know we'll get 0. */
294 	if (split == 0)
295 		return 0;
296 
297 	/*
298 	 * Then we count the total number of integers in this set.  This
299 	 * is twice the number of integers in positive and negative
300 	 * directions, plus zero (-1, 0, 1 is 3, -2..2 adds 2 to 5, so forth).
301 	 */
302 	range = (split * 2) + 1;
303 
304 	/* Take a random number from [0..(range-1)]. */
305 	rval = random();
306 	rval %= range;
307 
308 	/* Offset it to uncover potential negative values. */
309 	rval -= split;
310 
311 	return rval;
312 }
313 
314 /* Initialize message exchange timers (set RT from Initial-RT). */
315 static void
dhc6_retrans_init(struct client_state * client)316 dhc6_retrans_init(struct client_state *client)
317 {
318 	int xid;
319 
320 	/* Initialize timers. */
321 	client->txcount = 0;
322 	client->RT = client->IRT + dhc6_rand(client->IRT);
323 
324 	/* Generate a new random 24-bit transaction ID for this exchange. */
325 
326 #if (RAND_MAX >= 0x00ffffff)
327 	xid = random();
328 #elif (RAND_MAX >= 0x0000ffff)
329 	xid = (random() << 16) ^ random();
330 #elif (RAND_MAX >= 0x000000ff)
331 	xid = (random() << 16) ^ (random() << 8) ^ random();
332 #else
333 # error "Random number generator of less than 8 bits not supported."
334 #endif
335 
336 	client->dhcpv6_transaction_id[0] = (xid >> 16) & 0xff;
337 	client->dhcpv6_transaction_id[1] = (xid >>  8) & 0xff;
338 	client->dhcpv6_transaction_id[2] =  xid        & 0xff;
339 }
340 
341 /* Advance the DHCPv6 retransmission state once. */
342 static void
dhc6_retrans_advance(struct client_state * client)343 dhc6_retrans_advance(struct client_state *client)
344 {
345 	struct timeval elapsed, elapsed_plus_rt;
346 
347 	/* elapsed = cur - start */
348 	elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
349 	elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
350 	if (elapsed.tv_usec < 0) {
351 		elapsed.tv_sec -= 1;
352 		elapsed.tv_usec += 1000000;
353 	}
354 	/* retrans_advance is called after consuming client->RT. */
355 	/* elapsed += RT */
356 	elapsed.tv_sec += client->RT / 100;
357 	elapsed.tv_usec += (client->RT % 100) * 10000;
358 	if (elapsed.tv_usec >= 1000000) {
359 		elapsed.tv_sec += 1;
360 		elapsed.tv_usec -= 1000000;
361 	}
362 	/*
363 	 * Save what the time will be after the current RT to determine
364 	 * what the delta to MRD will be.
365 	 */
366 	elapsed_plus_rt.tv_sec = elapsed.tv_sec;
367 	elapsed_plus_rt.tv_usec = elapsed.tv_usec;
368 
369 	/*
370 	 * RT for each subsequent message transmission is based on the previous
371 	 * value of RT:
372 	 *
373 	 *    RT = 2*RTprev + RAND*RTprev
374 	 */
375 	client->RT += client->RT + dhc6_rand(client->RT);
376 
377 	/*
378 	 * MRT specifies an upper bound on the value of RT (disregarding the
379 	 * randomization added by the use of RAND).  If MRT has a value of 0,
380 	 * there is no upper limit on the value of RT.  Otherwise:
381 	 *
382 	 *    if (RT > MRT)
383 	 *       RT = MRT + RAND*MRT
384 	 */
385 	if ((client->MRT != 0) && (client->RT > client->MRT))
386 		client->RT = client->MRT + dhc6_rand(client->MRT);
387 
388 	/*
389 	 * Further, if there's an MRD, we should wake up upon reaching
390 	 * the MRD rather than at some point after it.
391 	 */
392 	if (client->MRD == 0) {
393 		/* Done. */
394 		client->txcount++;
395 		return;
396 	}
397 	/* elapsed += client->RT */
398 	elapsed.tv_sec += client->RT / 100;
399 	elapsed.tv_usec += (client->RT % 100) * 10000;
400 	if (elapsed.tv_usec >= 1000000) {
401 		elapsed.tv_sec += 1;
402 		elapsed.tv_usec -= 1000000;
403 	}
404 	if (elapsed.tv_sec >= client->MRD) {
405 		/*
406 		 * The desired RT is the time that will be remaining in MRD
407 		 * when the current timeout finishes.  We then have
408 		 * desired RT = MRD - (elapsed time + previous RT); or
409 		 * desired RT = MRD - elapsed_plut_rt;
410 		 */
411 		client->RT = client->MRD - elapsed_plus_rt.tv_sec;
412 		client->RT = (client->RT * 100) -
413 			(elapsed_plus_rt.tv_usec / 10000);
414 		if (client->RT < 0)
415 			client->RT = 0;
416 	}
417 	client->txcount++;
418 }
419 
420 /* Quick validation of DHCPv6 ADVERTISE packet contents. */
421 static int
valid_reply(struct packet * packet,struct client_state * client)422 valid_reply(struct packet *packet, struct client_state *client)
423 {
424 	struct data_string sid, cid;
425 	struct option_cache *oc;
426 	int rval = ISC_TRUE;
427 
428 	memset(&sid, 0, sizeof(sid));
429 	memset(&cid, 0, sizeof(cid));
430 
431 	if (!lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID)) {
432 		log_error("Response without a server identifier received.");
433 		rval = ISC_FALSE;
434 	}
435 
436 	oc = lookup_option(&dhcpv6_universe, packet->options, D6O_CLIENTID);
437 	if (!oc ||
438 	    !evaluate_option_cache(&sid, packet, NULL, client, packet->options,
439 				   client->sent_options, &global_scope, oc,
440 				   MDL)) {
441 		log_error("Response without a client identifier.");
442 		rval = ISC_FALSE;
443 	}
444 
445 	oc = lookup_option(&dhcpv6_universe, client->sent_options,
446 			   D6O_CLIENTID);
447 	if (!oc ||
448 	    !evaluate_option_cache(&cid, packet, NULL, client,
449 				   client->sent_options, NULL, &global_scope,
450 				   oc, MDL)) {
451 		log_error("Local client identifier is missing!");
452 		rval = ISC_FALSE;
453 	}
454 
455 	if (sid.len == 0 ||
456 	    sid.len != cid.len ||
457 	    memcmp(sid.data, cid.data, sid.len)) {
458 		log_error("Advertise with matching transaction ID, but "
459 			  "mismatching client id.");
460 		rval = ISC_FALSE;
461 	}
462 
463 	/* clean up pointers to the strings */
464 	if (sid.data != NULL)
465 		data_string_forget(&sid, MDL);
466 	if (cid.data != NULL)
467 		data_string_forget(&cid, MDL);
468 
469 	return rval;
470 }
471 
472 /*
473  * Create a complete copy of a DHCPv6 lease structure.
474  */
475 static struct dhc6_lease *
dhc6_dup_lease(struct dhc6_lease * lease,const char * file,int line)476 dhc6_dup_lease(struct dhc6_lease *lease, const char *file, int line)
477 {
478 	struct dhc6_lease *copy;
479 	struct dhc6_ia **insert_ia, *ia;
480 
481 	copy = dmalloc(sizeof(*copy), file, line);
482 	if (copy == NULL) {
483 		log_error("Out of memory for v6 lease structure.");
484 		return NULL;
485 	}
486 
487 	data_string_copy(&copy->server_id, &lease->server_id, file, line);
488 	copy->pref = lease->pref;
489 
490 	memcpy(copy->dhcpv6_transaction_id, lease->dhcpv6_transaction_id,
491 	       sizeof(copy->dhcpv6_transaction_id));
492 
493 	option_state_reference(&copy->options, lease->options, file, line);
494 
495 	insert_ia = &copy->bindings;
496 	for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
497 		*insert_ia = dhc6_dup_ia(ia, file, line);
498 
499 		if (*insert_ia == NULL) {
500 			dhc6_lease_destroy(&copy, file, line);
501 			return NULL;
502 		}
503 
504 		insert_ia = &(*insert_ia)->next;
505 	}
506 
507 	return copy;
508 }
509 
510 /*
511  * Duplicate an IA structure.
512  */
513 static struct dhc6_ia *
dhc6_dup_ia(struct dhc6_ia * ia,const char * file,int line)514 dhc6_dup_ia(struct dhc6_ia *ia, const char *file, int line)
515 {
516 	struct dhc6_ia *copy;
517 	struct dhc6_addr **insert_addr, *addr;
518 
519 	copy = dmalloc(sizeof(*ia), file, line);
520 	if (copy == NULL) {
521 		log_error("Out of memory for v6 duplicate IA structure.");
522 		return NULL;
523 	}
524 
525 	memcpy(copy->iaid, ia->iaid, sizeof(copy->iaid));
526 
527 	copy->ia_type = ia->ia_type;
528 	copy->starts = ia->starts;
529 	copy->renew = ia->renew;
530 	copy->rebind = ia->rebind;
531 
532 	insert_addr = &copy->addrs;
533 	for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
534 		*insert_addr = dhc6_dup_addr(addr, file, line);
535 
536 		if (*insert_addr == NULL) {
537 			dhc6_ia_destroy(&copy, file, line);
538 			return NULL;
539 		}
540 
541 		insert_addr = &(*insert_addr)->next;
542 	}
543 
544 	if (ia->options != NULL)
545 		option_state_reference(&copy->options, ia->options,
546 				       file, line);
547 
548 	return copy;
549 }
550 
551 /*
552  * Duplicate an IAADDR or IAPREFIX structure.
553  */
554 static struct dhc6_addr *
dhc6_dup_addr(struct dhc6_addr * addr,const char * file,int line)555 dhc6_dup_addr(struct dhc6_addr *addr, const char *file, int line)
556 {
557 	struct dhc6_addr *copy;
558 
559 	copy = dmalloc(sizeof(*addr), file, line);
560 
561 	if (copy == NULL)
562 		return NULL;
563 
564 	memcpy(&copy->address, &addr->address, sizeof(copy->address));
565 
566 	copy->plen = addr->plen;
567 	copy->flags = addr->flags;
568 	copy->starts = addr->starts;
569 	copy->preferred_life = addr->preferred_life;
570 	copy->max_life = addr->max_life;
571 
572 	if (addr->options != NULL)
573 		option_state_reference(&copy->options, addr->options,
574 				       file, line);
575 
576 	return copy;
577 }
578 
579 /*
580  * Form a DHCPv6 lease structure based upon packet contents.  Creates and
581  * populates IA's and any IAADDR/IAPREFIX's they contain.
582  * Parsed options are deleted in order to not save them in the lease file.
583  *
584  * If we get a status code of NoAddrs or NoPrefix we toss the affected
585  * IAs.  If it as at the top level we toss all IAs of that type.  If it
586  * is in an IA we only toss that one.  According to the spec we shouldn't
587  * get a NoPrefix status at the top level but we will allow it.
588  *
589  */
590 static struct dhc6_lease *
dhc6_leaseify(struct packet * packet,struct client_state * client)591 dhc6_leaseify(struct packet *packet, struct client_state* client)
592 {
593 	struct data_string ds;
594 	struct dhc6_lease *lease;
595 	struct option_cache *oc;
596 	unsigned code;
597 
598 	lease = dmalloc(sizeof(*lease), MDL);
599 	if (lease == NULL) {
600 		log_error("Out of memory for v6 lease structure.");
601 		return NULL;
602 	}
603 
604 	memcpy(lease->dhcpv6_transaction_id, packet->dhcpv6_transaction_id, 3);
605 	option_state_reference(&lease->options, packet->options, MDL);
606 
607 	memset(&ds, 0, sizeof(ds));
608 
609 	/* Determine preference (default zero). */
610 	oc = lookup_option(&dhcpv6_universe, lease->options, D6O_PREFERENCE);
611 	if (oc &&
612 	    evaluate_option_cache(&ds, packet, NULL, NULL, lease->options,
613 				  NULL, &global_scope, oc, MDL)) {
614 		if (ds.len != 1) {
615 			log_error("Invalid length of DHCPv6 Preference option "
616 				  "(%d != 1)", ds.len);
617 			data_string_forget(&ds, MDL);
618 			dhc6_lease_destroy(&lease, MDL);
619 			return NULL;
620 		} else {
621 			lease->pref = ds.data[0];
622 			log_debug("RCV:  X-- Preference %u.",
623 				  (unsigned)lease->pref);
624 		}
625 
626 		data_string_forget(&ds, MDL);
627 	}
628 	delete_option(&dhcpv6_universe, lease->options, D6O_PREFERENCE);
629 
630 	/* Get the top level status code.  If the code is NoAddrsAvail
631 	 * or NoPrefixAvail strip it from the options as we don't
632 	 * want it to show up in check_[advertise reply].  We
633 	 * pass it along to the parse_ia_xx routines and they
634 	 * will drop the affected IAs for NoAddrs or NoPrefix,
635 	 * other status codes will be ignored and handled by
636 	 * the check_[advertise reply] routines.
637 	 */
638 	code = STATUS_Success;
639 	if ((dhc6_get_status_code(lease->options, &code, NULL) == ISC_R_SUCCESS)
640 	    &&
641 	    ((code == STATUS_NoAddrsAvail) || (code == STATUS_NoPrefixAvail))) {
642 		delete_option(&dhcpv6_universe, lease->options,
643 			      D6O_STATUS_CODE);
644 	}
645 
646 	/*
647 	 * Dig into recursive DHCPv6 pockets for IA_NA and contained IAADDR
648 	 * options.
649 	 */
650 	if (dhc6_parse_ia_na(&lease->bindings, packet,
651 			     lease->options, code) != ISC_R_SUCCESS) {
652 		/* Error conditions are logged by the caller. */
653 		dhc6_lease_destroy(&lease, MDL);
654 		return NULL;
655 	}
656 	/*
657 	 * Dig into recursive DHCPv6 pockets for IA_TA and contained IAADDR
658 	 * options.
659 	 */
660 	if (dhc6_parse_ia_ta(&lease->bindings, packet,
661 			     lease->options, code) != ISC_R_SUCCESS) {
662 		/* Error conditions are logged by the caller. */
663 		dhc6_lease_destroy(&lease, MDL);
664 		return NULL;
665 	}
666 	/*
667 	 * Dig into recursive DHCPv6 pockets for IA_PD and contained IAPREFIX
668 	 * options.
669 	 */
670 	if (dhc6_parse_ia_pd(&lease->bindings, packet,
671 			     lease->options, code) != ISC_R_SUCCESS) {
672 		/* Error conditions are logged by the caller. */
673 		dhc6_lease_destroy(&lease, MDL);
674 		return NULL;
675 	}
676 
677 	/*
678 	 * This is last because in the future we may want to make a different
679 	 * key based upon additional information from the packet (we may need
680 	 * to allow multiple leases in one client state per server, but we're
681 	 * not sure based on what additional keys now).
682 	 */
683 	oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
684 	if ((oc == NULL) ||
685 	    !evaluate_option_cache(&lease->server_id, packet, NULL, NULL,
686 				   lease->options, NULL, &global_scope,
687 				   oc, MDL) ||
688 	    lease->server_id.len == 0) {
689 		/* This should be impossible due to validation checks earlier.
690 		 */
691 		log_error("Invalid SERVERID option cache.");
692 		dhc6_lease_destroy(&lease, MDL);
693 		return NULL;
694 	} else {
695 		log_debug("RCV:  X-- Server ID: %s",
696 			  print_hex_1(lease->server_id.len,
697 				      lease->server_id.data, 52));
698 	}
699 
700 	execute_statements_in_scope(NULL, (struct packet *)packet, NULL,
701 				    client, lease->options, lease->options,
702 				    &global_scope, client->config->on_receipt,
703 				    NULL, NULL);
704 
705 	return lease;
706 }
707 
708 static isc_result_t
dhc6_parse_ia_na(struct dhc6_ia ** pia,struct packet * packet,struct option_state * options,unsigned code)709 dhc6_parse_ia_na(struct dhc6_ia **pia, struct packet *packet,
710 		 struct option_state *options, unsigned code)
711 {
712 	struct data_string ds;
713 	struct dhc6_ia *ia;
714 	struct option_cache *oc;
715 	isc_result_t result;
716 	unsigned ia_code;
717 
718 	memset(&ds, 0, sizeof(ds));
719 
720 	oc = lookup_option(&dhcpv6_universe, options, D6O_IA_NA);
721 	for ( ; oc != NULL ; oc = oc->next) {
722 		ia = dmalloc(sizeof(*ia), MDL);
723 		if (ia == NULL) {
724 			log_error("Out of memory allocating IA_NA structure.");
725 			return ISC_R_NOMEMORY;
726 		} else if (evaluate_option_cache(&ds, packet, NULL, NULL,
727 						 options, NULL,
728 						 &global_scope, oc, MDL) &&
729 			   ds.len >= 12) {
730 			memcpy(ia->iaid, ds.data, 4);
731 			ia->ia_type = D6O_IA_NA;
732 			ia->starts = cur_time;
733 			ia->renew = getULong(ds.data + 4);
734 			ia->rebind = getULong(ds.data + 8);
735 
736 			log_debug("RCV:  X-- IA_NA %s",
737 				  print_hex_1(4, ia->iaid, 59));
738 			/* XXX: This should be the printed time I think. */
739 			log_debug("RCV:  | X-- starts %u",
740 				  (unsigned)ia->starts);
741 			log_debug("RCV:  | X-- t1 - renew  +%u", ia->renew);
742 			log_debug("RCV:  | X-- t2 - rebind +%u", ia->rebind);
743 
744 			/*
745 			 * RFC3315 section 22.4, discard IA_NA's that
746 			 * have t1 greater than t2, and both not zero.
747 			 * Since RFC3315 defines this behaviour, it is not
748 			 * an error - just normal operation.
749 			 *
750 			 * Note that RFC3315 says we MUST honor these values
751 			 * if they are not zero.  So insane values are
752 			 * totally OK.
753 			 */
754 			if ((ia->renew > 0) && (ia->rebind > 0) &&
755 			    (ia->renew > ia->rebind)) {
756 				log_debug("RCV:  | !-- INVALID renew/rebind "
757 					  "times, IA_NA discarded.");
758 				dfree(ia, MDL);
759 				data_string_forget(&ds, MDL);
760 				continue;
761 			}
762 
763 			if (ds.len > 12) {
764 				log_debug("RCV:  | X-- [Options]");
765 
766 				if (!option_state_allocate(&ia->options,
767 							   MDL)) {
768 					log_error("Out of memory allocating "
769 						  "IA_NA option state.");
770 					dfree(ia, MDL);
771 					data_string_forget(&ds, MDL);
772 					return ISC_R_NOMEMORY;
773 				}
774 
775 				if (!parse_option_buffer(ia->options,
776 							 ds.data + 12,
777 							 ds.len - 12,
778 							 &dhcpv6_universe)) {
779 					log_error("Corrupt IA_NA options.");
780 					option_state_dereference(&ia->options,
781 								 MDL);
782 					dfree(ia, MDL);
783 					data_string_forget(&ds, MDL);
784 					return DHCP_R_BADPARSE;
785 				}
786 			}
787 			data_string_forget(&ds, MDL);
788 
789 			if (ia->options != NULL) {
790 				result = dhc6_parse_addrs(&ia->addrs, packet,
791 							  ia->options);
792 				if (result != ISC_R_SUCCESS) {
793 					option_state_dereference(&ia->options,
794 								 MDL);
795 					dfree(ia, MDL);
796 					return result;
797 				}
798 			}
799 
800 			/* If we have no addresses or the top level status code
801 			 * or the status code in this IA indicate no addresses
802 			 * toss the IA.
803 			 */
804 			ia_code = STATUS_Success;
805 			if ((ia->addrs == NULL) ||
806 			    (code == STATUS_NoAddrsAvail) ||
807 			    ((ia->options != NULL) &&
808 			     (dhc6_get_status_code(ia->options, &ia_code, NULL)
809 			      == ISC_R_SUCCESS) &&
810 			     (ia_code == STATUS_NoAddrsAvail))) {
811 				log_debug("RCV:  | !-- Status code of "
812 					  "no addrs, IA_NA discarded.");
813 				dhc6_ia_destroy(&ia, MDL);
814 				continue;
815 			}
816 
817 			while (*pia != NULL)
818 				pia = &(*pia)->next;
819 			*pia = ia;
820 			pia = &ia->next;
821 		} else {
822 			log_error("Invalid IA_NA option cache.");
823 			dfree(ia, MDL);
824 			data_string_forget(&ds, MDL);
825 			return ISC_R_UNEXPECTED;
826 		}
827 	}
828 	delete_option(&dhcpv6_universe, options, D6O_IA_NA);
829 
830 	return ISC_R_SUCCESS;
831 }
832 
833 static isc_result_t
dhc6_parse_ia_ta(struct dhc6_ia ** pia,struct packet * packet,struct option_state * options,unsigned code)834 dhc6_parse_ia_ta(struct dhc6_ia **pia, struct packet *packet,
835 		 struct option_state *options, unsigned code)
836 {
837 	struct data_string ds;
838 	struct dhc6_ia *ia;
839 	struct option_cache *oc;
840 	isc_result_t result;
841 	unsigned ia_code;
842 
843 	memset(&ds, 0, sizeof(ds));
844 
845 	oc = lookup_option(&dhcpv6_universe, options, D6O_IA_TA);
846 	for ( ; oc != NULL ; oc = oc->next) {
847 		ia = dmalloc(sizeof(*ia), MDL);
848 		if (ia == NULL) {
849 			log_error("Out of memory allocating IA_TA structure.");
850 			return ISC_R_NOMEMORY;
851 		} else if (evaluate_option_cache(&ds, packet, NULL, NULL,
852 						 options, NULL,
853 						 &global_scope, oc, MDL) &&
854 			   ds.len >= 4) {
855 			memcpy(ia->iaid, ds.data, 4);
856 			ia->ia_type = D6O_IA_TA;
857 			ia->starts = cur_time;
858 
859 			log_debug("RCV:  X-- IA_TA %s",
860 				  print_hex_1(4, ia->iaid, 59));
861 			/* XXX: This should be the printed time I think. */
862 			log_debug("RCV:  | X-- starts %u",
863 				  (unsigned)ia->starts);
864 
865 			if (ds.len > 4) {
866 				log_debug("RCV:  | X-- [Options]");
867 
868 				if (!option_state_allocate(&ia->options,
869 							   MDL)) {
870 					log_error("Out of memory allocating "
871 						  "IA_TA option state.");
872 					dfree(ia, MDL);
873 					data_string_forget(&ds, MDL);
874 					return ISC_R_NOMEMORY;
875 				}
876 
877 				if (!parse_option_buffer(ia->options,
878 							 ds.data + 4,
879 							 ds.len - 4,
880 							 &dhcpv6_universe)) {
881 					log_error("Corrupt IA_TA options.");
882 					option_state_dereference(&ia->options,
883 								 MDL);
884 					dfree(ia, MDL);
885 					data_string_forget(&ds, MDL);
886 					return DHCP_R_BADPARSE;
887 				}
888 			}
889 			data_string_forget(&ds, MDL);
890 
891 			if (ia->options != NULL) {
892 				result = dhc6_parse_addrs(&ia->addrs, packet,
893 							  ia->options);
894 				if (result != ISC_R_SUCCESS) {
895 					option_state_dereference(&ia->options,
896 								 MDL);
897 					dfree(ia, MDL);
898 					return result;
899 				}
900 			}
901 
902 			/* If we have no addresses or the top level status code
903 			 * or the status code in this IA indicate no addresses
904 			 * toss the IA.
905 			 */
906 			ia_code = STATUS_Success;
907 			if ((ia->addrs == NULL) ||
908 			    (code == STATUS_NoAddrsAvail) ||
909 			    ((ia->options != NULL) &&
910 			     (dhc6_get_status_code(ia->options, &ia_code, NULL)
911 			      == ISC_R_SUCCESS) &&
912 			     (ia_code == STATUS_NoAddrsAvail))) {
913 				log_debug("RCV:  | !-- Status code of "
914 					  "no addrs, IA_TA discarded.");
915 				dhc6_ia_destroy(&ia, MDL);
916 				continue;
917 			}
918 
919 			while (*pia != NULL)
920 				pia = &(*pia)->next;
921 			*pia = ia;
922 			pia = &ia->next;
923 		} else {
924 			log_error("Invalid IA_TA option cache.");
925 			dfree(ia, MDL);
926 			data_string_forget(&ds, MDL);
927 			return ISC_R_UNEXPECTED;
928 		}
929 	}
930 	delete_option(&dhcpv6_universe, options, D6O_IA_TA);
931 
932 	return ISC_R_SUCCESS;
933 }
934 
935 static isc_result_t
dhc6_parse_ia_pd(struct dhc6_ia ** pia,struct packet * packet,struct option_state * options,unsigned code)936 dhc6_parse_ia_pd(struct dhc6_ia **pia, struct packet *packet,
937 		 struct option_state *options, unsigned code)
938 {
939 	struct data_string ds;
940 	struct dhc6_ia *ia;
941 	struct option_cache *oc;
942 	isc_result_t result;
943 	unsigned ia_code;
944 
945 	memset(&ds, 0, sizeof(ds));
946 
947 	oc = lookup_option(&dhcpv6_universe, options, D6O_IA_PD);
948 	for ( ; oc != NULL ; oc = oc->next) {
949 		ia = dmalloc(sizeof(*ia), MDL);
950 		if (ia == NULL) {
951 			log_error("Out of memory allocating IA_PD structure.");
952 			return ISC_R_NOMEMORY;
953 		} else if (evaluate_option_cache(&ds, packet, NULL, NULL,
954 						 options, NULL,
955 						 &global_scope, oc, MDL) &&
956 			   ds.len >= 12) {
957 			memcpy(ia->iaid, ds.data, 4);
958 			ia->ia_type = D6O_IA_PD;
959 			ia->starts = cur_time;
960 			ia->renew = getULong(ds.data + 4);
961 			ia->rebind = getULong(ds.data + 8);
962 
963 			log_debug("RCV:  X-- IA_PD %s",
964 				  print_hex_1(4, ia->iaid, 59));
965 			/* XXX: This should be the printed time I think. */
966 			log_debug("RCV:  | X-- starts %u",
967 				  (unsigned)ia->starts);
968 			log_debug("RCV:  | X-- t1 - renew  +%u", ia->renew);
969 			log_debug("RCV:  | X-- t2 - rebind +%u", ia->rebind);
970 
971 			/*
972 			 * RFC3633 section 9, discard IA_PD's that
973 			 * have t1 greater than t2, and both not zero.
974 			 * Since RFC3633 defines this behaviour, it is not
975 			 * an error - just normal operation.
976 			 */
977 			if ((ia->renew > 0) && (ia->rebind > 0) &&
978 			    (ia->renew > ia->rebind)) {
979 				log_debug("RCV:  | !-- INVALID renew/rebind "
980 					  "times, IA_PD discarded.");
981 				dfree(ia, MDL);
982 				data_string_forget(&ds, MDL);
983 				continue;
984 			}
985 
986 			if (ds.len > 12) {
987 				log_debug("RCV:  | X-- [Options]");
988 
989 				if (!option_state_allocate(&ia->options,
990 							   MDL)) {
991 					log_error("Out of memory allocating "
992 						  "IA_PD option state.");
993 					dfree(ia, MDL);
994 					data_string_forget(&ds, MDL);
995 					return ISC_R_NOMEMORY;
996 				}
997 
998 				if (!parse_option_buffer(ia->options,
999 							 ds.data + 12,
1000 							 ds.len - 12,
1001 							 &dhcpv6_universe)) {
1002 					log_error("Corrupt IA_PD options.");
1003 					option_state_dereference(&ia->options,
1004 								 MDL);
1005 					dfree(ia, MDL);
1006 					data_string_forget(&ds, MDL);
1007 					return DHCP_R_BADPARSE;
1008 				}
1009 			}
1010 			data_string_forget(&ds, MDL);
1011 
1012 			if (ia->options != NULL) {
1013 				result = dhc6_parse_prefixes(&ia->addrs,
1014 							     packet,
1015 							     ia->options);
1016 				if (result != ISC_R_SUCCESS) {
1017 					option_state_dereference(&ia->options,
1018 								 MDL);
1019 					dfree(ia, MDL);
1020 					return result;
1021 				}
1022 			}
1023 
1024 			/* If we have no prefixes or the top level status code
1025 			 * or the status code in this IA indicate no prefixes
1026 			 * toss the IA.
1027 			 */
1028 			ia_code = STATUS_Success;
1029 			if ((ia->addrs == NULL) ||
1030 			    (code == STATUS_NoPrefixAvail) ||
1031 			    ((ia->options != NULL) &&
1032 			     (dhc6_get_status_code(ia->options, &ia_code, NULL)
1033 			      == ISC_R_SUCCESS) &&
1034 			     (ia_code == STATUS_NoPrefixAvail))) {
1035 				log_debug("RCV:  | !-- Status code of "
1036 					  "no prefix, IA_PD discarded.");
1037 				dhc6_ia_destroy(&ia, MDL);
1038 				continue;
1039 			}
1040 
1041 			while (*pia != NULL)
1042 				pia = &(*pia)->next;
1043 			*pia = ia;
1044 			pia = &ia->next;
1045 		} else {
1046 			log_error("Invalid IA_PD option cache.");
1047 			dfree(ia, MDL);
1048 			data_string_forget(&ds, MDL);
1049 			return ISC_R_UNEXPECTED;
1050 		}
1051 	}
1052 	delete_option(&dhcpv6_universe, options, D6O_IA_PD);
1053 
1054 	return ISC_R_SUCCESS;
1055 }
1056 
1057 
1058 static isc_result_t
dhc6_parse_addrs(struct dhc6_addr ** paddr,struct packet * packet,struct option_state * options)1059 dhc6_parse_addrs(struct dhc6_addr **paddr, struct packet *packet,
1060 		 struct option_state *options)
1061 {
1062 	struct data_string ds;
1063 	struct option_cache *oc;
1064 	struct dhc6_addr *addr;
1065 	isc_result_t rval = ISC_R_SUCCESS;
1066 	unsigned code;
1067 
1068 	memset(&ds, 0, sizeof(ds));
1069 
1070 	oc = lookup_option(&dhcpv6_universe, options, D6O_IAADDR);
1071 	for ( ; oc != NULL ; oc = oc->next) {
1072 		addr = dmalloc(sizeof(*addr), MDL);
1073 		if (addr == NULL) {
1074 			log_error("Out of memory allocating "
1075 				  "address structure.");
1076 			return ISC_R_NOMEMORY;
1077 		} else if (evaluate_option_cache(&ds, packet, NULL, NULL,
1078 						 options, NULL, &global_scope,
1079 						 oc, MDL) &&
1080 			   (ds.len >= 24)) {
1081 
1082 			addr->address.len = 16;
1083 			memcpy(addr->address.iabuf, ds.data, 16);
1084 			addr->starts = cur_time;
1085 			addr->preferred_life = getULong(ds.data + 16);
1086 			addr->max_life = getULong(ds.data + 20);
1087 
1088 			log_debug("RCV:  | | X-- IAADDR %s",
1089 				  piaddr(addr->address));
1090 			log_debug("RCV:  | | | X-- Preferred lifetime %u.",
1091 				  addr->preferred_life);
1092 			log_debug("RCV:  | | | X-- Max lifetime %u.",
1093 				  addr->max_life);
1094 
1095 			/*
1096 			 * RFC 3315 section 22.6 says we must discard
1097 			 * addresses whose pref is later than valid.
1098 			 */
1099 			if ((addr->preferred_life > addr->max_life)) {
1100 				log_debug("RCV:  | | | !-- INVALID lifetimes, "
1101 					  "IAADDR discarded.  Check your "
1102 					  "server configuration.");
1103 				dfree(addr, MDL);
1104 				data_string_forget(&ds, MDL);
1105 				continue;
1106 			}
1107 
1108 			/*
1109 			 * Fortunately this is the last recursion in the
1110 			 * protocol.
1111 			 */
1112 			if (ds.len > 24) {
1113 				if (!option_state_allocate(&addr->options,
1114 							   MDL)) {
1115 					log_error("Out of memory allocating "
1116 						  "IAADDR option state.");
1117 					dfree(addr, MDL);
1118 					data_string_forget(&ds, MDL);
1119 					return ISC_R_NOMEMORY;
1120 				}
1121 
1122 				if (!parse_option_buffer(addr->options,
1123 							 ds.data + 24,
1124 							 ds.len - 24,
1125 							 &dhcpv6_universe)) {
1126 					log_error("Corrupt IAADDR options.");
1127 					option_state_dereference(&addr->options,
1128 								 MDL);
1129 					dfree(addr, MDL);
1130 					data_string_forget(&ds, MDL);
1131 					return DHCP_R_BADPARSE;
1132 				}
1133 			}
1134 
1135 			data_string_forget(&ds, MDL);
1136 
1137 			if (addr->options != NULL) {
1138 				log_debug("RCV:  | | | X-- [Options]");
1139 
1140 				/* Get the status code if the return value
1141 				 * indicates an error or the status code
1142 				 * indicates no address toss the address
1143 				 */
1144 				code = STATUS_Success;
1145 				rval = dhc6_check_status(ISC_R_SUCCESS,
1146 							 addr->options,
1147 							 "IAADDR", &code);
1148 				if (rval != ISC_R_SUCCESS) {
1149 					log_debug("RCV:  | | | X-- Status code"
1150 						  " issue, IAADDR discarded.");
1151 					option_state_dereference(&addr->options,
1152 								 MDL);
1153 					dfree(addr, MDL);
1154 					continue;
1155 				}
1156 			}
1157 
1158 			*paddr = addr;
1159 			paddr = &addr->next;
1160 		} else {
1161 			log_error("Invalid IAADDR option cache.");
1162 			dfree(addr, MDL);
1163 			data_string_forget(&ds, MDL);
1164 			return ISC_R_UNEXPECTED;
1165 		}
1166 	}
1167 	delete_option(&dhcpv6_universe, options, D6O_IAADDR);
1168 
1169 	return ISC_R_SUCCESS;
1170 }
1171 
1172 static isc_result_t
dhc6_parse_prefixes(struct dhc6_addr ** ppfx,struct packet * packet,struct option_state * options)1173 dhc6_parse_prefixes(struct dhc6_addr **ppfx, struct packet *packet,
1174 		    struct option_state *options)
1175 {
1176 	struct data_string ds;
1177 	struct option_cache *oc;
1178 	struct dhc6_addr *pfx;
1179 	isc_result_t rval = ISC_R_SUCCESS;
1180 	unsigned code;
1181 
1182 	memset(&ds, 0, sizeof(ds));
1183 
1184 	oc = lookup_option(&dhcpv6_universe, options, D6O_IAPREFIX);
1185 	for ( ; oc != NULL ; oc = oc->next) {
1186 		pfx = dmalloc(sizeof(*pfx), MDL);
1187 		if (pfx == NULL) {
1188 			log_error("Out of memory allocating "
1189 				  "prefix structure.");
1190 			return ISC_R_NOMEMORY;
1191 		} else if (evaluate_option_cache(&ds, packet, NULL, NULL,
1192 						 options, NULL, &global_scope,
1193 						 oc, MDL) &&
1194 			   (ds.len >= 25)) {
1195 
1196 			pfx->preferred_life = getULong(ds.data);
1197 			pfx->max_life = getULong(ds.data + 4);
1198 			pfx->plen = getUChar(ds.data + 8);
1199 			pfx->address.len = 16;
1200 			memcpy(pfx->address.iabuf, ds.data + 9, 16);
1201 			pfx->starts = cur_time;
1202 
1203 			log_debug("RCV:  | | X-- IAPREFIX %s/%d",
1204 				  piaddr(pfx->address), (int)pfx->plen);
1205 			log_debug("RCV:  | | | X-- Preferred lifetime %u.",
1206 				  pfx->preferred_life);
1207 			log_debug("RCV:  | | | X-- Max lifetime %u.",
1208 				  pfx->max_life);
1209 
1210 			/* Sanity check over the prefix length */
1211 			if ((pfx->plen < 4) || (pfx->plen > 128)) {
1212 				log_debug("RCV:  | | | !-- INVALID prefix "
1213 					  "length, IAPREFIX discarded.  "
1214 					  "Check your server configuration.");
1215 				dfree(pfx, MDL);
1216 				data_string_forget(&ds, MDL);
1217 				continue;
1218 			}
1219 			/*
1220 			 * RFC 3633 section 10 says we must discard
1221 			 * prefixes whose pref is later than valid.
1222 			 */
1223 			if ((pfx->preferred_life > pfx->max_life)) {
1224 				log_debug("RCV:  | | | !-- INVALID lifetimes, "
1225 					  "IAPREFIX discarded.  Check your "
1226 					  "server configuration.");
1227 				dfree(pfx, MDL);
1228 				data_string_forget(&ds, MDL);
1229 				continue;
1230 			}
1231 
1232 			/*
1233 			 * Fortunately this is the last recursion in the
1234 			 * protocol.
1235 			 */
1236 			if (ds.len > 25) {
1237 				if (!option_state_allocate(&pfx->options,
1238 							   MDL)) {
1239 					log_error("Out of memory allocating "
1240 						  "IAPREFIX option state.");
1241 					dfree(pfx, MDL);
1242 					data_string_forget(&ds, MDL);
1243 					return ISC_R_NOMEMORY;
1244 				}
1245 
1246 				if (!parse_option_buffer(pfx->options,
1247 							 ds.data + 25,
1248 							 ds.len - 25,
1249 							 &dhcpv6_universe)) {
1250 					log_error("Corrupt IAPREFIX options.");
1251 					option_state_dereference(&pfx->options,
1252 								 MDL);
1253 					dfree(pfx, MDL);
1254 					data_string_forget(&ds, MDL);
1255 					return DHCP_R_BADPARSE;
1256 				}
1257 			}
1258 
1259 			data_string_forget(&ds, MDL);
1260 
1261 			if (pfx->options != NULL) {
1262 				log_debug("RCV:  | | | X-- [Options]");
1263 
1264 				/* Get the status code if the return value
1265 				 * indicates an error or the status code
1266 				 * indicates no prefix toss the prefix
1267 				 */
1268 				code = STATUS_Success;
1269 				rval = dhc6_check_status(ISC_R_SUCCESS,
1270 							 pfx->options,
1271 							 "IAPREFIX", &code);
1272 				if (rval != ISC_R_SUCCESS) {
1273 					log_debug("RCV:  | | | X-- Status code"
1274 						  " issue IAPREFIX discarded.");
1275 					option_state_dereference(&pfx->options,
1276 								 MDL);
1277 					dfree(pfx, MDL);
1278 					continue;
1279 				}
1280 			}
1281 
1282 			*ppfx = pfx;
1283 			ppfx = &pfx->next;
1284 		} else {
1285 			log_error("Invalid IAPREFIX option cache.");
1286 			dfree(pfx, MDL);
1287 			data_string_forget(&ds, MDL);
1288 			return ISC_R_UNEXPECTED;
1289 		}
1290 	}
1291 	delete_option(&dhcpv6_universe, options, D6O_IAPREFIX);
1292 
1293 	return ISC_R_SUCCESS;
1294 }
1295 
1296 /* Clean up a lease object, deallocate all its parts, and set it to NULL. */
1297 void
dhc6_lease_destroy(struct dhc6_lease ** src,const char * file,int line)1298 dhc6_lease_destroy(struct dhc6_lease **src, const char *file, int line)
1299 {
1300 	struct dhc6_ia *ia, *nia;
1301 	struct dhc6_lease *lease;
1302 
1303 	if (src == NULL || *src == NULL) {
1304 		log_error("Attempt to destroy null lease.");
1305 		return;
1306 	}
1307 	lease = *src;
1308 
1309 	data_string_forget(&lease->server_id, file, line);
1310 	for (ia = lease->bindings ; ia != NULL ; ia = nia) {
1311 		nia = ia->next;
1312 
1313 		dhc6_ia_destroy(&ia, file, line);
1314 	}
1315 
1316 	if (lease->options != NULL)
1317 		option_state_dereference(&lease->options, file, line);
1318 
1319 	dfree(lease, file, line);
1320 	*src = NULL;
1321 }
1322 
1323 /*
1324  * Traverse the addresses list, and destroy their contents, and NULL the
1325  * list pointer.
1326  */
1327 static void
dhc6_ia_destroy(struct dhc6_ia ** src,const char * file,int line)1328 dhc6_ia_destroy(struct dhc6_ia **src, const char *file, int line)
1329 {
1330 	struct dhc6_addr *addr, *naddr;
1331 	struct dhc6_ia *ia;
1332 
1333 	if (src == NULL || *src == NULL) {
1334 		log_error("Attempt to destroy null IA.");
1335 		return;
1336 	}
1337 	ia = *src;
1338 
1339 	for (addr = ia->addrs ; addr != NULL ; addr = naddr) {
1340 		naddr = addr->next;
1341 
1342 		if (addr->options != NULL)
1343 			option_state_dereference(&addr->options, file, line);
1344 
1345 		dfree(addr, file, line);
1346 	}
1347 
1348 	if (ia->options != NULL)
1349 		option_state_dereference(&ia->options, file, line);
1350 
1351 	dfree(ia, file, line);
1352 	*src = NULL;
1353 }
1354 
1355 /*
1356  * For a given lease, insert it into the tail of the lease list.  Upon
1357  * finding a duplicate by server id, remove it and take over its position.
1358  */
1359 static void
insert_lease(struct dhc6_lease ** head,struct dhc6_lease * new)1360 insert_lease(struct dhc6_lease **head, struct dhc6_lease *new)
1361 {
1362 	while (*head != NULL) {
1363 		if ((*head)->server_id.len == new->server_id.len &&
1364 		    memcmp((*head)->server_id.data, new->server_id.data,
1365 			   new->server_id.len) == 0) {
1366 			new->next = (*head)->next;
1367 			dhc6_lease_destroy(head, MDL);
1368 			break;
1369 		}
1370 
1371 		head= &(*head)->next;
1372 	}
1373 
1374 	*head = new;
1375 	return;
1376 }
1377 
1378 /*!
1379  *
1380  * \brief Determine a score for a lease.  We use this to
1381  * compare and choose leases if we receive multiple candidates.
1382  *
1383  * We originally started with scores of 50 for a binding and 100 for
1384  * an address.  This would select multiple adresses over multiple
1385  * bindings.  As part of the 7550 work I've changed this to be
1386  * 10000 for a binding, 100 for an address and 1 for an option.
1387  * This will cause us to choose a lease with more bindings over
1388  * a lease with less bindings but more addresses which seems
1389  * to be the best selection criteria to me.
1390  * In theory we could end up with a lease with enough addresses
1391  * or options being better but at 100 to 1 I don't think it's likely.
1392  *
1393  * \param client = the state of the entire client
1394  * \param lease  = the lease to score.
1395  *
1396  * \retrun the score of the lease
1397  */
1398 
1399 /* The scores for individual items. */
1400 #ifdef USE_ORIGINAL_CLIENT_LEASE_WEIGHTS
1401 #define SCORE_BINDING  50
1402 #define SCORE_ADDRESS 100
1403 #else
1404 #define SCORE_BINDING 10000
1405 #define SCORE_ADDRESS   100
1406 #endif
1407 
1408 #define SCORE_OPTION      1
1409 /* We need a lease with at least 1 binding and 1 address */
1410 #define SCORE_MIN (SCORE_BINDING + SCORE_ADDRESS)
1411 
1412 static int
dhc6_score_lease(struct client_state * client,struct dhc6_lease * lease)1413 dhc6_score_lease(struct client_state *client, struct dhc6_lease *lease)
1414 {
1415 	struct dhc6_ia *ia;
1416 	struct dhc6_addr *addr;
1417 	struct option **req;
1418 	int i;
1419 
1420 	if (lease->score)
1421 		return lease->score;
1422 
1423 	lease->score = SCORE_OPTION;
1424 
1425 	/* If this lease lacks a required option, dump it. */
1426 	/* XXX: we should be able to cache the failure... */
1427 	req = client->config->required_options;
1428 	if (req != NULL) {
1429 		for (i = 0 ; req[i] != NULL ; i++) {
1430 			if (lookup_option(&dhcpv6_universe, lease->options,
1431 					  req[i]->code) == NULL) {
1432 				lease->score = 0;
1433 				return lease->score;
1434 			}
1435 		}
1436 	}
1437 
1438 	/* If this lease contains a requested option, improve its score. */
1439 	req = client->config->requested_options;
1440 	if (req != NULL) {
1441 		for (i = 0 ; req[i] != NULL ; i++) {
1442 			if (lookup_option(&dhcpv6_universe, lease->options,
1443 					  req[i]->code) != NULL)
1444 				lease->score += SCORE_OPTION;
1445 		}
1446 	}
1447 
1448 	for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
1449 		lease->score += SCORE_BINDING;
1450 
1451 		for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
1452 			lease->score += SCORE_ADDRESS;
1453 		}
1454 	}
1455 
1456 	return lease->score;
1457 }
1458 
1459 /*
1460  * start_init6() kicks off the process, transmitting a packet and
1461  * scheduling a retransmission event.
1462  */
1463 void
start_init6(struct client_state * client)1464 start_init6(struct client_state *client)
1465 {
1466 	struct timeval tv;
1467 
1468 	log_debug("PRC: Soliciting for leases (INIT).");
1469 	client->state = S_INIT;
1470 
1471 	/* Initialize timers, RFC3315 section 17.1.2. */
1472 	client->IRT = SOL_TIMEOUT * 100;
1473 	client->MRT = SOL_MAX_RT * 100;
1474 	client->MRC = 0;
1475 	/* Default is 0 (no max) but -1 changes this. */
1476 	if (!onetry)
1477 		client->MRD = 0;
1478 	else
1479 		client->MRD = client->config->timeout;
1480 
1481 	dhc6_retrans_init(client);
1482 
1483 	/*
1484 	 * RFC3315 section 17.1.2 goes out of its way:
1485 	 * Also, the first RT MUST be selected to be strictly greater than IRT
1486 	 * by choosing RAND to be strictly greater than 0.
1487 	 */
1488 	/* if RAND < 0 then RAND = -RAND */
1489 	if (client->RT <= client->IRT)
1490 		client->RT = client->IRT + (client->IRT - client->RT);
1491 	/* if RAND == 0 then RAND = 1 */
1492 	if (client->RT <= client->IRT)
1493 		client->RT = client->IRT + 1;
1494 
1495 	client->v6_handler = init_handler;
1496 
1497 	/*
1498 	 * RFC3315 section 17.1.2 says we MUST start the first packet
1499 	 * between 0 and SOL_MAX_DELAY seconds.  The good news is
1500 	 * SOL_MAX_DELAY is 1.
1501 	 */
1502 	tv.tv_sec = cur_tv.tv_sec;
1503 	tv.tv_usec = cur_tv.tv_usec;
1504 	tv.tv_usec += (random() % (SOL_MAX_DELAY * 100)) * 10000;
1505 	if (tv.tv_usec >= 1000000) {
1506 		tv.tv_sec += 1;
1507 		tv.tv_usec -= 1000000;
1508 	}
1509 	add_timeout(&tv, do_init6, client, NULL, NULL);
1510 
1511 	if (nowait)
1512 		detach();
1513 }
1514 
1515 /*
1516  * start_info_request6() kicks off the process, transmitting an info
1517  * request packet and scheduling a retransmission event.
1518  */
1519 void
start_info_request6(struct client_state * client)1520 start_info_request6(struct client_state *client)
1521 {
1522 	struct timeval tv;
1523 
1524 	log_debug("PRC: Requesting information (INIT).");
1525 	client->state = S_INIT;
1526 
1527 	/* Initialize timers, RFC3315 section 18.1.5. */
1528 	client->IRT = INF_TIMEOUT * 100;
1529 	client->MRT = INF_MAX_RT * 100;
1530 	client->MRC = 0;
1531 	/* Default is 0 (no max) but -1 changes this. */
1532 	if (!onetry)
1533 		client->MRD = 0;
1534 	else
1535 		client->MRD = client->config->timeout;
1536 
1537 	dhc6_retrans_init(client);
1538 
1539 	client->v6_handler = info_request_handler;
1540 
1541 	/*
1542 	 * RFC3315 section 18.1.5 says we MUST start the first packet
1543 	 * between 0 and INF_MAX_DELAY seconds.  The good news is
1544 	 * INF_MAX_DELAY is 1.
1545 	 */
1546 	tv.tv_sec = cur_tv.tv_sec;
1547 	tv.tv_usec = cur_tv.tv_usec;
1548 	tv.tv_usec += (random() % (INF_MAX_DELAY * 100)) * 10000;
1549 	if (tv.tv_usec >= 1000000) {
1550 		tv.tv_sec += 1;
1551 		tv.tv_usec -= 1000000;
1552 	}
1553 	add_timeout(&tv, do_info_request6, client, NULL, NULL);
1554 
1555 	if (nowait)
1556 		detach();
1557 }
1558 
1559 /*
1560  * start_confirm6() kicks off an "init-reboot" version of the process, at
1561  * startup to find out if old bindings are 'fair' and at runtime whenever
1562  * a link cycles state we'll eventually want to do this.
1563  */
1564 void
start_confirm6(struct client_state * client)1565 start_confirm6(struct client_state *client)
1566 {
1567 	struct timeval tv;
1568 
1569 	/* If there is no active lease, there is nothing to check. */
1570 	if ((client->active_lease == NULL) ||
1571 	    !active_prefix(client) ||
1572 	    client->active_lease->released ||
1573 	    !unexpired_address_in_lease(client->active_lease)) {
1574 		dhc6_lease_destroy(&client->active_lease, MDL);
1575 		start_init6(client);
1576 		return;
1577 	}
1578 
1579 	log_debug("PRC: Confirming active lease (INIT-REBOOT).");
1580 	client->state = S_REBOOTING;
1581 
1582 	/* Initialize timers, RFC3315 section 17.1.3. */
1583 	client->IRT = CNF_TIMEOUT * 100;
1584 	client->MRT = CNF_MAX_RT * 100;
1585 	client->MRC = 0;
1586 	client->MRD = CNF_MAX_RD;
1587 
1588 	dhc6_retrans_init(client);
1589 
1590 	client->v6_handler = reply_handler;
1591 
1592 	/*
1593 	 * RFC3315 section 18.1.2 says we MUST start the first packet
1594 	 * between 0 and CNF_MAX_DELAY seconds.  The good news is
1595 	 * CNF_MAX_DELAY is 1.
1596 	 */
1597 	tv.tv_sec = cur_tv.tv_sec;
1598 	tv.tv_usec = cur_tv.tv_usec;
1599 	tv.tv_usec += (random() % (CNF_MAX_DELAY * 100)) * 10000;
1600 	if (tv.tv_usec >= 1000000) {
1601 		tv.tv_sec += 1;
1602 		tv.tv_usec -= 1000000;
1603 	}
1604 
1605 	/* We do a rebind instead of a confirm if the user
1606 	 * is requesting PDs or previously requesed PDs or
1607 	 * increased the number of NAs or TAs they want
1608 	 * Confirms don't tell us if PDs are still on-link and
1609 	 * we won't add new IAs on a confirm.
1610 	 */
1611 
1612 	if ((wanted_ia_pd != 0) ||
1613 	    (dhc6_count_ia(client->active_lease, D6O_IA_PD) != 0) ||
1614 	    (dhc6_count_ia(client->active_lease, D6O_IA_NA) < wanted_ia_na) ||
1615 	    (dhc6_count_ia(client->active_lease, D6O_IA_TA) < wanted_ia_ta)) {
1616 		client->state = S_REBINDING;
1617 		client->refresh_type = DHCPV6_REBIND;
1618 		add_timeout(&tv, do_refresh6, client, NULL, NULL);
1619 	} else
1620 		add_timeout(&tv, do_confirm6, client, NULL, NULL);
1621 }
1622 
1623 /*
1624  * check_timing6() check on the timing for sending a v6 message
1625  * and then do the basic initialization for a v6 message.
1626  */
1627 #define CHK_TIM_SUCCESS		0
1628 #define CHK_TIM_MRC_EXCEEDED	1
1629 #define CHK_TIM_MRD_EXCEEDED	2
1630 #define CHK_TIM_ALLOC_FAILURE	3
1631 
1632 int
check_timing6(struct client_state * client,u_int8_t msg_type,char * msg_str,struct dhc6_lease * lease,struct data_string * ds)1633 check_timing6 (struct client_state *client, u_int8_t msg_type,
1634 	       char *msg_str, struct dhc6_lease *lease,
1635 	       struct data_string *ds)
1636 {
1637 	struct timeval elapsed;
1638 
1639 	/*
1640 	 * Start_time starts at the first transmission.
1641 	 */
1642 	if (client->txcount == 0) {
1643 		client->start_time.tv_sec = cur_tv.tv_sec;
1644 		client->start_time.tv_usec = cur_tv.tv_usec;
1645 	} else if ((client->MRC != 0) && (client->txcount > client->MRC)) {
1646 		log_info("Max retransmission count exceeded.");
1647 		return(CHK_TIM_MRC_EXCEEDED);
1648 	}
1649 
1650 	/* elapsed = cur - start */
1651 	elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
1652 	elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
1653 	if (elapsed.tv_usec < 0) {
1654 		elapsed.tv_sec -= 1;
1655 		elapsed.tv_usec += 1000000;
1656 	}
1657 
1658 	/* Check if finished (-1 argument). */
1659 	if ((client->MRD != 0) && (elapsed.tv_sec >= client->MRD)) {
1660 		log_info("Max retransmission duration exceeded.");
1661 		return(CHK_TIM_MRD_EXCEEDED);
1662 	}
1663 
1664 	memset(ds, 0, sizeof(*ds));
1665 	if (!buffer_allocate(&(ds->buffer), 4, MDL)) {
1666 		log_error("Unable to allocate memory for %s.", msg_str);
1667 		return(CHK_TIM_ALLOC_FAILURE);
1668 	}
1669 	ds->data = ds->buffer->data;
1670 	ds->len = 4;
1671 
1672 	ds->buffer->data[0] = msg_type;
1673 	memcpy(ds->buffer->data + 1, client->dhcpv6_transaction_id, 3);
1674 
1675 	/* Form an elapsed option. */
1676 	/* Maximum value is 65535 1/100s coded as 0xffff. */
1677 	if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
1678 	    ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
1679 		client->elapsed = 0xffff;
1680 	} else {
1681 		client->elapsed = elapsed.tv_sec * 100;
1682 		client->elapsed += elapsed.tv_usec / 10000;
1683 	}
1684 
1685 	if (client->elapsed == 0)
1686 		log_debug("XMT: Forming %s, 0 ms elapsed.", msg_str);
1687 	else
1688 		log_debug("XMT: Forming %s, %u0 ms elapsed.", msg_str,
1689 			  (unsigned)client->elapsed);
1690 
1691 	client->elapsed = htons(client->elapsed);
1692 
1693 	make_client6_options(client, &client->sent_options, lease, msg_type);
1694 
1695 	return(CHK_TIM_SUCCESS);
1696 }
1697 
1698 /*!
1699  *
1700  * \brief Create an iaid from information from the client.
1701  *
1702  * \param client = the state of the entire client
1703  * \param ia     = the ia to fill in
1704  * \param idx    = index of the ia in case we are doing multiples
1705  * \param len    = length of the base IA (4 for TA, 12 for NA & PD)
1706  *
1707  * \return ISC_R_SUCCESS - all is well continue, any other return indicates
1708  *                         an error and the packet should be tossed
1709  */
1710 
1711 static isc_result_t
dhc6_create_iaid(struct client_state * client,struct data_string * ia,int idx,unsigned len)1712 dhc6_create_iaid(struct client_state *client,
1713 		 struct data_string *ia,
1714 		 int idx,
1715 		 unsigned len)
1716 {
1717 	int start_idx, copy_len;
1718 
1719 	memset(ia, 0, sizeof(*ia));
1720 	if (!buffer_allocate(&ia->buffer, len, MDL)) {
1721 		return (ISC_R_NOMEMORY);
1722 	}
1723 	ia->data = ia->buffer->data;
1724 	ia->len = len;
1725 
1726 	/*
1727 	 * A simple IAID is the last 4 bytes
1728 	 * of the hardware address.
1729 	 */
1730 	if (client->interface->hw_address.hlen > 4) {
1731 		start_idx = client->interface->hw_address.hlen - 4;
1732 		copy_len = 4;
1733 	} else {
1734 		start_idx = 0;
1735 		copy_len = client->interface->hw_address.hlen;
1736 	}
1737 	memcpy(ia->buffer->data,
1738 	       client->interface->hw_address.hbuf + start_idx,
1739 	       copy_len);
1740 	if (idx)
1741 		ia->buffer->data[3] += idx;
1742 
1743 	return (ISC_R_SUCCESS);
1744 }
1745 
1746 /*!
1747  *
1748  * \brief Add bare IA_NAs, IA_TAs or IA_PDs to the packet we are building.
1749  *
1750  * Attempt to add the number of bare IAs indicated by wanted to
1751  * the packet.  As we have already added a number of IAs based
1752  * on what is in the current lease after we create an IAID we check
1753  * it against the current lease and skip any that are already in use.
1754  *
1755  * \param client = the state of the entire client
1756  * \param packet = the packet we are building and where we
1757  *                 shall append the IA_NA, IA_TA  or IA_PDs we create
1758  * \param wanted = the number of IA_NA, IA_TA or IA_PDs we want to create
1759  * \param ia_type = the type of the IAs we want to create: NA, TA or PD.
1760  *
1761  * \return ISC_R_SUCCESS - all is well continue, any other return indicates
1762  *                         an error and the packet should be tossed
1763  */
1764 static isc_result_t
dhc6_bare_ia_xx(struct client_state * client,struct data_string * packet,int wanted,u_int16_t ia_type)1765 dhc6_bare_ia_xx(struct client_state *client,
1766 		struct data_string *packet,
1767 		int wanted,
1768 		u_int16_t ia_type)
1769 {
1770 	struct dhc6_ia *old_ia;
1771 	struct data_string ia;
1772 	u_int32_t t1, t2;
1773 	int i, len;
1774 	isc_result_t rval;
1775 	char *type_string;
1776 	struct option *type_option;
1777 
1778 	/* figure out what type of option we are working with */
1779 	switch (ia_type) {
1780 	      case D6O_IA_NA:
1781 		type_string = "IA_NA";
1782 		type_option = ia_na_option;
1783 		len = IA_NA_OFFSET;
1784 		break;
1785 	      case D6O_IA_TA:
1786 		type_string = "IA_TA";
1787 		type_option = ia_ta_option;
1788 		len = IA_TA_OFFSET;
1789 		break;
1790 	      case D6O_IA_PD:
1791 		type_string = "IA_PD";
1792 		type_option = ia_pd_option;
1793 		len = IA_PD_OFFSET;
1794 		if (prefix_len_hint > 0) {
1795 			len += IASUBOPT_PD_LEN;
1796 		}
1797 		break;
1798 
1799 	      default:
1800 		return (ISC_R_FAILURE);
1801 	}
1802 
1803 	for (i = 0; wanted != 0; i++) {
1804 		rval = dhc6_create_iaid(client, &ia, i, len);
1805 		if (rval != ISC_R_SUCCESS) {
1806 			log_error("Unable to allocate memory for %s.",
1807 				  type_string);
1808 			return (rval);
1809 		}
1810 
1811 		/* If we are already using this IAID, skip it and try again */
1812 		if ((client->active_lease != NULL) &&
1813 		    ((old_ia = find_ia(client->active_lease->bindings,
1814 				       ia_type,
1815 				       (char *)ia.buffer->data)) != NULL)) {
1816 			data_string_forget(&ia, MDL);
1817 			continue;
1818 		}
1819 
1820 		/* We have a good IAID, log it */
1821 		log_debug("XMT:  X-- %s %s",
1822 			  type_string, print_hex_1(4, ia.buffer->data, 55));
1823 
1824 		/* If we are requesting an NA or a PD we also want to add
1825 		 * the renew and rebind times we are requesting.
1826 		 */
1827 		if (ia_type != D6O_IA_TA) {
1828 			t1 = client->config->requested_lease / 2;
1829 			t2 = t1 + (t1 / 2);
1830 			putULong(ia.buffer->data + 4, t1);
1831 			putULong(ia.buffer->data + 8, t2);
1832 
1833 			log_debug("XMT:  | X-- Request renew in  +%u",
1834 				  (unsigned)t1);
1835 			log_debug("XMT:  | X-- Request rebind in +%u",
1836 				  (unsigned)t2);
1837 		}
1838 
1839 		if (ia_type == D6O_IA_PD && prefix_len_hint > 0) {
1840 			unsigned char *ptr = ia.buffer->data + IA_NA_OFFSET;
1841 			putUShort(ptr, D6O_IAPREFIX);
1842 			ptr += 2;
1843 			putUShort(ptr, IASUBOPT_PD_LEN);
1844 			ptr += 2;
1845 			putUChar(ptr + IASUBOPT_PD_PREFLEN_OFFSET,
1846 				 prefix_len_hint);
1847 			log_debug("XMT:  | | X-- Request prefix ::/%u.",
1848 				  prefix_len_hint);
1849 		}
1850 
1851 		/* and append it to the packet */
1852 		append_option(packet, &dhcpv6_universe, type_option, &ia);
1853 		data_string_forget(&ia, MDL);
1854 
1855 		/* decrement the number of IAs we want */
1856 		wanted--;
1857 	}
1858 
1859 	return (ISC_R_SUCCESS);
1860 }
1861 
1862 /*
1863  * do_init6() marshals and transmits a solicit.
1864  */
1865 void
do_init6(void * input)1866 do_init6(void *input)
1867 {
1868 	struct client_state *client;
1869 	struct dhc6_ia *old_ia;
1870 	struct dhc6_addr *old_addr;
1871 	struct data_string ds;
1872 	struct data_string ia;
1873 	struct data_string addr;
1874 	struct timeval tv;
1875 	u_int32_t t1, t2;
1876 	int i, send_ret;
1877 
1878 	client = input;
1879 
1880 	/*
1881 	 * In RFC3315 section 17.1.2, the retransmission timer is
1882 	 * used as the selecting timer.
1883 	 */
1884 	if (client->advertised_leases != NULL) {
1885 		start_selecting6(client);
1886 		return;
1887 	}
1888 
1889 	switch(check_timing6(client, DHCPV6_SOLICIT, "Solicit", NULL, &ds)) {
1890 	      case CHK_TIM_MRC_EXCEEDED:
1891 	      case CHK_TIM_ALLOC_FAILURE:
1892 		return;
1893 	      case CHK_TIM_MRD_EXCEEDED:
1894 		client->state = S_STOPPED;
1895 		if (client->active_lease != NULL) {
1896 			dhc6_lease_destroy(&client->active_lease, MDL);
1897 			client->active_lease = NULL;
1898 		}
1899 		/* Stop if and only if this is the last client. */
1900 		if (stopping_finished())
1901 			finish(2);
1902 		return;
1903 	}
1904 
1905 	/*
1906 	 * Fetch any configured 'sent' options (includes DUID) in wire format.
1907 	 */
1908 	dhcpv6_universe.encapsulate(&ds, NULL, NULL, client,
1909 				    NULL, client->sent_options, &global_scope,
1910 				    &dhcpv6_universe);
1911 
1912 	/* Use a specific handler with rapid-commit. */
1913 	if (lookup_option(&dhcpv6_universe, client->sent_options,
1914 			  D6O_RAPID_COMMIT) != NULL) {
1915 		client->v6_handler = rapid_commit_handler;
1916 	}
1917 
1918 	/* Append IA_NA. */
1919 	for (i = 0; i < wanted_ia_na; i++) {
1920 		/*
1921 		 * XXX: maybe the IA_NA('s) should be put into the sent_options
1922 		 * cache.  They'd have to be pulled down as they also contain
1923 		 * different option caches in the same universe...
1924 		 */
1925 		if (dhc6_create_iaid(client, &ia, i, 12) != ISC_R_SUCCESS) {
1926 			log_error("Unable to allocate memory for IA_NA.");
1927 			data_string_forget(&ds, MDL);
1928 			return;
1929 		}
1930 
1931 		t1 = client->config->requested_lease / 2;
1932 		t2 = t1 + (t1 / 2);
1933 		putULong(ia.buffer->data + 4, t1);
1934 		putULong(ia.buffer->data + 8, t2);
1935 
1936 		log_debug("XMT:  X-- IA_NA %s",
1937 			  print_hex_1(4, ia.buffer->data, 55));
1938 		log_debug("XMT:  | X-- Request renew in  +%u", (unsigned)t1);
1939 		log_debug("XMT:  | X-- Request rebind in +%u", (unsigned)t2);
1940 
1941 		if ((client->active_lease != NULL) &&
1942 		    ((old_ia = find_ia(client->active_lease->bindings,
1943 				       D6O_IA_NA,
1944 				       (char *)ia.buffer->data)) != NULL)) {
1945 			/*
1946 			 * For each address in the old IA_NA,
1947 			 * request a binding.
1948 			 */
1949 			memset(&addr, 0, sizeof(addr));
1950 			for (old_addr = old_ia->addrs ; old_addr != NULL ;
1951 			     old_addr = old_addr->next) {
1952 				if (old_addr->address.len != 16) {
1953 					log_error("Invalid IPv6 address "
1954 						  "length %d.  "
1955 						  "Ignoring.  (%s:%d)",
1956 						  old_addr->address.len,
1957 						  MDL);
1958 					continue;
1959 				}
1960 
1961 				if (!buffer_allocate(&addr.buffer, 24, MDL)) {
1962 					log_error("Unable to allocate memory "
1963 						  "for IAADDR.");
1964 					data_string_forget(&ia, MDL);
1965 					data_string_forget(&ds, MDL);
1966 					return;
1967 				}
1968 				addr.data = addr.buffer->data;
1969 				addr.len = 24;
1970 
1971 				memcpy(addr.buffer->data,
1972 				       old_addr->address.iabuf,
1973 				       16);
1974 
1975 				t1 = client->config->requested_lease;
1976 				t2 = t1 + (t1 / 2);
1977 				putULong(addr.buffer->data + 16, t1);
1978 				putULong(addr.buffer->data + 20, t2);
1979 
1980 				log_debug("XMT:  | X-- Request address %s.",
1981 					  piaddr(old_addr->address));
1982 				log_debug("XMT:  | | X-- Request "
1983 					  "preferred in +%u",
1984 					  (unsigned)t1);
1985 				log_debug("XMT:  | | X-- Request valid "
1986 					  "in     +%u",
1987 					  (unsigned)t2);
1988 
1989 				append_option(&ia, &dhcpv6_universe,
1990 					      iaaddr_option,
1991 					      &addr);
1992 
1993 				data_string_forget(&addr, MDL);
1994 			}
1995 		}
1996 
1997 		append_option(&ds, &dhcpv6_universe, ia_na_option, &ia);
1998 		data_string_forget(&ia, MDL);
1999 	}
2000 
2001 	/* Append IA_TA. */
2002 	for (i = 0; i < wanted_ia_ta; i++) {
2003 		/*
2004 		 * XXX: maybe the IA_TA('s) should be put into the sent_options
2005 		 * cache.  They'd have to be pulled down as they also contain
2006 		 * different option caches in the same universe...
2007 		 */
2008 		if (dhc6_create_iaid(client, &ia, i, 4) != ISC_R_SUCCESS) {
2009 			log_error("Unable to allocate memory for IA_TA.");
2010 			data_string_forget(&ds, MDL);
2011 			return;
2012 		}
2013 
2014 		log_debug("XMT:  X-- IA_TA %s",
2015 			  print_hex_1(4, ia.buffer->data, 55));
2016 
2017 		if ((client->active_lease != NULL) &&
2018 		    ((old_ia = find_ia(client->active_lease->bindings,
2019 				       D6O_IA_TA,
2020 				       (char *)ia.buffer->data)) != NULL)) {
2021 			/*
2022 			 * For each address in the old IA_TA,
2023 			 * request a binding.
2024 			 */
2025 			memset(&addr, 0, sizeof(addr));
2026 			for (old_addr = old_ia->addrs ; old_addr != NULL ;
2027 			     old_addr = old_addr->next) {
2028 				if (old_addr->address.len != 16) {
2029 					log_error("Invalid IPv6 address "
2030 						  "length %d.  "
2031 						  "Ignoring.  (%s:%d)",
2032 						  old_addr->address.len,
2033 						  MDL);
2034 					continue;
2035 				}
2036 
2037 				if (!buffer_allocate(&addr.buffer, 24, MDL)) {
2038 					log_error("Unable to allocate memory "
2039 						  "for IAADDR.");
2040 					data_string_forget(&ia, MDL);
2041 					data_string_forget(&ds, MDL);
2042 					return;
2043 				}
2044 				addr.data = addr.buffer->data;
2045 				addr.len = 24;
2046 
2047 				memcpy(addr.buffer->data,
2048 				       old_addr->address.iabuf,
2049 				       16);
2050 
2051 				t1 = client->config->requested_lease;
2052 				t2 = t1 + (t1 / 2);
2053 				putULong(addr.buffer->data + 16, t1);
2054 				putULong(addr.buffer->data + 20, t2);
2055 
2056 				log_debug("XMT:  | X-- Request address %s.",
2057 					  piaddr(old_addr->address));
2058 				log_debug("XMT:  | | X-- Request "
2059 					  "preferred in +%u",
2060 					  (unsigned)t1);
2061 				log_debug("XMT:  | | X-- Request valid "
2062 					  "in     +%u",
2063 					  (unsigned)t2);
2064 
2065 				append_option(&ia, &dhcpv6_universe,
2066 					      iaaddr_option,
2067 					      &addr);
2068 
2069 				data_string_forget(&addr, MDL);
2070 			}
2071 		}
2072 
2073 		append_option(&ds, &dhcpv6_universe, ia_ta_option, &ia);
2074 		data_string_forget(&ia, MDL);
2075 	}
2076 
2077 	/* Append IA_PD. */
2078 	for (i = 0; i < wanted_ia_pd; i++) {
2079 		/*
2080 		 * XXX: maybe the IA_PD('s) should be put into the sent_options
2081 		 * cache.  They'd have to be pulled down as they also contain
2082 		 * different option caches in the same universe...
2083 		 */
2084 		memset(&ia, 0, sizeof(ia));
2085 		if (dhc6_create_iaid(client, &ia, i, 12) != ISC_R_SUCCESS) {
2086 			log_error("Unable to allocate memory for IA_PD.");
2087 			data_string_forget(&ds, MDL);
2088 			return;
2089 		}
2090 
2091 		t1 = client->config->requested_lease / 2;
2092 		t2 = t1 + (t1 / 2);
2093 		putULong(ia.buffer->data + 4, t1);
2094 		putULong(ia.buffer->data + 8, t2);
2095 
2096 		log_debug("XMT:  X-- IA_PD %s",
2097 			  print_hex_1(4, ia.buffer->data, 55));
2098 		log_debug("XMT:  | X-- Request renew in  +%u", (unsigned)t1);
2099 		log_debug("XMT:  | X-- Request rebind in +%u", (unsigned)t2);
2100 
2101 		if ((client->active_lease != NULL) &&
2102 		    ((old_ia = find_ia(client->active_lease->bindings,
2103 				       D6O_IA_PD,
2104 				       (char *)ia.buffer->data)) != NULL)) {
2105 			/*
2106 			 * For each prefix in the old IA_PD,
2107 			 * request a binding.
2108 			 */
2109 			memset(&addr, 0, sizeof(addr));
2110 			for (old_addr = old_ia->addrs ; old_addr != NULL ;
2111 			     old_addr = old_addr->next) {
2112 				if (old_addr->address.len != 16) {
2113 					log_error("Invalid IPv6 prefix, "
2114 						  "Ignoring.  (%s:%d)",
2115 						  MDL);
2116 					continue;
2117 				}
2118 
2119 				if (!buffer_allocate(&addr.buffer, 25, MDL)) {
2120 					log_error("Unable to allocate memory "
2121 						  "for IAPREFIX.");
2122 					data_string_forget(&ia, MDL);
2123 					data_string_forget(&ds, MDL);
2124 					return;
2125 				}
2126 				addr.data = addr.buffer->data;
2127 				addr.len = 25;
2128 
2129 				t1 = client->config->requested_lease;
2130 				t2 = t1 + (t1 / 2);
2131 				putULong(addr.buffer->data, t1);
2132 				putULong(addr.buffer->data + 4, t2);
2133 
2134 				putUChar(addr.buffer->data + 8,
2135 					 old_addr->plen);
2136 				memcpy(addr.buffer->data + 9,
2137 				       old_addr->address.iabuf,
2138 				       16);
2139 
2140 				log_debug("XMT:  | X-- Request prefix %s/%u.",
2141 					  piaddr(old_addr->address),
2142 					  (unsigned) old_addr->plen);
2143 				log_debug("XMT:  | | X-- Request "
2144 					  "preferred in +%u",
2145 					  (unsigned)t1);
2146 				log_debug("XMT:  | | X-- Request valid "
2147 					  "in     +%u",
2148 					  (unsigned)t2);
2149 
2150 				append_option(&ia, &dhcpv6_universe,
2151 					      iaprefix_option,
2152 					      &addr);
2153 
2154 				data_string_forget(&addr, MDL);
2155 			}
2156 		} else if (prefix_len_hint > 0) {
2157 			memset(&addr, 0, sizeof(addr));
2158 			if (!buffer_allocate(&addr.buffer, 25, MDL)) {
2159 				log_error("Unable to allocate memory "
2160 					  "for IAPREFIX.");
2161 				data_string_forget(&ia, MDL);
2162 				data_string_forget(&ds, MDL);
2163 				return;
2164 			}
2165 
2166 			addr.data = addr.buffer->data;
2167 			addr.len = 25;
2168 
2169 			putUChar(addr.buffer->data + 8, prefix_len_hint);
2170 			log_debug("XMT:  | | X-- Request prefix ::/%u.",
2171 				  prefix_len_hint);
2172 			append_option(&ia, &dhcpv6_universe, iaprefix_option,
2173 				      &addr);
2174 			data_string_forget(&addr, MDL);
2175 		}
2176 
2177 		append_option(&ds, &dhcpv6_universe, ia_pd_option, &ia);
2178 		data_string_forget(&ia, MDL);
2179 	}
2180 
2181 	/* Transmit and wait. */
2182 
2183 	log_info("XMT: Solicit on %s, interval %ld0ms.",
2184 		 client->name ? client->name : client->interface->name,
2185 		 (long int)client->RT);
2186 
2187 	send_ret = send_packet6(client->interface,
2188 				ds.data, ds.len, &DHCPv6DestAddr);
2189 	if (send_ret != ds.len) {
2190 		log_error("dhc6: send_packet6() sent %d of %d bytes",
2191 			  send_ret, ds.len);
2192 	}
2193 
2194 	data_string_forget(&ds, MDL);
2195 
2196 	/* Wait RT */
2197 	tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
2198 	tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
2199 	if (tv.tv_usec >= 1000000) {
2200 		tv.tv_sec += 1;
2201 		tv.tv_usec -= 1000000;
2202 	}
2203 	add_timeout(&tv, do_init6, client, NULL, NULL);
2204 
2205 	dhc6_retrans_advance(client);
2206 }
2207 
2208 /* do_info_request6() marshals and transmits an information-request. */
2209 void
do_info_request6(void * input)2210 do_info_request6(void *input)
2211 {
2212 	struct client_state *client;
2213 	struct data_string ds;
2214 	struct timeval tv;
2215 	int send_ret;
2216 
2217 	client = input;
2218 
2219 	switch(check_timing6(client, DHCPV6_INFORMATION_REQUEST,
2220 			     "Info-Request", NULL, &ds)) {
2221 	      case CHK_TIM_MRC_EXCEEDED:
2222 	      case CHK_TIM_ALLOC_FAILURE:
2223 		return;
2224 	      case CHK_TIM_MRD_EXCEEDED:
2225 		finish(2);
2226 	      case CHK_TIM_SUCCESS:
2227 		break;
2228 	}
2229 
2230 	/* Fetch any configured 'sent' options (includes DUID) in wire format.
2231 	 */
2232 	dhcpv6_universe.encapsulate(&ds, NULL, NULL, client,
2233 				    NULL, client->sent_options, &global_scope,
2234 				    &dhcpv6_universe);
2235 
2236 	/* Transmit and wait. */
2237 
2238 	log_info("XMT: Info-Request on %s, interval %ld0ms.",
2239 		 client->name ? client->name : client->interface->name,
2240 		 (long int)client->RT);
2241 
2242 	send_ret = send_packet6(client->interface,
2243 				ds.data, ds.len, &DHCPv6DestAddr);
2244 	if (send_ret != ds.len) {
2245 		log_error("dhc6: send_packet6() sent %d of %d bytes",
2246 			  send_ret, ds.len);
2247 	}
2248 
2249 	data_string_forget(&ds, MDL);
2250 
2251 	/* Wait RT */
2252 	tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
2253 	tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
2254 	if (tv.tv_usec >= 1000000) {
2255 		tv.tv_sec += 1;
2256 		tv.tv_usec -= 1000000;
2257 	}
2258 	add_timeout(&tv, do_info_request6, client, NULL, NULL);
2259 
2260 	dhc6_retrans_advance(client);
2261 }
2262 
2263 /* do_confirm6() creates a Confirm packet and transmits it.  This function
2264  * is called on every timeout to (re)transmit.
2265  */
2266 void
do_confirm6(void * input)2267 do_confirm6(void *input)
2268 {
2269 	struct client_state *client;
2270 	struct data_string ds;
2271 	int send_ret, added;
2272 	struct timeval tv;
2273 
2274 	client = input;
2275 
2276 	if (client->active_lease == NULL)
2277 		log_fatal("Impossible condition at %s:%d.", MDL);
2278 
2279 	/* In section 17.1.3, it is said:
2280 	 *
2281 	 *   If the client receives no responses before the message
2282 	 *   transmission process terminates, as described in section 14,
2283 	 *   the client SHOULD continue to use any IP addresses, using the
2284 	 *   last known lifetimes for those addresses, and SHOULD continue
2285 	 *   to use any other previously obtained configuration parameters.
2286 	 *
2287 	 * So if confirm times out, we go active.
2288 	 *
2289 	 * XXX: Should we reduce all IA's t1 to 0, so that we renew and
2290 	 * stick there until we get a reply?
2291 	 */
2292 
2293 	switch(check_timing6(client, DHCPV6_CONFIRM, "Confirm",
2294 			     client->active_lease, &ds)) {
2295 	      case CHK_TIM_MRC_EXCEEDED:
2296 	      case CHK_TIM_MRD_EXCEEDED:
2297 		start_bound(client);
2298 		return;
2299 	      case CHK_TIM_ALLOC_FAILURE:
2300 		return;
2301 	      case CHK_TIM_SUCCESS:
2302 		break;
2303 	}
2304 
2305 	/* Fetch any configured 'sent' options (includes DUID') in wire format.
2306 	 */
2307 	dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
2308 				    client->sent_options, &global_scope,
2309 				    &dhcpv6_universe);
2310 
2311 	/* Append IA's. */
2312 	if (wanted_ia_na &&
2313 	    dhc6_add_ia_na(client, &ds, client->active_lease,
2314 			   DHCPV6_CONFIRM, 0, &added) != ISC_R_SUCCESS) {
2315 		data_string_forget(&ds, MDL);
2316 		return;
2317 	}
2318 	if (wanted_ia_ta &&
2319 	    dhc6_add_ia_ta(client, &ds, client->active_lease,
2320 			   DHCPV6_CONFIRM, 0, &added) != ISC_R_SUCCESS) {
2321 		data_string_forget(&ds, MDL);
2322 		return;
2323 	}
2324 
2325 	/* Transmit and wait. */
2326 
2327 	log_info("XMT: Confirm on %s, interval %ld0ms.",
2328 		 client->name ? client->name : client->interface->name,
2329 		 (long int)client->RT);
2330 
2331 	send_ret = send_packet6(client->interface, ds.data, ds.len,
2332 				&DHCPv6DestAddr);
2333 	if (send_ret != ds.len) {
2334 		log_error("dhc6: sendpacket6() sent %d of %d bytes",
2335 			  send_ret, ds.len);
2336 	}
2337 
2338 	data_string_forget(&ds, MDL);
2339 
2340 	/* Wait RT */
2341 	tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
2342 	tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
2343 	if (tv.tv_usec >= 1000000) {
2344 		tv.tv_sec += 1;
2345 		tv.tv_usec -= 1000000;
2346 	}
2347 	add_timeout(&tv, do_confirm6, client, NULL, NULL);
2348 
2349 	dhc6_retrans_advance(client);
2350 }
2351 
2352 /*
2353  * Release addresses.
2354  */
2355 void
start_release6(struct client_state * client)2356 start_release6(struct client_state *client)
2357 {
2358 	/* Cancel any pending transmissions */
2359 	cancel_timeout(do_confirm6, client);
2360 	cancel_timeout(do_select6, client);
2361 	cancel_timeout(do_refresh6, client);
2362 	cancel_timeout(do_release6, client);
2363 	cancel_timeout(do_decline6, client);
2364 	client->state = S_STOPPED;
2365 
2366 	/*
2367 	 * It is written:  "The client MUST NOT use any of the addresses it
2368 	 * is releasing as the source address in the Release message or in
2369 	 * any subsequently transmitted message."  So unconfigure now.
2370 	 */
2371 	unconfigure6(client, "RELEASE6");
2372 
2373 	/* Note this in the lease file. */
2374 	if (client->active_lease == NULL)
2375 		return;
2376 	client->active_lease->released = ISC_TRUE;
2377 	write_client6_lease(client, client->active_lease, 0, 1);
2378 
2379 	/* Set timers per RFC3315 section 18.1.6. */
2380 	client->IRT = REL_TIMEOUT * 100;
2381 	client->MRT = 0;
2382 	client->MRC = REL_MAX_RC;
2383 	client->MRD = 0;
2384 
2385 	dhc6_retrans_init(client);
2386 	client->v6_handler = reply_handler;
2387 
2388 	do_release6(client);
2389 }
2390 /*
2391  * do_release6() creates a Release packet and transmits it.
2392  */
2393 static void
do_release6(void * input)2394 do_release6(void *input)
2395 {
2396 	struct client_state *client;
2397 	struct data_string ds;
2398 	int send_ret, added;
2399 	struct timeval tv;
2400 
2401 	client = input;
2402 
2403 	if ((client->active_lease == NULL) || !active_prefix(client))
2404 		return;
2405 
2406 	switch(check_timing6(client, DHCPV6_RELEASE, "Release",
2407 			     client->active_lease, &ds)) {
2408 	      case CHK_TIM_MRC_EXCEEDED:
2409 	      case CHK_TIM_ALLOC_FAILURE:
2410 	      case CHK_TIM_MRD_EXCEEDED:
2411 		goto release_done;
2412 	      case CHK_TIM_SUCCESS:
2413 		break;
2414 	}
2415 
2416 	/*
2417 	 * Don't use unicast as we don't know if we still have an
2418 	 * available address with enough scope.
2419 	 */
2420 
2421 	dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
2422 				    client->sent_options, &global_scope,
2423 				    &dhcpv6_universe);
2424 
2425 	/* Append IA's (but don't release temporary addresses). */
2426 	if (wanted_ia_na &&
2427 	    dhc6_add_ia_na(client, &ds, client->active_lease,
2428 			   DHCPV6_RELEASE, 0, &added) != ISC_R_SUCCESS) {
2429 		data_string_forget(&ds, MDL);
2430 		goto release_done;
2431 	}
2432 	if (wanted_ia_pd &&
2433 	    dhc6_add_ia_pd(client, &ds, client->active_lease,
2434 			   DHCPV6_RELEASE, 0, &added) != ISC_R_SUCCESS) {
2435 		data_string_forget(&ds, MDL);
2436 		goto release_done;
2437 	}
2438 
2439 	/* Transmit and wait. */
2440 	log_info("XMT: Release on %s, interval %ld0ms.",
2441 		 client->name ? client->name : client->interface->name,
2442 		 (long int)client->RT);
2443 
2444 	send_ret = send_packet6(client->interface, ds.data, ds.len,
2445 				&DHCPv6DestAddr);
2446 	if (send_ret != ds.len) {
2447 		log_error("dhc6: sendpacket6() sent %d of %d bytes",
2448 			  send_ret, ds.len);
2449 	}
2450 
2451 	data_string_forget(&ds, MDL);
2452 
2453 	/* Wait RT */
2454 	tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
2455 	tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
2456 	if (tv.tv_usec >= 1000000) {
2457 		tv.tv_sec += 1;
2458 		tv.tv_usec -= 1000000;
2459 	}
2460 	add_timeout(&tv, do_release6, client, NULL, NULL);
2461 	dhc6_retrans_advance(client);
2462 	return;
2463 
2464       release_done:
2465 	dhc6_lease_destroy(&client->active_lease, MDL);
2466 	client->active_lease = NULL;
2467 	if (stopping_finished())
2468 		finish(0);
2469 }
2470 
2471 /* status_log() just puts a status code into displayable form and logs it
2472  * to info level.
2473  */
2474 static void
status_log(int code,const char * scope,const char * additional,int len)2475 status_log(int code, const char *scope, const char *additional, int len)
2476 {
2477 	const char *msg = NULL;
2478 
2479 	switch(code) {
2480 	      case STATUS_Success:
2481 		msg = "Success";
2482 		break;
2483 
2484 	      case STATUS_UnspecFail:
2485 		msg = "UnspecFail";
2486 		break;
2487 
2488 	      case STATUS_NoAddrsAvail:
2489 		msg = "NoAddrsAvail";
2490 		break;
2491 
2492 	      case STATUS_NoBinding:
2493 		msg = "NoBinding";
2494 		break;
2495 
2496 	      case STATUS_NotOnLink:
2497 		msg = "NotOnLink";
2498 		break;
2499 
2500 	      case STATUS_UseMulticast:
2501 		msg = "UseMulticast";
2502 		break;
2503 
2504 	      case STATUS_NoPrefixAvail:
2505 		msg = "NoPrefixAvail";
2506 		break;
2507 
2508 	      default:
2509 		msg = "UNKNOWN";
2510 		break;
2511 	}
2512 
2513 	if (len > 0)
2514 		log_info("%s status code %s: %s", scope, msg,
2515 			 print_hex_1(len,
2516 				     (const unsigned char *)additional, 50));
2517 	else
2518 		log_info("%s status code %s.", scope, msg);
2519 }
2520 
2521 /* Acquire a status code.
2522  */
2523 static isc_result_t
dhc6_get_status_code(struct option_state * options,unsigned * code,struct data_string * msg)2524 dhc6_get_status_code(struct option_state *options, unsigned *code,
2525 		     struct data_string *msg)
2526 {
2527 	struct option_cache *oc;
2528 	struct data_string ds;
2529 	isc_result_t rval = ISC_R_SUCCESS;
2530 
2531 	if ((options == NULL) || (code == NULL))
2532 		return DHCP_R_INVALIDARG;
2533 
2534 	if ((msg != NULL) && (msg->len != 0))
2535 		return DHCP_R_INVALIDARG;
2536 
2537 	memset(&ds, 0, sizeof(ds));
2538 
2539 	/* Assume success if there is no option. */
2540 	*code = STATUS_Success;
2541 
2542 	oc = lookup_option(&dhcpv6_universe, options, D6O_STATUS_CODE);
2543 	if ((oc != NULL) &&
2544 	    evaluate_option_cache(&ds, NULL, NULL, NULL, options,
2545 				  NULL, &global_scope, oc, MDL)) {
2546 		if (ds.len < 2) {
2547 			log_error("Invalid status code length %d.", ds.len);
2548 			rval = DHCP_R_FORMERR;
2549 		} else
2550 			*code = getUShort(ds.data);
2551 
2552 		if ((msg != NULL) && (ds.len > 2)) {
2553 			data_string_copy(msg, &ds, MDL);
2554 			msg->data += 2;
2555 			msg->len -= 2;
2556 		}
2557 
2558 		data_string_forget(&ds, MDL);
2559 		return rval;
2560 	}
2561 
2562 	return ISC_R_NOTFOUND;
2563 }
2564 
2565 /* Look at status codes in an advertise, and reform the return value.
2566  */
2567 static isc_result_t
dhc6_check_status(isc_result_t rval,struct option_state * options,const char * scope,unsigned * code)2568 dhc6_check_status(isc_result_t rval, struct option_state *options,
2569 		  const char *scope, unsigned *code)
2570 {
2571 	struct data_string msg;
2572 	isc_result_t status;
2573 
2574 	if ((scope == NULL) || (code == NULL))
2575 		return DHCP_R_INVALIDARG;
2576 
2577 	/* If we don't find a code, we assume success. */
2578 	*code = STATUS_Success;
2579 
2580 	/* If there is no options cache, then there is no code. */
2581 	if (options != NULL) {
2582 		memset(&msg, 0, sizeof(msg));
2583 		status = dhc6_get_status_code(options, code, &msg);
2584 
2585 		if (status == ISC_R_SUCCESS) {
2586 			status_log(*code, scope, (char *)msg.data, msg.len);
2587 			data_string_forget(&msg, MDL);
2588 
2589 			if (*code != STATUS_Success)
2590 				rval = ISC_R_FAILURE;
2591 
2592 		} else if (status != ISC_R_NOTFOUND)
2593 			rval = status;
2594 	}
2595 
2596 	return rval;
2597 }
2598 
2599 /* Determine if this packet could provide usable information.
2600  * We check the status codes at the top level and at the IA level,
2601  * IAADDRS have already been checked in the leaseify step and any with
2602  * a bad format or status code that wasn't success have been dropped.
2603  *
2604  * leaseify has also already removed any IAs for which the top level status
2605  * code or the IA status code indicated no addresses or prefixes were
2606  * available.
2607  */
2608 static isc_result_t
dhc6_check_advertise(struct dhc6_lease * lease)2609 dhc6_check_advertise(struct dhc6_lease *lease)
2610 {
2611 	struct dhc6_ia *ia;
2612 	isc_result_t rval = ISC_R_SUCCESS;
2613 	int have_addrs = ISC_FALSE;
2614 	unsigned code;
2615 	const char *scope;
2616 	int got_na = 0, got_ta = 0, got_pd = 0;
2617 
2618 	rval = dhc6_check_status(rval, lease->options, "message", &code);
2619 
2620 	for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
2621 		switch (ia->ia_type) {
2622 			case D6O_IA_NA:
2623 				scope = "IA_NA";
2624 				got_na++;
2625 				break;
2626 			case D6O_IA_TA:
2627 				scope = "IA_TA";
2628 				got_ta++;
2629 				break;
2630 			case D6O_IA_PD:
2631 				scope = "IA_PD";
2632 				got_pd++;
2633 				break;
2634 			default:
2635 				log_error("dhc6_check_advertise: no type.");
2636 				return ISC_R_FAILURE;
2637 		}
2638 		/* Currently we toss packets if we have an error getting a
2639 		 * status code or if the status code isn't success, so
2640 		 * no need to loop through the addresses */
2641 		rval = dhc6_check_status(rval, ia->options, scope, &code);
2642 		if (rval != ISC_R_SUCCESS)
2643 			continue;
2644 
2645 		/* We don't need to check status on IAADDRS here as we already
2646 		 * did it as part of the leaseify step and tossed bad IAADDRS.
2647 		 * We are just checking to see if we have any addrs.
2648 		 * Should we check the addr itself for usability?
2649 		 */
2650 		if (ia->addrs != NULL) {
2651 			have_addrs = ISC_TRUE;
2652 		}
2653 	}
2654 
2655 	/* If we didn't get some addrs or the user required us to
2656 	 * get all of the requested IAs and we didn't return an error
2657 	 */
2658 	if ((have_addrs != ISC_TRUE) ||
2659 	    ((require_all_ias != 0) &&
2660 	     ((got_na < wanted_ia_na) ||
2661 	      (got_ta < wanted_ia_ta) ||
2662 	      (got_pd < wanted_ia_pd))))
2663 		rval = ISC_R_ADDRNOTAVAIL;
2664 
2665 	return rval;
2666 }
2667 
2668 /* status code <-> action matrix for the client in INIT state
2669  * (rapid/commit).  Returns always false as no action is defined.
2670  */
2671 static isc_boolean_t
dhc6_init_action(struct client_state * client,isc_result_t * rvalp,unsigned code)2672 dhc6_init_action(struct client_state *client, isc_result_t *rvalp,
2673 		 unsigned code)
2674 {
2675 	if (rvalp == NULL)
2676 		log_fatal("Impossible condition at %s:%d.", MDL);
2677 
2678 	if (client == NULL) {
2679 		*rvalp = DHCP_R_INVALIDARG;
2680 		return ISC_FALSE;
2681 	}
2682 
2683 	if (*rvalp == ISC_R_SUCCESS)
2684 		return ISC_FALSE;
2685 
2686 	/* No possible action in any case... */
2687 	return ISC_FALSE;
2688 }
2689 
2690 /* status code <-> action matrix for the client in SELECT state
2691  * (request/reply).  Returns true if action was taken (and the
2692  * packet should be ignored), or false if no action was taken.
2693  */
2694 static isc_boolean_t
dhc6_select_action(struct client_state * client,isc_result_t * rvalp,unsigned code)2695 dhc6_select_action(struct client_state *client, isc_result_t *rvalp,
2696 		   unsigned code)
2697 {
2698 	struct dhc6_lease *lease;
2699 	isc_result_t rval;
2700 
2701 	if (rvalp == NULL)
2702 		log_fatal("Impossible condition at %s:%d.", MDL);
2703 
2704 	if (client == NULL) {
2705 		*rvalp = DHCP_R_INVALIDARG;
2706 		return ISC_FALSE;
2707 	}
2708 	rval = *rvalp;
2709 
2710 	if (rval == ISC_R_SUCCESS)
2711 		return ISC_FALSE;
2712 
2713 	switch (code) {
2714 		/* We may have an earlier failure status code (so no
2715 		 * success rval), and a success code now.  This
2716 		 * doesn't upgrade the rval to success, but it does
2717 		 * mean we take no action here.
2718 		 */
2719 	      case STATUS_Success:
2720 		/* Gimpy server, or possibly an attacker. */
2721 	      case STATUS_NoBinding:
2722 	      case STATUS_UseMulticast:
2723 		/* Take no action. */
2724 		return ISC_FALSE;
2725 
2726 		/* If the server can't deal with us, either try the
2727 		 * next advertised server, or continue retrying if there
2728 		 * weren't any.
2729 		 */
2730 	      default:
2731 	      case STATUS_UnspecFail:
2732 		if (client->advertised_leases != NULL) {
2733 			dhc6_lease_destroy(&client->selected_lease, MDL);
2734 			client->selected_lease = NULL;
2735 
2736 			start_selecting6(client);
2737 
2738 			break;
2739 		} else /* Take no action - continue to retry. */
2740 			return ISC_FALSE;
2741 
2742 		/* If the server has no addresses, try other servers if
2743 		 * we got some, otherwise go to INIT to hope for more
2744 		 * servers.
2745 		 */
2746 	      case STATUS_NoAddrsAvail:
2747 	      case STATUS_NoPrefixAvail:
2748 		if (client->state == S_REBOOTING)
2749 			return ISC_FALSE;
2750 
2751 		if (client->selected_lease == NULL)
2752 			log_fatal("Impossible case at %s:%d.", MDL);
2753 
2754 		dhc6_lease_destroy(&client->selected_lease, MDL);
2755 		client->selected_lease = NULL;
2756 
2757 		if (client->advertised_leases != NULL)
2758 			start_selecting6(client);
2759 		else
2760 			start_init6(client);
2761 
2762 		break;
2763 
2764 		/* If we got a NotOnLink from a Confirm, then we're not
2765 		 * on link.  Kill the old-active binding and start over.
2766 		 *
2767 		 * If we got a NotOnLink from our Request, something weird
2768 		 * happened.  Start over from scratch anyway.
2769 		 */
2770 	      case STATUS_NotOnLink:
2771 		if (client->state == S_REBOOTING) {
2772 			if (client->active_lease == NULL)
2773 				log_fatal("Impossible case at %s:%d.", MDL);
2774 
2775 			dhc6_lease_destroy(&client->active_lease, MDL);
2776 		} else {
2777 			if (client->selected_lease == NULL)
2778 				log_fatal("Impossible case at %s:%d.", MDL);
2779 
2780 			dhc6_lease_destroy(&client->selected_lease, MDL);
2781 			client->selected_lease = NULL;
2782 
2783 			while (client->advertised_leases != NULL) {
2784 				lease = client->advertised_leases;
2785 				client->advertised_leases = lease->next;
2786 
2787 				dhc6_lease_destroy(&lease, MDL);
2788 			}
2789 		}
2790 
2791 		start_init6(client);
2792 		break;
2793 	}
2794 
2795 	return ISC_TRUE;
2796 }
2797 
2798 static void
dhc6_withdraw_lease(struct client_state * client)2799 dhc6_withdraw_lease(struct client_state *client)
2800 {
2801 	struct dhc6_ia *ia;
2802 	struct dhc6_addr *addr;
2803 
2804 	if ((client == NULL) || (client->active_lease == NULL))
2805 		return;
2806 
2807 	for (ia = client->active_lease->bindings ; ia != NULL ;
2808 	     ia = ia->next) {
2809 		for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
2810 			addr->max_life = addr->preferred_life = 0;
2811 		}
2812 	}
2813 
2814 	/* Perform expiry. */
2815 	do_expire(client);
2816 }
2817 
2818 /* status code <-> action matrix for the client in BOUND state
2819  * (request/reply).  Returns true if action was taken (and the
2820  * packet should be ignored), or false if no action was taken.
2821  */
2822 static isc_boolean_t
dhc6_reply_action(struct client_state * client,isc_result_t * rvalp,unsigned code)2823 dhc6_reply_action(struct client_state *client, isc_result_t *rvalp,
2824 		  unsigned code)
2825 {
2826 	isc_result_t rval;
2827 
2828 	if (rvalp == NULL)
2829 		log_fatal("Impossible condition at %s:%d.", MDL);
2830 
2831 	if (client == NULL) {
2832 		*rvalp = DHCP_R_INVALIDARG;
2833 		return ISC_FALSE;
2834 	}
2835 	rval = *rvalp;
2836 
2837 	if (rval == ISC_R_SUCCESS)
2838 		return ISC_FALSE;
2839 
2840 	switch (code) {
2841 		/* It's possible an earlier status code set rval to a failure
2842 		 * code, and we've encountered a later success.
2843 		 */
2844 	      case STATUS_Success:
2845 		/* In "refreshes" (where we get replies), we probably
2846 		 * still have a valid lease.  So "take no action" and
2847 		 * the upper levels will keep retrying until the lease
2848 		 * expires (or we rebind).
2849 		 */
2850 	      case STATUS_UnspecFail:
2851 		/* For unknown codes...it's a soft (retryable) error. */
2852 	      default:
2853 		return ISC_FALSE;
2854 
2855 		/* The server is telling us to use a multicast address, so
2856 		 * we have to delete the unicast option from the active
2857 		 * lease, then allow retransmission to occur normally.
2858 		 * (XXX: It might be preferable in this case to retransmit
2859 		 * sooner than the current interval, but for now we don't.)
2860 		 */
2861 	      case STATUS_UseMulticast:
2862 		if (client->active_lease != NULL)
2863 			delete_option(&dhcp_universe,
2864 				      client->active_lease->options,
2865 				      D6O_UNICAST);
2866 		return ISC_FALSE;
2867 
2868 		/* "When the client receives a NotOnLink status from the
2869 		 *  server in response to a Request, the client can either
2870 		 *  re-issue the Request without specifying any addresses
2871 		 *  or restart the DHCP server discovery process."
2872 		 *
2873 		 * This is strange.  If competing server evaluation is
2874 		 * useful (and therefore in the protocol), then why would
2875 		 * a client's first reaction be to request from the same
2876 		 * server on a different link?  Surely you'd want to
2877 		 * re-evaluate your server selection.
2878 		 *
2879 		 * Well, I guess that's the answer.
2880 		 */
2881 	      case STATUS_NotOnLink:
2882 		/* In this case, we need to rescind all current active
2883 		 * bindings (just 'expire' them all normally, if early).
2884 		 * They're no use to us on the wrong link.  Then head back
2885 		 * to init, redo server selection and get new addresses.
2886 		 */
2887 		dhc6_withdraw_lease(client);
2888 		break;
2889 
2890 		/* "If the status code is NoAddrsAvail, the client has
2891 		 *  received no usable addresses in the IA and may choose
2892 		 *  to try obtaining addresses for the IA from another
2893 		 *  server."
2894 		 */
2895 	      case STATUS_NoAddrsAvail:
2896 	      case STATUS_NoPrefixAvail:
2897 		/* Head back to init, keeping any active bindings (!). */
2898 		start_init6(client);
2899 		break;
2900 
2901 		/* -  sends a Request message if the IA contained a Status
2902 		 *    Code option with the NoBinding status (and does not
2903 		 *    send any additional Renew/Rebind messages)
2904 		 */
2905 	      case STATUS_NoBinding:
2906 		if (client->advertised_leases != NULL)
2907 			log_fatal("Impossible condition at %s:%d.", MDL);
2908 
2909 		client->advertised_leases =
2910 				dhc6_dup_lease(client->active_lease, MDL);
2911 		start_selecting6(client);
2912 		break;
2913 	}
2914 
2915 	return ISC_TRUE;
2916 }
2917 
2918 /* status code <-> action matrix for the client in STOPPED state
2919  * (release/decline).  Returns true if action was taken (and the
2920  * packet should be ignored), or false if no action was taken.
2921  * NoBinding is translated into Success.
2922  */
2923 static isc_boolean_t
dhc6_stop_action(struct client_state * client,isc_result_t * rvalp,unsigned code)2924 dhc6_stop_action(struct client_state *client, isc_result_t *rvalp,
2925 		  unsigned code)
2926 {
2927 	isc_result_t rval;
2928 
2929 	if (rvalp == NULL)
2930 		log_fatal("Impossible condition at %s:%d.", MDL);
2931 
2932 	if (client == NULL) {
2933 		*rvalp = DHCP_R_INVALIDARG;
2934 		return ISC_FALSE;
2935 	}
2936 	rval = *rvalp;
2937 
2938 	if (rval == ISC_R_SUCCESS)
2939 		return ISC_FALSE;
2940 
2941 	switch (code) {
2942 		/* It's possible an earlier status code set rval to a failure
2943 		 * code, and we've encountered a later success.
2944 		 */
2945 	      case STATUS_Success:
2946 		/* For unknown codes...it's a soft (retryable) error. */
2947 	      case STATUS_UnspecFail:
2948 	      default:
2949 		return ISC_FALSE;
2950 
2951 		/* NoBinding is not an error */
2952 	      case STATUS_NoBinding:
2953 		if (rval == ISC_R_FAILURE)
2954 			*rvalp = ISC_R_SUCCESS;
2955 		return ISC_FALSE;
2956 
2957 		/* Should not happen */
2958 	      case STATUS_NoAddrsAvail:
2959 	      case STATUS_NoPrefixAvail:
2960 		break;
2961 
2962 		/* Give up on it */
2963 	      case STATUS_NotOnLink:
2964 		break;
2965 
2966 		/* The server is telling us to use a multicast address, so
2967 		 * we have to delete the unicast option from the active
2968 		 * lease, then allow retransmission to occur normally.
2969 		 * (XXX: It might be preferable in this case to retransmit
2970 		 * sooner than the current interval, but for now we don't.)
2971 		 */
2972 	      case STATUS_UseMulticast:
2973 		if (client->active_lease != NULL)
2974 			delete_option(&dhcp_universe,
2975 				      client->active_lease->options,
2976 				      D6O_UNICAST);
2977 		return ISC_FALSE;
2978 	}
2979 
2980 	return ISC_TRUE;
2981 }
2982 
2983 static isc_boolean_t
dhc6_decline_action(struct client_state * client,isc_result_t * rvalp,unsigned code)2984 dhc6_decline_action(struct client_state *client, isc_result_t *rvalp,
2985 		  unsigned code)
2986 {
2987 	isc_result_t rval;
2988 
2989 	if (rvalp == NULL)
2990 		log_fatal("Impossible condition at %s:%d.", MDL);
2991 
2992 	if (client == NULL) {
2993 		*rvalp = DHCP_R_INVALIDARG;
2994 		return ISC_FALSE;
2995 	}
2996 	rval = *rvalp;
2997 
2998 	if (rval == ISC_R_SUCCESS) {
2999 		return ISC_FALSE;
3000 	}
3001 
3002 	switch (code) {
3003 	case STATUS_UseMulticast:
3004 		/* The server is telling us to use a multicast address, so
3005 		* we have to delete the unicast option from the active
3006 		* lease, then allow retransmission to occur normally.
3007 		* (XXX: It might be preferable in this case to retransmit
3008 		* sooner than the current interval, but for now we don't.)
3009 		*/
3010 		if (client->active_lease != NULL)
3011 			delete_option(&dhcp_universe,
3012 				      client->active_lease->options,
3013 				      D6O_UNICAST);
3014 		return ISC_FALSE;
3015 	default:
3016 		/* Anything else is basically meaningless */
3017 		break;
3018 	}
3019 
3020 	return ISC_TRUE;
3021 }
3022 
3023 
3024 /* Look at a new and old lease, and make sure the new information is not
3025  * losing us any state.
3026  */
3027 static isc_result_t
dhc6_check_reply(struct client_state * client,struct dhc6_lease * new)3028 dhc6_check_reply(struct client_state *client, struct dhc6_lease *new)
3029 {
3030 	isc_boolean_t (*action)(struct client_state *,
3031 				isc_result_t *, unsigned);
3032 	struct dhc6_ia *ia;
3033 	isc_result_t rval = ISC_R_SUCCESS;
3034 	unsigned code;
3035 	const char *scope;
3036 	int nscore, sscore;
3037 	int have_addrs = ISC_FALSE;
3038 	int got_na = 0, got_ta = 0, got_pd = 0;
3039 
3040 	if ((client == NULL) || (new == NULL))
3041 		return DHCP_R_INVALIDARG;
3042 
3043 	switch (client->state) {
3044 	      case S_INIT:
3045 		action = dhc6_init_action;
3046 		break;
3047 
3048 	      case S_SELECTING:
3049 	      case S_REBOOTING:
3050 		action = dhc6_select_action;
3051 		break;
3052 
3053 	      case S_RENEWING:
3054 	      case S_REBINDING:
3055 		action = dhc6_reply_action;
3056 		break;
3057 
3058 	      case S_STOPPED:
3059 		action = dhc6_stop_action;
3060 		break;
3061 
3062 	      case S_DECLINING:
3063 		action = dhc6_decline_action;
3064 		break;
3065 
3066 	      default:
3067 		log_fatal("Impossible condition at %s:%d.", MDL);
3068 		return ISC_R_CANCELED;
3069 	}
3070 
3071 	/* If there is a code to extract, and if there is some
3072 	 * action to take based on that code, then take the action
3073 	 * and do not continue.
3074 	 */
3075 	rval = dhc6_check_status(rval, new->options, "message", &code);
3076 	if (action(client, &rval, code))
3077 		return ISC_R_CANCELED;
3078 
3079 	for (ia = new->bindings ; ia != NULL ; ia = ia->next) {
3080 		switch (ia->ia_type) {
3081 			case D6O_IA_NA:
3082 				scope = "IA_NA";
3083 				got_na++;
3084 				break;
3085 			case D6O_IA_TA:
3086 				scope = "IA_TA";
3087 				got_ta++;
3088 				break;
3089 			case D6O_IA_PD:
3090 				scope = "IA_PD";
3091 				got_pd++;
3092 				break;
3093 			default:
3094 				log_error("dhc6_check_reply: no type.");
3095 				return DHCP_R_INVALIDARG;
3096 		}
3097 		rval = dhc6_check_status(rval, ia->options, scope, &code);
3098 
3099 		if (action(client, &rval, code))
3100 			return ISC_R_CANCELED;
3101 
3102 		if (ia->addrs != NULL) {
3103 			have_addrs = ISC_TRUE;
3104 		}
3105 	}
3106 
3107 	/* A Confirm->Reply is unsuitable for comparison to the old lease. */
3108 	if (client->state == S_REBOOTING)
3109 		return rval;
3110 
3111 	/* We expect the lease to have at least one address and if
3112 	 * required all of the requested IAs if not flag it as
3113 	 * NoAddrs and call the action routine to try again.
3114 	 *
3115 	 * Currently we don't completely handle TAs in all cases
3116 	 * so we don't check them for requires.  I've left the
3117 	 * check in and commented it as I eventually do want
3118 	 * us to check for TAs as well.  SAR
3119 	 */
3120 	if ((have_addrs != ISC_TRUE) ||
3121 	    ((require_all_ias != 0) &&
3122 	     ((got_na < wanted_ia_na) ||
3123 	      /*(got_ta < wanted_ia_ta) ||*/
3124 	      (got_pd < wanted_ia_pd)))) {
3125 		rval = ISC_R_FAILURE;
3126 		if (action(client, &rval, STATUS_NoAddrsAvail) == ISC_TRUE) {
3127 			return ISC_R_CANCELED;
3128 		}
3129 	}
3130 
3131 	/* No old lease in rapid-commit. */
3132 	if (client->state == S_INIT)
3133 		return rval;
3134 
3135 	switch (client->state) {
3136 	      case S_SELECTING:
3137 		/* Compare the new lease with the selected lease to make
3138 		 * sure there is no risky business.
3139 		 */
3140 		nscore = dhc6_score_lease(client, new);
3141 		sscore = dhc6_score_lease(client, client->selected_lease);
3142 		if ((client->advertised_leases != NULL) &&
3143 		    (nscore < (sscore / 2))) {
3144 			/* XXX: An attacker might reply this way to make
3145 			 * XXX: sure we latch onto their configuration.
3146 			 * XXX: We might want to ignore the packet and
3147 			 * XXX: schedule re-selection at the next timeout?
3148 			 */
3149 			log_error("PRC: BAIT AND SWITCH detected.  Score of "
3150 				  "supplied lease (%d) is substantially "
3151 				  "smaller than the advertised score (%d).  "
3152 				  "Trying other servers.",
3153 				  nscore, sscore);
3154 
3155 			dhc6_lease_destroy(&client->selected_lease, MDL);
3156 			client->selected_lease = NULL;
3157 
3158 			start_selecting6(client);
3159 
3160 			return ISC_R_CANCELED;
3161 		}
3162 		break;
3163 
3164 	      case S_RENEWING:
3165 	      case S_REBINDING:
3166 		/* This leaves one RFC3315 status check unimplemented:
3167 		 *
3168 		 * -  sends a Renew/Rebind if the IA is not in the Reply
3169 		 *    message
3170 		 *
3171 		 * We rely on the scheduling system to note that the IA has
3172 		 * not left Renewal/Rebinding/whatever since it still carries
3173 		 * old times from the last successful binding.  So this is
3174 		 * implemented actually, just not explicitly.
3175 		 */
3176 		break;
3177 
3178 	      case S_STOPPED:
3179 	      case S_DECLINING:
3180 		/* Nothing critical to do at this stage. */
3181 		break;
3182 
3183 	      default:
3184 		log_fatal("REALLY impossible condition at %s:%d.", MDL);
3185 		return ISC_R_CANCELED;
3186 	}
3187 
3188 	return rval;
3189 }
3190 
3191 /* While in init state, we only collect advertisements.  If there happens
3192  * to be an advertisement with a preference option of 255, that's an
3193  * automatic exit.  Otherwise, we collect advertisements until our timeout
3194  * expires (client->RT).
3195  */
3196 void
init_handler(struct packet * packet,struct client_state * client)3197 init_handler(struct packet *packet, struct client_state *client)
3198 {
3199 	struct dhc6_lease *lease;
3200 
3201 	/* In INIT state, we send solicits, we only expect to get
3202 	 * advertises (rapid commit has its own handler).
3203 	 */
3204 	if (packet->dhcpv6_msg_type != DHCPV6_ADVERTISE)
3205 		return;
3206 
3207 	/* RFC3315 section 15.3 validation (same as 15.10 since we
3208 	 * always include a client id).
3209 	 */
3210 	if (!valid_reply(packet, client)) {
3211 		log_error("Invalid Advertise - rejecting.");
3212 		return;
3213 	}
3214 
3215 	lease = dhc6_leaseify(packet, client);
3216 
3217 	/* Out of memory or corrupt packet condition...hopefully a temporary
3218 	 * problem.  Returning now makes us try to retransmit later.
3219 	 */
3220 	if (lease == NULL)
3221 		return;
3222 
3223 	if (dhc6_check_advertise(lease) != ISC_R_SUCCESS) {
3224 		log_debug("PRC: Lease failed to satisfy.");
3225 		dhc6_lease_destroy(&lease, MDL);
3226 		return;
3227 	}
3228 
3229 	int lease_score =  dhc6_score_lease(client, lease);
3230 #ifdef ENFORCE_DHCPV6_CLIENT_REQUIRE
3231 	if (lease_score == 0) {
3232 		log_debug("RCV:Advertised lease scored 0, toss it.");
3233 		dhc6_lease_destroy(&lease, MDL);
3234 		return;
3235 	}
3236 #endif
3237 
3238 	insert_lease(&client->advertised_leases, lease);
3239 
3240 	/* According to RFC3315 section 17.1.2, the client MUST wait for
3241 	 * the first RT before selecting a lease.  But on the 400th RT,
3242 	 * we dont' want to wait the full timeout if we finally get an
3243 	 * advertise.  We could probably wait a second, but ohwell,
3244 	 * RFC3315 doesn't say so.
3245 	 *
3246 	 * If the lease is highest possible preference, 255, RFC3315 claims
3247 	 * we should continue immediately even on the first RT.  We probably
3248 	 * should not if the advertise contains less than one IA and address.
3249 	 */
3250 	if ((client->txcount > 1) ||
3251 	    ((lease->pref == 255) && (lease_score > SCORE_MIN))) {
3252 		log_debug("RCV:  Advertisement immediately selected.");
3253 		cancel_timeout(do_init6, client);
3254 		start_selecting6(client);
3255 	} else
3256 		log_debug("RCV:  Advertisement recorded.");
3257 }
3258 
3259 /* info_request_handler() accepts a Reply to an Info-request.
3260  */
3261 void
info_request_handler(struct packet * packet,struct client_state * client)3262 info_request_handler(struct packet *packet, struct client_state *client)
3263 {
3264 	isc_result_t check_status;
3265 	unsigned code;
3266 
3267 	if (packet->dhcpv6_msg_type != DHCPV6_REPLY)
3268 		return;
3269 
3270 	/* RFC3315 section 15.10 validation (same as 15.3 since we
3271 	 * always include a client id).
3272 	 */
3273 	if (!valid_reply(packet, client)) {
3274 		log_error("Invalid Reply - rejecting.");
3275 		return;
3276 	}
3277 
3278 	check_status = dhc6_check_status(ISC_R_SUCCESS, packet->options,
3279 					 "message", &code);
3280 
3281 	if (check_status != ISC_R_SUCCESS) {
3282 		/* If no action was taken, but there is an error, then
3283 		 * we wait for a retransmission.
3284 		 */
3285 		if (check_status != ISC_R_CANCELED)
3286 			return;
3287 	}
3288 
3289 	/* We're done retransmitting at this point. */
3290 	cancel_timeout(do_info_request6, client);
3291 
3292 	/* Action was taken, so now that we've torn down our scheduled
3293 	 * retransmissions, return.
3294 	 */
3295 	if (check_status == ISC_R_CANCELED)
3296 		return;
3297 
3298 	/* Cleanup if a previous attempt to go bound failed. */
3299 	if (client->old_lease != NULL) {
3300 		dhc6_lease_destroy(&client->old_lease, MDL);
3301 		client->old_lease = NULL;
3302 	}
3303 
3304 	/* Cache options in the active_lease. */
3305 	if (client->active_lease != NULL)
3306 		client->old_lease = client->active_lease;
3307 	client->active_lease = dmalloc(sizeof(struct dhc6_lease), MDL);
3308 	if (client->active_lease == NULL)
3309 		log_fatal("Out of memory for v6 lease structure.");
3310 	option_state_reference(&client->active_lease->options,
3311 			       packet->options, MDL);
3312 
3313 	execute_statements_in_scope(NULL, (struct packet *)packet, NULL, client,
3314 				    client->active_lease->options,
3315 				    client->active_lease->options,
3316 				    &global_scope, client->config->on_receipt,
3317 				    NULL, NULL);
3318 
3319 	start_informed(client);
3320 }
3321 
3322 /* Specific version of init_handler() for rapid-commit.
3323  */
3324 void
rapid_commit_handler(struct packet * packet,struct client_state * client)3325 rapid_commit_handler(struct packet *packet, struct client_state *client)
3326 {
3327 	struct dhc6_lease *lease;
3328 	isc_result_t check_status;
3329 
3330 	/* On ADVERTISE just fall back to the init_handler().
3331 	 */
3332 	if (packet->dhcpv6_msg_type == DHCPV6_ADVERTISE) {
3333 		init_handler(packet, client);
3334 		return;
3335 	} else if (packet->dhcpv6_msg_type != DHCPV6_REPLY)
3336 		return;
3337 
3338 	/* RFC3315 section 15.10 validation (same as 15.3 since we
3339 	 * always include a client id).
3340 	 */
3341 	if (!valid_reply(packet, client)) {
3342 		log_error("Invalid Reply - rejecting.");
3343 		return;
3344 	}
3345 
3346 	/* A rapid-commit option MUST be here. */
3347 	if (lookup_option(&dhcpv6_universe, packet->options,
3348 			  D6O_RAPID_COMMIT) == 0) {
3349 		log_error("Reply without Rapid-Commit - rejecting.");
3350 		return;
3351 	}
3352 
3353 	lease = dhc6_leaseify(packet, client);
3354 
3355 	/* Out of memory or corrupt packet condition...hopefully a temporary
3356 	 * problem.  Returning now makes us try to retransmit later.
3357 	 */
3358 	if (lease == NULL)
3359 		return;
3360 
3361 	check_status = dhc6_check_reply(client, lease);
3362 	if (check_status != ISC_R_SUCCESS) {
3363 		dhc6_lease_destroy(&lease, MDL);
3364 		return;
3365 	}
3366 
3367 	/* Jump to the selecting state. */
3368 	cancel_timeout(do_init6, client);
3369 	client->state = S_SELECTING;
3370 
3371 	/* Merge any bindings in the active lease (if there is one) into
3372 	 * the new active lease.
3373 	 */
3374 	dhc6_merge_lease(client->active_lease, lease);
3375 
3376 	/* Cleanup if a previous attempt to go bound failed. */
3377 	if (client->old_lease != NULL) {
3378 		dhc6_lease_destroy(&client->old_lease, MDL);
3379 		client->old_lease = NULL;
3380 	}
3381 
3382 	/* Make this lease active and BIND to it. */
3383 	if (client->active_lease != NULL)
3384 		client->old_lease = client->active_lease;
3385 	client->active_lease = lease;
3386 
3387 	/* We're done with the ADVERTISEd leases, if any. */
3388 	while(client->advertised_leases != NULL) {
3389 		lease = client->advertised_leases;
3390 		client->advertised_leases = lease->next;
3391 
3392 		dhc6_lease_destroy(&lease, MDL);
3393 	}
3394 
3395 	start_bound(client);
3396 }
3397 
3398 /* Find the 'best' lease in the cache of advertised leases (usually).  From
3399  * RFC3315 Section 17.1.3:
3400  *
3401  *   Upon receipt of one or more valid Advertise messages, the client
3402  *   selects one or more Advertise messages based upon the following
3403  *   criteria.
3404  *
3405  *   -  Those Advertise messages with the highest server preference value
3406  *      are preferred over all other Advertise messages.
3407  *
3408  *   -  Within a group of Advertise messages with the same server
3409  *      preference value, a client MAY select those servers whose
3410  *      Advertise messages advertise information of interest to the
3411  *      client.  For example, the client may choose a server that returned
3412  *      an advertisement with configuration options of interest to the
3413  *      client.
3414  *
3415  *   -  The client MAY choose a less-preferred server if that server has a
3416  *      better set of advertised parameters, such as the available
3417  *      addresses advertised in IAs.
3418  *
3419  * Note that the first and third contradict each other.  The third should
3420  * probably be taken to mean that the client should prefer answers that
3421  * offer bindings, even if that violates the preference rule.
3422  *
3423  * The above also isn't deterministic where there are ties.  So the final
3424  * tiebreaker we add, if all other values are equal, is to compare the
3425  * server identifiers and to select the numerically lower one.
3426  */
3427 static struct dhc6_lease *
dhc6_best_lease(struct client_state * client,struct dhc6_lease ** head)3428 dhc6_best_lease(struct client_state *client, struct dhc6_lease **head)
3429 {
3430 	struct dhc6_lease **rpos, *rval, **candp, *cand;
3431 	int cscore, rscore;
3432 
3433 	if (head == NULL || *head == NULL)
3434 		return NULL;
3435 
3436 	rpos = head;
3437 	rval = *rpos;
3438 	rscore = dhc6_score_lease(client, rval);
3439 	candp = &rval->next;
3440 	cand = *candp;
3441 
3442 	log_debug("PRC: Considering best lease.");
3443 	log_debug("PRC:  X-- Initial candidate %s (s: %d, p: %u).",
3444 		  print_hex_1(rval->server_id.len,
3445 			      rval->server_id.data, 48),
3446 		  rscore, (unsigned)rval->pref);
3447 
3448 	for (; cand != NULL ; candp = &cand->next, cand = *candp) {
3449 		cscore = dhc6_score_lease(client, cand);
3450 
3451 		log_debug("PRC:  X-- Candidate %s (s: %d, p: %u).",
3452 			  print_hex_1(cand->server_id.len,
3453 				      cand->server_id.data, 48),
3454 			  cscore, (unsigned)cand->pref);
3455 
3456 		/* Above you'll find quoted RFC3315 Section 17.1.3.
3457 		 *
3458 		 * The third clause tells us to give up on leases that
3459 		 * have no bindings even if their preference is better.
3460 		 * So where our 'selected' lease's score is less than
3461 		 * SCORE_MIN (1 ia + 1 addr), choose any candidate >= SCORE_MIN.
3462 		 *
3463 		 * The first clause tells us to make preference the primary
3464 		 * deciding factor.  So if it's lower, reject, if it's
3465 		 * higher, select.
3466 		 *
3467 		 * The second clause tells us where the preference is
3468 		 * equal, we should use 'our judgement' of what we like
3469 		 * to see in an advertisement primarily.
3470 		 *
3471 		 * But there can still be a tie.  To make this deterministic,
3472 		 * we compare the server identifiers and select the binary
3473 		 * lowest.
3474 		 *
3475 		 * Since server id's are unique in this list, there is
3476 		 * no further tie to break.
3477 		 */
3478 		if ((rscore < SCORE_MIN) && (cscore >= SCORE_MIN)) {
3479 			log_debug("PRC:  | X-- Selected, has bindings.");
3480 		} else if (cand->pref < rval->pref) {
3481 			log_debug("PRC:  | X-- Rejected, lower preference.");
3482 			continue;
3483 		} else if (cand->pref > rval->pref) {
3484 			log_debug("PRC:  | X-- Selected, higher preference.");
3485 		} else if (cscore > rscore) {
3486 			log_debug("PRC:  | X-- Selected, equal preference, "
3487 				  "higher score.");
3488 		} else if (cscore < rscore) {
3489 			log_debug("PRC:  | X-- Rejected, equal preference, "
3490 				  "lower score.");
3491 			continue;
3492 		} else if ((cand->server_id.len < rval->server_id.len) ||
3493 			   ((cand->server_id.len == rval->server_id.len) &&
3494 			    (memcmp(cand->server_id.data,
3495 				    rval->server_id.data,
3496 				    cand->server_id.len) < 0))) {
3497 			log_debug("PRC:  | X-- Selected, equal preference, "
3498 				  "equal score, binary lesser server ID.");
3499 		} else {
3500 			log_debug("PRC:  | X-- Rejected, equal preference, "
3501 				  "equal score, binary greater server ID.");
3502 			continue;
3503 		}
3504 
3505 		rpos = candp;
3506 		rval = cand;
3507 		rscore = cscore;
3508 	}
3509 
3510 	/* Remove the selected lease from the chain. */
3511 	*rpos = rval->next;
3512 
3513 	return rval;
3514 }
3515 
3516 /* Select a lease out of the advertised leases and setup state to try and
3517  * acquire that lease.
3518  */
3519 void
start_selecting6(struct client_state * client)3520 start_selecting6(struct client_state *client)
3521 {
3522 	struct dhc6_lease *lease;
3523 
3524 	if (client->advertised_leases == NULL) {
3525 		log_error("Can not enter DHCPv6 SELECTING state with no "
3526 			  "leases to select from!");
3527 		return;
3528 	}
3529 
3530 	log_debug("PRC: Selecting best advertised lease.");
3531 	client->state = S_SELECTING;
3532 
3533 	lease = dhc6_best_lease(client, &client->advertised_leases);
3534 
3535 	if (lease == NULL)
3536 		log_fatal("Impossible error at %s:%d.", MDL);
3537 
3538 	client->selected_lease = lease;
3539 
3540 	/* Set timers per RFC3315 section 18.1.1. */
3541 	client->IRT = REQ_TIMEOUT * 100;
3542 	client->MRT = REQ_MAX_RT * 100;
3543 	client->MRC = REQ_MAX_RC;
3544 	client->MRD = 0;
3545 
3546 	dhc6_retrans_init(client);
3547 
3548 	client->v6_handler = reply_handler;
3549 
3550 	/* ("re")transmit the first packet. */
3551 	do_select6(client);
3552 }
3553 
3554 /* Transmit a Request to select a lease offered in Advertisements.  In
3555  * the event of failure, either move on to the next-best advertised lease,
3556  * or head back to INIT state if there are none.
3557  */
3558 void
do_select6(void * input)3559 do_select6(void *input)
3560 {
3561 	struct client_state *client;
3562 	struct dhc6_lease *lease;
3563 	struct data_string ds;
3564 	struct timeval tv;
3565 	int send_ret, added;
3566 
3567 	client = input;
3568 
3569 	/* 'lease' is fewer characters to type. */
3570 	lease = client->selected_lease;
3571 	if (lease == NULL || lease->bindings == NULL) {
3572 		log_error("Illegal to attempt selection without selecting "
3573 			  "a lease.");
3574 		return;
3575 	}
3576 
3577 	switch(check_timing6(client, DHCPV6_REQUEST, "Request", lease, &ds)) {
3578 	      case CHK_TIM_MRC_EXCEEDED:
3579 	      case CHK_TIM_MRD_EXCEEDED:
3580 		log_debug("PRC: Lease %s failed.",
3581 			  print_hex_1(lease->server_id.len,
3582 				      lease->server_id.data, 56));
3583 
3584 		/* Get rid of the lease that timed/counted out. */
3585 		dhc6_lease_destroy(&lease, MDL);
3586 		client->selected_lease = NULL;
3587 
3588 		/* If there are more leases great.  If not, get more. */
3589 		if (client->advertised_leases != NULL)
3590 			start_selecting6(client);
3591 		else
3592 			start_init6(client);
3593 		return;
3594 	      case CHK_TIM_ALLOC_FAILURE:
3595 		return;
3596 	      case CHK_TIM_SUCCESS:
3597 		break;
3598 	}
3599 
3600 	/* Now make a packet that looks suspiciously like the one we
3601 	 * got from the server.  But different.
3602 	 *
3603 	 * XXX: I guess IAID is supposed to be something the client
3604 	 * indicates and uses as a key to its internal state.  It is
3605 	 * kind of odd to ask the server for IA's whose IAID the client
3606 	 * did not manufacture.  We first need a formal dhclient.conf
3607 	 * construct for the iaid, then we can delve into this matter
3608 	 * more properly.  In the time being, this will work.
3609 	 */
3610 
3611 	/* Fetch any configured 'sent' options (includes DUID) in wire format.
3612 	 */
3613 	dhcpv6_universe.encapsulate(&ds, NULL, NULL, client,
3614 				    NULL, client->sent_options, &global_scope,
3615 				    &dhcpv6_universe);
3616 
3617 	/* Now append any IA's, and within them any IAADDR/IAPREFIXs.
3618 	 * For each type of IA (na, ta, pd) we start with the ones for
3619 	 * which we already have addresses (dhc6_add_ia_xx) and then
3620 	 * if we still want more we add aditional IAs (dhc6_bare_ia_xx)
3621 	 */
3622 	if (wanted_ia_na &&
3623 	    ((dhc6_add_ia_na(client, &ds, lease, DHCPV6_REQUEST,
3624 			     wanted_ia_na, &added) != ISC_R_SUCCESS) ||
3625 	     (dhc6_bare_ia_xx(client, &ds, wanted_ia_na - added,
3626 			      D6O_IA_NA) != ISC_R_SUCCESS))) {
3627 		data_string_forget(&ds, MDL);
3628 		return;
3629 	}
3630 	if (wanted_ia_ta &&
3631 	    ((dhc6_add_ia_ta(client, &ds, lease, DHCPV6_REQUEST,
3632 			     wanted_ia_ta, &added) != ISC_R_SUCCESS) ||
3633 	     (dhc6_bare_ia_xx(client, &ds, wanted_ia_ta - added,
3634 			      D6O_IA_TA) != ISC_R_SUCCESS))) {
3635 		data_string_forget(&ds, MDL);
3636 		return;
3637 	}
3638 	if (wanted_ia_pd &&
3639 	    ((dhc6_add_ia_pd(client, &ds, lease, DHCPV6_REQUEST,
3640 			     wanted_ia_pd, &added) != ISC_R_SUCCESS) ||
3641 	     (dhc6_bare_ia_xx(client, &ds, wanted_ia_pd - added,
3642 			      D6O_IA_PD) != ISC_R_SUCCESS))) {
3643 		data_string_forget(&ds, MDL);
3644 		return;
3645 	}
3646 
3647 	log_info("XMT: Request on %s, interval %ld0ms.",
3648 		 client->name ? client->name : client->interface->name,
3649 		 (long int)client->RT);
3650 
3651 	send_ret = send_packet6(client->interface,
3652 				ds.data, ds.len, &DHCPv6DestAddr);
3653 	if (send_ret != ds.len) {
3654 		log_error("dhc6: send_packet6() sent %d of %d bytes",
3655 			  send_ret, ds.len);
3656 	}
3657 
3658 	data_string_forget(&ds, MDL);
3659 
3660 	/* Wait RT */
3661 	tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
3662 	tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
3663 	if (tv.tv_usec >= 1000000) {
3664 		tv.tv_sec += 1;
3665 		tv.tv_usec -= 1000000;
3666 	}
3667 	add_timeout(&tv, do_select6, client, NULL, NULL);
3668 
3669 	dhc6_retrans_advance(client);
3670 }
3671 
3672 /*!
3673  *
3674  * \brief Count the number of IAs in the bindings
3675  *
3676  * \param lease  the lease to count
3677  * \param ia_type the type of the IA we wish to count
3678  *
3679  * \return The number of IAs of the specified type we found
3680  */
3681 static int
dhc6_count_ia(struct dhc6_lease * lease,u_int16_t ia_type)3682 dhc6_count_ia(struct dhc6_lease *lease, u_int16_t ia_type)
3683 {
3684 	struct dhc6_ia *ia;
3685 	int i = 0;
3686 
3687 	for (ia = lease->bindings; ia != NULL; ia = ia->next) {
3688 		if (ia->ia_type == ia_type)
3689 			/* bump the counter for the correct types */
3690 			i++;
3691 	}
3692 
3693 	return (i);
3694 }
3695 
3696 /*!
3697  *
3698  * \brief Add IA_NA information from the lease to the packet
3699  * we are building.
3700  *
3701  * Walk through the lease and for each IA_NA in the lease
3702  * and for each address in the IA_NA append that information
3703  * onto the packet-so-far.  If wanted is 0 include all IA_NAs
3704  * in the lease if wanted is non-zero include only that many
3705  * IA_NAs (this may occur if sommebody restarts a client with
3706  * arugments for a smaller number of NAs than before).
3707  *
3708  * \param client = the state of the entire client
3709  * \param packet = the packet we are building and where we
3710  *                 shall append the IA_NAs we create
3711  * \param lease  = the current lease
3712  * \param message = the type of the packet
3713  * \param wanted  = the number of IA_NAs to include in the packet
3714  *                  0 means include all
3715  * \param added   = the number of IA_NAs that were added to the packet
3716  *
3717  * \return ISC_R_SUCCESS - all is well continue, any other return
3718  *                         indicates an error (most likely memory issues)
3719  *                         and the packet should be tossed.
3720  */
3721 static isc_result_t
dhc6_add_ia_na(struct client_state * client,struct data_string * packet,struct dhc6_lease * lease,u_int8_t message,int wanted,int * added)3722 dhc6_add_ia_na(struct client_state *client, struct data_string *packet,
3723 	       struct dhc6_lease *lease, u_int8_t message,
3724 	       int wanted, int *added)
3725 {
3726 	struct data_string iads;
3727 	struct data_string addrds;
3728 	struct dhc6_addr *addr;
3729 	struct dhc6_ia *ia;
3730 	isc_result_t rval = ISC_R_SUCCESS;
3731 	TIME t1, t2;
3732 	int i;
3733 
3734 	*added = 0;
3735 	memset(&iads, 0, sizeof(iads));
3736 	memset(&addrds, 0, sizeof(addrds));
3737 	for (ia = lease->bindings, i = 0;
3738 	     ia != NULL && rval == ISC_R_SUCCESS && (wanted == 0 || i < wanted);
3739 	     ia = ia->next) {
3740 		if (ia->ia_type != D6O_IA_NA)
3741 			continue;
3742 
3743 		/* Now that we know this is an NA bump the counter */
3744 		i++;
3745 
3746 		if (!buffer_allocate(&iads.buffer, 12, MDL)) {
3747 			log_error("Unable to allocate memory for IA_NA.");
3748 			rval = ISC_R_NOMEMORY;
3749 			break;
3750 		}
3751 
3752 		/* Copy the IAID into the packet buffer. */
3753 		memcpy(iads.buffer->data, ia->iaid, 4);
3754 		iads.data = iads.buffer->data;
3755 		iads.len = 12;
3756 
3757 		switch (message) {
3758 		      case DHCPV6_REQUEST:
3759 		      case DHCPV6_RENEW:
3760 		      case DHCPV6_REBIND:
3761 
3762 			t1 = client->config->requested_lease / 2;
3763 			t2 = t1 + (t1 / 2);
3764 #if MAX_TIME > 0xffffffff
3765 			if (t1 > 0xffffffff)
3766 				t1 = 0xffffffff;
3767 			if (t2 > 0xffffffff)
3768 				t2 = 0xffffffff;
3769 #endif
3770 			putULong(iads.buffer->data + 4, t1);
3771 			putULong(iads.buffer->data + 8, t2);
3772 
3773 			log_debug("XMT:  X-- IA_NA %s",
3774 				  print_hex_1(4, iads.data, 59));
3775 			log_debug("XMT:  | X-- Requested renew  +%u",
3776 				  (unsigned) t1);
3777 			log_debug("XMT:  | X-- Requested rebind +%u",
3778 				  (unsigned) t2);
3779 			break;
3780 
3781 		      case DHCPV6_CONFIRM:
3782 		      case DHCPV6_RELEASE:
3783 		      case DHCPV6_DECLINE:
3784 			/* Set t1 and t2 to zero; server will ignore them */
3785 			memset(iads.buffer->data + 4, 0, 8);
3786 			log_debug("XMT:  X-- IA_NA %s",
3787 				  print_hex_1(4, iads.buffer->data, 55));
3788 
3789 			break;
3790 
3791 		      default:
3792 			log_fatal("Impossible condition at %s:%d.", MDL);
3793 		}
3794 
3795 		for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
3796 			/*
3797 			 * Do not confirm expired addresses, do not request
3798 			 * expired addresses (but we keep them around for
3799 			 * solicit).
3800 			 */
3801 			if (addr->flags & DHC6_ADDR_EXPIRED)
3802 				continue;
3803 
3804 			if (addr->address.len != 16) {
3805 				log_error("Illegal IPv6 address length (%d), "
3806 					  "ignoring.  (%s:%d)",
3807 					  addr->address.len, MDL);
3808 				continue;
3809 			}
3810 
3811 			if (!buffer_allocate(&addrds.buffer, 24, MDL)) {
3812 				log_error("Unable to allocate memory for "
3813 					  "IAADDR.");
3814 				rval = ISC_R_NOMEMORY;
3815 				break;
3816 			}
3817 
3818 			addrds.data = addrds.buffer->data;
3819 			addrds.len = 24;
3820 
3821 			/* Copy the address into the packet buffer. */
3822 			memcpy(addrds.buffer->data, addr->address.iabuf, 16);
3823 
3824 			/* Copy in additional information as appropriate */
3825 			switch (message) {
3826 			      case DHCPV6_REQUEST:
3827 			      case DHCPV6_RENEW:
3828 			      case DHCPV6_REBIND:
3829 				t1 = client->config->requested_lease;
3830 				t2 = t1 + 300;
3831 				putULong(addrds.buffer->data + 16, t1);
3832 				putULong(addrds.buffer->data + 20, t2);
3833 
3834 				log_debug("XMT:  | | X-- IAADDR %s",
3835 					  piaddr(addr->address));
3836 				log_debug("XMT:  | | | X-- Preferred "
3837 					  "lifetime +%u", (unsigned)t1);
3838 				log_debug("XMT:  | | | X-- Max lifetime +%u",
3839 					  (unsigned)t2);
3840 
3841 				break;
3842 
3843 			      case DHCPV6_CONFIRM:
3844 				/*
3845 				 * Set preferred and max life to zero,
3846 				 * per 17.1.3.
3847 				 */
3848 				memset(addrds.buffer->data + 16, 0, 8);
3849 				log_debug("XMT:  | X-- Confirm Address %s",
3850 					  piaddr(addr->address));
3851 				break;
3852 
3853 			      case DHCPV6_RELEASE:
3854 				/* Preferred and max life are irrelevant */
3855 				memset(addrds.buffer->data + 16, 0, 8);
3856 				log_debug("XMT:  | X-- Release Address %s",
3857 					  piaddr(addr->address));
3858 				break;
3859 
3860 			      case DHCPV6_DECLINE:
3861 				/* Preferred and max life are irrelevant */
3862 				memset(addrds.buffer->data + 16, 0, 8);
3863 				log_debug("XMT:  | X-- Decline Address %s",
3864 					  piaddr(addr->address));
3865 				break;
3866 
3867 			      default:
3868 				log_fatal("Impossible condition at %s:%d.",
3869 					  MDL);
3870 			}
3871 
3872 			append_option(&iads, &dhcpv6_universe, iaaddr_option,
3873 				      &addrds);
3874 			data_string_forget(&addrds, MDL);
3875 		}
3876 
3877 		/*
3878 		 * It doesn't make sense to make a request without an
3879 		 * address.
3880 		 */
3881 		if (ia->addrs == NULL) {
3882 			log_debug("!!!:  V IA_NA has no IAADDRs - removed.");
3883 			rval = ISC_R_FAILURE;
3884 		} else if (rval == ISC_R_SUCCESS) {
3885 			log_debug("XMT:  V IA_NA appended.");
3886 			append_option(packet, &dhcpv6_universe, ia_na_option,
3887 				      &iads);
3888 		}
3889 
3890 		data_string_forget(&iads, MDL);
3891 	}
3892 
3893 	if (rval == ISC_R_SUCCESS)
3894 		*added = i;
3895 
3896 	return (rval);
3897 }
3898 
3899 /*!
3900  *
3901  * \brief Add IA_TA information from the lease to the packet
3902  * we are building.
3903  *
3904  * Walk through the lease and for each IA_TA in the lease
3905  * and for each address in the IA_TA append that information
3906  * onto the packet-so-far.  If wanted is 0 include all IA_TAs
3907  * in the lease if wanted is non-zero include only that many
3908  * IA_TAs (this may occur if sommebody restarts a client with
3909  * arugments for a smaller number of TAs than before).
3910  *
3911  * \param client = the state of the entire client
3912  * \param packet = the packet we are building and where we
3913  *                 shall append the IA_TAs we create
3914  * \param lease  = the current lease
3915  * \param message = the type of the packet
3916  * \param wanted  = the number of IA_TAs to include in the packet
3917  *                  0 means include all
3918  * \param added   = the number of IA_TAs that were added to the packet
3919  *
3920  * \return ISC_R_SUCCESS - all is well continue, any other return
3921  *                         indicates an error (most likely memory issues)
3922  *                         and the packet should be tossed.
3923  */
3924 static isc_result_t
dhc6_add_ia_ta(struct client_state * client,struct data_string * packet,struct dhc6_lease * lease,u_int8_t message,int wanted,int * added)3925 dhc6_add_ia_ta(struct client_state *client, struct data_string *packet,
3926 	       struct dhc6_lease *lease, u_int8_t message,
3927 	       int wanted, int *added)
3928 {
3929 	struct data_string iads;
3930 	struct data_string addrds;
3931 	struct dhc6_addr *addr;
3932 	struct dhc6_ia *ia;
3933 	isc_result_t rval = ISC_R_SUCCESS;
3934 	TIME t1, t2;
3935 	int i;
3936 
3937 	*added = 0;
3938 	memset(&iads, 0, sizeof(iads));
3939 	memset(&addrds, 0, sizeof(addrds));
3940 	for (ia = lease->bindings, i = 0;
3941 	     ia != NULL && rval == ISC_R_SUCCESS && (wanted == 0 || i < wanted);
3942 	     ia = ia->next) {
3943 		if (ia->ia_type != D6O_IA_TA)
3944 			continue;
3945 
3946 		/* Now that we know this is an TA bump the counter */
3947 		i++;
3948 
3949 		if (!buffer_allocate(&iads.buffer, 4, MDL)) {
3950 			log_error("Unable to allocate memory for IA_TA.");
3951 			rval = ISC_R_NOMEMORY;
3952 			break;
3953 		}
3954 
3955 		/* Copy the IAID into the packet buffer. */
3956 		memcpy(iads.buffer->data, ia->iaid, 4);
3957 		iads.data = iads.buffer->data;
3958 		iads.len = 4;
3959 
3960 		log_debug("XMT:  X-- IA_TA %s",
3961 			  print_hex_1(4, iads.buffer->data, 55));
3962 
3963 		for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
3964 			/*
3965 			 * Do not confirm expired addresses, do not request
3966 			 * expired addresses (but we keep them around for
3967 			 * solicit).
3968 			 */
3969 			if (addr->flags & DHC6_ADDR_EXPIRED)
3970 				continue;
3971 
3972 			if (addr->address.len != 16) {
3973 				log_error("Illegal IPv6 address length (%d), "
3974 					  "ignoring.  (%s:%d)",
3975 					  addr->address.len, MDL);
3976 				continue;
3977 			}
3978 
3979 			if (!buffer_allocate(&addrds.buffer, 24, MDL)) {
3980 				log_error("Unable to allocate memory for "
3981 					  "IAADDR.");
3982 				rval = ISC_R_NOMEMORY;
3983 				break;
3984 			}
3985 
3986 			addrds.data = addrds.buffer->data;
3987 			addrds.len = 24;
3988 
3989 			/* Copy the address into the packet buffer. */
3990 			memcpy(addrds.buffer->data, addr->address.iabuf, 16);
3991 
3992 			/* Copy in additional information as appropriate */
3993 			switch (message) {
3994 			      case DHCPV6_REQUEST:
3995 			      case DHCPV6_RENEW:
3996 			      case DHCPV6_REBIND:
3997 				t1 = client->config->requested_lease;
3998 				t2 = t1 + 300;
3999 				putULong(addrds.buffer->data + 16, t1);
4000 				putULong(addrds.buffer->data + 20, t2);
4001 
4002 				log_debug("XMT:  | | X-- IAADDR %s",
4003 					  piaddr(addr->address));
4004 				log_debug("XMT:  | | | X-- Preferred "
4005 					  "lifetime +%u", (unsigned)t1);
4006 				log_debug("XMT:  | | | X-- Max lifetime +%u",
4007 					  (unsigned)t2);
4008 
4009 				break;
4010 
4011 			      case DHCPV6_CONFIRM:
4012 				/*
4013 				 * Set preferred and max life to zero,
4014 				 * per 17.1.3.
4015 				 */
4016 				memset(addrds.buffer->data + 16, 0, 8);
4017 				log_debug("XMT:  | X-- Confirm Address %s",
4018 					  piaddr(addr->address));
4019 				break;
4020 
4021 			      case DHCPV6_RELEASE:
4022 				/* Preferred and max life are irrelevant */
4023 				memset(addrds.buffer->data + 16, 0, 8);
4024 				log_debug("XMT:  | X-- Release Address %s",
4025 					  piaddr(addr->address));
4026 				break;
4027 
4028 			      default:
4029 				log_fatal("Impossible condition at %s:%d.",
4030 					  MDL);
4031 			}
4032 
4033 			append_option(&iads, &dhcpv6_universe, iaaddr_option,
4034 				      &addrds);
4035 			data_string_forget(&addrds, MDL);
4036 		}
4037 
4038 		/*
4039 		 * It doesn't make sense to make a request without an
4040 		 * address.
4041 		 */
4042 		if (ia->addrs == NULL) {
4043 			log_debug("!!!:  V IA_TA has no IAADDRs - removed.");
4044 			rval = ISC_R_FAILURE;
4045 		} else if (rval == ISC_R_SUCCESS) {
4046 			log_debug("XMT:  V IA_TA appended.");
4047 			append_option(packet, &dhcpv6_universe, ia_ta_option,
4048 				      &iads);
4049 		}
4050 
4051 		data_string_forget(&iads, MDL);
4052 	}
4053 
4054 	if (rval == ISC_R_SUCCESS)
4055 		*added = i;
4056 
4057 	return (rval);
4058 }
4059 
4060 /*!
4061  *
4062  * \brief Add IA_PD information from the lease to the packet
4063  * we are building.
4064  *
4065  * Walk through the lease and for each IA_PD in the lease
4066  * and for each address in the IA_PD append that information
4067  * onto the packet-so-far.  If wanted is 0 include all IA_PDs
4068  * in the lease if wanted is non-zero include only that many
4069  * IA_PDs (this may occur if sommebody restarts a client with
4070  * arugments for a smaller number of PDs than before).
4071  *
4072  * \param client = the state of the entire client
4073  * \param packet = the packet we are building and where we
4074  *                 shall append the IA_PDs we create
4075  * \param lease  = the current lease
4076  * \param message = the type of the packet
4077  * \param wanted  = the number of IA_PDs to include in the packet
4078  *                  0 means include all
4079  * \param added   = the number of IA_PDs that were added to the packet
4080  *
4081  * \return ISC_R_SUCCESS - all is well continue, any other return
4082  *                         indicates an error (most likely memory issues)
4083  *                         and the packet should be tossed.
4084  */
4085 static isc_result_t
dhc6_add_ia_pd(struct client_state * client,struct data_string * packet,struct dhc6_lease * lease,u_int8_t message,int wanted,int * added)4086 dhc6_add_ia_pd(struct client_state *client, struct data_string *packet,
4087 	       struct dhc6_lease *lease, u_int8_t message,
4088 	       int wanted, int *added)
4089 {
4090 	struct data_string iads;
4091 	struct data_string prefds;
4092 	struct dhc6_addr *pref;
4093 	struct dhc6_ia *ia;
4094 	isc_result_t rval = ISC_R_SUCCESS;
4095 	TIME t1, t2;
4096 	int i;
4097 
4098 	*added = 0;
4099 	memset(&iads, 0, sizeof(iads));
4100 	memset(&prefds, 0, sizeof(prefds));
4101 	for (ia = lease->bindings, i = 0;
4102 	     ia != NULL && rval == ISC_R_SUCCESS && (wanted == 0 || i < wanted);
4103 	     ia = ia->next) {
4104 		if (ia->ia_type != D6O_IA_PD)
4105 			continue;
4106 
4107 		/* Now that we know this is an PD bump the counter */
4108 		i++;
4109 
4110 		if (!buffer_allocate(&iads.buffer, 12, MDL)) {
4111 			log_error("Unable to allocate memory for IA_PD.");
4112 			rval = ISC_R_NOMEMORY;
4113 			break;
4114 		}
4115 
4116 		/* Copy the IAID into the packet buffer. */
4117 		memcpy(iads.buffer->data, ia->iaid, 4);
4118 		iads.data = iads.buffer->data;
4119 		iads.len = 12;
4120 
4121 		switch (message) {
4122 		      case DHCPV6_REQUEST:
4123 		      case DHCPV6_RENEW:
4124 		      case DHCPV6_REBIND:
4125 
4126 			t1 = client->config->requested_lease / 2;
4127 			t2 = t1 + (t1 / 2);
4128 #if MAX_TIME > 0xffffffff
4129 			if (t1 > 0xffffffff)
4130 				t1 = 0xffffffff;
4131 			if (t2 > 0xffffffff)
4132 				t2 = 0xffffffff;
4133 #endif
4134 			putULong(iads.buffer->data + 4, t1);
4135 			putULong(iads.buffer->data + 8, t2);
4136 
4137 			log_debug("XMT:  X-- IA_PD %s",
4138 				  print_hex_1(4, iads.data, 59));
4139 			log_debug("XMT:  | X-- Requested renew  +%u",
4140 				  (unsigned) t1);
4141 			log_debug("XMT:  | X-- Requested rebind +%u",
4142 				  (unsigned) t2);
4143 			break;
4144 
4145 		      case DHCPV6_RELEASE:
4146 			/* Set t1 and t2 to zero; server will ignore them */
4147 			memset(iads.buffer->data + 4, 0, 8);
4148 			log_debug("XMT:  X-- IA_PD %s",
4149 				  print_hex_1(4, iads.buffer->data, 55));
4150 
4151 			break;
4152 
4153 		      default:
4154 			log_fatal("Impossible condition at %s:%d.", MDL);
4155 		}
4156 
4157 		for (pref = ia->addrs ; pref != NULL ; pref = pref->next) {
4158 			/*
4159 			 * Do not confirm expired prefixes, do not request
4160 			 * expired prefixes (but we keep them around for
4161 			 * solicit).
4162 			 */
4163 			if (pref->flags & DHC6_ADDR_EXPIRED)
4164 				continue;
4165 
4166 			if (pref->address.len != 16) {
4167 				log_error("Illegal IPv6 prefix "
4168 					  "ignoring.  (%s:%d)",
4169 					  MDL);
4170 				continue;
4171 			}
4172 
4173 			if (pref->plen == 0) {
4174 				log_info("Null IPv6 prefix, "
4175 					 "ignoring. (%s:%d)",
4176 					 MDL);
4177 			}
4178 
4179 			if (!buffer_allocate(&prefds.buffer, 25, MDL)) {
4180 				log_error("Unable to allocate memory for "
4181 					  "IAPREFIX.");
4182 				rval = ISC_R_NOMEMORY;
4183 				break;
4184 			}
4185 
4186 			prefds.data = prefds.buffer->data;
4187 			prefds.len = 25;
4188 
4189 			/* Copy the prefix into the packet buffer. */
4190 			putUChar(prefds.buffer->data + 8, pref->plen);
4191 			memcpy(prefds.buffer->data + 9,
4192 			       pref->address.iabuf,
4193 			       16);
4194 
4195 			/* Copy in additional information as appropriate */
4196 			switch (message) {
4197 			      case DHCPV6_REQUEST:
4198 			      case DHCPV6_RENEW:
4199 			      case DHCPV6_REBIND:
4200 				t1 = client->config->requested_lease;
4201 				t2 = t1 + 300;
4202 				putULong(prefds.buffer->data, t1);
4203 				putULong(prefds.buffer->data + 4, t2);
4204 
4205 				log_debug("XMT:  | | X-- IAPREFIX %s/%u",
4206 					  piaddr(pref->address),
4207 					  (unsigned) pref->plen);
4208 				log_debug("XMT:  | | | X-- Preferred "
4209 					  "lifetime +%u", (unsigned)t1);
4210 				log_debug("XMT:  | | | X-- Max lifetime +%u",
4211 					  (unsigned)t2);
4212 
4213 				break;
4214 
4215 			      case DHCPV6_RELEASE:
4216 				/* Preferred and max life are irrelevant */
4217 				memset(prefds.buffer->data, 0, 8);
4218 				log_debug("XMT:  | X-- Release Prefix %s/%u",
4219 					  piaddr(pref->address),
4220 					  (unsigned) pref->plen);
4221 				break;
4222 
4223 			      default:
4224 				log_fatal("Impossible condition at %s:%d.",
4225 					  MDL);
4226 			}
4227 
4228 			append_option(&iads, &dhcpv6_universe,
4229 				      iaprefix_option, &prefds);
4230 			data_string_forget(&prefds, MDL);
4231 		}
4232 
4233 		/*
4234 		 * It doesn't make sense to make a request without an
4235 		 * address.
4236 		 */
4237 		if (ia->addrs == NULL) {
4238 			log_debug("!!!:  V IA_PD has no IAPREFIXs - removed.");
4239 			rval = ISC_R_FAILURE;
4240 		} else if (rval == ISC_R_SUCCESS) {
4241 			log_debug("XMT:  V IA_PD appended.");
4242 			append_option(packet, &dhcpv6_universe,
4243 				      ia_pd_option, &iads);
4244 		}
4245 
4246 		data_string_forget(&iads, MDL);
4247 	}
4248 
4249 	if (rval == ISC_R_SUCCESS)
4250 		*added = i;
4251 
4252 	return (rval);
4253 }
4254 
4255 /* stopping_finished() checks if there is a remaining work to do.
4256  */
4257 static isc_boolean_t
stopping_finished(void)4258 stopping_finished(void)
4259 {
4260 	struct interface_info *ip;
4261 	struct client_state *client;
4262 
4263 	for (ip = interfaces; ip; ip = ip -> next) {
4264 		for (client = ip -> client; client; client = client -> next) {
4265 			if (client->state != S_STOPPED)
4266 				return ISC_FALSE;
4267 			if (client->active_lease != NULL)
4268 				return ISC_FALSE;
4269 		}
4270 	}
4271 	return ISC_TRUE;
4272 }
4273 
4274 /* reply_handler() accepts a Reply while we're attempting Select or Renew or
4275  * Rebind.  Basically any Reply packet.
4276  */
4277 void
reply_handler(struct packet * packet,struct client_state * client)4278 reply_handler(struct packet *packet, struct client_state *client)
4279 {
4280 	struct dhc6_lease *lease;
4281 	isc_result_t check_status;
4282 
4283 	if (packet->dhcpv6_msg_type != DHCPV6_REPLY)
4284 		return;
4285 
4286 	/* RFC3315 section 15.10 validation (same as 15.3 since we
4287 	 * always include a client id).
4288 	 */
4289 	if (!valid_reply(packet, client)) {
4290 		log_error("Invalid Reply - rejecting.");
4291 		return;
4292 	}
4293 
4294 	lease = dhc6_leaseify(packet, client);
4295 
4296 	/* Out of memory or corrupt packet condition...hopefully a temporary
4297 	 * problem.  Returning now makes us try to retransmit later.
4298 	 */
4299 	if (lease == NULL)
4300 		return;
4301 
4302 	check_status = dhc6_check_reply(client, lease);
4303 	if (check_status != ISC_R_SUCCESS) {
4304 		dhc6_lease_destroy(&lease, MDL);
4305 
4306 		/* If no action was taken, but there is an error, then
4307 		 * we wait for a retransmission.
4308 		 */
4309 		if (check_status != ISC_R_CANCELED)
4310 			return;
4311 	}
4312 
4313 	/* We're done retransmitting at this point. */
4314 	cancel_timeout(do_confirm6, client);
4315 	cancel_timeout(do_select6, client);
4316 	cancel_timeout(do_refresh6, client);
4317 	cancel_timeout(do_release6, client);
4318 	cancel_timeout(do_decline6, client);
4319 
4320 	/* If this is in response to a Release, clean up and return. */
4321 	if (client->state == S_STOPPED) {
4322 		if (client->active_lease != NULL) {
4323 			dhc6_lease_destroy(&client->active_lease, MDL);
4324 			client->active_lease = NULL;
4325 			/* We should never wait for nothing!? */
4326 			if (stopping_finished()) {
4327 				finish(0);
4328 			}
4329 		}
4330 
4331 		return;
4332 	}
4333 
4334 	if (client->state == S_DECLINING) {
4335 		/* Weed thru the lease and delete all declined addresses.
4336 		 * Toss the lease if there aren't any addresses left */
4337 		int live_cnt = drop_declined_addrs(client->active_lease);
4338 		if (live_cnt == 0) {
4339 			dhc6_lease_destroy(&client->active_lease, MDL);
4340 			client->active_lease = NULL;
4341 		}
4342 
4343 		/* Solicit with any live addresses we have so far, and
4344 		* add additional empty NA iasubopts for those we had
4345 		* to decline. */
4346 		start_init6(client);
4347 		return;
4348 	}
4349 
4350 	/* Action was taken, so now that we've torn down our scheduled
4351 	 * retransmissions, return.
4352 	 */
4353 	if (check_status == ISC_R_CANCELED)
4354 		return;
4355 
4356 	if (client->selected_lease != NULL) {
4357 		dhc6_lease_destroy(&client->selected_lease, MDL);
4358 		client->selected_lease = NULL;
4359 	}
4360 
4361 	/* If this is in response to a confirm, we use the lease we've
4362 	 * already got, not the reply we were sent.
4363 	 */
4364 	if (client->state == S_REBOOTING) {
4365 		if (client->active_lease == NULL)
4366 			log_fatal("Impossible condition at %s:%d.", MDL);
4367 
4368 		dhc6_lease_destroy(&lease, MDL);
4369 		start_bound(client);
4370 		return;
4371 	}
4372 
4373 	/* Merge any bindings in the active lease (if there is one) into
4374 	 * the new active lease.
4375 	 */
4376 	dhc6_merge_lease(client->active_lease, lease);
4377 
4378 	/* Cleanup if a previous attempt to go bound failed. */
4379 	if (client->old_lease != NULL) {
4380 		dhc6_lease_destroy(&client->old_lease, MDL);
4381 		client->old_lease = NULL;
4382 	}
4383 
4384 	/* Make this lease active and BIND to it. */
4385 	if (client->active_lease != NULL)
4386 		client->old_lease = client->active_lease;
4387 	client->active_lease = lease;
4388 
4389 	/* We're done with the ADVERTISEd leases, if any. */
4390 	while(client->advertised_leases != NULL) {
4391 		lease = client->advertised_leases;
4392 		client->advertised_leases = lease->next;
4393 
4394 		dhc6_lease_destroy(&lease, MDL);
4395 	}
4396 
4397 	start_bound(client);
4398 }
4399 
4400 /* DHCPv6 packets are a little sillier than they needed to be - the root
4401  * packet contains options, then IA's which contain options, then within
4402  * that IAADDR's which contain options.
4403  *
4404  * To sort this out at dhclient-script time (which fetches config parameters
4405  * in environment variables), start_bound() iterates over each IAADDR, and
4406  * calls this function to marshall an environment variable set that includes
4407  * the most-specific option values related to that IAADDR in particular.
4408  *
4409  * To achieve this, we load environment variables for the root options space,
4410  * then the IA, then the IAADDR.  Any duplicate option names will be
4411  * over-written by the later versions.
4412  */
4413 static void
dhc6_marshall_values(const char * prefix,struct client_state * client,struct dhc6_lease * lease,struct dhc6_ia * ia,struct dhc6_addr * addr)4414 dhc6_marshall_values(const char *prefix, struct client_state *client,
4415 		     struct dhc6_lease *lease, struct dhc6_ia *ia,
4416 		     struct dhc6_addr *addr)
4417 {
4418 	/* Option cache contents, in descending order of
4419 	 * scope.
4420 	 */
4421 	if ((lease != NULL) && (lease->options != NULL))
4422 		script_write_params6(client, prefix, lease->options);
4423 	if ((ia != NULL) && (ia->options != NULL))
4424 		script_write_params6(client, prefix, ia->options);
4425 	if ((addr != NULL) && (addr->options != NULL))
4426 		script_write_params6(client, prefix, addr->options);
4427 
4428 	/* addr fields. */
4429 	if (addr != NULL) {
4430 		if ((ia != NULL) && (ia->ia_type == D6O_IA_PD)) {
4431 			client_envadd(client, prefix,
4432 				      "ip6_prefix", "%s/%u",
4433 				      piaddr(addr->address),
4434 				      (unsigned) addr->plen);
4435 		} else {
4436 			client_envadd(client, prefix, "ip6_prefixlen",
4437 				      "%d", address_prefix_len);
4438 			client_envadd(client, prefix, "ip6_address",
4439 				      "%s", piaddr(addr->address));
4440 		}
4441 		if ((ia != NULL) && (ia->ia_type == D6O_IA_TA)) {
4442 			client_envadd(client, prefix,
4443 				      "ip6_type", "temporary");
4444 		}
4445 		client_envadd(client, prefix, "life_starts", "%d",
4446 			      (int)(addr->starts));
4447 		client_envadd(client, prefix, "preferred_life", "%u",
4448 			      addr->preferred_life);
4449 		client_envadd(client, prefix, "max_life", "%u",
4450 			      addr->max_life);
4451 	}
4452 
4453 	/* ia fields. */
4454 	if (ia != NULL) {
4455 		client_envadd(client, prefix, "iaid", "%s",
4456 			      print_hex_1(4, ia->iaid, 12));
4457 		client_envadd(client, prefix, "starts", "%d",
4458 			      (int)(ia->starts));
4459 		client_envadd(client, prefix, "renew", "%u", ia->renew);
4460 		client_envadd(client, prefix, "rebind", "%u", ia->rebind);
4461 	}
4462 }
4463 
4464 /* Look at where the client's active lease is sitting.  If it's looking to
4465  * time out on renew, rebind, depref, or expiration, do those things.
4466  */
4467 static void
dhc6_check_times(struct client_state * client)4468 dhc6_check_times(struct client_state *client)
4469 {
4470 	struct dhc6_lease *lease;
4471 	struct dhc6_ia *ia;
4472 	struct dhc6_addr *addr;
4473 	TIME renew=MAX_TIME, rebind=MAX_TIME, depref=MAX_TIME,
4474 	     lo_expire=MAX_TIME, hi_expire=0, max_ia_starts = 0, tmp;
4475 	int has_addrs = ISC_FALSE;
4476 	int has_preferred_addrs = ISC_FALSE;
4477 	struct timeval tv;
4478 
4479 	lease = client->active_lease;
4480 
4481 	/* Bit spammy.  We should probably keep record of scheduled
4482 	 * events instead.
4483 	 */
4484 	cancel_timeout(start_renew6, client);
4485 	cancel_timeout(start_rebind6, client);
4486 	cancel_timeout(do_depref, client);
4487 	cancel_timeout(do_expire, client);
4488 
4489 	for(ia = lease->bindings ; ia != NULL ; ia = ia->next) {
4490 		TIME this_ia_lo_expire, this_ia_hi_expire, use_expire;
4491 
4492 		this_ia_lo_expire = MAX_TIME;
4493 		this_ia_hi_expire = 0;
4494 
4495 		for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
4496 			if(!(addr->flags & DHC6_ADDR_DEPREFFED)) {
4497 				if (addr->preferred_life == 0xffffffff)
4498 					tmp = MAX_TIME;
4499 				else
4500 					tmp = addr->starts +
4501 					      addr->preferred_life;
4502 
4503 				if (tmp < depref)
4504 					depref = tmp;
4505 
4506 				if (!(addr->flags & DHC6_ADDR_EXPIRED)) {
4507 					has_preferred_addrs = ISC_TRUE;
4508 				}
4509 			}
4510 
4511 			if (!(addr->flags & DHC6_ADDR_EXPIRED)) {
4512 				/* Find EPOCH-relative expiration. */
4513 				if (addr->max_life == 0xffffffff)
4514 					tmp = MAX_TIME;
4515 				else
4516 					tmp = addr->starts + addr->max_life;
4517 
4518 				/* Make the times ia->starts relative. */
4519 				tmp -= ia->starts;
4520 
4521 				if (tmp > this_ia_hi_expire)
4522 					this_ia_hi_expire = tmp;
4523 				if (tmp < this_ia_lo_expire)
4524 					this_ia_lo_expire = tmp;
4525 
4526 				has_addrs = ISC_TRUE;
4527 			}
4528 		}
4529 
4530 		/* These times are ia->starts relative. */
4531 		if (this_ia_lo_expire <= (this_ia_hi_expire / 2))
4532 			use_expire = this_ia_hi_expire;
4533 		else
4534 			use_expire = this_ia_lo_expire;
4535 
4536 		/*
4537 		 * If the auto-selected expiration time is "infinite", or
4538 		 * zero, assert a reasonable default.
4539 		 */
4540 		if ((use_expire == MAX_TIME) || (use_expire <= 1))
4541 			use_expire = client->config->requested_lease / 2;
4542 		else
4543 			use_expire /= 2;
4544 
4545 		/* Don't renew/rebind temporary addresses. */
4546 		/* For NA and PD we find the most recent IA and the smallest
4547 		 * values for the renew and rebind then base the timer on
4548 		 * the sum of the them.
4549 		 * Normally all the IAs will have the same time as they
4550 		 * are requested and served as a group but in some cases the
4551 		 * client isn't asking for all of the IAs (for example
4552 		 * restarted with a different set of arguments) or the server
4553 		 * isn't updating the client on all of them (probably a
4554 		 * broken server).
4555 		 */
4556 		if (ia->ia_type != D6O_IA_TA) {
4557 			if (ia->starts > max_ia_starts)
4558 				max_ia_starts = ia->starts;
4559 
4560 			if (ia->renew == 0) {
4561 				tmp = use_expire;
4562 			} else if (ia->renew == 0xffffffff)
4563 				tmp = MAX_TIME;
4564 			else
4565 				tmp = ia->renew;
4566 
4567 			if (tmp < renew)
4568 				renew = tmp;
4569 
4570 			if (ia->rebind == 0) {
4571 				/* Set rebind to 3/4 expiration interval. */
4572 				tmp = use_expire + (use_expire / 2);
4573 			} else if (ia->rebind == 0xffffffff)
4574 				tmp = MAX_TIME;
4575 			else
4576 				tmp = ia->rebind;
4577 
4578 			if (tmp < rebind)
4579 				rebind = tmp;
4580 		}
4581 
4582 		/*
4583 		 * Return expiration ranges to EPOCH relative for event
4584 		 * scheduling (add_timeout()).
4585 		 */
4586 		this_ia_hi_expire += ia->starts;
4587 		this_ia_lo_expire += ia->starts;
4588 
4589 		if (this_ia_hi_expire > hi_expire)
4590 			hi_expire = this_ia_hi_expire;
4591 		if (this_ia_lo_expire < lo_expire)
4592 			lo_expire = this_ia_lo_expire;
4593 	}
4594 
4595 	/* If there are no addresses, give up, go to INIT.
4596 	 * Note that if an address is unexpired with a date in the past,
4597 	 * we're scheduling an expiration event to ocurr in the past.  We
4598 	 * could probably optimize this to expire now (but then there's
4599 	 * recursion).
4600 	 *
4601 	 * In the future, we may decide that we're done here, or to
4602 	 * schedule a future request (using 4-pkt info-request model).
4603 	 */
4604 	if (has_addrs == ISC_FALSE) {
4605 		dhc6_lease_destroy(&client->active_lease, MDL);
4606 		client->active_lease = NULL;
4607 
4608 		/* Go back to the beginning. */
4609 		start_init6(client);
4610 		return;
4611 	}
4612 
4613 	/* Second part of calculating the renew and rebind times.
4614 	 * We have the start time and the desired periods for renew
4615 	 * and rebind, just add them to get the desired end time.
4616 	 */
4617 	if (renew != MAX_TIME)
4618 		renew += max_ia_starts;
4619 	if (rebind != MAX_TIME)
4620 		rebind += max_ia_starts;
4621 
4622 	switch(client->state) {
4623 	      case S_BOUND:
4624 		/* We'd like to hit renewing, but if rebinding has already
4625 		 * passed (time warp), head straight there.
4626 		 */
4627 		if ((rebind > cur_time) && (renew < rebind)) {
4628 			log_debug("PRC: Renewal event scheduled in %d seconds, "
4629 				  "to run for %u seconds.",
4630 				  (int)(renew - cur_time),
4631 				  (unsigned)(rebind - renew));
4632 			client->next_MRD = rebind;
4633 			tv.tv_sec = renew;
4634 			tv.tv_usec = 0;
4635 			add_timeout(&tv, start_renew6, client, NULL, NULL);
4636 
4637 			break;
4638 		}
4639 		/* FALL THROUGH */
4640 	      case S_RENEWING:
4641 		/* While actively renewing, MRD is bounded by the time
4642 		 * we stop renewing and start rebinding.  This helps us
4643 		 * process the state change on time.
4644 		 */
4645 		client->MRD = rebind - cur_time;
4646 		if (rebind != MAX_TIME) {
4647 			log_debug("PRC: Rebind event scheduled in %d seconds, "
4648 				  "to run for %d seconds.",
4649 				  (int)(rebind - cur_time),
4650 				  (int)(hi_expire - rebind));
4651 			client->next_MRD = hi_expire;
4652 			tv.tv_sec = rebind;
4653 			tv.tv_usec = 0;
4654 			add_timeout(&tv, start_rebind6, client, NULL, NULL);
4655 		}
4656 		break;
4657 
4658 	      case S_REBINDING:
4659 		/* For now, we rebind up until the last lease expires.  In
4660 		 * the future, we might want to start SOLICITing when we've
4661 		 * depreffed an address.
4662 		 */
4663 		client->MRD = hi_expire - cur_time;
4664 		break;
4665 
4666 	      default:
4667 		if (has_preferred_addrs) {
4668 			log_fatal("Impossible condition, state %d at %s:%d.",
4669 				  client->state, MDL);
4670 		}
4671 	}
4672 
4673 	/* Separately, set a time at which we will depref and expire
4674 	 * leases.  This might happen with multiple addresses while we
4675 	 * keep trying to refresh.
4676 	 */
4677 	if (depref != MAX_TIME) {
4678 		log_debug("PRC: Depreference scheduled in %d seconds.",
4679 			  (int)(depref - cur_time));
4680 		tv.tv_sec = depref;
4681 		tv.tv_usec = 0;
4682 		add_timeout(&tv, do_depref, client, NULL, NULL);
4683 	}
4684 	if (lo_expire != MAX_TIME) {
4685 		log_debug("PRC: Expiration scheduled in %d seconds.",
4686 			  (int)(lo_expire - cur_time));
4687 		tv.tv_sec = lo_expire;
4688 		tv.tv_usec = 0;
4689 		add_timeout(&tv, do_expire, client, NULL, NULL);
4690 	}
4691 }
4692 
4693 /* In a given IA chain, find the IA with the same type and 'iaid'. */
4694 static struct dhc6_ia *
find_ia(struct dhc6_ia * head,u_int16_t type,const char * id)4695 find_ia(struct dhc6_ia *head, u_int16_t type, const char *id)
4696 {
4697 	struct dhc6_ia *ia;
4698 
4699 	for (ia = head ; ia != NULL ; ia = ia->next) {
4700 		if (ia->ia_type != type)
4701 			continue;
4702 		if (memcmp(ia->iaid, id, 4) == 0)
4703 			return ia;
4704 	}
4705 
4706 	return NULL;
4707 }
4708 
4709 /* In a given address chain, find a matching address. */
4710 static struct dhc6_addr *
find_addr(struct dhc6_addr * head,struct iaddr * address)4711 find_addr(struct dhc6_addr *head, struct iaddr *address)
4712 {
4713 	struct dhc6_addr *addr;
4714 
4715 	for (addr = head ; addr != NULL ; addr = addr->next) {
4716 		if ((addr->address.len == address->len) &&
4717 		    (memcmp(addr->address.iabuf, address->iabuf,
4718 			    address->len) == 0))
4719 			return addr;
4720 	}
4721 
4722 	return NULL;
4723 }
4724 
4725 /* In a given prefix chain, find a matching prefix. */
4726 static struct dhc6_addr *
find_pref(struct dhc6_addr * head,struct iaddr * prefix,u_int8_t plen)4727 find_pref(struct dhc6_addr *head, struct iaddr *prefix, u_int8_t plen)
4728 {
4729 	struct dhc6_addr *pref;
4730 
4731 	for (pref = head ; pref != NULL ; pref = pref->next) {
4732 		if ((pref->address.len == prefix->len) &&
4733 		    (pref->plen == plen) &&
4734 		    (memcmp(pref->address.iabuf, prefix->iabuf,
4735 			    prefix->len) == 0))
4736 			return pref;
4737 	}
4738 
4739 	return NULL;
4740 }
4741 
4742 /*
4743  *
4744  * \brief  Merge the bindings from the source lease into the destination
4745  * lease structure, where they are missing.
4746  *
4747  * This is used to merge any extra information we have in the current
4748  * (older, src) lease into the lease we have just received.  For example
4749  * the src lease might include a binding for an NA that is still usable
4750  * but that we didn't request or that the server is no longer serving.
4751  * We want to keep that information until we toss the binding (expire,
4752  * release) so we move it to the new lease.
4753  *
4754  * We have to copy the stateful objects rather than move them over,
4755  * because later code needs to be able to compare new versus old if
4756  * they contain any bindings.
4757  *
4758  * \param src The older lease to copy the objects from
4759  * \param dst The newer lease to copy the objects to
4760  */
4761 static void
dhc6_merge_lease(struct dhc6_lease * src,struct dhc6_lease * dst)4762 dhc6_merge_lease(struct dhc6_lease *src, struct dhc6_lease *dst)
4763 {
4764 	struct dhc6_ia *sia, *dia, *tia, **eia;
4765 	struct dhc6_addr *saddr, *daddr, *taddr;
4766 	int changes = 0;
4767 
4768 	if ((dst == NULL) || (src == NULL))
4769 		return;
4770 
4771 	for (sia = src->bindings ; sia != NULL ; sia = sia->next) {
4772 		dia = find_ia(dst->bindings, sia->ia_type, (char *)sia->iaid);
4773 
4774 		if (dia == NULL) {
4775 			tia = dhc6_dup_ia(sia, MDL);
4776 
4777 			if (tia == NULL)
4778 				log_fatal("Out of memory merging lease - "
4779 					  "Unable to continue without losing "
4780 					  "state! (%s:%d)", MDL);
4781 
4782 			/* Put any bindings that aren't in the new lease at the
4783 			 * end of the list.  If the user or server reduces the
4784 			 * number of IAs the ones in use will be at the front
4785 			 * and will be used when building the next requests
4786 			 * We could be more efficient by finding the end
4787 			 * of the list once but we don't expect to do this
4788 			 * often.
4789 			 */
4790 			for (eia = &dst->bindings;
4791 			     *eia != NULL;
4792 			     eia = &(*eia)->next) {
4793 				; /* no work just find the end */
4794 			}
4795 			*eia = tia;
4796 			changes = 1;
4797 		} else {
4798 			for (saddr = sia->addrs ; saddr != NULL ;
4799 			     saddr = saddr->next) {
4800 				if (sia->ia_type != D6O_IA_PD)
4801 					daddr = find_addr(dia->addrs,
4802 							  &saddr->address);
4803 				else
4804 					daddr = find_pref(dia->addrs,
4805 							  &saddr->address,
4806 							  saddr->plen);
4807 
4808 				if (daddr == NULL) {
4809 					taddr = dhc6_dup_addr(saddr, MDL);
4810 
4811 					if (taddr == NULL)
4812 						log_fatal("Out of memory "
4813 							  "merging lease - "
4814 							  "Unable to continue "
4815 							  "without losing "
4816 							  "state! (%s:%d)",
4817 							  MDL);
4818 
4819 					/* XXX: consider sorting? */
4820 					taddr->next = dia->addrs;
4821 					dia->addrs = taddr;
4822 					changes = 1;
4823 				}
4824 			}
4825 		}
4826 	}
4827 
4828 	/* If we made changes, reset the score to 0 so it is recalculated. */
4829 	if (changes)
4830 		dst->score = 0;
4831 }
4832 
4833 /* We've either finished selecting or succeeded in Renew or Rebinding our
4834  * lease.  In all cases we got a Reply.  Give dhclient-script a tickle
4835  * to inform it about the new values, and then lay in wait for the next
4836  * event.
4837  */
4838 static void
start_bound(struct client_state * client)4839 start_bound(struct client_state *client)
4840 {
4841 	struct dhc6_ia *ia, *oldia;
4842 	struct dhc6_addr *addr, *oldaddr;
4843 	struct dhc6_lease *lease, *old;
4844 	const char *reason;
4845 	int decline_cnt = 0;
4846 #if defined (NSUPDATE)
4847 	TIME dns_update_offset = 1;
4848 #endif
4849 
4850 	lease = client->active_lease;
4851 	if (lease == NULL) {
4852 		log_error("Cannot enter bound state unless an active lease "
4853 			  "is selected.");
4854 		return;
4855 	}
4856 	lease->released = ISC_FALSE;
4857 	old = client->old_lease;
4858 
4859 	client->v6_handler = bound_handler;
4860 
4861 	switch (client->state) {
4862 	      case S_SELECTING:
4863 	      case S_REBOOTING: /* Pretend we got bound. */
4864 		reason = "BOUND6";
4865 		break;
4866 
4867 	      case S_RENEWING:
4868 		reason = "RENEW6";
4869 		break;
4870 
4871 	      case S_REBINDING:
4872 		reason = "REBIND6";
4873 		break;
4874 
4875 	      default:
4876 		log_fatal("Impossible condition at %s:%d.", MDL);
4877 		/* Silence compiler warnings. */
4878 		return;
4879 	}
4880 
4881 	log_debug("PRC: Bound to lease %s.",
4882 		  print_hex_1(client->active_lease->server_id.len,
4883 			      client->active_lease->server_id.data, 55));
4884 	client->state = S_BOUND;
4885 
4886 	write_client6_lease(client, lease, 0, 1);
4887 
4888 	oldia = NULL;
4889 	for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
4890 		if (old != NULL)
4891 			oldia = find_ia(old->bindings,
4892 					ia->ia_type,
4893 					(char *)ia->iaid);
4894 		else
4895 			oldia = NULL;
4896 
4897 		for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
4898 			/* Don't try to use the address if it's already expired */
4899 			if (addr->flags & DHC6_ADDR_EXPIRED)
4900 				continue;
4901 
4902 			if (oldia != NULL) {
4903 				if (ia->ia_type != D6O_IA_PD)
4904 					oldaddr = find_addr(oldia->addrs,
4905 							    &addr->address);
4906 				else
4907 					oldaddr = find_pref(oldia->addrs,
4908 							    &addr->address,
4909 							    addr->plen);
4910 			} else
4911 				oldaddr = NULL;
4912 
4913 #if defined (NSUPDATE)
4914 			if ((oldaddr == NULL) && (ia->ia_type == D6O_IA_NA))
4915 				dhclient_schedule_updates(client,
4916 							  &addr->address,
4917 							  dns_update_offset++);
4918 #endif
4919 
4920 			/* Shell out to setup the new binding. */
4921 			script_init(client, reason, NULL);
4922 
4923 			if (old != NULL)
4924 				dhc6_marshall_values("old_", client, old,
4925 						     oldia, oldaddr);
4926 			dhc6_marshall_values("new_", client, lease, ia, addr);
4927 			script_write_requested6(client);
4928 
4929 			/* When script returns 3, DAD failed */
4930 			if (script_go(client) == 3) {
4931 				if (ia->ia_type == D6O_IA_NA) {
4932 					addr->flags |= DHC6_ADDR_DECLINED;
4933 					log_debug ("Flag address declined:%s",
4934 						   piaddr(addr->address));
4935 					decline_cnt++;
4936 				}
4937 			}
4938 		}
4939 
4940 		/* If the client script DAD failed any addresses we need
4941 		* build and issue a DECLINE */
4942 		if (decline_cnt) {
4943 			start_decline6(client);
4944 			return;
4945 		}
4946 
4947 		/* XXX: maybe we should loop on the old values instead? */
4948 		if (ia->addrs == NULL) {
4949 			script_init(client, reason, NULL);
4950 
4951 			if (old != NULL)
4952 				dhc6_marshall_values("old_", client, old,
4953 						     oldia,
4954 						     oldia != NULL ?
4955 							 oldia->addrs : NULL);
4956 
4957 			dhc6_marshall_values("new_", client, lease, ia,
4958 					     NULL);
4959 			script_write_requested6(client);
4960 
4961 			script_go(client);
4962 		}
4963 	}
4964 
4965 	/* XXX: maybe we should loop on the old values instead? */
4966 	if (lease->bindings == NULL) {
4967 		script_init(client, reason, NULL);
4968 
4969 		if (old != NULL)
4970 			dhc6_marshall_values("old_", client, old,
4971 					     old->bindings,
4972 					     (old->bindings != NULL) ?
4973 						old->bindings->addrs : NULL);
4974 
4975 		dhc6_marshall_values("new_", client, lease, NULL, NULL);
4976 		script_write_requested6(client);
4977 
4978 		script_go(client);
4979 	}
4980 
4981 #ifdef DHCP4o6
4982 	if (dhcpv4_over_dhcpv6)
4983 		dhcp4o6_start();
4984 #endif
4985 
4986 	detach();
4987 
4988 	if (client->old_lease != NULL) {
4989 		dhc6_lease_destroy(&client->old_lease, MDL);
4990 		client->old_lease = NULL;
4991 	}
4992 
4993 	/* Schedule events. */
4994 	dhc6_check_times(client);
4995 }
4996 
4997 /* While bound, ignore packets.  In the future we'll want to answer
4998  * Reconfigure-Request messages and the like.
4999  */
5000 void
bound_handler(struct packet * packet,struct client_state * client)5001 bound_handler(struct packet *packet, struct client_state *client)
5002 {
5003 	log_debug("RCV: Input packets are ignored once bound.");
5004 }
5005 
5006 /*
5007  * start_decline6() kicks off the decline process, transmitting
5008  * an decline packet and scheduling a retransmission event.
5009  */
5010 void
start_decline6(struct client_state * client)5011 start_decline6(struct client_state *client)
5012 {
5013 	/* Cancel any pending transmissions */
5014 	cancel_timeout(do_confirm6, client);
5015 	cancel_timeout(do_select6, client);
5016 	cancel_timeout(do_refresh6, client);
5017 	cancel_timeout(do_release6, client);
5018 	cancel_timeout(do_decline6, client);
5019 	client->state = S_DECLINING;
5020 
5021 	if (client->active_lease == NULL)
5022 		return;
5023 
5024 	/* Set timers per RFC3315 section 18.1.7. */
5025 	client->IRT = DEC_TIMEOUT * 100;
5026 	client->MRT = 0;
5027 	client->MRC = DEC_MAX_RC;
5028 	client->MRD = 0;
5029 
5030 	dhc6_retrans_init(client);
5031 	client->v6_handler = reply_handler;
5032 
5033 	client->refresh_type = DHCPV6_DECLINE;
5034 	do_decline6(client);
5035 }
5036 
5037 /*
5038  * do_decline6() creates a Decline packet and transmits it.
5039  * The decline will contain an IA_NA with iasubopt(s) for
5040  * each IA_NA containing declined address(es) in the active
5041  * lease.
5042  */
5043 static void
do_decline6(void * input)5044 do_decline6(void *input)
5045 {
5046 	struct client_state *client;
5047 	struct data_string ds;
5048 	int send_ret;
5049 	struct timeval elapsed, tv;
5050 
5051 	client = input;
5052 	if (client == NULL || client->active_lease == NULL) {
5053 		return;
5054 	}
5055 
5056 	if ((client->MRC != 0) && (client->txcount > client->MRC))  {
5057 		log_info("Max retransmission count exceeded.");
5058 		goto decline_done;
5059 	}
5060 
5061 	/*
5062 	 * Start_time starts at the first transmission.
5063 	 */
5064 	if (client->txcount == 0) {
5065 		client->start_time.tv_sec = cur_tv.tv_sec;
5066 		client->start_time.tv_usec = cur_tv.tv_usec;
5067 	}
5068 
5069 	/* elapsed = cur - start */
5070 	elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
5071 	elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
5072 	if (elapsed.tv_usec < 0) {
5073 		elapsed.tv_sec -= 1;
5074 		elapsed.tv_usec += 1000000;
5075 	}
5076 
5077 	memset(&ds, 0, sizeof(ds));
5078 	if (!buffer_allocate(&ds.buffer, 4, MDL)) {
5079 		log_error("Unable to allocate memory for Decline.");
5080 		goto decline_done;
5081 	}
5082 
5083 	ds.data = ds.buffer->data;
5084 	ds.len = 4;
5085 	ds.buffer->data[0] = DHCPV6_DECLINE;
5086 	memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
5087 
5088 	/* Form an elapsed option. */
5089 	/* Maximum value is 65535 1/100s coded as 0xffff. */
5090 	if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
5091 	    ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
5092 		client->elapsed = 0xffff;
5093 	} else {
5094 		client->elapsed = elapsed.tv_sec * 100;
5095 		client->elapsed += elapsed.tv_usec / 10000;
5096 	}
5097 
5098 	client->elapsed = htons(client->elapsed);
5099 
5100 	log_debug("XMT: Forming Decline.");
5101 	make_client6_options(client, &client->sent_options,
5102 			     client->active_lease, DHCPV6_DECLINE);
5103 	dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
5104 				    client->sent_options, &global_scope,
5105 				    &dhcpv6_universe);
5106 
5107 	/* Append IA_NA's. */
5108 	if (dhc6_add_ia_na_decline(client, &ds, client->active_lease)
5109 	    != ISC_R_SUCCESS) {
5110 		data_string_forget(&ds, MDL);
5111 		goto decline_done;
5112 	}
5113 
5114 	/* Transmit and wait. */
5115 	log_info("XMT: Decline on %s, interval %ld0ms.",
5116 		 client->name ? client->name : client->interface->name,
5117 		 (long int)client->RT);
5118 
5119 	send_ret = send_packet6(client->interface, ds.data, ds.len,
5120 				&DHCPv6DestAddr);
5121 	if (send_ret != ds.len) {
5122 		log_error("dhc6: sendpacket6() sent %d of %d bytes",
5123 			  send_ret, ds.len);
5124 	}
5125 
5126 	data_string_forget(&ds, MDL);
5127 
5128 	/* Wait RT */
5129 	tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
5130 	tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
5131 	if (tv.tv_usec >= 1000000) {
5132 		tv.tv_sec += 1;
5133 		tv.tv_usec -= 1000000;
5134 	}
5135 	add_timeout(&tv, do_decline6, client, NULL, NULL);
5136 	dhc6_retrans_advance(client);
5137 	return;
5138 
5139 decline_done:
5140 	/* We here because we've exhausted our retry limits or
5141 	 * something else has gone wrong with the decline process.
5142 	 * So let's just toss the existing lease and start over. */
5143 	dhc6_lease_destroy(&client->active_lease, MDL);
5144 	client->active_lease = NULL;
5145 
5146 	start_init6(client);
5147 	return;
5148 }
5149 
5150 /* start_renew6() gets us all ready to go to start transmitting Renew packets.
5151  * Note that client->next_MRD must be set before entering this function -
5152  * it must be set to the time at which the client should start Rebinding.
5153  */
5154 void
start_renew6(void * input)5155 start_renew6(void *input)
5156 {
5157 	struct client_state *client;
5158 
5159 	client = (struct client_state *)input;
5160 
5161 	log_info("PRC: Renewing lease on %s.",
5162 		 client->name ? client->name : client->interface->name);
5163 	client->state = S_RENEWING;
5164 
5165 	client->v6_handler = reply_handler;
5166 
5167 	/* Times per RFC3315 section 18.1.3. */
5168 	client->IRT = REN_TIMEOUT * 100;
5169 	client->MRT = REN_MAX_RT * 100;
5170 	client->MRC = 0;
5171 	/* MRD is special in renew - we need to set it by checking timer
5172 	 * state.
5173 	 */
5174 	client->MRD = client->next_MRD - cur_time;
5175 
5176 	dhc6_retrans_init(client);
5177 
5178 	client->refresh_type = DHCPV6_RENEW;
5179 	do_refresh6(client);
5180 }
5181 
5182 /* do_refresh6() transmits one DHCPv6 packet, be it a Renew or Rebind, and
5183  * gives the retransmission state a bump for the next time.  Note that
5184  * client->refresh_type must be set before entering this function.
5185  */
5186 void
do_refresh6(void * input)5187 do_refresh6(void *input)
5188 {
5189 	struct option_cache *oc;
5190 	struct sockaddr_in6 unicast, *dest_addr = &DHCPv6DestAddr;
5191 	struct data_string ds;
5192 	struct client_state *client;
5193 	struct dhc6_lease *lease;
5194 	struct timeval elapsed, tv;
5195 	int send_ret, added;
5196 
5197 	client = (struct client_state *)input;
5198 	memset(&ds, 0, sizeof(ds));
5199 
5200 	lease = client->active_lease;
5201 	if (lease == NULL) {
5202 		log_error("Cannot renew without an active binding.");
5203 		return;
5204 	}
5205 
5206 	/* Ensure we're emitting a valid message type. */
5207 	switch (client->refresh_type) {
5208 	      case DHCPV6_RENEW:
5209 	      case DHCPV6_REBIND:
5210 		break;
5211 
5212 	      default:
5213 		log_fatal("Internal inconsistency (%d) at %s:%d.",
5214 			  client->refresh_type, MDL);
5215 	}
5216 
5217 	/*
5218 	 * Start_time starts at the first transmission.
5219 	 */
5220 	if (client->txcount == 0) {
5221 		client->start_time.tv_sec = cur_tv.tv_sec;
5222 		client->start_time.tv_usec = cur_tv.tv_usec;
5223 	}
5224 
5225 	/* elapsed = cur - start */
5226 	elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
5227 	elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
5228 	if (elapsed.tv_usec < 0) {
5229 		elapsed.tv_sec -= 1;
5230 		elapsed.tv_usec += 1000000;
5231 	}
5232 	if (((client->MRC != 0) && (client->txcount > client->MRC)) ||
5233 	    ((client->MRD != 0) && (elapsed.tv_sec >= client->MRD))) {
5234 		/* We're done.  Move on to the next phase, if any. */
5235 		dhc6_check_times(client);
5236 		return;
5237 	}
5238 
5239 	/*
5240 	 * Check whether the server has sent a unicast option; if so, we can
5241 	 * use the address it specified for RENEWs.
5242 	 */
5243 	oc = lookup_option(&dhcpv6_universe, lease->options, D6O_UNICAST);
5244 	if (oc && evaluate_option_cache(&ds, NULL, NULL, NULL,
5245 					lease->options, NULL, &global_scope,
5246 					oc, MDL)) {
5247 		if (ds.len < 16) {
5248 			log_error("Invalid unicast option length %d.", ds.len);
5249 		} else {
5250 			memset(&unicast, 0, sizeof(DHCPv6DestAddr));
5251 			unicast.sin6_family = AF_INET6;
5252 			unicast.sin6_port = remote_port;
5253 			memcpy(&unicast.sin6_addr, ds.data, 16);
5254 			if (client->refresh_type == DHCPV6_RENEW) {
5255 				dest_addr = &unicast;
5256 			}
5257 		}
5258 
5259 		data_string_forget(&ds, MDL);
5260 	}
5261 
5262 	/* Commence forming a renew packet. */
5263 	memset(&ds, 0, sizeof(ds));
5264 	if (!buffer_allocate(&ds.buffer, 4, MDL)) {
5265 		log_error("Unable to allocate memory for packet.");
5266 		return;
5267 	}
5268 	ds.data = ds.buffer->data;
5269 	ds.len = 4;
5270 
5271 	ds.buffer->data[0] = client->refresh_type;
5272 	memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
5273 
5274 	/* Form an elapsed option. */
5275 	/* Maximum value is 65535 1/100s coded as 0xffff. */
5276 	if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
5277 	    ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
5278 		client->elapsed = 0xffff;
5279 	} else {
5280 		client->elapsed = elapsed.tv_sec * 100;
5281 		client->elapsed += elapsed.tv_usec / 10000;
5282 	}
5283 
5284 	if (client->elapsed == 0)
5285 		log_debug("XMT: Forming %s, 0 ms elapsed.",
5286 			  dhcpv6_type_names[client->refresh_type]);
5287 	else
5288 		log_debug("XMT: Forming %s, %u0 ms elapsed.",
5289 			  dhcpv6_type_names[client->refresh_type],
5290 			  (unsigned)client->elapsed);
5291 
5292 	client->elapsed = htons(client->elapsed);
5293 
5294 	make_client6_options(client, &client->sent_options, lease,
5295 			     client->refresh_type);
5296 
5297 	/* Put in any options from the sent cache. */
5298 	dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
5299 				    client->sent_options, &global_scope,
5300 				    &dhcpv6_universe);
5301 
5302 	/* Now append any IA's, and within them any IAADDR/IAPREFIXs.
5303 	 * For each type of IA (na, ta, pd) we start with the ones for
5304 	 * which we already have addresses (dhc6_add_ia_xx) and then
5305 	 * if we still want more we add aditional IAs (dhc6_bare_ia_xx)
5306 	 */
5307 	if (wanted_ia_na &&
5308 	    ((dhc6_add_ia_na(client, &ds, lease, client->refresh_type,
5309 			     wanted_ia_na, &added) != ISC_R_SUCCESS) ||
5310 	     (dhc6_bare_ia_xx(client, &ds, wanted_ia_na - added,
5311 			      D6O_IA_NA) != ISC_R_SUCCESS))) {
5312 		data_string_forget(&ds, MDL);
5313 		return;
5314 	}
5315 	if (wanted_ia_pd &&
5316 	    ((dhc6_add_ia_pd(client, &ds, lease, client->refresh_type,
5317 			     wanted_ia_pd, &added) != ISC_R_SUCCESS) ||
5318 	     (dhc6_bare_ia_xx(client, &ds, wanted_ia_pd - added,
5319 			      D6O_IA_PD) != ISC_R_SUCCESS))) {
5320 		data_string_forget(&ds, MDL);
5321 		return;
5322 	}
5323 
5324 	log_info("XMT: %s on %s, interval %ld0ms.",
5325 		 dhcpv6_type_names[client->refresh_type],
5326 		 client->name ? client->name : client->interface->name,
5327 		 (long int)client->RT);
5328 
5329 	send_ret = send_packet6(client->interface, ds.data, ds.len, dest_addr);
5330 
5331 	if (send_ret != ds.len) {
5332 		log_error("dhc6: send_packet6() sent %d of %d bytes",
5333 			  send_ret, ds.len);
5334 	}
5335 
5336 	data_string_forget(&ds, MDL);
5337 
5338 	/* Wait RT */
5339 	tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
5340 	tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
5341 	if (tv.tv_usec >= 1000000) {
5342 		tv.tv_sec += 1;
5343 		tv.tv_usec -= 1000000;
5344 	}
5345 	add_timeout(&tv, do_refresh6, client, NULL, NULL);
5346 
5347 	dhc6_retrans_advance(client);
5348 }
5349 
5350 /* start_rebind6() gets us all set up to go and rebind a lease.  Note that
5351  * client->next_MRD must be set before entering this function.  In this case,
5352  * MRD must be set to the maximum time any address in the packet will
5353  * expire.
5354  */
5355 void
start_rebind6(void * input)5356 start_rebind6(void *input)
5357 {
5358 	struct client_state *client;
5359 
5360 	client = (struct client_state *)input;
5361 
5362 	log_info("PRC: Rebinding lease on %s.",
5363 		 client->name ? client->name : client->interface->name);
5364 	client->state = S_REBINDING;
5365 
5366 	client->v6_handler = reply_handler;
5367 
5368 	/* Times per RFC3315 section 18.1.4. */
5369 	client->IRT = REB_TIMEOUT * 100;
5370 	client->MRT = REB_MAX_RT * 100;
5371 	client->MRC = 0;
5372 	/* MRD is special in rebind - it's determined by the timer
5373 	 * state.
5374 	 */
5375 	client->MRD = client->next_MRD - cur_time;
5376 
5377 	dhc6_retrans_init(client);
5378 
5379 	client->refresh_type = DHCPV6_REBIND;
5380 	do_refresh6(client);
5381 }
5382 
5383 /* do_depref() runs through a given lease's addresses, for each that has
5384  * not yet been depreffed, shells out to the dhclient-script to inform it
5385  * of the status change.  The dhclient-script should then do...something...
5386  * to encourage applications to move off the address and onto one of the
5387  * remaining 'preferred' addresses.
5388  */
5389 void
do_depref(void * input)5390 do_depref(void *input)
5391 {
5392 	struct client_state *client;
5393 	struct dhc6_lease *lease;
5394 	struct dhc6_ia *ia;
5395 	struct dhc6_addr *addr;
5396 
5397 	client = (struct client_state *)input;
5398 
5399 	lease = client->active_lease;
5400 	if (lease == NULL)
5401 		return;
5402 
5403 	for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
5404 		for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
5405 			if (addr->flags & DHC6_ADDR_DEPREFFED)
5406 				continue;
5407 
5408 			if (addr->starts + addr->preferred_life <= cur_time) {
5409 				script_init(client, "DEPREF6", NULL);
5410 				dhc6_marshall_values("cur_", client, lease,
5411 						     ia, addr);
5412 				script_write_requested6(client);
5413 				script_go(client);
5414 
5415 				addr->flags |= DHC6_ADDR_DEPREFFED;
5416 
5417 				if (ia->ia_type != D6O_IA_PD)
5418 				    log_info("PRC: Address %s depreferred.",
5419 					     piaddr(addr->address));
5420 				else
5421 				    log_info("PRC: Prefix %s/%u depreferred.",
5422 					     piaddr(addr->address),
5423 					     (unsigned) addr->plen);
5424 
5425 #if defined (NSUPDATE)
5426 				/* Remove DDNS bindings at depref time. */
5427 				if ((ia->ia_type == D6O_IA_NA) &&
5428 				    client->config->do_forward_update)
5429 					client_dns_remove(client,
5430 							  &addr->address);
5431 #endif
5432 			}
5433 		}
5434 	}
5435 
5436 	dhc6_check_times(client);
5437 }
5438 
5439 /* do_expire() searches through all the addresses on a given lease, and
5440  * expires/removes any addresses that are no longer valid.
5441  */
5442 void
do_expire(void * input)5443 do_expire(void *input)
5444 {
5445 	struct client_state *client;
5446 	struct dhc6_lease *lease;
5447 	struct dhc6_ia *ia, **tia;
5448 	struct dhc6_addr *addr;
5449 	int has_addrs = ISC_FALSE;
5450 	int ia_has_addrs = ISC_FALSE;
5451 
5452 	client = (struct client_state *)input;
5453 
5454 	lease = client->active_lease;
5455 	if (lease == NULL)
5456 		return;
5457 
5458 	for (ia = lease->bindings, tia = &lease->bindings; ia != NULL ; ) {
5459 		ia_has_addrs = ISC_FALSE;
5460 		for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
5461 			if (addr->flags & DHC6_ADDR_EXPIRED)
5462 				continue;
5463 
5464 			if (addr->starts + addr->max_life <= cur_time) {
5465 				script_init(client, "EXPIRE6", NULL);
5466 				dhc6_marshall_values("old_", client, lease,
5467 						     ia, addr);
5468 				script_write_requested6(client);
5469 				script_go(client);
5470 
5471 				addr->flags |= DHC6_ADDR_EXPIRED;
5472 
5473 				if (ia->ia_type != D6O_IA_PD)
5474 				    log_info("PRC: Address %s expired.",
5475 					     piaddr(addr->address));
5476 				else
5477 				    log_info("PRC: Prefix %s/%u expired.",
5478 					     piaddr(addr->address),
5479 					     (unsigned) addr->plen);
5480 
5481 #if defined (NSUPDATE)
5482 				/* We remove DNS records at depref time, but
5483 				 * it is possible that we might get here
5484 				 * without depreffing.
5485 				 */
5486 				if ((ia->ia_type == D6O_IA_NA) &&
5487 				    client->config->do_forward_update &&
5488 				    !(addr->flags & DHC6_ADDR_DEPREFFED))
5489 					client_dns_remove(client,
5490 							  &addr->address);
5491 #endif
5492 
5493 				continue;
5494 			}
5495 
5496 			ia_has_addrs = ISC_TRUE;
5497 			has_addrs = ISC_TRUE;
5498 		}
5499 
5500 		/* Update to the next ia and git rid of this ia
5501 		 * if it doesn't have any leases.
5502 		 */
5503 		if (ia_has_addrs == ISC_TRUE) {
5504 			/* leases, just advance the list pointer */
5505 			tia = &(*tia)->next;
5506 		} else {
5507 			/* no leases, update the list pointer
5508 			 * and free the ia
5509 			 */
5510 			*tia = ia->next;
5511 			dhc6_ia_destroy(&ia, MDL);
5512 		}
5513 		/* lastly update the ia pointer to our new ia */
5514 		ia = *tia;
5515 	}
5516 
5517 	/* Clean up empty leases. */
5518 	if (has_addrs == ISC_FALSE) {
5519 		log_info("PRC: Bound lease is devoid of active addresses."
5520 			 "  Re-initializing.");
5521 
5522 		dhc6_lease_destroy(&lease, MDL);
5523 		client->active_lease = NULL;
5524 
5525 		start_init6(client);
5526 		return;
5527 	}
5528 
5529 	/* Schedule the next run through. */
5530 	dhc6_check_times(client);
5531 }
5532 
5533 /*
5534  * Run client script to unconfigure interface.
5535  * Called with reason STOP6 when dhclient -x is run, or with reason
5536  * RELEASE6 when server has replied to a Release message.
5537  * Stateless is a special case.
5538  */
5539 void
unconfigure6(struct client_state * client,const char * reason)5540 unconfigure6(struct client_state *client, const char *reason)
5541 {
5542 	struct dhc6_ia *ia;
5543 	struct dhc6_addr *addr;
5544 
5545 	if (stateless) {
5546 		script_init(client, reason, NULL);
5547 		if (client->active_lease != NULL)
5548 			script_write_params6(client, "old_",
5549 					     client->active_lease->options);
5550 		script_write_requested6(client);
5551 		script_go(client);
5552 		return;
5553 	}
5554 
5555 	if (client->active_lease == NULL)
5556 		return;
5557 
5558 	for (ia = client->active_lease->bindings ; ia != NULL ; ia = ia->next) {
5559 		if (ia->ia_type == D6O_IA_TA)
5560 			continue;
5561 
5562 		for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
5563 			script_init(client, reason, NULL);
5564 			dhc6_marshall_values("old_", client,
5565 					     client->active_lease, ia, addr);
5566 			script_write_requested6(client);
5567 			script_go(client);
5568 
5569 #if defined (NSUPDATE)
5570 			if ((ia->ia_type == D6O_IA_NA) &&
5571 			    client->config->do_forward_update)
5572 				client_dns_remove(client, &addr->address);
5573 #endif
5574 		}
5575 	}
5576 }
5577 
5578 static void
refresh_info_request6(void * input)5579 refresh_info_request6(void *input)
5580 {
5581 	struct client_state *client;
5582 
5583 	client = (struct client_state *)input;
5584 	start_info_request6(client);
5585 }
5586 
5587 /* Timeout for Information-Request (using the IRT option).
5588  */
5589 static void
dhc6_check_irt(struct client_state * client)5590 dhc6_check_irt(struct client_state *client)
5591 {
5592 	struct option **req;
5593 	struct option_cache *oc;
5594 	TIME expire = MAX_TIME;
5595 	struct timeval tv;
5596 	int i;
5597 	isc_boolean_t found = ISC_FALSE;
5598 
5599 	cancel_timeout(refresh_info_request6, client);
5600 
5601 	req = client->config->requested_options;
5602 	for (i = 0; req[i] != NULL; i++) {
5603 		if (req[i] == irt_option) {
5604 			found = ISC_TRUE;
5605 			break;
5606 		}
5607 	}
5608 	/* Simply return gives a endless loop waiting for nothing. */
5609 	if (!found) {
5610 #ifdef DHCP4o6
5611 		if (!dhcpv4_over_dhcpv6)
5612 #endif
5613 		finish(0);
5614 	}
5615 
5616 	oc = lookup_option(&dhcpv6_universe, client->active_lease->options,
5617 			   D6O_INFORMATION_REFRESH_TIME);
5618 	if (oc != NULL) {
5619 		struct data_string irt;
5620 
5621 		memset(&irt, 0, sizeof(irt));
5622 		if (!evaluate_option_cache(&irt, NULL, NULL, client,
5623 					   client->active_lease->options,
5624 					   NULL, &global_scope, oc, MDL) ||
5625 		    (irt.len < 4)) {
5626 			log_error("Can't evaluate IRT.");
5627 		} else {
5628 			expire = getULong(irt.data);
5629 			if (expire < IRT_MINIMUM)
5630 				expire = IRT_MINIMUM;
5631 			if (expire == 0xffffffff)
5632 				expire = MAX_TIME;
5633 		}
5634 		data_string_forget(&irt, MDL);
5635 	} else
5636 		expire = IRT_DEFAULT;
5637 
5638 	if (expire != MAX_TIME) {
5639 		log_debug("PRC: Refresh event scheduled in %u seconds.",
5640 			  (unsigned) expire);
5641 		tv.tv_sec = cur_time + expire;
5642 		tv.tv_usec = 0;
5643 		add_timeout(&tv, refresh_info_request6, client, NULL, NULL);
5644 	}
5645 }
5646 
5647 /* We got a Reply. Give dhclient-script a tickle to inform it about
5648  * the new values, and then lay in wait for the next event.
5649  */
5650 static void
start_informed(struct client_state * client)5651 start_informed(struct client_state *client)
5652 {
5653 	client->v6_handler = informed_handler;
5654 
5655 	log_debug("PRC: Done.");
5656 
5657 	client->state = S_BOUND;
5658 
5659 	script_init(client, "RENEW6", NULL);
5660 	if (client->old_lease != NULL)
5661 		script_write_params6(client, "old_",
5662 				     client->old_lease->options);
5663 	script_write_params6(client, "new_", client->active_lease->options);
5664 	script_write_requested6(client);
5665 	script_go(client);
5666 
5667 #ifdef DHCP4o6
5668 	if (dhcpv4_over_dhcpv6)
5669 		dhcp4o6_start();
5670 #endif
5671 
5672 	detach();
5673 
5674 	if (client->old_lease != NULL) {
5675 		dhc6_lease_destroy(&client->old_lease, MDL);
5676 		client->old_lease = NULL;
5677 	}
5678 
5679 	/* Schedule events. */
5680 	dhc6_check_irt(client);
5681 }
5682 
5683 /* While informed, ignore packets.
5684  */
5685 void
informed_handler(struct packet * packet,struct client_state * client)5686 informed_handler(struct packet *packet, struct client_state *client)
5687 {
5688 	log_debug("RCV: Input packets are ignored once bound.");
5689 }
5690 
5691 /* make_client6_options() fetches option caches relevant to the client's
5692  * scope and places them into the sent_options cache.  This cache is later
5693  * used to populate DHCPv6 output packets with options.
5694  */
5695 static void
make_client6_options(struct client_state * client,struct option_state ** op,struct dhc6_lease * lease,u_int8_t message)5696 make_client6_options(struct client_state *client, struct option_state **op,
5697 		     struct dhc6_lease *lease, u_int8_t message)
5698 {
5699 	struct option_cache *oc;
5700 	struct option **req;
5701 	struct buffer *buffer;
5702 	int buflen, i, oro_len;
5703 
5704 	if ((op == NULL) || (client == NULL))
5705 		return;
5706 
5707 	if (*op)
5708 		option_state_dereference(op, MDL);
5709 
5710 	/* Create a cache to carry options to transmission. */
5711 	option_state_allocate(op, MDL);
5712 
5713 	/* Create and store an 'elapsed time' option in the cache. */
5714 	oc = NULL;
5715 	if (option_cache_allocate(&oc, MDL)) {
5716 		const unsigned char *cdata;
5717 
5718 		cdata = (unsigned char *)&client->elapsed;
5719 
5720 		if (make_const_data(&oc->expression, cdata, 2, 0, 0, MDL)) {
5721 			option_reference(&oc->option, elapsed_option, MDL);
5722 			save_option(&dhcpv6_universe, *op, oc);
5723 		}
5724 
5725 		option_cache_dereference(&oc, MDL);
5726 	}
5727 
5728 	/* Bring in any configured options to send. */
5729 	if (client->config->on_transmission)
5730 		execute_statements_in_scope(NULL, NULL, NULL, client,
5731 					    lease ? lease->options : NULL,
5732 					    *op, &global_scope,
5733 					    client->config->on_transmission,
5734 					    NULL, NULL);
5735 
5736 	/* Rapid-commit is only for SOLICITs. */
5737 	if (message != DHCPV6_SOLICIT)
5738 		delete_option(&dhcpv6_universe, *op, D6O_RAPID_COMMIT);
5739 
5740 	/* See if the user configured a DUID in a relevant scope.  If not,
5741 	 * introduce our default manufactured id.
5742 	 */
5743 	if ((oc = lookup_option(&dhcpv6_universe, *op,
5744 				D6O_CLIENTID)) == NULL) {
5745 		if (!option_cache(&oc, &default_duid, NULL, clientid_option,
5746 				  MDL))
5747 			log_fatal("Failure assembling a DUID.");
5748 
5749 		save_option(&dhcpv6_universe, *op, oc);
5750 		option_cache_dereference(&oc, MDL);
5751 	}
5752 
5753 	/* In cases where we're responding to a single server, put the
5754 	 * server's id in the response.
5755 	 *
5756 	 * Note that lease is NULL for SOLICIT or INFO request messages,
5757 	 * and otherwise MUST be present.
5758 	 */
5759 	if (lease == NULL) {
5760 		if ((message != DHCPV6_SOLICIT) &&
5761 		    (message != DHCPV6_INFORMATION_REQUEST))
5762 			log_fatal("Impossible condition at %s:%d.", MDL);
5763 	} else if ((message != DHCPV6_REBIND) &&
5764 		   (message != DHCPV6_CONFIRM)) {
5765 		oc = lookup_option(&dhcpv6_universe, lease->options,
5766 				   D6O_SERVERID);
5767 		if (oc != NULL)
5768 			save_option(&dhcpv6_universe, *op, oc);
5769 	}
5770 
5771 	/* 'send dhcp6.oro foo;' syntax we used in 4.0.0a1/a2 has been
5772 	 * deprecated by adjustments to the 'request' syntax also used for
5773 	 * DHCPv4.
5774 	 */
5775 	if (lookup_option(&dhcpv6_universe, *op, D6O_ORO) != NULL)
5776 		log_error("'send dhcp6.oro' syntax is deprecated, please "
5777 			  "use the 'request' syntax (\"man dhclient.conf\").");
5778 
5779 	/* Construct and store an ORO (Option Request Option).  It is a
5780 	 * fatal error to fail to send an ORO (of at least zero length).
5781 	 *
5782 	 * Discussion:  RFC3315 appears to be inconsistent in its statements
5783 	 * of whether or not the ORO is mandatory.  In section 18.1.1
5784 	 * ("Creation and Transmission of Request Messages"):
5785 	 *
5786 	 *    The client MUST include an Option Request option (see section
5787 	 *    22.7) to indicate the options the client is interested in
5788 	 *    receiving.  The client MAY include options with data values as
5789 	 *    hints to the server about parameter values the client would like
5790 	 *    to have returned.
5791 	 *
5792 	 * This MUST is missing from the creation/transmission of other
5793 	 * messages (such as Renew and Rebind), and the section 22.7 ("Option
5794 	 * Request Option" format and definition):
5795 	 *
5796 	 *    A client MAY include an Option Request option in a Solicit,
5797 	 *    Request, Renew, Rebind, Confirm or Information-request message to
5798 	 *    inform the server about options the client wants the server to
5799 	 *    send to the client.  A server MAY include an Option Request
5800 	 *    option in a Reconfigure option to indicate which options the
5801 	 *    client should request from the server.
5802 	 *
5803 	 * seems to relax the requirement from MUST to MAY (and still other
5804 	 * language in RFC3315 supports this).
5805 	 *
5806 	 * In lieu of a clarification of RFC3315, we will conform with the
5807 	 * MUST.  Instead of an absent ORO, we will if there are no options
5808 	 * to request supply an empty ORO.  Theoretically, an absent ORO is
5809 	 * difficult to interpret (does the client want all options or no
5810 	 * options?).  A zero-length ORO is intuitively clear: requesting
5811 	 * nothing.
5812 	 */
5813 	buffer = NULL;
5814 	oro_len = 0;
5815 	buflen = 32;
5816 	if (!buffer_allocate(&buffer, buflen, MDL))
5817 		log_fatal("Out of memory constructing DHCPv6 ORO.");
5818 	req = client->config->requested_options;
5819 	if (req != NULL) {
5820 		for (i = 0 ; req[i] != NULL ; i++) {
5821 			if (buflen == oro_len) {
5822 				struct buffer *tmpbuf = NULL;
5823 
5824 				buflen += 32;
5825 
5826 				/* Shell game. */
5827 				buffer_reference(&tmpbuf, buffer, MDL);
5828 				buffer_dereference(&buffer, MDL);
5829 
5830 				if (!buffer_allocate(&buffer, buflen, MDL))
5831 					log_fatal("Out of memory resizing "
5832 						  "DHCPv6 ORO buffer.");
5833 
5834 				memcpy(buffer->data, tmpbuf->data, oro_len);
5835 
5836 				buffer_dereference(&tmpbuf, MDL);
5837 			}
5838 
5839 			if (req[i]->universe == &dhcpv6_universe) {
5840 				/* Append the code to the ORO. */
5841 				putUShort(buffer->data + oro_len,
5842 					  req[i]->code);
5843 				oro_len += 2;
5844 			}
5845 		}
5846 	}
5847 
5848 	oc = NULL;
5849 	if (make_const_option_cache(&oc, &buffer, NULL, oro_len,
5850 				    oro_option, MDL)) {
5851 		save_option(&dhcpv6_universe, *op, oc);
5852 	} else {
5853 		log_fatal("Unable to create ORO option cache.");
5854 	}
5855 
5856 	/*
5857 	 * Note: make_const_option_cache() consumes the buffer, we do not
5858 	 * need to dereference it (XXX).
5859 	 */
5860 	option_cache_dereference(&oc, MDL);
5861 }
5862 
5863 /* A clone of the DHCPv4 script_write_params() minus the DHCPv4-specific
5864  * filename, server-name, etc specifics.
5865  *
5866  * Simply, store all values present in all universes of the option state
5867  * (probably derived from a DHCPv6 packet) into environment variables
5868  * named after the option names (and universe names) but with the 'prefix'
5869  * prepended.
5870  *
5871  * Later, dhclient-script may compare for example "new_time_servers" and
5872  * "old_time_servers" for differences, and only upon detecting a change
5873  * bother to rewrite ntp.conf and restart it.  Or something along those
5874  * generic lines.
5875  */
5876 static void
script_write_params6(struct client_state * client,const char * prefix,struct option_state * options)5877 script_write_params6(struct client_state *client, const char *prefix,
5878 		     struct option_state *options)
5879 {
5880 	struct envadd_state es;
5881 	int i;
5882 
5883 	if (options == NULL)
5884 		return;
5885 
5886 	es.client = client;
5887 	es.prefix = prefix;
5888 
5889 	for (i = 0 ; i < options->universe_count ; i++) {
5890 		option_space_foreach(NULL, NULL, client, NULL, options,
5891 				     &global_scope, universes[i], &es,
5892 				     client_option_envadd);
5893 	}
5894 }
5895 
5896 /*
5897  * A clone of the DHCPv4 routine.
5898  * Write out the environment variables for the objects that the
5899  * client requested.  If the object was requested the variable will be:
5900  * requested_<option_name>=1
5901  * If it wasn't requested there won't be a variable.
5902  */
script_write_requested6(client)5903 static void script_write_requested6(client)
5904 	struct client_state *client;
5905 {
5906 	int i;
5907 	struct option **req;
5908 	char name[256];
5909 	req = client->config->requested_options;
5910 
5911 	if (req == NULL)
5912 		return;
5913 
5914 	for (i = 0 ; req[i] != NULL ; i++) {
5915 		if ((req[i]->universe == &dhcpv6_universe) &&
5916 		    dhcp_option_ev_name (name, sizeof(name), req[i])) {
5917 			client_envadd(client, "requested_", name, "%d", 1);
5918 		}
5919 	}
5920 }
5921 
5922 /*
5923  * Check if there is something not fully defined in the active lease.
5924  */
5925 static isc_boolean_t
active_prefix(struct client_state * client)5926 active_prefix(struct client_state *client)
5927 {
5928 	struct dhc6_lease *lease;
5929 	struct dhc6_ia *ia;
5930 	struct dhc6_addr *pref;
5931 	char zeros[16];
5932 
5933 	lease = client->active_lease;
5934 	if (lease == NULL)
5935 		return ISC_FALSE;
5936 	memset(zeros, 0, 16);
5937 	for (ia = lease->bindings; ia != NULL; ia = ia->next) {
5938 		if (ia->ia_type != D6O_IA_PD)
5939 			continue;
5940 		for (pref = ia->addrs; pref != NULL; pref = pref->next) {
5941 			if (pref->plen == 0)
5942 				return ISC_FALSE;
5943 			if (pref->address.len != 16)
5944 				return ISC_FALSE;
5945 			if (memcmp(pref->address.iabuf, zeros, 16) == 0)
5946 				return ISC_FALSE;
5947 		}
5948 	}
5949 	return ISC_TRUE;
5950 }
5951 
5952 /* Adds a leases's declined addreses to the outbound packet
5953  *
5954  * For each IA_NA in the lease that contains one or more declined
5955  * addresses, an IA_NA option with an iasubopt for each declined
5956  * address is added to the outbound packet.
5957  *
5958  * We skip PDs and TAs as declines are undefined for them.
5959  */
5960 static isc_result_t
dhc6_add_ia_na_decline(struct client_state * client,struct data_string * packet,struct dhc6_lease * lease)5961 dhc6_add_ia_na_decline(struct client_state *client, struct data_string *packet,
5962 		       struct dhc6_lease *lease) {
5963 	struct data_string iads;
5964 	struct data_string addrds;
5965 	struct dhc6_addr *addr;
5966 	struct dhc6_ia *ia;
5967 	isc_result_t rval = ISC_R_SUCCESS;
5968 
5969 	memset(&iads, 0, sizeof(iads));
5970 	memset(&addrds, 0, sizeof(addrds));
5971 	for (ia = lease->bindings; ia != NULL && rval == ISC_R_SUCCESS;
5972 	     ia = ia->next) {
5973 		if (ia->ia_type != D6O_IA_NA)
5974 			continue;
5975 
5976 		int start_new_ia = 1;
5977 		for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
5978 			/*
5979 			 * Do not confirm expired addresses, do not request
5980 			 * expired addresses (but we keep them around for
5981 			 * solicit).
5982 			 */
5983 			if (!(addr->flags & DHC6_ADDR_DECLINED)) {
5984 				continue;
5985 			}
5986 
5987 			if (start_new_ia) {
5988 				if (!buffer_allocate(&iads.buffer, 12, MDL)) {
5989 					log_error("Unable to allocate memory"
5990 						  " for IA_NA.");
5991 					rval = ISC_R_NOMEMORY;
5992 					break;
5993 				}
5994 
5995 				/* Copy the IAID into the packet buffer. */
5996 				memcpy(iads.buffer->data, ia->iaid, 4);
5997 				iads.data = iads.buffer->data;
5998 				iads.len = 12;
5999 
6000 				/* Set t1/t2 to zero; server will ignore them */
6001 				memset(iads.buffer->data + 4, 0, 8);
6002 				log_debug("XMT:  X-- IA_NA %s",
6003 				print_hex_1(4, iads.buffer->data, 55));
6004 				start_new_ia = 0;
6005 			}
6006 
6007 			if (addr->address.len != 16) {
6008 				log_error("Illegal IPv6 address length (%d), "
6009 					  "ignoring.  (%s:%d)",
6010 					  addr->address.len, MDL);
6011 				continue;
6012 			}
6013 
6014 			if (!buffer_allocate(&addrds.buffer, 24, MDL)) {
6015 				log_error("Unable to allocate memory for "
6016 					  "IAADDR.");
6017 				rval = ISC_R_NOMEMORY;
6018 				break;
6019 			}
6020 
6021 			addrds.data = addrds.buffer->data;
6022 			addrds.len = 24;
6023 
6024 			/* Copy the address into the packet buffer. */
6025 			memcpy(addrds.buffer->data, addr->address.iabuf, 16);
6026 
6027 			/* Preferred and max life are irrelevant */
6028 			memset(addrds.buffer->data + 16, 0, 8);
6029 			log_debug("XMT:  | X-- Decline Address %s",
6030 				  piaddr(addr->address));
6031 
6032 			append_option(&iads, &dhcpv6_universe, iaaddr_option,
6033 				      &addrds);
6034 			data_string_forget(&addrds, MDL);
6035 		}
6036 
6037 		/*
6038 		 * It doesn't make sense to make a request without an
6039 		 * address.
6040 		 */
6041 		if (ia->addrs == NULL) {
6042 			log_debug("!!!:  V IA_NA has no IAADDRs - removed.");
6043 			rval = ISC_R_FAILURE;
6044 		} else if (rval == ISC_R_SUCCESS) {
6045 			log_debug("XMT:  V IA_NA appended.");
6046 			append_option(packet, &dhcpv6_universe, ia_na_option,
6047 				      &iads);
6048 		}
6049 
6050 		data_string_forget(&iads, MDL);
6051 	}
6052 
6053 	return (rval);
6054 }
6055 
6056 /*
6057  * Remove any declined NA addresses from the lease.
6058  *
6059  * Returns zero if the all of the bindings on the lease
6060  * were removed, non-zero if there are PD, TA, or usuable NA
6061  * bindings
6062  */
drop_declined_addrs(struct dhc6_lease * lease)6063 int drop_declined_addrs(struct dhc6_lease *lease) {
6064 	struct dhc6_ia *ia;
6065 	int live_cnt = 0;
6066 
6067 	for (ia = lease->bindings; ia != NULL; ia = ia->next) {
6068 		struct dhc6_addr* prev_addr;
6069 		struct dhc6_addr* addr;
6070 		struct dhc6_addr* next;
6071 
6072 		/* If it's a PD or TA, we assume it has at least
6073 		* one usuable binding */
6074 		if (ia->ia_type != D6O_IA_NA) {
6075 			live_cnt++;
6076 			continue;
6077 		}
6078 
6079 		prev_addr = NULL;
6080 		for (addr = ia->addrs ; addr != NULL ; ) {
6081 			if (!(addr->flags & DHC6_ADDR_DECLINED))  {
6082 				live_cnt++;
6083 				addr = addr->next;
6084 				prev_addr = addr;
6085 				continue;
6086 			}
6087 
6088 			/* If we're deleting head, move it up one */
6089 			if (ia->addrs == addr) {
6090 				ia->addrs = addr->next;
6091 				prev_addr = addr->next;
6092 			} else {
6093 				prev_addr->next = addr->next;
6094 			}
6095 
6096 			if (addr->options != NULL) {
6097                         	option_state_dereference(&addr->options, MDL);
6098 			}
6099 
6100 			next = addr->next;
6101 			dfree(addr, MDL);
6102 			addr = next;
6103 		}
6104 	}
6105 
6106 	return (live_cnt);
6107 }
6108 
6109 /* Run through the addresses in lease and return true if there's any unexpired.
6110  * Return false otherwise.
6111  */
6112 static isc_boolean_t
unexpired_address_in_lease(struct dhc6_lease * lease)6113 unexpired_address_in_lease(struct dhc6_lease *lease)
6114 {
6115 	struct dhc6_ia *ia;
6116 	struct dhc6_addr *addr;
6117 
6118 	if (lease == NULL) {
6119 		return ISC_FALSE;
6120 	}
6121 
6122 	for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
6123 		for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
6124 			if (!(addr->flags & DHC6_ADDR_EXPIRED) &&
6125 			    (addr->starts + addr->max_life > cur_time)) {
6126 				return ISC_TRUE;
6127 			}
6128 		}
6129 	}
6130 
6131 	log_debug("PRC: Previous lease is devoid of active addresses.");
6132 	return ISC_FALSE;
6133 }
6134 #endif /* DHCPv6 */
6135