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