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