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