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