ISC DHCP  4.3.2
A reference DHCPv4 and DHCPv6 implementation
dhc6.c
Go to the documentation of this file.
1 /* dhc6.c - DHCPv6 client routines. */
2 
3 /*
4  * Copyright (c) 2012-2014 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  if (dhc6_check_advertise(lease) != ISC_R_SUCCESS) {
2835  log_debug("PRC: Lease failed to satisfy.");
2836  dhc6_lease_destroy(&lease, MDL);
2837  return;
2838  }
2839 
2840  insert_lease(&client->advertised_leases, lease);
2841 
2842  /* According to RFC3315 section 17.1.2, the client MUST wait for
2843  * the first RT before selecting a lease. But on the 400th RT,
2844  * we dont' want to wait the full timeout if we finally get an
2845  * advertise. We could probably wait a second, but ohwell,
2846  * RFC3315 doesn't say so.
2847  *
2848  * If the lease is highest possible preference, 255, RFC3315 claims
2849  * we should continue immediately even on the first RT. We probably
2850  * should not if the advertise contains less than one IA and address.
2851  */
2852  if ((client->txcount > 1) ||
2853  ((lease->pref == 255) &&
2854  (dhc6_score_lease(client, lease) > 150))) {
2855  log_debug("RCV: Advertisement immediately selected.");
2856  cancel_timeout(do_init6, client);
2857  start_selecting6(client);
2858  } else
2859  log_debug("RCV: Advertisement recorded.");
2860 }
2861 
2862 /* info_request_handler() accepts a Reply to an Info-request.
2863  */
2864 void
2865 info_request_handler(struct packet *packet, struct client_state *client)
2866 {
2867  isc_result_t check_status;
2868  unsigned code;
2869 
2870  if (packet->dhcpv6_msg_type != DHCPV6_REPLY)
2871  return;
2872 
2873  /* RFC3315 section 15.10 validation (same as 15.3 since we
2874  * always include a client id).
2875  */
2876  if (!valid_reply(packet, client)) {
2877  log_error("Invalid Reply - rejecting.");
2878  return;
2879  }
2880 
2881  check_status = dhc6_check_status(ISC_R_SUCCESS, packet->options,
2882  "message", &code);
2883  if (check_status != ISC_R_SUCCESS) {
2884  /* If no action was taken, but there is an error, then
2885  * we wait for a retransmission.
2886  */
2887  if (check_status != ISC_R_CANCELED)
2888  return;
2889  }
2890 
2891  /* We're done retransmitting at this point. */
2892  cancel_timeout(do_info_request6, client);
2893 
2894  /* Action was taken, so now that we've torn down our scheduled
2895  * retransmissions, return.
2896  */
2897  if (check_status == ISC_R_CANCELED)
2898  return;
2899 
2900  /* Cleanup if a previous attempt to go bound failed. */
2901  if (client->old_lease != NULL) {
2902  dhc6_lease_destroy(&client->old_lease, MDL);
2903  client->old_lease = NULL;
2904  }
2905 
2906  /* Cache options in the active_lease. */
2907  if (client->active_lease != NULL)
2908  client->old_lease = client->active_lease;
2909  client->active_lease = dmalloc(sizeof(struct dhc6_lease), MDL);
2910  if (client->active_lease == NULL)
2911  log_fatal("Out of memory for v6 lease structure.");
2913  packet->options, MDL);
2914 
2915  start_informed(client);
2916 }
2917 
2918 /* Specific version of init_handler() for rapid-commit.
2919  */
2920 void
2921 rapid_commit_handler(struct packet *packet, struct client_state *client)
2922 {
2923  struct dhc6_lease *lease;
2924  isc_result_t check_status;
2925 
2926  /* On ADVERTISE just fall back to the init_handler().
2927  */
2928  if (packet->dhcpv6_msg_type == DHCPV6_ADVERTISE) {
2929  init_handler(packet, client);
2930  return;
2931  } else if (packet->dhcpv6_msg_type != DHCPV6_REPLY)
2932  return;
2933 
2934  /* RFC3315 section 15.10 validation (same as 15.3 since we
2935  * always include a client id).
2936  */
2937  if (!valid_reply(packet, client)) {
2938  log_error("Invalid Reply - rejecting.");
2939  return;
2940  }
2941 
2942  /* A rapid-commit option MUST be here. */
2943  if (lookup_option(&dhcpv6_universe, packet->options,
2944  D6O_RAPID_COMMIT) == 0) {
2945  log_error("Reply without Rapid-Commit - rejecting.");
2946  return;
2947  }
2948 
2949  lease = dhc6_leaseify(packet);
2950 
2951  /* This is an out of memory condition...hopefully a temporary
2952  * problem. Returning now makes us try to retransmit later.
2953  */
2954  if (lease == NULL)
2955  return;
2956 
2957  check_status = dhc6_check_reply(client, lease);
2958  if (check_status != ISC_R_SUCCESS) {
2959  dhc6_lease_destroy(&lease, MDL);
2960  return;
2961  }
2962 
2963  /* Jump to the selecting state. */
2964  cancel_timeout(do_init6, client);
2965  client->state = S_SELECTING;
2966 
2967  /* Merge any bindings in the active lease (if there is one) into
2968  * the new active lease.
2969  */
2970  dhc6_merge_lease(client->active_lease, lease);
2971 
2972  /* Cleanup if a previous attempt to go bound failed. */
2973  if (client->old_lease != NULL) {
2974  dhc6_lease_destroy(&client->old_lease, MDL);
2975  client->old_lease = NULL;
2976  }
2977 
2978  /* Make this lease active and BIND to it. */
2979  if (client->active_lease != NULL)
2980  client->old_lease = client->active_lease;
2981  client->active_lease = lease;
2982 
2983  /* We're done with the ADVERTISEd leases, if any. */
2984  while(client->advertised_leases != NULL) {
2985  lease = client->advertised_leases;
2986  client->advertised_leases = lease->next;
2987 
2988  dhc6_lease_destroy(&lease, MDL);
2989  }
2990 
2991  start_bound(client);
2992 }
2993 
2994 /* Find the 'best' lease in the cache of advertised leases (usually). From
2995  * RFC3315 Section 17.1.3:
2996  *
2997  * Upon receipt of one or more valid Advertise messages, the client
2998  * selects one or more Advertise messages based upon the following
2999  * criteria.
3000  *
3001  * - Those Advertise messages with the highest server preference value
3002  * are preferred over all other Advertise messages.
3003  *
3004  * - Within a group of Advertise messages with the same server
3005  * preference value, a client MAY select those servers whose
3006  * Advertise messages advertise information of interest to the
3007  * client. For example, the client may choose a server that returned
3008  * an advertisement with configuration options of interest to the
3009  * client.
3010  *
3011  * - The client MAY choose a less-preferred server if that server has a
3012  * better set of advertised parameters, such as the available
3013  * addresses advertised in IAs.
3014  *
3015  * Note that the first and third contradict each other. The third should
3016  * probably be taken to mean that the client should prefer answers that
3017  * offer bindings, even if that violates the preference rule.
3018  *
3019  * The above also isn't deterministic where there are ties. So the final
3020  * tiebreaker we add, if all other values are equal, is to compare the
3021  * server identifiers and to select the numerically lower one.
3022  */
3023 static struct dhc6_lease *
3024 dhc6_best_lease(struct client_state *client, struct dhc6_lease **head)
3025 {
3026  struct dhc6_lease **rpos, *rval, **candp, *cand;
3027  int cscore, rscore;
3028 
3029  if (head == NULL || *head == NULL)
3030  return NULL;
3031 
3032  rpos = head;
3033  rval = *rpos;
3034  rscore = dhc6_score_lease(client, rval);
3035  candp = &rval->next;
3036  cand = *candp;
3037 
3038  log_debug("PRC: Considering best lease.");
3039  log_debug("PRC: X-- Initial candidate %s (s: %d, p: %u).",
3040  print_hex_1(rval->server_id.len,
3041  rval->server_id.data, 48),
3042  rscore, (unsigned)rval->pref);
3043 
3044  for (; cand != NULL ; candp = &cand->next, cand = *candp) {
3045  cscore = dhc6_score_lease(client, cand);
3046 
3047  log_debug("PRC: X-- Candidate %s (s: %d, p: %u).",
3048  print_hex_1(cand->server_id.len,
3049  cand->server_id.data, 48),
3050  cscore, (unsigned)cand->pref);
3051 
3052  /* Above you'll find quoted RFC3315 Section 17.1.3.
3053  *
3054  * The third clause tells us to give up on leases that
3055  * have no bindings even if their preference is better.
3056  * So where our 'selected' lease's score is less than 150
3057  * (1 ia + 1 addr), choose any candidate >= 150.
3058  *
3059  * The first clause tells us to make preference the primary
3060  * deciding factor. So if it's lower, reject, if it's
3061  * higher, select.
3062  *
3063  * The second clause tells us where the preference is
3064  * equal, we should use 'our judgement' of what we like
3065  * to see in an advertisement primarily.
3066  *
3067  * But there can still be a tie. To make this deterministic,
3068  * we compare the server identifiers and select the binary
3069  * lowest.
3070  *
3071  * Since server id's are unique in this list, there is
3072  * no further tie to break.
3073  */
3074  if ((rscore < 150) && (cscore >= 150)) {
3075  log_debug("PRC: | X-- Selected, has bindings.");
3076  } else if (cand->pref < rval->pref) {
3077  log_debug("PRC: | X-- Rejected, lower preference.");
3078  continue;
3079  } else if (cand->pref > rval->pref) {
3080  log_debug("PRC: | X-- Selected, higher preference.");
3081  } else if (cscore > rscore) {
3082  log_debug("PRC: | X-- Selected, equal preference, "
3083  "higher score.");
3084  } else if (cscore < rscore) {
3085  log_debug("PRC: | X-- Rejected, equal preference, "
3086  "lower score.");
3087  continue;
3088  } else if ((cand->server_id.len < rval->server_id.len) ||
3089  ((cand->server_id.len == rval->server_id.len) &&
3090  (memcmp(cand->server_id.data,
3091  rval->server_id.data,
3092  cand->server_id.len) < 0))) {
3093  log_debug("PRC: | X-- Selected, equal preference, "
3094  "equal score, binary lesser server ID.");
3095  } else {
3096  log_debug("PRC: | X-- Rejected, equal preference, "
3097  "equal score, binary greater server ID.");
3098  continue;
3099  }
3100 
3101  rpos = candp;
3102  rval = cand;
3103  rscore = cscore;
3104  }
3105 
3106  /* Remove the selected lease from the chain. */
3107  *rpos = rval->next;
3108 
3109  return rval;
3110 }
3111 
3112 /* Select a lease out of the advertised leases and setup state to try and
3113  * acquire that lease.
3114  */
3115 void
3116 start_selecting6(struct client_state *client)
3117 {
3118  struct dhc6_lease *lease;
3119 
3120  if (client->advertised_leases == NULL) {
3121  log_error("Can not enter DHCPv6 SELECTING state with no "
3122  "leases to select from!");
3123  return;
3124  }
3125 
3126  log_debug("PRC: Selecting best advertised lease.");
3127  client->state = S_SELECTING;
3128 
3129  lease = dhc6_best_lease(client, &client->advertised_leases);
3130 
3131  if (lease == NULL)
3132  log_fatal("Impossible error at %s:%d.", MDL);
3133 
3134  client->selected_lease = lease;
3135 
3136  /* Set timers per RFC3315 section 18.1.1. */
3137  client->IRT = REQ_TIMEOUT * 100;
3138  client->MRT = REQ_MAX_RT * 100;
3139  client->MRC = REQ_MAX_RC;
3140  client->MRD = 0;
3141 
3142  dhc6_retrans_init(client);
3143 
3144  client->v6_handler = reply_handler;
3145 
3146  /* ("re")transmit the first packet. */
3147  do_select6(client);
3148 }
3149 
3150 /* Transmit a Request to select a lease offered in Advertisements. In
3151  * the event of failure, either move on to the next-best advertised lease,
3152  * or head back to INIT state if there are none.
3153  */
3154 void
3155 do_select6(void *input)
3156 {
3157  struct client_state *client;
3158  struct dhc6_lease *lease;
3159  struct data_string ds;
3160  struct timeval tv;
3161  int send_ret;
3162 
3163  client = input;
3164 
3165  /* 'lease' is fewer characters to type. */
3166  lease = client->selected_lease;
3167  if (lease == NULL || lease->bindings == NULL) {
3168  log_error("Illegal to attempt selection without selecting "
3169  "a lease.");
3170  return;
3171  }
3172 
3173  switch(check_timing6(client, DHCPV6_REQUEST, "Request", lease, &ds)) {
3174  case CHK_TIM_MRC_EXCEEDED:
3175  case CHK_TIM_MRD_EXCEEDED:
3176  log_debug("PRC: Lease %s failed.",
3177  print_hex_1(lease->server_id.len,
3178  lease->server_id.data, 56));
3179 
3180  /* Get rid of the lease that timed/counted out. */
3181  dhc6_lease_destroy(&lease, MDL);
3182  client->selected_lease = NULL;
3183 
3184  /* If there are more leases great. If not, get more. */
3185  if (client->advertised_leases != NULL)
3186  start_selecting6(client);
3187  else
3188  start_init6(client);
3189  return;
3190  case CHK_TIM_ALLOC_FAILURE:
3191  return;
3192  case CHK_TIM_SUCCESS:
3193  break;
3194  }
3195 
3196  /* Now make a packet that looks suspiciously like the one we
3197  * got from the server. But different.
3198  *
3199  * XXX: I guess IAID is supposed to be something the client
3200  * indicates and uses as a key to its internal state. It is
3201  * kind of odd to ask the server for IA's whose IAID the client
3202  * did not manufacture. We first need a formal dhclient.conf
3203  * construct for the iaid, then we can delve into this matter
3204  * more properly. In the time being, this will work.
3205  */
3206 
3207  /* Fetch any configured 'sent' options (includes DUID) in wire format.
3208  */
3209  dhcpv6_universe.encapsulate(&ds, NULL, NULL, client,
3210  NULL, client->sent_options, &global_scope,
3211  &dhcpv6_universe);
3212 
3213  /* Now append any IA's, and within them any IAADDR/IAPREFIXs. */
3214  if (wanted_ia_na &&
3215  dhc6_add_ia_na(client, &ds, lease,
3216  DHCPV6_REQUEST) != ISC_R_SUCCESS) {
3217  data_string_forget(&ds, MDL);
3218  return;
3219  }
3220  if (wanted_ia_ta &&
3221  dhc6_add_ia_ta(client, &ds, lease,
3222  DHCPV6_REQUEST) != ISC_R_SUCCESS) {
3223  data_string_forget(&ds, MDL);
3224  return;
3225  }
3226  if (wanted_ia_pd &&
3227  dhc6_add_ia_pd(client, &ds, lease,
3228  DHCPV6_REQUEST) != ISC_R_SUCCESS) {
3229  data_string_forget(&ds, MDL);
3230  return;
3231  }
3232 
3233  log_info("XMT: Request on %s, interval %ld0ms.",
3234  client->name ? client->name : client->interface->name,
3235  (long int)client->RT);
3236 
3237  send_ret = send_packet6(client->interface,
3238  ds.data, ds.len, &DHCPv6DestAddr);
3239  if (send_ret != ds.len) {
3240  log_error("dhc6: send_packet6() sent %d of %d bytes",
3241  send_ret, ds.len);
3242  }
3243 
3244  data_string_forget(&ds, MDL);
3245 
3246  /* Wait RT */
3247  tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
3248  tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
3249  if (tv.tv_usec >= 1000000) {
3250  tv.tv_sec += 1;
3251  tv.tv_usec -= 1000000;
3252  }
3253  add_timeout(&tv, do_select6, client, NULL, NULL);
3254 
3255  dhc6_retrans_advance(client);
3256 }
3257 
3258 /* For each IA_NA in the lease, for each address in the IA_NA,
3259  * append that information onto the packet-so-far.
3260  */
3261 static isc_result_t
3262 dhc6_add_ia_na(struct client_state *client, struct data_string *packet,
3263  struct dhc6_lease *lease, u_int8_t message)
3264 {
3265  struct data_string iads;
3266  struct data_string addrds;
3267  struct dhc6_addr *addr;
3268  struct dhc6_ia *ia;
3269  isc_result_t rval = ISC_R_SUCCESS;
3270  TIME t1, t2;
3271 
3272  memset(&iads, 0, sizeof(iads));
3273  memset(&addrds, 0, sizeof(addrds));
3274  for (ia = lease->bindings;
3275  ia != NULL && rval == ISC_R_SUCCESS;
3276  ia = ia->next) {
3277  if (ia->ia_type != D6O_IA_NA)
3278  continue;
3279 
3280  if (!buffer_allocate(&iads.buffer, 12, MDL)) {
3281  log_error("Unable to allocate memory for IA_NA.");
3282  rval = ISC_R_NOMEMORY;
3283  break;
3284  }
3285 
3286  /* Copy the IAID into the packet buffer. */
3287  memcpy(iads.buffer->data, ia->iaid, 4);
3288  iads.data = iads.buffer->data;
3289  iads.len = 12;
3290 
3291  switch (message) {
3292  case DHCPV6_REQUEST:
3293  case DHCPV6_RENEW:
3294  case DHCPV6_REBIND:
3295 
3296  t1 = client->config->requested_lease / 2;
3297  t2 = t1 + (t1 / 2);
3298 #if MAX_TIME > 0xffffffff
3299  if (t1 > 0xffffffff)
3300  t1 = 0xffffffff;
3301  if (t2 > 0xffffffff)
3302  t2 = 0xffffffff;
3303 #endif
3304  putULong(iads.buffer->data + 4, t1);
3305  putULong(iads.buffer->data + 8, t2);
3306 
3307  log_debug("XMT: X-- IA_NA %s",
3308  print_hex_1(4, iads.data, 59));
3309  log_debug("XMT: | X-- Requested renew +%u",
3310  (unsigned) t1);
3311  log_debug("XMT: | X-- Requested rebind +%u",
3312  (unsigned) t2);
3313  break;
3314 
3315  case DHCPV6_CONFIRM:
3316  case DHCPV6_RELEASE:
3317  case DHCPV6_DECLINE:
3318  /* Set t1 and t2 to zero; server will ignore them */
3319  memset(iads.buffer->data + 4, 0, 8);
3320  log_debug("XMT: X-- IA_NA %s",
3321  print_hex_1(4, iads.buffer->data, 55));
3322 
3323  break;
3324 
3325  default:
3326  log_fatal("Impossible condition at %s:%d.", MDL);
3327  }
3328 
3329  for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
3330  /*
3331  * Do not confirm expired addresses, do not request
3332  * expired addresses (but we keep them around for
3333  * solicit).
3334  */
3335  if (addr->flags & DHC6_ADDR_EXPIRED)
3336  continue;
3337 
3338  if (addr->address.len != 16) {
3339  log_error("Illegal IPv6 address length (%d), "
3340  "ignoring. (%s:%d)",
3341  addr->address.len, MDL);
3342  continue;
3343  }
3344 
3345  if (!buffer_allocate(&addrds.buffer, 24, MDL)) {
3346  log_error("Unable to allocate memory for "
3347  "IAADDR.");
3348  rval = ISC_R_NOMEMORY;
3349  break;
3350  }
3351 
3352  addrds.data = addrds.buffer->data;
3353  addrds.len = 24;
3354 
3355  /* Copy the address into the packet buffer. */
3356  memcpy(addrds.buffer->data, addr->address.iabuf, 16);
3357 
3358  /* Copy in additional information as appropriate */
3359  switch (message) {
3360  case DHCPV6_REQUEST:
3361  case DHCPV6_RENEW:
3362  case DHCPV6_REBIND:
3363  t1 = client->config->requested_lease;
3364  t2 = t1 + 300;
3365  putULong(addrds.buffer->data + 16, t1);
3366  putULong(addrds.buffer->data + 20, t2);
3367 
3368  log_debug("XMT: | | X-- IAADDR %s",
3369  piaddr(addr->address));
3370  log_debug("XMT: | | | X-- Preferred "
3371  "lifetime +%u", (unsigned)t1);
3372  log_debug("XMT: | | | X-- Max lifetime +%u",
3373  (unsigned)t2);
3374 
3375  break;
3376 
3377  case DHCPV6_CONFIRM:
3378  /*
3379  * Set preferred and max life to zero,
3380  * per 17.1.3.
3381  */
3382  memset(addrds.buffer->data + 16, 0, 8);
3383  log_debug("XMT: | X-- Confirm Address %s",
3384  piaddr(addr->address));
3385  break;
3386 
3387  case DHCPV6_RELEASE:
3388  /* Preferred and max life are irrelevant */
3389  memset(addrds.buffer->data + 16, 0, 8);
3390  log_debug("XMT: | X-- Release Address %s",
3391  piaddr(addr->address));
3392  break;
3393 
3394  case DHCPV6_DECLINE:
3395  /* Preferred and max life are irrelevant */
3396  memset(addrds.buffer->data + 16, 0, 8);
3397  log_debug("XMT: | X-- Decline Address %s",
3398  piaddr(addr->address));
3399  break;
3400 
3401  default:
3402  log_fatal("Impossible condition at %s:%d.",
3403  MDL);
3404  }
3405 
3406  append_option(&iads, &dhcpv6_universe, iaaddr_option,
3407  &addrds);
3408  data_string_forget(&addrds, MDL);
3409  }
3410 
3411  /*
3412  * It doesn't make sense to make a request without an
3413  * address.
3414  */
3415  if (ia->addrs == NULL) {
3416  log_debug("!!!: V IA_NA has no IAADDRs - removed.");
3417  rval = ISC_R_FAILURE;
3418  } else if (rval == ISC_R_SUCCESS) {
3419  log_debug("XMT: V IA_NA appended.");
3420  append_option(packet, &dhcpv6_universe, ia_na_option,
3421  &iads);
3422  }
3423 
3424  data_string_forget(&iads, MDL);
3425  }
3426 
3427  return rval;
3428 }
3429 
3430 /* For each IA_TA in the lease, for each address in the IA_TA,
3431  * append that information onto the packet-so-far.
3432  */
3433 static isc_result_t
3434 dhc6_add_ia_ta(struct client_state *client, struct data_string *packet,
3435  struct dhc6_lease *lease, u_int8_t message)
3436 {
3437  struct data_string iads;
3438  struct data_string addrds;
3439  struct dhc6_addr *addr;
3440  struct dhc6_ia *ia;
3441  isc_result_t rval = ISC_R_SUCCESS;
3442  TIME t1, t2;
3443 
3444  memset(&iads, 0, sizeof(iads));
3445  memset(&addrds, 0, sizeof(addrds));
3446  for (ia = lease->bindings;
3447  ia != NULL && rval == ISC_R_SUCCESS;
3448  ia = ia->next) {
3449  if (ia->ia_type != D6O_IA_TA)
3450  continue;
3451 
3452  if (!buffer_allocate(&iads.buffer, 4, MDL)) {
3453  log_error("Unable to allocate memory for IA_TA.");
3454  rval = ISC_R_NOMEMORY;
3455  break;
3456  }
3457 
3458  /* Copy the IAID into the packet buffer. */
3459  memcpy(iads.buffer->data, ia->iaid, 4);
3460  iads.data = iads.buffer->data;
3461  iads.len = 4;
3462 
3463  log_debug("XMT: X-- IA_TA %s",
3464  print_hex_1(4, iads.buffer->data, 55));
3465 
3466  for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
3467  /*
3468  * Do not confirm expired addresses, do not request
3469  * expired addresses (but we keep them around for
3470  * solicit).
3471  */
3472  if (addr->flags & DHC6_ADDR_EXPIRED)
3473  continue;
3474 
3475  if (addr->address.len != 16) {
3476  log_error("Illegal IPv6 address length (%d), "
3477  "ignoring. (%s:%d)",
3478  addr->address.len, MDL);
3479  continue;
3480  }
3481 
3482  if (!buffer_allocate(&addrds.buffer, 24, MDL)) {
3483  log_error("Unable to allocate memory for "
3484  "IAADDR.");
3485  rval = ISC_R_NOMEMORY;
3486  break;
3487  }
3488 
3489  addrds.data = addrds.buffer->data;
3490  addrds.len = 24;
3491 
3492  /* Copy the address into the packet buffer. */
3493  memcpy(addrds.buffer->data, addr->address.iabuf, 16);
3494 
3495  /* Copy in additional information as appropriate */
3496  switch (message) {
3497  case DHCPV6_REQUEST:
3498  case DHCPV6_RENEW:
3499  case DHCPV6_REBIND:
3500  t1 = client->config->requested_lease;
3501  t2 = t1 + 300;
3502  putULong(addrds.buffer->data + 16, t1);
3503  putULong(addrds.buffer->data + 20, t2);
3504 
3505  log_debug("XMT: | | X-- IAADDR %s",
3506  piaddr(addr->address));
3507  log_debug("XMT: | | | X-- Preferred "
3508  "lifetime +%u", (unsigned)t1);
3509  log_debug("XMT: | | | X-- Max lifetime +%u",
3510  (unsigned)t2);
3511 
3512  break;
3513 
3514  case DHCPV6_CONFIRM:
3515  /*
3516  * Set preferred and max life to zero,
3517  * per 17.1.3.
3518  */
3519  memset(addrds.buffer->data + 16, 0, 8);
3520  log_debug("XMT: | X-- Confirm Address %s",
3521  piaddr(addr->address));
3522  break;
3523 
3524  case DHCPV6_RELEASE:
3525  /* Preferred and max life are irrelevant */
3526  memset(addrds.buffer->data + 16, 0, 8);
3527  log_debug("XMT: | X-- Release Address %s",
3528  piaddr(addr->address));
3529  break;
3530 
3531  default:
3532  log_fatal("Impossible condition at %s:%d.",
3533  MDL);
3534  }
3535 
3536  append_option(&iads, &dhcpv6_universe, iaaddr_option,
3537  &addrds);
3538  data_string_forget(&addrds, MDL);
3539  }
3540 
3541  /*
3542  * It doesn't make sense to make a request without an
3543  * address.
3544  */
3545  if (ia->addrs == NULL) {
3546  log_debug("!!!: V IA_TA has no IAADDRs - removed.");
3547  rval = ISC_R_FAILURE;
3548  } else if (rval == ISC_R_SUCCESS) {
3549  log_debug("XMT: V IA_TA appended.");
3550  append_option(packet, &dhcpv6_universe, ia_ta_option,
3551  &iads);
3552  }
3553 
3554  data_string_forget(&iads, MDL);
3555  }
3556 
3557  return rval;
3558 }
3559 
3560 /* For each IA_PD in the lease, for each prefix in the IA_PD,
3561  * append that information onto the packet-so-far.
3562  */
3563 static isc_result_t
3564 dhc6_add_ia_pd(struct client_state *client, struct data_string *packet,
3565  struct dhc6_lease *lease, u_int8_t message)
3566 {
3567  struct data_string iads;
3568  struct data_string prefds;
3569  struct dhc6_addr *pref;
3570  struct dhc6_ia *ia;
3571  isc_result_t rval = ISC_R_SUCCESS;
3572  TIME t1, t2;
3573 
3574  memset(&iads, 0, sizeof(iads));
3575  memset(&prefds, 0, sizeof(prefds));
3576  for (ia = lease->bindings;
3577  ia != NULL && rval == ISC_R_SUCCESS;
3578  ia = ia->next) {
3579  if (ia->ia_type != D6O_IA_PD)
3580  continue;
3581 
3582  if (!buffer_allocate(&iads.buffer, 12, MDL)) {
3583  log_error("Unable to allocate memory for IA_PD.");
3584  rval = ISC_R_NOMEMORY;
3585  break;
3586  }
3587 
3588  /* Copy the IAID into the packet buffer. */
3589  memcpy(iads.buffer->data, ia->iaid, 4);
3590  iads.data = iads.buffer->data;
3591  iads.len = 12;
3592 
3593  switch (message) {
3594  case DHCPV6_REQUEST:
3595  case DHCPV6_RENEW:
3596  case DHCPV6_REBIND:
3597 
3598  t1 = client->config->requested_lease / 2;
3599  t2 = t1 + (t1 / 2);
3600 #if MAX_TIME > 0xffffffff
3601  if (t1 > 0xffffffff)
3602  t1 = 0xffffffff;
3603  if (t2 > 0xffffffff)
3604  t2 = 0xffffffff;
3605 #endif
3606  putULong(iads.buffer->data + 4, t1);
3607  putULong(iads.buffer->data + 8, t2);
3608 
3609  log_debug("XMT: X-- IA_PD %s",
3610  print_hex_1(4, iads.data, 59));
3611  log_debug("XMT: | X-- Requested renew +%u",
3612  (unsigned) t1);
3613  log_debug("XMT: | X-- Requested rebind +%u",
3614  (unsigned) t2);
3615  break;
3616 
3617  case DHCPV6_RELEASE:
3618  /* Set t1 and t2 to zero; server will ignore them */
3619  memset(iads.buffer->data + 4, 0, 8);
3620  log_debug("XMT: X-- IA_PD %s",
3621  print_hex_1(4, iads.buffer->data, 55));
3622 
3623  break;
3624 
3625  default:
3626  log_fatal("Impossible condition at %s:%d.", MDL);
3627  }
3628 
3629  for (pref = ia->addrs ; pref != NULL ; pref = pref->next) {
3630  /*
3631  * Do not confirm expired prefixes, do not request
3632  * expired prefixes (but we keep them around for
3633  * solicit).
3634  */
3635  if (pref->flags & DHC6_ADDR_EXPIRED)
3636  continue;
3637 
3638  if (pref->address.len != 16) {
3639  log_error("Illegal IPv6 prefix "
3640  "ignoring. (%s:%d)",
3641  MDL);
3642  continue;
3643  }
3644 
3645  if (pref->plen == 0) {
3646  log_info("Null IPv6 prefix, "
3647  "ignoring. (%s:%d)",
3648  MDL);
3649  }
3650 
3651  if (!buffer_allocate(&prefds.buffer, 25, MDL)) {
3652  log_error("Unable to allocate memory for "
3653  "IAPREFIX.");
3654  rval = ISC_R_NOMEMORY;
3655  break;
3656  }
3657 
3658  prefds.data = prefds.buffer->data;
3659  prefds.len = 25;
3660 
3661  /* Copy the prefix into the packet buffer. */
3662  putUChar(prefds.buffer->data + 8, pref->plen);
3663  memcpy(prefds.buffer->data + 9,
3664  pref->address.iabuf,
3665  16);
3666 
3667  /* Copy in additional information as appropriate */
3668  switch (message) {
3669  case DHCPV6_REQUEST:
3670  case DHCPV6_RENEW:
3671  case DHCPV6_REBIND:
3672  t1 = client->config->requested_lease;
3673  t2 = t1 + 300;
3674  putULong(prefds.buffer->data, t1);
3675  putULong(prefds.buffer->data + 4, t2);
3676 
3677  log_debug("XMT: | | X-- IAPREFIX %s/%u",
3678  piaddr(pref->address),
3679  (unsigned) pref->plen);
3680  log_debug("XMT: | | | X-- Preferred "
3681  "lifetime +%u", (unsigned)t1);
3682  log_debug("XMT: | | | X-- Max lifetime +%u",
3683  (unsigned)t2);
3684 
3685  break;
3686 
3687  case DHCPV6_RELEASE:
3688  /* Preferred and max life are irrelevant */
3689  memset(prefds.buffer->data, 0, 8);
3690  log_debug("XMT: | X-- Release Prefix %s/%u",
3691  piaddr(pref->address),
3692  (unsigned) pref->plen);
3693  break;
3694 
3695  default:
3696  log_fatal("Impossible condition at %s:%d.",
3697  MDL);
3698  }
3699 
3701  iaprefix_option, &prefds);
3702  data_string_forget(&prefds, MDL);
3703  }
3704 
3705  /*
3706  * It doesn't make sense to make a request without an
3707  * address.
3708  */
3709  if (ia->addrs == NULL) {
3710  log_debug("!!!: V IA_PD has no IAPREFIXs - removed.");
3711  rval = ISC_R_FAILURE;
3712  } else if (rval == ISC_R_SUCCESS) {
3713  log_debug("XMT: V IA_PD appended.");
3714  append_option(packet, &dhcpv6_universe,
3715  ia_pd_option, &iads);
3716  }
3717 
3718  data_string_forget(&iads, MDL);
3719  }
3720 
3721  return rval;
3722 }
3723 
3724 /* stopping_finished() checks if there is a remaining work to do.
3725  */
3726 static isc_boolean_t
3727 stopping_finished(void)
3728 {
3729  struct interface_info *ip;
3730  struct client_state *client;
3731 
3732  for (ip = interfaces; ip; ip = ip -> next) {
3733  for (client = ip -> client; client; client = client -> next) {
3734  if (client->state != S_STOPPED)
3735  return ISC_FALSE;
3736  if (client->active_lease != NULL)
3737  return ISC_FALSE;
3738  }
3739  }
3740  return ISC_TRUE;
3741 }
3742 
3743 /* reply_handler() accepts a Reply while we're attempting Select or Renew or
3744  * Rebind. Basically any Reply packet.
3745  */
3746 void
3747 reply_handler(struct packet *packet, struct client_state *client)
3748 {
3749  struct dhc6_lease *lease;
3750  isc_result_t check_status;
3751 
3752  if (packet->dhcpv6_msg_type != DHCPV6_REPLY)
3753  return;
3754 
3755  /* RFC3315 section 15.10 validation (same as 15.3 since we
3756  * always include a client id).
3757  */
3758  if (!valid_reply(packet, client)) {
3759  log_error("Invalid Reply - rejecting.");
3760  return;
3761  }
3762 
3763  lease = dhc6_leaseify(packet);
3764 
3765  /* This is an out of memory condition...hopefully a temporary
3766  * problem. Returning now makes us try to retransmit later.
3767  */
3768  if (lease == NULL)
3769  return;
3770 
3771  check_status = dhc6_check_reply(client, lease);
3772  if (check_status != ISC_R_SUCCESS) {
3773  dhc6_lease_destroy(&lease, MDL);
3774 
3775  /* If no action was taken, but there is an error, then
3776  * we wait for a retransmission.
3777  */
3778  if (check_status != ISC_R_CANCELED)
3779  return;
3780  }
3781 
3782  /* We're done retransmitting at this point. */
3783  cancel_timeout(do_confirm6, client);
3784  cancel_timeout(do_select6, client);
3785  cancel_timeout(do_refresh6, client);
3786  cancel_timeout(do_release6, client);
3787  cancel_timeout(do_decline6, client);
3788 
3789  /* If this is in response to a Release/Decline, clean up and return. */
3790  if ((client->state == S_STOPPED) ||
3791  (client->state == S_DECLINED)) {
3792 
3793  if (client->active_lease != NULL) {
3794  dhc6_lease_destroy(&client->active_lease, MDL);
3795  client->active_lease = NULL;
3796  /* We should never wait for nothing!? */
3797  if (stopping_finished())
3798  exit(0);
3799  }
3800 
3801  if (client->state == S_DECLINED)
3802  start_init6(client);
3803 
3804  return;
3805  }
3806 
3807  /* Action was taken, so now that we've torn down our scheduled
3808  * retransmissions, return.
3809  */
3810  if (check_status == ISC_R_CANCELED)
3811  return;
3812 
3813  if (client->selected_lease != NULL) {
3815  client->selected_lease = NULL;
3816  }
3817 
3818  /* If this is in response to a confirm, we use the lease we've
3819  * already got, not the reply we were sent.
3820  */
3821  if (client->state == S_REBOOTING) {
3822  if (client->active_lease == NULL)
3823  log_fatal("Impossible condition at %s:%d.", MDL);
3824 
3825  dhc6_lease_destroy(&lease, MDL);
3826  start_bound(client);
3827  return;
3828  }
3829 
3830  /* Merge any bindings in the active lease (if there is one) into
3831  * the new active lease.
3832  */
3833  dhc6_merge_lease(client->active_lease, lease);
3834 
3835  /* Cleanup if a previous attempt to go bound failed. */
3836  if (client->old_lease != NULL) {
3837  dhc6_lease_destroy(&client->old_lease, MDL);
3838  client->old_lease = NULL;
3839  }
3840 
3841  /* Make this lease active and BIND to it. */
3842  if (client->active_lease != NULL)
3843  client->old_lease = client->active_lease;
3844  client->active_lease = lease;
3845 
3846  /* We're done with the ADVERTISEd leases, if any. */
3847  while(client->advertised_leases != NULL) {
3848  lease = client->advertised_leases;
3849  client->advertised_leases = lease->next;
3850 
3851  dhc6_lease_destroy(&lease, MDL);
3852  }
3853 
3854  start_bound(client);
3855 }
3856 
3857 /* DHCPv6 packets are a little sillier than they needed to be - the root
3858  * packet contains options, then IA's which contain options, then within
3859  * that IAADDR's which contain options.
3860  *
3861  * To sort this out at dhclient-script time (which fetches config parameters
3862  * in environment variables), start_bound() iterates over each IAADDR, and
3863  * calls this function to marshall an environment variable set that includes
3864  * the most-specific option values related to that IAADDR in particular.
3865  *
3866  * To achieve this, we load environment variables for the root options space,
3867  * then the IA, then the IAADDR. Any duplicate option names will be
3868  * over-written by the later versions.
3869  */
3870 static void
3871 dhc6_marshall_values(const char *prefix, struct client_state *client,
3872  struct dhc6_lease *lease, struct dhc6_ia *ia,
3873  struct dhc6_addr *addr)
3874 {
3875  /* Option cache contents, in descending order of
3876  * scope.
3877  */
3878  if ((lease != NULL) && (lease->options != NULL))
3879  script_write_params6(client, prefix, lease->options);
3880  if ((ia != NULL) && (ia->options != NULL))
3881  script_write_params6(client, prefix, ia->options);
3882  if ((addr != NULL) && (addr->options != NULL))
3883  script_write_params6(client, prefix, addr->options);
3884 
3885  /* addr fields. */
3886  if (addr != NULL) {
3887  if ((ia != NULL) && (ia->ia_type == D6O_IA_PD)) {
3888  client_envadd(client, prefix,
3889  "ip6_prefix", "%s/%u",
3890  piaddr(addr->address),
3891  (unsigned) addr->plen);
3892  } else {
3893  client_envadd(client, prefix, "ip6_prefixlen",
3895  client_envadd(client, prefix, "ip6_address",
3896  "%s", piaddr(addr->address));
3897  }
3898  if ((ia != NULL) && (ia->ia_type == D6O_IA_TA)) {
3899  client_envadd(client, prefix,
3900  "ip6_type", "temporary");
3901  }
3902  client_envadd(client, prefix, "life_starts", "%d",
3903  (int)(addr->starts));
3904  client_envadd(client, prefix, "preferred_life", "%u",
3905  addr->preferred_life);
3906  client_envadd(client, prefix, "max_life", "%u",
3907  addr->max_life);
3908  }
3909 
3910  /* ia fields. */
3911  if (ia != NULL) {
3912  client_envadd(client, prefix, "iaid", "%s",
3913  print_hex_1(4, ia->iaid, 12));
3914  client_envadd(client, prefix, "starts", "%d",
3915  (int)(ia->starts));
3916  client_envadd(client, prefix, "renew", "%u", ia->renew);
3917  client_envadd(client, prefix, "rebind", "%u", ia->rebind);
3918  }
3919 }
3920 
3921 /* Look at where the client's active lease is sitting. If it's looking to
3922  * time out on renew, rebind, depref, or expiration, do those things.
3923  */
3924 static void
3925 dhc6_check_times(struct client_state *client)
3926 {
3927  struct dhc6_lease *lease;
3928  struct dhc6_ia *ia;
3929  struct dhc6_addr *addr;
3930  TIME renew=MAX_TIME, rebind=MAX_TIME, depref=MAX_TIME,
3931  lo_expire=MAX_TIME, hi_expire=0, tmp;
3932  int has_addrs = ISC_FALSE;
3933  struct timeval tv;
3934 
3935  lease = client->active_lease;
3936 
3937  /* Bit spammy. We should probably keep record of scheduled
3938  * events instead.
3939  */
3940  cancel_timeout(start_renew6, client);
3941  cancel_timeout(start_rebind6, client);
3942  cancel_timeout(do_depref, client);
3943  cancel_timeout(do_expire, client);
3944 
3945  for(ia = lease->bindings ; ia != NULL ; ia = ia->next) {
3946  TIME this_ia_lo_expire, this_ia_hi_expire, use_expire;
3947 
3948  this_ia_lo_expire = MAX_TIME;
3949  this_ia_hi_expire = 0;
3950 
3951  for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
3952  if(!(addr->flags & DHC6_ADDR_DEPREFFED)) {
3953  if (addr->preferred_life == 0xffffffff)
3954  tmp = MAX_TIME;
3955  else
3956  tmp = addr->starts +
3957  addr->preferred_life;
3958 
3959  if (tmp < depref)
3960  depref = tmp;
3961  }
3962 
3963  if (!(addr->flags & DHC6_ADDR_EXPIRED)) {
3964  /* Find EPOCH-relative expiration. */
3965  if (addr->max_life == 0xffffffff)
3966  tmp = MAX_TIME;
3967  else
3968  tmp = addr->starts + addr->max_life;
3969 
3970  /* Make the times ia->starts relative. */
3971  tmp -= ia->starts;
3972 
3973  if (tmp > this_ia_hi_expire)
3974  this_ia_hi_expire = tmp;
3975  if (tmp < this_ia_lo_expire)
3976  this_ia_lo_expire = tmp;
3977 
3978  has_addrs = ISC_TRUE;
3979  }
3980  }
3981 
3982  /* These times are ia->starts relative. */
3983  if (this_ia_lo_expire <= (this_ia_hi_expire / 2))
3984  use_expire = this_ia_hi_expire;
3985  else
3986  use_expire = this_ia_lo_expire;
3987 
3988  /*
3989  * If the auto-selected expiration time is "infinite", or
3990  * zero, assert a reasonable default.
3991  */
3992  if ((use_expire == MAX_TIME) || (use_expire <= 1))
3993  use_expire = client->config->requested_lease / 2;
3994  else
3995  use_expire /= 2;
3996 
3997  /* Don't renew/rebind temporary addresses. */
3998  if (ia->ia_type != D6O_IA_TA) {
3999 
4000  if (ia->renew == 0) {
4001  tmp = ia->starts + use_expire;
4002  } else if (ia->renew == 0xffffffff)
4003  tmp = MAX_TIME;
4004  else
4005  tmp = ia->starts + ia->renew;
4006 
4007  if (tmp < renew)
4008  renew = tmp;
4009 
4010  if (ia->rebind == 0) {
4011  /* Set rebind to 3/4 expiration interval. */
4012  tmp = ia->starts;
4013  tmp += use_expire + (use_expire / 2);
4014  } else if (ia->rebind == 0xffffffff)
4015  tmp = MAX_TIME;
4016  else
4017  tmp = ia->starts + ia->rebind;
4018 
4019  if (tmp < rebind)
4020  rebind = tmp;
4021  }
4022 
4023  /*
4024  * Return expiration ranges to EPOCH relative for event
4025  * scheduling (add_timeout()).
4026  */
4027  this_ia_hi_expire += ia->starts;
4028  this_ia_lo_expire += ia->starts;
4029 
4030  if (this_ia_hi_expire > hi_expire)
4031  hi_expire = this_ia_hi_expire;
4032  if (this_ia_lo_expire < lo_expire)
4033  lo_expire = this_ia_lo_expire;
4034  }
4035 
4036  /* If there are no addresses, give up, go to INIT.
4037  * Note that if an address is unexpired with a date in the past,
4038  * we're scheduling an expiration event to ocurr in the past. We
4039  * could probably optimize this to expire now (but then there's
4040  * recursion).
4041  *
4042  * In the future, we may decide that we're done here, or to
4043  * schedule a future request (using 4-pkt info-request model).
4044  */
4045  if (has_addrs == ISC_FALSE) {
4046  dhc6_lease_destroy(&client->active_lease, MDL);
4047  client->active_lease = NULL;
4048 
4049  /* Go back to the beginning. */
4050  start_init6(client);
4051  return;
4052  }
4053 
4054  switch(client->state) {
4055  case S_BOUND:
4056  /* We'd like to hit renewing, but if rebinding has already
4057  * passed (time warp), head straight there.
4058  */
4059  if ((rebind > cur_time) && (renew < rebind)) {
4060  log_debug("PRC: Renewal event scheduled in %d seconds, "
4061  "to run for %u seconds.",
4062  (int)(renew - cur_time),
4063  (unsigned)(rebind - renew));
4064  client->next_MRD = rebind;
4065  tv.tv_sec = renew;
4066  tv.tv_usec = 0;
4067  add_timeout(&tv, start_renew6, client, NULL, NULL);
4068 
4069  break;
4070  }
4071  /* FALL THROUGH */
4072  case S_RENEWING:
4073  /* While actively renewing, MRD is bounded by the time
4074  * we stop renewing and start rebinding. This helps us
4075  * process the state change on time.
4076  */
4077  client->MRD = rebind - cur_time;
4078  if (rebind != MAX_TIME) {
4079  log_debug("PRC: Rebind event scheduled in %d seconds, "
4080  "to run for %d seconds.",
4081  (int)(rebind - cur_time),
4082  (int)(hi_expire - rebind));
4083  client->next_MRD = hi_expire;
4084  tv.tv_sec = rebind;
4085  tv.tv_usec = 0;
4086  add_timeout(&tv, start_rebind6, client, NULL, NULL);
4087  }
4088  break;
4089 
4090  case S_REBINDING:
4091  /* For now, we rebind up until the last lease expires. In
4092  * the future, we might want to start SOLICITing when we've
4093  * depreffed an address.
4094  */
4095  client->MRD = hi_expire - cur_time;
4096  break;
4097 
4098  default:
4099  log_fatal("Impossible condition at %s:%d.", MDL);
4100  }
4101 
4102  /* Separately, set a time at which we will depref and expire
4103  * leases. This might happen with multiple addresses while we
4104  * keep trying to refresh.
4105  */
4106  if (depref != MAX_TIME) {
4107  log_debug("PRC: Depreference scheduled in %d seconds.",
4108  (int)(depref - cur_time));
4109  tv.tv_sec = depref;
4110  tv.tv_usec = 0;
4111  add_timeout(&tv, do_depref, client, NULL, NULL);
4112  }
4113  if (lo_expire != MAX_TIME) {
4114  log_debug("PRC: Expiration scheduled in %d seconds.",
4115  (int)(lo_expire - cur_time));
4116  tv.tv_sec = lo_expire;
4117  tv.tv_usec = 0;
4118  add_timeout(&tv, do_expire, client, NULL, NULL);
4119  }
4120 }
4121 
4122 /* In a given IA chain, find the IA with the same type and 'iaid'. */
4123 static struct dhc6_ia *
4124 find_ia(struct dhc6_ia *head, u_int16_t type, const char *id)
4125 {
4126  struct dhc6_ia *ia;
4127 
4128  for (ia = head ; ia != NULL ; ia = ia->next) {
4129  if (ia->ia_type != type)
4130  continue;
4131  if (memcmp(ia->iaid, id, 4) == 0)
4132  return ia;
4133  }
4134 
4135  return NULL;
4136 }
4137 
4138 /* In a given address chain, find a matching address. */
4139 static struct dhc6_addr *
4140 find_addr(struct dhc6_addr *head, struct iaddr *address)
4141 {
4142  struct dhc6_addr *addr;
4143 
4144  for (addr = head ; addr != NULL ; addr = addr->next) {
4145  if ((addr->address.len == address->len) &&
4146  (memcmp(addr->address.iabuf, address->iabuf,
4147  address->len) == 0))
4148  return addr;
4149  }
4150 
4151  return NULL;
4152 }
4153 
4154 /* In a given prefix chain, find a matching prefix. */
4155 static struct dhc6_addr *
4156 find_pref(struct dhc6_addr *head, struct iaddr *prefix, u_int8_t plen)
4157 {
4158  struct dhc6_addr *pref;
4159 
4160  for (pref = head ; pref != NULL ; pref = pref->next) {
4161  if ((pref->address.len == prefix->len) &&
4162  (pref->plen == plen) &&
4163  (memcmp(pref->address.iabuf, prefix->iabuf,
4164  prefix->len) == 0))
4165  return pref;
4166  }
4167 
4168  return NULL;
4169 }
4170 
4171 /* Merge the bindings from the source lease into the destination lease
4172  * structure, where they are missing. We have to copy the stateful
4173  * objects rather than move them over, because later code needs to be
4174  * able to compare new versus old if they contain any bindings.
4175  */
4176 static void
4177 dhc6_merge_lease(struct dhc6_lease *src, struct dhc6_lease *dst)
4178 {
4179  struct dhc6_ia *sia, *dia, *tia;
4180  struct dhc6_addr *saddr, *daddr, *taddr;
4181  int changes = 0;
4182 
4183  if ((dst == NULL) || (src == NULL))
4184  return;
4185 
4186  for (sia = src->bindings ; sia != NULL ; sia = sia->next) {
4187  dia = find_ia(dst->bindings, sia->ia_type, (char *)sia->iaid);
4188 
4189  if (dia == NULL) {
4190  tia = dhc6_dup_ia(sia, MDL);
4191 
4192  if (tia == NULL)
4193  log_fatal("Out of memory merging lease - "
4194  "Unable to continue without losing "
4195  "state! (%s:%d)", MDL);
4196 
4197  /* XXX: consider sorting? */
4198  tia->next = dst->bindings;
4199  dst->bindings = tia;
4200  changes = 1;
4201  } else {
4202  for (saddr = sia->addrs ; saddr != NULL ;
4203  saddr = saddr->next) {
4204  if (sia->ia_type != D6O_IA_PD)
4205  daddr = find_addr(dia->addrs,
4206  &saddr->address);
4207  else
4208  daddr = find_pref(dia->addrs,
4209  &saddr->address,
4210  saddr->plen);
4211 
4212  if (daddr == NULL) {
4213  taddr = dhc6_dup_addr(saddr, MDL);
4214 
4215  if (taddr == NULL)
4216  log_fatal("Out of memory "
4217  "merging lease - "
4218  "Unable to continue "
4219  "without losing "
4220  "state! (%s:%d)",
4221  MDL);
4222 
4223  /* XXX: consider sorting? */
4224  taddr->next = dia->addrs;
4225  dia->addrs = taddr;
4226  changes = 1;
4227  }
4228  }
4229  }
4230  }
4231 
4232  /* If we made changes, reset the score to 0 so it is recalculated. */
4233  if (changes)
4234  dst->score = 0;
4235 }
4236 
4237 /* We've either finished selecting or succeeded in Renew or Rebinding our
4238  * lease. In all cases we got a Reply. Give dhclient-script a tickle
4239  * to inform it about the new values, and then lay in wait for the next
4240  * event.
4241  */
4242 static void
4243 start_bound(struct client_state *client)
4244 {
4245  struct dhc6_ia *ia, *oldia;
4246  struct dhc6_addr *addr, *oldaddr;
4247  struct dhc6_lease *lease, *old;
4248  const char *reason;
4249 #if defined (NSUPDATE)
4250  TIME dns_update_offset = 1;
4251 #endif
4252 
4253  lease = client->active_lease;
4254  if (lease == NULL) {
4255  log_error("Cannot enter bound state unless an active lease "
4256  "is selected.");
4257  return;
4258  }
4259  lease->released = ISC_FALSE;
4260  old = client->old_lease;
4261 
4262  client->v6_handler = bound_handler;
4263 
4264  switch (client->state) {
4265  case S_SELECTING:
4266  case S_REBOOTING: /* Pretend we got bound. */
4267  reason = "BOUND6";
4268  break;
4269 
4270  case S_RENEWING:
4271  reason = "RENEW6";
4272  break;
4273 
4274  case S_REBINDING:
4275  reason = "REBIND6";
4276  break;
4277 
4278  default:
4279  log_fatal("Impossible condition at %s:%d.", MDL);
4280  /* Silence compiler warnings. */
4281  return;
4282  }
4283 
4284  log_debug("PRC: Bound to lease %s.",
4286  client->active_lease->server_id.data, 55));
4287  client->state = S_BOUND;
4288 
4289  write_client6_lease(client, lease, 0, 1);
4290 
4291  oldia = NULL;
4292  for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
4293  if (old != NULL)
4294  oldia = find_ia(old->bindings,
4295  ia->ia_type,
4296  (char *)ia->iaid);
4297  else
4298  oldia = NULL;
4299 
4300  for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
4301  if (oldia != NULL) {
4302  if (ia->ia_type != D6O_IA_PD)
4303  oldaddr = find_addr(oldia->addrs,
4304  &addr->address);
4305  else
4306  oldaddr = find_pref(oldia->addrs,
4307  &addr->address,
4308  addr->plen);
4309  } else
4310  oldaddr = NULL;
4311 
4312 #if defined (NSUPDATE)
4313  if ((oldaddr == NULL) && (ia->ia_type == D6O_IA_NA))
4315  &addr->address,
4316  dns_update_offset++);
4317 #endif
4318 
4319  /* Shell out to setup the new binding. */
4320  script_init(client, reason, NULL);
4321 
4322  if (old != NULL)
4323  dhc6_marshall_values("old_", client, old,
4324  oldia, oldaddr);
4325  dhc6_marshall_values("new_", client, lease, ia, addr);
4326  script_write_requested6(client);
4327 
4328  // when script returns 3, DAD failed
4329  if (script_go(client) == 3) {
4330  start_decline6(client);
4331  return;
4332  }
4333  }
4334 
4335  /* XXX: maybe we should loop on the old values instead? */
4336  if (ia->addrs == NULL) {
4337  script_init(client, reason, NULL);
4338 
4339  if (old != NULL)
4340  dhc6_marshall_values("old_", client, old,
4341  oldia,
4342  oldia != NULL ?
4343  oldia->addrs : NULL);
4344 
4345  dhc6_marshall_values("new_", client, lease, ia,
4346  NULL);
4347  script_write_requested6(client);
4348 
4349  script_go(client);
4350  }
4351  }
4352 
4353  /* XXX: maybe we should loop on the old values instead? */
4354  if (lease->bindings == NULL) {
4355  script_init(client, reason, NULL);
4356 
4357  if (old != NULL)
4358  dhc6_marshall_values("old_", client, old,
4359  old->bindings,
4360  (old->bindings != NULL) ?
4361  old->bindings->addrs : NULL);
4362 
4363  dhc6_marshall_values("new_", client, lease, NULL, NULL);
4364  script_write_requested6(client);
4365 
4366  script_go(client);
4367  }
4368 
4369  go_daemon();
4370 
4371  if (client->old_lease != NULL) {
4372  dhc6_lease_destroy(&client->old_lease, MDL);
4373  client->old_lease = NULL;
4374  }
4375 
4376  /* Schedule events. */
4377  dhc6_check_times(client);
4378 }
4379 
4380 /*
4381  * Decline addresses.
4382  */
4383 void
4384 start_decline6(struct client_state *client)
4385 {
4386  /* Cancel any pending transmissions */
4387  cancel_timeout(do_confirm6, client);
4388  cancel_timeout(do_select6, client);
4389  cancel_timeout(do_refresh6, client);
4390  cancel_timeout(do_release6, client);
4391  cancel_timeout(do_decline6, client);
4392  client->state = S_DECLINED;
4393 
4394  if (client->active_lease == NULL)
4395  return;
4396 
4397  /* Set timers per RFC3315 section 18.1.7. */
4398  client->IRT = DEC_TIMEOUT * 100;
4399  client->MRT = 0;
4400  client->MRC = DEC_MAX_RC;
4401  client->MRD = 0;
4402 
4403  dhc6_retrans_init(client);
4404  client->v6_handler = reply_handler;
4405 
4406  client->refresh_type = DHCPV6_DECLINE;
4407  do_decline6(client);
4408 }
4409 
4410 /*
4411  * do_decline6() creates a Decline packet and transmits it.
4412  */
4413 static void
4414 do_decline6(void *input)
4415 {
4416  struct client_state *client;
4417  struct data_string ds;
4418  int send_ret;
4419  struct timeval elapsed, tv;
4420 
4421  client = input;
4422 
4423  if ((client->active_lease == NULL) || !active_prefix(client))
4424  return;
4425 
4426  if ((client->MRC != 0) && (client->txcount > client->MRC)) {
4427  log_info("Max retransmission count exceeded.");
4428  goto decline_done;
4429  }
4430 
4431  /*
4432  * Start_time starts at the first transmission.
4433  */
4434  if (client->txcount == 0) {
4435  client->start_time.tv_sec = cur_tv.tv_sec;
4436  client->start_time.tv_usec = cur_tv.tv_usec;
4437  }
4438 
4439  /* elapsed = cur - start */
4440  elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
4441  elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
4442  if (elapsed.tv_usec < 0) {
4443  elapsed.tv_sec -= 1;
4444  elapsed.tv_usec += 1000000;
4445  }
4446 
4447  memset(&ds, 0, sizeof(ds));
4448  if (!buffer_allocate(&ds.buffer, 4, MDL)) {
4449  log_error("Unable to allocate memory for Decline.");
4450  goto decline_done;
4451  }
4452 
4453  ds.data = ds.buffer->data;
4454  ds.len = 4;
4455  ds.buffer->data[0] = DHCPV6_DECLINE;
4456  memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
4457 
4458  /* Form an elapsed option. */
4459  /* Maximum value is 65535 1/100s coded as 0xffff. */
4460  if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
4461  ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
4462  client->elapsed = 0xffff;
4463  } else {
4464  client->elapsed = elapsed.tv_sec * 100;
4465  client->elapsed += elapsed.tv_usec / 10000;
4466  }
4467 
4468  client->elapsed = htons(client->elapsed);
4469 
4470  log_debug("XMT: Forming Decline.");
4471  make_client6_options(client, &client->sent_options,
4472  client->active_lease, DHCPV6_DECLINE);
4473  dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
4474  client->sent_options, &global_scope,
4475  &dhcpv6_universe);
4476 
4477  /* Append IA's (but don't release temporary addresses). */
4478  if (wanted_ia_na &&
4479  dhc6_add_ia_na(client, &ds, client->active_lease,
4480  DHCPV6_DECLINE) != ISC_R_SUCCESS) {
4481  data_string_forget(&ds, MDL);
4482  goto decline_done;
4483  }
4484  if (wanted_ia_pd &&
4485  dhc6_add_ia_pd(client, &ds, client->active_lease,
4486  DHCPV6_DECLINE) != ISC_R_SUCCESS) {
4487  data_string_forget(&ds, MDL);
4488  goto decline_done;
4489  }
4490 
4491  /* Transmit and wait. */
4492  log_info("XMT: Decline on %s, interval %ld0ms.",
4493  client->name ? client->name : client->interface->name,
4494  (long int)client->RT);
4495 
4496  send_ret = send_packet6(client->interface, ds.data, ds.len,
4497  &DHCPv6DestAddr);
4498  if (send_ret != ds.len) {
4499  log_error("dhc6: sendpacket6() sent %d of %d bytes",
4500  send_ret, ds.len);
4501  }
4502 
4503  data_string_forget(&ds, MDL);
4504 
4505  /* Wait RT */
4506  tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
4507  tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
4508  if (tv.tv_usec >= 1000000) {
4509  tv.tv_sec += 1;
4510  tv.tv_usec -= 1000000;
4511  }
4512  add_timeout(&tv, do_decline6, client, NULL, NULL);
4513  dhc6_retrans_advance(client);
4514  return;
4515 
4516 decline_done:
4517  dhc6_lease_destroy(&client->active_lease, MDL);
4518  client->active_lease = NULL;
4519  start_init6(client);
4520  return;
4521 }
4522 
4523 /* While bound, ignore packets. In the future we'll want to answer
4524  * Reconfigure-Request messages and the like.
4525  */
4526 void
4527 bound_handler(struct packet *packet, struct client_state *client)
4528 {
4529  log_debug("RCV: Input packets are ignored once bound.");
4530 }
4531 
4532 /* start_renew6() gets us all ready to go to start transmitting Renew packets.
4533  * Note that client->next_MRD must be set before entering this function -
4534  * it must be set to the time at which the client should start Rebinding.
4535  */
4536 void
4537 start_renew6(void *input)
4538 {
4539  struct client_state *client;
4540 
4541  client = (struct client_state *)input;
4542 
4543  log_info("PRC: Renewing lease on %s.",
4544  client->name ? client->name : client->interface->name);
4545  client->state = S_RENEWING;
4546 
4547  client->v6_handler = reply_handler;
4548 
4549  /* Times per RFC3315 section 18.1.3. */
4550  client->IRT = REN_TIMEOUT * 100;
4551  client->MRT = REN_MAX_RT * 100;
4552  client->MRC = 0;
4553  /* MRD is special in renew - we need to set it by checking timer
4554  * state.
4555  */
4556  client->MRD = client->next_MRD - cur_time;
4557 
4558  dhc6_retrans_init(client);
4559 
4560  client->refresh_type = DHCPV6_RENEW;
4561  do_refresh6(client);
4562 }
4563 
4564 /* do_refresh6() transmits one DHCPv6 packet, be it a Renew or Rebind, and
4565  * gives the retransmission state a bump for the next time. Note that
4566  * client->refresh_type must be set before entering this function.
4567  */
4568 void
4569 do_refresh6(void *input)
4570 {
4571  struct option_cache *oc;
4572  struct sockaddr_in6 unicast, *dest_addr = &DHCPv6DestAddr;
4573  struct data_string ds;
4574  struct client_state *client;
4575  struct dhc6_lease *lease;
4576  struct timeval elapsed, tv;
4577  int send_ret;
4578 
4579  client = (struct client_state *)input;
4580  memset(&ds, 0, sizeof(ds));
4581 
4582  lease = client->active_lease;
4583  if (lease == NULL) {
4584  log_error("Cannot renew without an active binding.");
4585  return;
4586  }
4587 
4588  /* Ensure we're emitting a valid message type. */
4589  switch (client->refresh_type) {
4590  case DHCPV6_RENEW:
4591  case DHCPV6_REBIND:
4592  break;
4593 
4594  default:
4595  log_fatal("Internal inconsistency (%d) at %s:%d.",
4596  client->refresh_type, MDL);
4597  }
4598 
4599  /*
4600  * Start_time starts at the first transmission.
4601  */
4602  if (client->txcount == 0) {
4603  client->start_time.tv_sec = cur_tv.tv_sec;
4604  client->start_time.tv_usec = cur_tv.tv_usec;
4605  }
4606 
4607  /* elapsed = cur - start */
4608  elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
4609  elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
4610  if (elapsed.tv_usec < 0) {
4611  elapsed.tv_sec -= 1;
4612  elapsed.tv_usec += 1000000;
4613  }
4614  if (((client->MRC != 0) && (client->txcount > client->MRC)) ||
4615  ((client->MRD != 0) && (elapsed.tv_sec >= client->MRD))) {
4616  /* We're done. Move on to the next phase, if any. */
4617  dhc6_check_times(client);
4618  return;
4619  }
4620 
4621  /*
4622  * Check whether the server has sent a unicast option; if so, we can
4623  * use the address it specified for RENEWs.
4624  */
4626  if (oc && evaluate_option_cache(&ds, NULL, NULL, NULL,
4627  lease->options, NULL, &global_scope,
4628  oc, MDL)) {
4629  if (ds.len < 16) {
4630  log_error("Invalid unicast option length %d.", ds.len);
4631  } else {
4632  memset(&unicast, 0, sizeof(DHCPv6DestAddr));
4633  unicast.sin6_family = AF_INET6;
4634  unicast.sin6_port = remote_port;
4635  memcpy(&unicast.sin6_addr, ds.data, 16);
4636  if (client->refresh_type == DHCPV6_RENEW) {
4637  dest_addr = &unicast;
4638  }
4639  }
4640 
4641  data_string_forget(&ds, MDL);
4642  }
4643 
4644  /* Commence forming a renew packet. */
4645  memset(&ds, 0, sizeof(ds));
4646  if (!buffer_allocate(&ds.buffer, 4, MDL)) {
4647  log_error("Unable to allocate memory for packet.");
4648  return;
4649  }
4650  ds.data = ds.buffer->data;
4651  ds.len = 4;
4652 
4653  ds.buffer->data[0] = client->refresh_type;
4654  memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
4655 
4656  /* Form an elapsed option. */
4657  /* Maximum value is 65535 1/100s coded as 0xffff. */
4658  if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
4659  ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
4660  client->elapsed = 0xffff;
4661  } else {
4662  client->elapsed = elapsed.tv_sec * 100;
4663  client->elapsed += elapsed.tv_usec / 10000;
4664  }
4665 
4666  if (client->elapsed == 0)
4667  log_debug("XMT: Forming %s, 0 ms elapsed.",
4668  dhcpv6_type_names[client->refresh_type]);
4669  else
4670  log_debug("XMT: Forming %s, %u0 ms elapsed.",
4672  (unsigned)client->elapsed);
4673 
4674  client->elapsed = htons(client->elapsed);
4675 
4676  make_client6_options(client, &client->sent_options, lease,
4677  client->refresh_type);
4678 
4679  /* Put in any options from the sent cache. */
4680  dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
4681  client->sent_options, &global_scope,
4682  &dhcpv6_universe);
4683 
4684  /* Append IA's */
4685  if (wanted_ia_na &&
4686  dhc6_add_ia_na(client, &ds, lease,
4687  client->refresh_type) != ISC_R_SUCCESS) {
4688  data_string_forget(&ds, MDL);
4689  return;
4690  }
4691  if (wanted_ia_pd &&
4692  dhc6_add_ia_pd(client, &ds, lease,
4693  client->refresh_type) != ISC_R_SUCCESS) {
4694  data_string_forget(&ds, MDL);
4695  return;
4696  }
4697 
4698  log_info("XMT: %s on %s, interval %ld0ms.",
4700  client->name ? client->name : client->interface->name,
4701  (long int)client->RT);
4702 
4703  send_ret = send_packet6(client->interface, ds.data, ds.len, dest_addr);
4704 
4705  if (send_ret != ds.len) {
4706  log_error("dhc6: send_packet6() sent %d of %d bytes",
4707  send_ret, ds.len);
4708  }
4709 
4710  data_string_forget(&ds, MDL);
4711 
4712  /* Wait RT */
4713  tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
4714  tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
4715  if (tv.tv_usec >= 1000000) {
4716  tv.tv_sec += 1;
4717  tv.tv_usec -= 1000000;
4718  }
4719  add_timeout(&tv, do_refresh6, client, NULL, NULL);
4720 
4721  dhc6_retrans_advance(client);
4722 }
4723 
4724 /* start_rebind6() gets us all set up to go and rebind a lease. Note that
4725  * client->next_MRD must be set before entering this function. In this case,
4726  * MRD must be set to the maximum time any address in the packet will
4727  * expire.
4728  */
4729 void
4730 start_rebind6(void *input)
4731 {
4732  struct client_state *client;
4733 
4734  client = (struct client_state *)input;
4735 
4736  log_info("PRC: Rebinding lease on %s.",
4737  client->name ? client->name : client->interface->name);
4738  client->state = S_REBINDING;
4739 
4740  client->v6_handler = reply_handler;
4741 
4742  /* Times per RFC3315 section 18.1.4. */
4743  client->IRT = REB_TIMEOUT * 100;
4744  client->MRT = REB_MAX_RT * 100;
4745  client->MRC = 0;
4746  /* MRD is special in rebind - it's determined by the timer
4747  * state.
4748  */
4749  client->MRD = client->next_MRD - cur_time;
4750 
4751  dhc6_retrans_init(client);
4752 
4753  client->refresh_type = DHCPV6_REBIND;
4754  do_refresh6(client);
4755 }
4756 
4757 /* do_depref() runs through a given lease's addresses, for each that has
4758  * not yet been depreffed, shells out to the dhclient-script to inform it
4759  * of the status change. The dhclient-script should then do...something...
4760  * to encourage applications to move off the address and onto one of the
4761  * remaining 'preferred' addresses.
4762  */
4763 void
4764 do_depref(void *input)
4765 {
4766  struct client_state *client;
4767  struct dhc6_lease *lease;
4768  struct dhc6_ia *ia;
4769  struct dhc6_addr *addr;
4770 
4771  client = (struct client_state *)input;
4772 
4773  lease = client->active_lease;
4774  if (lease == NULL)
4775  return;
4776 
4777  for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
4778  for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
4779  if (addr->flags & DHC6_ADDR_DEPREFFED)
4780  continue;
4781 
4782  if (addr->starts + addr->preferred_life <= cur_time) {
4783  script_init(client, "DEPREF6", NULL);
4784  dhc6_marshall_values("cur_", client, lease,
4785  ia, addr);
4786  script_write_requested6(client);
4787  script_go(client);
4788 
4789  addr->flags |= DHC6_ADDR_DEPREFFED;
4790 
4791  if (ia->ia_type != D6O_IA_PD)
4792  log_info("PRC: Address %s depreferred.",
4793  piaddr(addr->address));
4794  else
4795  log_info("PRC: Prefix %s/%u depreferred.",
4796  piaddr(addr->address),
4797  (unsigned) addr->plen);
4798 
4799 #if defined (NSUPDATE)
4800  /* Remove DDNS bindings at depref time. */
4801  if ((ia->ia_type == D6O_IA_NA) &&
4802  client->config->do_forward_update)
4803  client_dns_remove(client,
4804  &addr->address);
4805 #endif
4806  }
4807  }
4808  }
4809 
4810  dhc6_check_times(client);
4811 }
4812 
4813 /* do_expire() searches through all the addresses on a given lease, and
4814  * expires/removes any addresses that are no longer valid.
4815  */
4816 void
4817 do_expire(void *input)
4818 {
4819  struct client_state *client;
4820  struct dhc6_lease *lease;
4821  struct dhc6_ia *ia;
4822  struct dhc6_addr *addr;
4823  int has_addrs = ISC_FALSE;
4824 
4825  client = (struct client_state *)input;
4826 
4827  lease = client->active_lease;
4828  if (lease == NULL)
4829  return;
4830 
4831  for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
4832  for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
4833  if (addr->flags & DHC6_ADDR_EXPIRED)
4834  continue;
4835 
4836  if (addr->starts + addr->max_life <= cur_time) {
4837  script_init(client, "EXPIRE6", NULL);
4838  dhc6_marshall_values("old_", client, lease,
4839  ia, addr);
4840  script_write_requested6(client);
4841  script_go(client);
4842 
4843  addr->flags |= DHC6_ADDR_EXPIRED;
4844 
4845  if (ia->ia_type != D6O_IA_PD)
4846  log_info("PRC: Address %s expired.",
4847  piaddr(addr->address));
4848  else
4849  log_info("PRC: Prefix %s/%u expired.",
4850  piaddr(addr->address),
4851  (unsigned) addr->plen);
4852 
4853 #if defined (NSUPDATE)
4854  /* We remove DNS records at depref time, but
4855  * it is possible that we might get here
4856  * without depreffing.
4857  */
4858  if ((ia->ia_type == D6O_IA_NA) &&
4859  client->config->do_forward_update &&
4860  !(addr->flags & DHC6_ADDR_DEPREFFED))
4861  client_dns_remove(client,
4862  &addr->address);
4863 #endif
4864 
4865  continue;
4866  }
4867 
4868  has_addrs = ISC_TRUE;
4869  }
4870  }
4871 
4872  /* Clean up empty leases. */
4873  if (has_addrs == ISC_FALSE) {
4874  log_info("PRC: Bound lease is devoid of active addresses."
4875  " Re-initializing.");
4876 
4877  dhc6_lease_destroy(&lease, MDL);
4878  client->active_lease = NULL;
4879 
4880  start_init6(client);
4881  return;
4882  }
4883 
4884  /* Schedule the next run through. */
4885  dhc6_check_times(client);
4886 }
4887 
4888 /*
4889  * Run client script to unconfigure interface.
4890  * Called with reason STOP6 when dhclient -x is run, or with reason
4891  * RELEASE6 when server has replied to a Release message.
4892  * Stateless is a special case.
4893  */
4894 void
4895 unconfigure6(struct client_state *client, const char *reason)
4896 {
4897  struct dhc6_ia *ia;
4898  struct dhc6_addr *addr;
4899 
4900  if (stateless) {
4901  script_init(client, reason, NULL);
4902  if (client->active_lease != NULL)
4903  script_write_params6(client, "old_",
4904  client->active_lease->options);
4905  script_write_requested6(client);
4906  script_go(client);
4907  return;
4908  }
4909 
4910  if (client->active_lease == NULL)
4911  return;
4912 
4913  for (ia = client->active_lease->bindings ; ia != NULL ; ia = ia->next) {
4914  if (ia->ia_type == D6O_IA_TA)
4915  continue;
4916 
4917  for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
4918  script_init(client, reason, NULL);
4919  dhc6_marshall_values("old_", client,
4920  client->active_lease, ia, addr);
4921  script_write_requested6(client);
4922  script_go(client);
4923 
4924 #if defined (NSUPDATE)
4925  if ((ia->ia_type == D6O_IA_NA) &&
4926  client->config->do_forward_update)
4927  client_dns_remove(client, &addr->address);
4928 #endif
4929  }
4930  }
4931 }
4932 
4933 void
4934 refresh_info_request6(void *input)
4935 {
4936  struct client_state *client;
4937 
4938  client = (struct client_state *)input;
4939  start_info_request6(client);
4940 }
4941 
4942 /* Timeout for Information-Request (using the IRT option).
4943  */
4944 static void
4945 dhc6_check_irt(struct client_state *client)
4946 {
4947  struct option **req;
4948  struct option_cache *oc;
4949  TIME expire = MAX_TIME;
4950  struct timeval tv;
4951  int i;
4952  isc_boolean_t found = ISC_FALSE;
4953 
4954  cancel_timeout(refresh_info_request6, client);
4955 
4956  req = client->config->requested_options;
4957  for (i = 0; req[i] != NULL; i++) {
4958  if (req[i] == irt_option) {
4959  found = ISC_TRUE;
4960  break;
4961  }
4962  }
4963  /* Simply return gives a endless loop waiting for nothing. */
4964  if (!found)
4965  exit(0);
4966 
4969  if (oc != NULL) {
4970  struct data_string irt;
4971 
4972  memset(&irt, 0, sizeof(irt));
4973  if (!evaluate_option_cache(&irt, NULL, NULL, client,
4974  client->active_lease->options,
4975  NULL, &global_scope, oc, MDL) ||
4976  (irt.len < 4)) {
4977  log_error("Can't evaluate IRT.");
4978  } else {
4979  expire = getULong(irt.data);
4980  if (expire < IRT_MINIMUM)
4981  expire = IRT_MINIMUM;
4982  if (expire == 0xffffffff)
4983  expire = MAX_TIME;
4984  }
4985  data_string_forget(&irt, MDL);
4986  } else
4987  expire = IRT_DEFAULT;
4988 
4989  if (expire != MAX_TIME) {
4990  log_debug("PRC: Refresh event scheduled in %u seconds.",
4991  (unsigned) expire);
4992  tv.tv_sec = cur_time + expire;
4993  tv.tv_usec = 0;
4994  add_timeout(&tv, refresh_info_request6, client, NULL, NULL);
4995  }
4996 }
4997 
4998 /* We got a Reply. Give dhclient-script a tickle to inform it about
4999  * the new values, and then lay in wait for the next event.
5000  */
5001 static void
5002 start_informed(struct client_state *client)
5003 {
5004  client->v6_handler = informed_handler;
5005 
5006  log_debug("PRC: Done.");
5007 
5008  client->state = S_BOUND;
5009 
5010  script_init(client, "RENEW6", NULL);
5011  if (client->old_lease != NULL)
5012  script_write_params6(client, "old_",
5013  client->old_lease->options);
5014  script_write_params6(client, "new_", client->active_lease->options);
5015  script_write_requested6(client);
5016  script_go(client);
5017 
5018  go_daemon();
5019 
5020  if (client->old_lease != NULL) {
5021  dhc6_lease_destroy(&client->old_lease, MDL);
5022  client->old_lease = NULL;
5023  }
5024 
5025  /* Schedule events. */
5026  dhc6_check_irt(client);
5027 }
5028 
5029 /* While informed, ignore packets.
5030  */
5031 void
5032 informed_handler(struct packet *packet, struct client_state *client)
5033 {
5034  log_debug("RCV: Input packets are ignored once bound.");
5035 }
5036 
5037 /* make_client6_options() fetches option caches relevant to the client's
5038  * scope and places them into the sent_options cache. This cache is later
5039  * used to populate DHCPv6 output packets with options.
5040  */
5041 static void
5042 make_client6_options(struct client_state *client, struct option_state **op,
5043  struct dhc6_lease *lease, u_int8_t message)
5044 {
5045  struct option_cache *oc;
5046  struct option **req;
5047  struct buffer *buffer;
5048  int buflen, i, oro_len;
5049 
5050  if ((op == NULL) || (client == NULL))
5051  return;
5052 
5053  if (*op)
5055 
5056  /* Create a cache to carry options to transmission. */
5058 
5059  /* Create and store an 'elapsed time' option in the cache. */
5060  oc = NULL;
5061  if (option_cache_allocate(&oc, MDL)) {
5062  const unsigned char *cdata;
5063 
5064  cdata = (unsigned char *)&client->elapsed;
5065 
5066  if (make_const_data(&oc->expression, cdata, 2, 0, 0, MDL)) {
5067  option_reference(&oc->option, elapsed_option, MDL);
5068  save_option(&dhcpv6_universe, *op, oc);
5069  }
5070 
5072  }
5073 
5074  /* Bring in any configured options to send. */
5075  if (client->config->on_transmission)
5076  execute_statements_in_scope(NULL, NULL, NULL, client,
5077  lease ? lease->options : NULL,
5078  *op, &global_scope,
5079  client->config->on_transmission,
5080  NULL, NULL);
5081 
5082  /* Rapid-commit is only for SOLICITs. */
5083  if (message != DHCPV6_SOLICIT)
5085 
5086  /* See if the user configured a DUID in a relevant scope. If not,
5087  * introduce our default manufactured id.
5088  */
5089  if ((oc = lookup_option(&dhcpv6_universe, *op,
5090  D6O_CLIENTID)) == NULL) {
5091  if (default_duid.len == 0 ||
5092  !option_cache(&oc, &default_duid, NULL, clientid_option,
5093  MDL))
5094  log_fatal("Failure assembling a DUID.");
5095 
5096  save_option(&dhcpv6_universe, *op, oc);
5098  }
5099 
5100  /* In cases where we're responding to a single server, put the
5101  * server's id in the response.
5102  *
5103  * Note that lease is NULL for SOLICIT or INFO request messages,
5104  * and otherwise MUST be present.
5105  */
5106  if (lease == NULL) {
5107  if ((message != DHCPV6_SOLICIT) &&
5108  (message != DHCPV6_INFORMATION_REQUEST))
5109  log_fatal("Impossible condition at %s:%d.", MDL);
5110  } else if ((message != DHCPV6_REBIND) &&
5111  (message != DHCPV6_CONFIRM)) {
5112  oc = lookup_option(&dhcpv6_universe, lease->options,
5113  D6O_SERVERID);
5114  if (oc != NULL)
5115  save_option(&dhcpv6_universe, *op, oc);
5116  }
5117 
5118  /* 'send dhcp6.oro foo;' syntax we used in 4.0.0a1/a2 has been
5119  * deprecated by adjustments to the 'request' syntax also used for
5120  * DHCPv4.
5121  */
5122  if (lookup_option(&dhcpv6_universe, *op, D6O_ORO) != NULL)
5123  log_error("'send dhcp6.oro' syntax is deprecated, please "
5124  "use the 'request' syntax (\"man dhclient.conf\").");
5125 
5126  /* Construct and store an ORO (Option Request Option). It is a
5127  * fatal error to fail to send an ORO (of at least zero length).
5128  *
5129  * Discussion: RFC3315 appears to be inconsistent in its statements
5130  * of whether or not the ORO is mandatory. In section 18.1.1
5131  * ("Creation and Transmission of Request Messages"):
5132  *
5133  * The client MUST include an Option Request option (see section
5134  * 22.7) to indicate the options the client is interested in
5135  * receiving. The client MAY include options with data values as
5136  * hints to the server about parameter values the client would like
5137  * to have returned.
5138  *
5139  * This MUST is missing from the creation/transmission of other
5140  * messages (such as Renew and Rebind), and the section 22.7 ("Option
5141  * Request Option" format and definition):
5142  *
5143  * A client MAY include an Option Request option in a Solicit,
5144  * Request, Renew, Rebind, Confirm or Information-request message to
5145  * inform the server about options the client wants the server to
5146  * send to the client. A server MAY include an Option Request
5147  * option in a Reconfigure option to indicate which options the
5148  * client should request from the server.
5149  *
5150  * seems to relax the requirement from MUST to MAY (and still other
5151  * language in RFC3315 supports this).
5152  *
5153  * In lieu of a clarification of RFC3315, we will conform with the
5154  * MUST. Instead of an absent ORO, we will if there are no options
5155  * to request supply an empty ORO. Theoretically, an absent ORO is
5156  * difficult to interpret (does the client want all options or no
5157  * options?). A zero-length ORO is intuitively clear: requesting
5158  * nothing.
5159  */
5160  buffer = NULL;
5161  oro_len = 0;
5162  buflen = 32;
5163  if (!buffer_allocate(&buffer, buflen, MDL))
5164  log_fatal("Out of memory constructing DHCPv6 ORO.");
5165  req = client->config->requested_options;
5166  if (req != NULL) {
5167  for (i = 0 ; req[i] != NULL ; i++) {
5168  if (buflen == oro_len) {
5169  struct buffer *tmpbuf = NULL;
5170 
5171  buflen += 32;
5172 
5173  /* Shell game. */
5174  buffer_reference(&tmpbuf, buffer, MDL);
5175  buffer_dereference(&buffer, MDL);
5176 
5177  if (!buffer_allocate(&buffer, buflen, MDL))
5178  log_fatal("Out of memory resizing "
5179  "DHCPv6 ORO buffer.");
5180 
5181  memcpy(buffer->data, tmpbuf->data, oro_len);
5182 
5183  buffer_dereference(&tmpbuf, MDL);
5184  }
5185 
5186  if (req[i]->universe == &dhcpv6_universe) {
5187  /* Append the code to the ORO. */
5188  putUShort(buffer->data + oro_len,
5189  req[i]->code);
5190  oro_len += 2;
5191  }
5192  }
5193  }
5194 
5195  oc = NULL;
5196  if (make_const_option_cache(&oc, &buffer, NULL, oro_len,
5197  oro_option, MDL)) {
5198  save_option(&dhcpv6_universe, *op, oc);
5199  } else {
5200  log_fatal("Unable to create ORO option cache.");
5201  }
5202 
5203  /*
5204  * Note: make_const_option_cache() consumes the buffer, we do not
5205  * need to dereference it (XXX).
5206  */
5208 }
5209 
5210 /* A clone of the DHCPv4 script_write_params() minus the DHCPv4-specific
5211  * filename, server-name, etc specifics.
5212  *
5213  * Simply, store all values present in all universes of the option state
5214  * (probably derived from a DHCPv6 packet) into environment variables
5215  * named after the option names (and universe names) but with the 'prefix'
5216  * prepended.
5217  *
5218  * Later, dhclient-script may compare for example "new_time_servers" and
5219  * "old_time_servers" for differences, and only upon detecting a change
5220  * bother to rewrite ntp.conf and restart it. Or something along those
5221  * generic lines.
5222  */
5223 static void
5224 script_write_params6(struct client_state *client, const char *prefix,
5225  struct option_state *options)
5226 {
5227  struct envadd_state es;
5228  int i;
5229 
5230  if (options == NULL)
5231  return;
5232 
5233  es.client = client;
5234  es.prefix = prefix;
5235 
5236  for (i = 0 ; i < options->universe_count ; i++) {
5237  option_space_foreach(NULL, NULL, client, NULL, options,
5238  &global_scope, universes[i], &es,
5240  }
5241 }
5242 
5243 /*
5244  * A clone of the DHCPv4 routine.
5245  * Write out the environment variables for the objects that the
5246  * client requested. If the object was requested the variable will be:
5247  * requested_<option_name>=1
5248  * If it wasn't requested there won't be a variable.
5249  */
5250 static void script_write_requested6(client)
5251  struct client_state *client;
5252 {
5253  int i;
5254  struct option **req;
5255  char name[256];
5256  req = client->config->requested_options;
5257 
5258  if (req == NULL)
5259  return;
5260 
5261  for (i = 0 ; req[i] != NULL ; i++) {
5262  if ((req[i]->universe == &dhcpv6_universe) &&
5263  dhcp_option_ev_name (name, sizeof(name), req[i])) {
5264  client_envadd(client, "requested_", name, "%d", 1);
5265  }
5266  }
5267 }
5268 
5269 /*
5270  * Check if there is something not fully defined in the active lease.
5271  */
5272 static isc_boolean_t
5273 active_prefix(struct client_state *client)
5274 {
5275  struct dhc6_lease *lease;
5276  struct dhc6_ia *ia;
5277  struct dhc6_addr *pref;
5278  char zeros[16];
5279 
5280  lease = client->active_lease;
5281  if (lease == NULL)
5282  return ISC_FALSE;
5283  memset(zeros, 0, 16);
5284  for (ia = lease->bindings; ia != NULL; ia = ia->next) {
5285  if (ia->ia_type != D6O_IA_PD)
5286  continue;
5287  for (pref = ia->addrs; pref != NULL; pref = pref->next) {
5288  if (pref->plen == 0)
5289  return ISC_FALSE;
5290  if (pref->address.len != 16)
5291  return ISC_FALSE;
5292  if (memcmp(pref->address.iabuf, zeros, 16) == 0)
5293  return ISC_FALSE;
5294  }
5295  }
5296  return ISC_TRUE;
5297 }
5298 #endif /* DHCPv6 */
int txcount
Definition: dhcpd.h:1239
struct timeval start_time
Definition: dhcpd.h:1237
#define REB_MAX_RT
Definition: dhcp6.h:160
TIME IRT
Definition: dhcpd.h:1243
#define REQ_TIMEOUT
Definition: dhcp6.h:150
TIME RT
Definition: dhcpd.h:1242
const char int line
Definition: dhcpd.h:3615
void start_selecting6(struct client_state *client)
int score
Definition: dhcpd.h:1105
#define D6O_IAADDR
Definition: dhcp6.h:35
u_int8_t plen
Definition: dhcpd.h:1073
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:1108
unsigned char dhcpv6_transaction_id[3]
Definition: dhcpd.h:1228
Definition: dhcpd.h:521
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:454
int do_forward_update
Definition: dhcpd.h:1186
#define D6O_STATUS_CODE
Definition: dhcp6.h:43
u_int32_t renew
Definition: dhcpd.h:1093
unsigned char dhcpv6_transaction_id[3]
Definition: dhcpd.h:385
char name[IFNAMSIZ]
Definition: dhcpd.h:1305
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:1106
#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:2477
Definition: dhcpd.h:1117
#define DHCP_R_INVALIDARG
Definition: result.h:48
#define STATUS_NoAddrsAvail
Definition: dhcp6.h:85
struct group * on_transmission
Definition: dhcpd.h:1142
#define INF_MAX_RT
Definition: dhcp6.h:163
int script_go(struct client_state *client)
Definition: dhclient.c:3962
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:1197
u_int16_t elapsed
Definition: dhcpd.h:1238
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:1084
#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:358
struct dhc6_ia * next
Definition: dhcpd.h:1088
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:4043
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:1109
TIME next_MRD
Definition: dhcpd.h:1247
u_int8_t flags
Definition: dhcpd.h:1078
struct expression * expression
Definition: dhcpd.h:359
#define D6O_CLIENTID
Definition: dhcp6.h:31
u_int8_t refresh_type
Definition: dhcpd.h:1229
struct data_string default_duid
Definition: dhclient.c:74
struct option_state * options
Definition: dhcpd.h:414
Definition: tree.h:302
unsigned char dhcpv6_msg_type
Definition: dhcpd.h:382
unsigned char iaid[4]
Definition: dhcpd.h:1089
TIME MRT
Definition: dhcpd.h:1245
void log_fatal(const char *,...) __attribute__((__format__(__printf__
void(* v6_handler)(struct packet *, struct client_state *)
Definition: dhcpd.h:1254
#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:1111
#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:555
char * name
Definition: dhcpd.h:1199
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:3782
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:1145
void script_init(struct client_state *client, const char *reason, struct string_list *medium)
Definition: dhclient.c:3751
#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:1102
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:1267
#define DHCPV6_REBIND
Definition: dhcp6.h:103
u_int16_t local_port
Definition: dhclient.c:88
Definition: dhcpd.h:376
#define SOL_MAX_DELAY
Definition: dhcp6.h:147
#define cur_time
Definition: dhcpd.h:1988
Definition: ip.h:47
struct dhc6_lease * advertised_leases
Definition: dhcpd.h:1233
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:1082
const char * name
Definition: tree.h:347
struct option_state * sent_options
Definition: dhcpd.h:1205
struct hardware hw_address
Definition: dhcpd.h:1283
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:1266
struct option_state * options
Definition: dhcpd.h:1097
struct option * option
Definition: dhcpd.h:360
struct dhc6_lease * selected_lease
Definition: dhcpd.h:1234
#define _PATH_DHCLIENT6_DB
Definition: config.h:224
int int log_info(const char *,...) __attribute__((__format__(__printf__
enum dhcp_state state
Definition: dhcpd.h:1206
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:1094
struct option ** required_options
Definition: dhcpd.h:1144
struct dhc6_addr * addrs
Definition: dhcpd.h:1095
void putUChar(unsigned char *, u_int32_t)
Definition: convert.c:102
#define _PATH_DHCLIENT6_PID
Definition: config.h:227
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:1081
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
struct dhc6_addr * next
Definition: dhcpd.h:1071
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:273
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:369
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:1072
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
#define DEC_TIMEOUT
Definition: dhcp6.h:166
void dhcpv6_client_assignments(void)
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
Definition: dhcpd.h:455
int wanted_ia_na
Definition: dhclient.c:97
struct client_config * config
Definition: dhcpd.h:1202
int wanted_ia_ta
Definition: dhclient.c:98
#define MAX_TIME
Definition: dhcpd.h:1526
#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:4076
#define SOL_MAX_RT
Definition: dhcp6.h:149
#define D6O_IA_PD
Definition: dhcp6.h:55
void go_daemon()
Definition: dhclient.c:4116
struct dhc6_lease * next
Definition: dhcpd.h:1101
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:1147
const char * file
Definition: dhcpd.h:3615
#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:1198
#define DHC6_ADDR_EXPIRED
Definition: dhcpd.h:1077
u_int16_t ia_type
Definition: dhcpd.h:1090
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:1104
#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:1232
u_int32_t requested_lease
Definition: dhcpd.h:1167
#define REQ_MAX_RC
Definition: dhcp6.h:152
#define DHC6_ADDR_DEPREFFED
Definition: dhcpd.h:1076
TIME MRD
Definition: dhcpd.h:1246
TIME starts
Definition: dhcpd.h:1092
#define DHCPV6_SOLICIT
Definition: dhcp6.h:98
struct dhc6_lease * active_lease
Definition: dhcpd.h:1231
TIME starts
Definition: dhcpd.h:1080
struct buffer * buffer
Definition: tree.h:78
TIME MRC
Definition: dhcpd.h:1244
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:3480
#define D6O_ELAPSED_TIME
Definition: dhcp6.h:38