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