ISC DHCP  4.3.6
A reference DHCPv4 and DHCPv6 implementation
dhclient.c
Go to the documentation of this file.
1 /* dhclient.c
2 
3  DHCP Client. */
4 
5 /*
6  * Copyright (c) 2004-2017 by Internet Systems Consortium, Inc. ("ISC")
7  * Copyright (c) 1995-2003 by Internet Software Consortium
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  *
21  * Internet Systems Consortium, Inc.
22  * 950 Charter Street
23  * Redwood City, CA 94063
24  * <info@isc.org>
25  * https://www.isc.org/
26  *
27  * This code is based on the original client state machine that was
28  * written by Elliot Poger. The code has been extensively hacked on
29  * by Ted Lemon since then, so any mistakes you find are probably his
30  * fault and not Elliot's.
31  */
32 
33 #include "dhcpd.h"
34 #include <syslog.h>
35 #include <signal.h>
36 #include <errno.h>
37 #include <sys/time.h>
38 #include <sys/wait.h>
39 #include <limits.h>
40 #include <isc/file.h>
41 #include <isc/util.h>
42 #include <dns/result.h>
43 
44 #ifdef HAVE_LIBCAP_NG
45 #include <cap-ng.h>
46 #endif
47 
48 /*
49  * Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define
50  * that when building ISC code.
51  */
52 extern int asprintf(char **strp, const char *fmt, ...);
53 
54 TIME default_lease_time = 43200; /* 12 hours... */
55 TIME max_lease_time = 86400; /* 24 hours... */
56 
58 const char *path_dhclient_db = NULL;
59 const char *path_dhclient_pid = NULL;
60 static char path_dhclient_script_array[] = _PATH_DHCLIENT_SCRIPT;
61 char *path_dhclient_script = path_dhclient_script_array;
62 const char *path_dhclient_duid = NULL;
63 
64 /* False (default) => we write and use a pid file */
65 isc_boolean_t no_pid_file = ISC_FALSE;
66 
68 
70 
71 struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
72 struct iaddr iaddr_any = { 4, { 0, 0, 0, 0 } };
73 struct in_addr inaddr_any;
74 struct sockaddr_in sockaddr_broadcast;
75 struct in_addr giaddr;
77 int duid_type = 0;
78 int duid_v4 = 1;
79 int std_dhcid = 0;
80 
81 /* ASSERT_STATE() does nothing now; it used to be
82  assert (state_is == state_shouldbe). */
83 #define ASSERT_STATE(state_is, state_shouldbe) {}
84 
85 #ifndef UNIT_TEST
86 static const char copyright[] = "Copyright 2004-2017 Internet Systems Consortium.";
87 static const char arr [] = "All rights reserved.";
88 static const char message [] = "Internet Systems Consortium DHCP Client";
89 static const char url [] = "For info, please visit https://www.isc.org/software/dhcp/";
90 #endif /* UNIT_TEST */
91 
92 u_int16_t local_port = 0;
93 u_int16_t remote_port = 0;
94 #if defined(DHCPv6) && defined(DHCP4o6)
95 int dhcp4o6_state = -1; /* -1 = stopped, 0 = polling, 1 = started */
96 #endif
97 int no_daemon = 0;
98 struct string_list *client_env = NULL;
100 int onetry = 0;
101 int quiet = 1;
102 int nowait = 0;
103 int stateless = 0;
104 int wanted_ia_na = -1; /* the absolute value is the real one. */
105 int wanted_ia_ta = 0;
106 int wanted_ia_pd = 0;
107 int require_all_ias = 0; /* If the user requires all of the IAs to
108  be available before accepting a lease
109  0 = no, 1 = requries */
111 char *mockup_relay = NULL;
112 
113 char *progname = NULL;
114 
116 
118 extern struct option *default_requested_options[];
119 
120 void run_stateless(int exit_mode, u_int16_t port);
121 
122 static isc_result_t write_duid(struct data_string *duid);
123 static void add_reject(struct packet *packet);
124 
125 static int check_domain_name(const char *ptr, size_t len, int dots);
126 static int check_domain_name_list(const char *ptr, size_t len, int dots);
127 static int check_option_values(struct universe *universe, unsigned int opt,
128  const char *ptr, size_t len);
129 
130 static void dhclient_ddns_cb_free(dhcp_ddns_cb_t *ddns_cb,
131  char* file, int line);
132 
149 #if defined(DHCPv6) && defined(DHCP4o6)
150 static void dhcp4o6_poll(void *dummy);
151 static void dhcp4o6_resume(void);
152 static void recv_dhcpv4_response(struct data_string *raw);
153 static int send_dhcpv4_query(struct client_state *client, int broadcast);
154 
155 static void dhcp4o6_stop(void);
156 static void forw_dhcpv4_response(struct packet *packet);
157 static void forw_dhcpv4_query(struct data_string *raw);
158 #endif
159 
160 #ifndef UNIT_TEST
161 /* These are only used when we call usage() from the main routine
162  * which isn't compiled when building for unit tests
163  */
164 static const char use_noarg[] = "No argument for command: %s";
165 #ifdef DHCPv6
166 static const char use_v6command[] = "Command not used for DHCPv4: %s";
167 #endif
168 
169 static void setup_ib_interface(struct interface_info *ip);
170 
171 static void
172 usage(const char *sfmt, const char *sarg)
173 {
174  log_info("%s %s", message, PACKAGE_VERSION);
175  log_info(copyright);
176  log_info(arr);
177  log_info(url);
178 
179  /* If desired print out the specific error message */
180 #ifdef PRINT_SPECIFIC_CL_ERRORS
181  if (sfmt != NULL)
182  log_error(sfmt, sarg);
183 #endif
184 
185  log_fatal("Usage: %s "
186 #ifdef DHCPv6
187 #ifdef DHCP4o6
188  "[-4|-6] [-SNTPRI1dvrxi] [-nw] -4o6 <port>] [-p <port>]\n"
189  " [-D LL|LLT] [--dad-wait-time seconds]\n"
190 #else /* DHCP4o6 */
191  "[-4|-6] [-SNTPRI1dvrxi] [-nw] [-p <port>]\n"
192  " [-D LL|LLT] [--dad-wait-time seconds]\n"
193 #endif
194 #else /* DHCPv6 */
195  "[-I1dvrxi] [-nw] [-p <port>] [-D LL|LLT] \n"
196 #endif /* DHCPv6 */
197  " [-s server-addr] [-cf config-file]\n"
198  " [-df duid-file] [-lf lease-file]\n"
199  " [-pf pid-file] [--no-pid] [-e VAR=val]\n"
200  " [-sf script-file] [interface]*\n"
201  " [-C <dhcp-client-identifier>] [-B]\n"
202  " [-H <host-name> | -F <fqdn.fqdn>] [--timeout <timeout>]\n"
203  " [-V <vendor-class-identifier>]\n"
204  " [--address-prefix-len length]\n"
205  " [--request-options <request option list>]",
206  isc_file_basename(progname));
207 }
208 
209 int
210 main(int argc, char **argv) {
211  int fd;
212  int i;
213  struct interface_info *ip;
214  struct client_state *client;
215  unsigned seed;
216  char *server = NULL;
217  isc_result_t status;
218  int exit_mode = 0;
219  int release_mode = 0;
220  struct timeval tv;
221  omapi_object_t *listener;
222  isc_result_t result;
223  int persist = 0;
224  int no_dhclient_conf = 0;
225  int no_dhclient_db = 0;
226  int no_dhclient_pid = 0;
227  int no_dhclient_script = 0;
228 #ifdef DHCPv6
229  int local_family_set = 0;
230 #ifdef DHCP4o6
231  u_int16_t dhcp4o6_port = 0;
232 #endif /* DHCP4o6 */
233 #endif /* DHCPv6 */
234  char *s;
235 
236 #ifdef OLD_LOG_NAME
237  progname = "dhclient";
238 #else
239  progname = argv[0];
240 #endif
241 
242  char *dhcp_client_identifier_arg = NULL;
243  char *dhcp_host_name_arg = NULL;
244  char *dhcp_fqdn_arg = NULL;
245  char *dhcp_vendor_class_identifier_arg = NULL;
246  char *dhclient_request_options = NULL;
247 
248  int timeout_arg = 0;
249  char *arg_conf = NULL;
250  int arg_conf_len = 0;
251 #ifdef HAVE_LIBCAP_NG
252  int keep_capabilities = 0;
253 #endif
254 
255  /* Initialize client globals. */
256  memset(&default_duid, 0, sizeof(default_duid));
257 
258  /* Make sure that file descriptors 0 (stdin), 1, (stdout), and
259  2 (stderr) are open. To do this, we assume that when we
260  open a file the lowest available file descriptor is used. */
261  fd = open("/dev/null", O_RDWR | O_CLOEXEC);
262  if (fd == 0)
263  fd = open("/dev/null", O_RDWR | O_CLOEXEC);
264  if (fd == 1)
265  fd = open("/dev/null", O_RDWR | O_CLOEXEC);
266  if (fd == 2)
267  log_perror = 0; /* No sense logging to /dev/null. */
268  else if (fd != -1)
269  close(fd);
270 
271  openlog(isc_file_basename(progname), DHCP_LOG_OPTIONS, LOG_DAEMON);
272 
273 #if !(defined(DEBUG) || defined(__CYGWIN32__))
274  setlogmask(LOG_UPTO(LOG_INFO));
275 #endif
276 
277  /* Set up the isc and dns library managers */
279  | DHCP_DNS_CLIENT_LAZY_INIT, NULL, NULL);
280  if (status != ISC_R_SUCCESS)
281  log_fatal("Can't initialize context: %s",
282  isc_result_totext(status));
283 
284  /* Set up the OMAPI. */
285  status = omapi_init();
286  if (status != ISC_R_SUCCESS)
287  log_fatal("Can't initialize OMAPI: %s",
288  isc_result_totext(status));
289 
290  /* Set up the OMAPI wrappers for various server database internal
291  objects. */
293 
297 
298  for (i = 1; i < argc; i++) {
299  if (!strcmp(argv[i], "-r")) {
300  release_mode = 1;
301  no_daemon = 1;
302 #ifdef DHCPv6
303  } else if (!strcmp(argv[i], "-4")) {
304  if (local_family_set && local_family != AF_INET)
305  log_fatal("Client can only do v4 or v6, not "
306  "both.");
307  local_family_set = 1;
308  local_family = AF_INET;
309  } else if (!strcmp(argv[i], "-6")) {
310  if (local_family_set && local_family != AF_INET6)
311  log_fatal("Client can only do v4 or v6, not "
312  "both.");
313  local_family_set = 1;
314  local_family = AF_INET6;
315 #ifdef DHCP4o6
316  } else if (!strcmp(argv[i], "-4o6")) {
317  if (++i == argc)
318  usage(use_noarg, argv[i-1]);
319  dhcp4o6_port = validate_port_pair(argv[i]);
320 
321  log_debug("DHCPv4 over DHCPv6 over ::1 port %d and %d",
322  ntohs(dhcp4o6_port),
323  ntohs(dhcp4o6_port) + 1);
324  dhcpv4_over_dhcpv6 = 1;
325 #endif /* DHCP4o6 */
326 #endif /* DHCPv6 */
327  } else if (!strcmp(argv[i], "-x")) { /* eXit, no release */
328  release_mode = 0;
329  no_daemon = 0;
330  exit_mode = 1;
331  } else if (!strcmp(argv[i], "-p")) {
332  if (++i == argc)
333  usage(use_noarg, argv[i-1]);
334  local_port = validate_port(argv[i]);
335  log_debug("binding to user-specified port %d",
336  ntohs(local_port));
337  } else if (!strcmp(argv[i], "-d")) {
338  no_daemon = 1;
339  quiet = 0;
340  } else if (!strcmp(argv[i], "-pf")) {
341  if (++i == argc)
342  usage(use_noarg, argv[i-1]);
343  path_dhclient_pid = argv[i];
344  no_dhclient_pid = 1;
345  } else if (!strcmp(argv[i], "--no-pid")) {
346  no_pid_file = ISC_TRUE;
347  } else if (!strcmp(argv[i], "-cf")) {
348  if (++i == argc)
349  usage(use_noarg, argv[i-1]);
350  path_dhclient_conf = argv[i];
351  no_dhclient_conf = 1;
352  } else if (!strcmp(argv[i], "-df")) {
353  if (++i == argc)
354  usage(use_noarg, argv[i-1]);
355  path_dhclient_duid = argv[i];
356  } else if (!strcmp(argv[i], "-lf")) {
357  if (++i == argc)
358  usage(use_noarg, argv[i-1]);
359  path_dhclient_db = argv[i];
360  no_dhclient_db = 1;
361  } else if (!strcmp(argv[i], "-sf")) {
362  if (++i == argc)
363  usage(use_noarg, argv[i-1]);
364  path_dhclient_script = argv[i];
365  no_dhclient_script = 1;
366  } else if (!strcmp(argv[i], "-1")) {
367  onetry = 1;
368  } else if (!strcmp(argv[i], "-q")) {
369  quiet = 1;
370  } else if (!strcmp(argv[i], "-s")) {
371  if (++i == argc)
372  usage(use_noarg, argv[i-1]);
373  server = argv[i];
374  } else if (!strcmp(argv[i], "-g")) {
375  if (++i == argc)
376  usage(use_noarg, argv[i-1]);
377  mockup_relay = argv[i];
378  } else if (!strcmp(argv[i], "-nw")) {
379  nowait = 1;
380  } else if (!strcmp(argv[i], "-n")) {
381  /* do not start up any interfaces */
383  } else if (!strcmp(argv[i], "-w")) {
384  /* do not exit if there are no broadcast interfaces. */
385  persist = 1;
386  } else if (!strcmp(argv[i], "-e")) {
387  struct string_list *tmp;
388  if (++i == argc)
389  usage(use_noarg, argv[i-1]);
390  tmp = dmalloc(strlen(argv[i]) + sizeof *tmp, MDL);
391  if (!tmp)
392  log_fatal("No memory for %s", argv[i]);
393  strcpy(tmp->string, argv[i]);
394  tmp->next = client_env;
395  client_env = tmp;
397  } else if (!strcmp(argv[i], "--address-prefix-len")) {
398  if (++i == argc) {
399  usage(use_noarg, argv[i-1]);
400  }
401  errno = 0;
402  address_prefix_len = (int)strtol(argv[i], &s, 10);
403  if (errno || (*s != '\0') ||
404  (address_prefix_len < 0)) {
405  usage("Invalid value for"
406  " --address-prefix-len: %s", argv[i]);
407  }
408 #ifdef DHCPv6
409  } else if (!strcmp(argv[i], "-S")) {
410  if (local_family_set && (local_family == AF_INET)) {
411  usage(use_v6command, argv[i]);
412  }
413  local_family_set = 1;
414  local_family = AF_INET6;
415  wanted_ia_na = 0;
416  stateless = 1;
417  } else if (!strcmp(argv[i], "-N")) {
418  if (local_family_set && (local_family == AF_INET)) {
419  usage(use_v6command, argv[i]);
420  }
421  local_family_set = 1;
422  local_family = AF_INET6;
423  if (wanted_ia_na < 0) {
424  wanted_ia_na = 0;
425  }
426  wanted_ia_na++;
427  } else if (!strcmp(argv[i], "-T")) {
428  if (local_family_set && (local_family == AF_INET)) {
429  usage(use_v6command, argv[i]);
430  }
431  local_family_set = 1;
432  local_family = AF_INET6;
433  if (wanted_ia_na < 0) {
434  wanted_ia_na = 0;
435  }
436  wanted_ia_ta++;
437  } else if (!strcmp(argv[i], "-P")) {
438  if (local_family_set && (local_family == AF_INET)) {
439  usage(use_v6command, argv[i]);
440  }
441  local_family_set = 1;
442  local_family = AF_INET6;
443  if (wanted_ia_na < 0) {
444  wanted_ia_na = 0;
445  }
446  wanted_ia_pd++;
447  } else if (!strcmp(argv[i], "-R")) {
448  if (local_family_set && (local_family == AF_INET)) {
449  usage(use_v6command, argv[i]);
450  }
451  local_family_set = 1;
452  local_family = AF_INET6;
453  require_all_ias = 1;
454  } else if (!strcmp(argv[i], "--dad-wait-time")) {
455  if (++i == argc) {
456  usage(use_noarg, argv[i-1]);
457  }
458  dad_wait_time = (int)strtol(argv[i], &s, 10);
459  if (errno || (*s != '\0') || (dad_wait_time < 0)) {
460  usage("Invalid value for --dad-wait-time: %s", argv[i]);
461  }
462 
463 #endif /* DHCPv6 */
464  } else if (!strcmp(argv[i], "-D")) {
465  duid_v4 = 1;
466  if (++i == argc)
467  usage(use_noarg, argv[i-1]);
468  if (!strcasecmp(argv[i], "LL")) {
469  duid_type = DUID_LL;
470  } else if (!strcasecmp(argv[i], "LLT")) {
472  } else {
473  usage("Unknown argument to -D: %s", argv[i]);
474  }
475  } else if (!strcmp(argv[i], "-i")) {
476  /* enable DUID support for DHCPv4 clients */
477  duid_v4 = 1;
478  } else if (!strcmp(argv[i], "-I")) {
479  /* enable standard DHCID support for DDNS updates */
480  std_dhcid = 1;
481  } else if (!strcmp(argv[i], "-v")) {
482  quiet = 0;
483  } else if (!strcmp(argv[i], "--version")) {
484  const char vstring[] = "isc-dhclient-";
485  IGNORE_RET(write(STDERR_FILENO, vstring,
486  strlen(vstring)));
489  strlen(PACKAGE_VERSION)));
490  IGNORE_RET(write(STDERR_FILENO, "\n", 1));
491  exit(0);
492  } else if (!strcmp(argv[i], "-C")) {
493  if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
494  usage(use_noarg, argv[i-1]);
495  exit(1);
496  }
497 
498  if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
499  log_error("-C option dhcp-client-identifier string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
500  exit(1);
501  }
502 
503  dhcp_client_identifier_arg = argv[i];
504  } else if (!strcmp(argv[i], "-B")) {
506  } else if (!strcmp(argv[i], "-H")) {
507  if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
508  usage(use_noarg, argv[i-1]);
509  exit(1);
510  }
511 
512  if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
513  log_error("-H option host-name string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
514  exit(1);
515  }
516 
517  if (dhcp_host_name_arg != NULL) {
518  log_error("The -H <host-name> and -F <fqdn> arguments are mutually exclusive");
519  exit(1);
520  }
521 
522  dhcp_host_name_arg = argv[i];
523  } else if (!strcmp(argv[i], "-F")) {
524  if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
525  usage(use_noarg, argv[i-1]);
526  exit(1);
527  }
528 
529  if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
530  log_error("-F option fqdn.fqdn string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
531  exit(1);
532  }
533 
534  if (dhcp_fqdn_arg != NULL) {
535  log_error("Only one -F <fqdn> argument can be specified");
536  exit(1);
537  }
538 
539  if (dhcp_host_name_arg != NULL) {
540  log_error("The -F <fqdn> and -H <host-name> arguments are mutually exclusive");
541  exit(1);
542  }
543 
544  dhcp_fqdn_arg = argv[i];
545  } else if (!strcmp(argv[i], "--timeout")) {
546  if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
547  usage(use_noarg, argv[i-1]);
548  exit(1);
549  }
550 
551  if ((timeout_arg = atoi(argv[i])) <= 0) {
552  log_error("timeout option must be > 0 - bad value: %s",argv[i]);
553  exit(1);
554  }
555  } else if (!strcmp(argv[i], "-V")) {
556  if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
557  usage(use_noarg, argv[i-1]);
558  exit(1);
559  }
560 
561  if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
562  log_error("-V option vendor-class-identifier string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
563  exit(1);
564  }
565 
566  dhcp_vendor_class_identifier_arg = argv[i];
567  } else if (!strcmp(argv[i], "--request-options")) {
568  if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
569  usage(use_noarg, argv[i-1]);
570  exit(1);
571  }
572 
573  dhclient_request_options = argv[i];
574  } else if (!strcmp(argv[i], "-nc")) {
575 #ifdef HAVE_LIBCAP_NG
576  keep_capabilities = 1;
577 #endif
578  } else if (argv[i][0] == '-') {
579  usage("Unknown command: %s", argv[i]);
580  } else if (interfaces_requested < 0) {
581  usage("No interfaces comamnd -n and "
582  " requested interface %s", argv[i]);
583  } else {
584  struct interface_info *tmp = NULL;
585 
586  status = interface_allocate(&tmp, MDL);
587  if (status != ISC_R_SUCCESS)
588  log_fatal("Can't record interface %s:%s",
589  argv[i], isc_result_totext(status));
590  if (strlen(argv[i]) >= sizeof(tmp->name))
591  log_fatal("%s: interface name too long (is %ld)",
592  argv[i], (long)strlen(argv[i]));
593  strcpy(tmp->name, argv[i]);
594  if (interfaces) {
595  interface_reference(&tmp->next,
596  interfaces, MDL);
597  interface_dereference(&interfaces, MDL);
598  }
599  interface_reference(&interfaces, tmp, MDL);
600  tmp->flags = INTERFACE_REQUESTED;
602  }
603  }
604 
605  if (wanted_ia_na < 0) {
606  wanted_ia_na = 1;
607  }
608 
609  /* Support only one (requested) interface for Prefix Delegation. */
610  if (wanted_ia_pd && (interfaces_requested != 1)) {
611  usage("PD %s only supports one requested interface", "-P");
612  }
613 
614 #if defined(DHCPv6) && defined(DHCP4o6)
615  if ((local_family == AF_INET6) && dhcpv4_over_dhcpv6 &&
616  (exit_mode || release_mode))
617  log_error("Can't relay DHCPv4-over-DHCPv6 "
618  "without a persistent DHCPv6 client");
619  if ((local_family == AF_INET) && dhcpv4_over_dhcpv6 &&
620  (interfaces_requested != 1))
621  log_fatal("DHCPv4-over-DHCPv6 requires an explicit "
622  "interface on which to be applied");
623 #endif
624 
625  if (!no_dhclient_conf && (s = getenv("PATH_DHCLIENT_CONF"))) {
626  path_dhclient_conf = s;
627  }
628  if (!no_dhclient_db && (s = getenv("PATH_DHCLIENT_DB"))) {
629  path_dhclient_db = s;
630  }
631  if (!no_dhclient_pid && (s = getenv("PATH_DHCLIENT_PID"))) {
632  path_dhclient_pid = s;
633  }
634  if (!no_dhclient_script && (s = getenv("PATH_DHCLIENT_SCRIPT"))) {
636  }
637 
638 #ifdef HAVE_LIBCAP_NG
639  /* Drop capabilities */
640  if (!keep_capabilities) {
641  capng_clear(CAPNG_SELECT_CAPS);
642  capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
643  CAP_DAC_OVERRIDE); // Drop this someday
644  capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
645  CAP_NET_ADMIN, CAP_NET_RAW,
646  CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN, -1);
647  capng_apply(CAPNG_SELECT_CAPS);
648  }
649 #endif
650 
651  /* Set up the initial dhcp option universe. */
653 
654  /* Assign v4 or v6 specific running parameters. */
655  if (local_family == AF_INET)
657 #ifdef DHCPv6
658  else if (local_family == AF_INET6)
660 #endif /* DHCPv6 */
661  else
662  log_fatal("Impossible condition at %s:%d.", MDL);
663 
664  /*
665  * convert relative path names to absolute, for files that need
666  * to be reopened after chdir() has been called
667  */
668  if (path_dhclient_db[0] != '/') {
669  const char *old_path = path_dhclient_db;
670  path_dhclient_db = realpath(path_dhclient_db, NULL);
671  if (path_dhclient_db == NULL)
672  log_fatal("Failed to get realpath for %s: %s", old_path, strerror(errno));
673  }
674 
675  if (path_dhclient_script[0] != '/') {
676  const char *old_path = path_dhclient_script;
677  path_dhclient_script = realpath(path_dhclient_script, NULL);
678  if (path_dhclient_script == NULL)
679  log_fatal("Failed to get realpath for %s: %s", old_path, strerror(errno));
680  }
681 
682  /*
683  * See if we should kill off any currently running client
684  * we don't try to kill it off if the user told us not
685  * to write a pid file - we assume they are controlling
686  * the process in some other fashion.
687  */
688  if ((release_mode || exit_mode) && (no_pid_file == ISC_FALSE)) {
689  FILE *pidfd;
690  pid_t oldpid;
691  long temp;
692  int e;
693 
694  if ((pidfd = fopen(path_dhclient_pid, "re")) != NULL) {
695  e = fscanf(pidfd, "%ld\n", &temp);
696  oldpid = (pid_t)temp;
697 
698  if (e != 0 && e != EOF && oldpid) {
699  if (kill(oldpid, SIGTERM) == 0) {
700  log_info("Killed old client process");
701  (void) unlink(path_dhclient_pid);
702  /*
703  * wait for the old process to
704  * cleanly terminate.
705  * Note kill() with sig=0 could
706  * detect termination but only
707  * the parent can be signaled...
708  */
709  sleep(1);
710  } else if (errno == ESRCH) {
711  log_info("Removed stale PID file");
712  (void) unlink(path_dhclient_pid);
713  }
714  }
715  fclose(pidfd);
716  } else {
717  /* handle release for interfaces requested with Red Hat
718  * /sbin/ifup - pidfile will be /var/run/dhclient-$interface.pid
719  */
720 
721  if ((path_dhclient_pid == NULL) || (*path_dhclient_pid == '\0'))
722  path_dhclient_pid = "/var/run/dhclient.pid";
723 
724  char *new_path_dhclient_pid;
725  struct interface_info *ip;
726  int pdp_len = strlen(path_dhclient_pid), pfx, dpfx;
727 
728  /* find append point: beginning of any trailing '.pid'
729  * or '-$IF.pid' */
730  for (pfx=pdp_len; (pfx >= 0) && (path_dhclient_pid[pfx] != '.') && (path_dhclient_pid[pfx] != '/'); pfx--);
731  if (pfx == -1)
732  pfx = pdp_len;
733 
734  if (path_dhclient_pid[pfx] == '/')
735  pfx += 1;
736 
737  for (dpfx=pfx; (dpfx >= 0) && (path_dhclient_pid[dpfx] != '-') && (path_dhclient_pid[dpfx] != '/'); dpfx--);
738  if ((dpfx > -1) && (path_dhclient_pid[dpfx] != '/'))
739  pfx = dpfx;
740 
741  for (ip = interfaces; ip; ip = ip->next) {
742  if (interfaces_requested && (ip->flags & (INTERFACE_REQUESTED))) {
743  int n_len = strlen(ip->name);
744 
745  new_path_dhclient_pid = (char*) malloc(pfx + n_len + 6);
746  strncpy(new_path_dhclient_pid, path_dhclient_pid, pfx);
747  sprintf(new_path_dhclient_pid + pfx, "-%s.pid", ip->name);
748 
749  if ((pidfd = fopen(new_path_dhclient_pid, "re")) != NULL) {
750  e = fscanf(pidfd, "%ld\n", &temp);
751  oldpid = (pid_t)temp;
752 
753  if (e != 0 && e != EOF) {
754  if (oldpid) {
755  if (kill(oldpid, SIGTERM) == 0)
756  unlink(path_dhclient_pid);
757  }
758  }
759 
760  fclose(pidfd);
761  }
762 
763  free(new_path_dhclient_pid);
764  }
765  }
766  }
767  } else {
768  FILE *pidfp = NULL;
769  long temp = 0;
770  pid_t dhcpid = 0;
771  int dhc_running = 0;
772  char procfn[256] = "";
773 
774  if ((pidfp = fopen(path_dhclient_pid, "re")) != NULL) {
775  if ((fscanf(pidfp, "%ld", &temp)==1) && ((dhcpid=(pid_t)temp) > 0)) {
776  snprintf(procfn,256,"/proc/%u",dhcpid);
777  dhc_running = (access(procfn, F_OK) == 0);
778  }
779 
780  fclose(pidfp);
781  }
782 
783  if (dhc_running) {
784  log_fatal("dhclient(%u) is already running - exiting. ", dhcpid);
785  return(1);
786  }
787  }
788 
790 
791  if (!quiet) {
792  log_info("%s %s", message, PACKAGE_VERSION);
793  log_info(copyright);
794  log_info(arr);
795  log_info(url);
796  log_info("%s", "");
797  } else {
798  log_perror = 0;
800  }
801 
802  /* If we're given a relay agent address to insert, for testing
803  purposes, figure out what it is. */
804  if (mockup_relay) {
805  if (!inet_aton(mockup_relay, &giaddr)) {
806  struct hostent *he;
807  he = gethostbyname(mockup_relay);
808  if (he) {
809  memcpy(&giaddr, he->h_addr_list[0],
810  sizeof giaddr);
811  } else {
812  log_fatal("%s: no such host", mockup_relay);
813  }
814  }
815  }
816 
817  /* Get the current time... */
818  gettimeofday(&cur_tv, NULL);
819 
820  sockaddr_broadcast.sin_family = AF_INET;
821  sockaddr_broadcast.sin_port = remote_port;
822  if (server) {
823  if (!inet_aton(server, &sockaddr_broadcast.sin_addr)) {
824  struct hostent *he;
825  he = gethostbyname(server);
826  if (he) {
827  memcpy(&sockaddr_broadcast.sin_addr,
828  he->h_addr_list[0],
829  sizeof sockaddr_broadcast.sin_addr);
830  } else
831  sockaddr_broadcast.sin_addr.s_addr =
832  INADDR_BROADCAST;
833  }
834  } else {
835  sockaddr_broadcast.sin_addr.s_addr = INADDR_BROADCAST;
836  }
837 
838  inaddr_any.s_addr = INADDR_ANY;
839 
840  /* Discover all the network interfaces. */
842 
843  /* Parse the dhclient.conf file. */
845 
846  /* Stateless special case. */
847  if (stateless) {
848  if (release_mode || (wanted_ia_na > 0) ||
850  (interfaces_requested != 1)) {
851  usage("Stateless commnad: %s incompatibile with "
852  "other commands", "-S");
853  }
854 #if defined(DHCPv6) && defined(DHCP4o6)
855  run_stateless(exit_mode, dhcp4o6_port);
856 #else
857  run_stateless(exit_mode, 0);
858 #endif
859  return 0;
860  }
861 
862  /* Parse any extra command line configuration arguments: */
863  if ((dhcp_client_identifier_arg != NULL) && (*dhcp_client_identifier_arg != '\0')) {
864  arg_conf_len = asprintf(&arg_conf, "send dhcp-client-identifier \"%s\";", dhcp_client_identifier_arg);
865 
866  if ((arg_conf == 0) || (arg_conf_len <= 0))
867  log_fatal("Unable to send -C option dhcp-client-identifier");
868  }
869 
870  if ((dhcp_host_name_arg != NULL) && (*dhcp_host_name_arg != '\0')) {
871  if (arg_conf == 0) {
872  arg_conf_len = asprintf(&arg_conf, "send host-name \"%s\";", dhcp_host_name_arg);
873 
874  if ((arg_conf == 0) || (arg_conf_len <= 0))
875  log_fatal("Unable to send -H option host-name");
876  } else {
877  char *last_arg_conf = arg_conf;
878  arg_conf = NULL;
879  arg_conf_len = asprintf(&arg_conf, "%s\nsend host-name \"%s\";", last_arg_conf, dhcp_host_name_arg);
880 
881  if ((arg_conf == 0) || (arg_conf_len <= 0))
882  log_fatal("Unable to send -H option host-name");
883 
884  free(last_arg_conf);
885  }
886  }
887 
888  if ((dhcp_fqdn_arg != NULL) && (*dhcp_fqdn_arg != '\0')) {
889  if (arg_conf == 0) {
890  arg_conf_len = asprintf(&arg_conf, "send fqdn.fqdn \"%s\";", dhcp_fqdn_arg);
891 
892  if ((arg_conf == 0) || (arg_conf_len <= 0))
893  log_fatal("Unable to send -F option fqdn.fqdn");
894  } else {
895  char *last_arg_conf = arg_conf;
896  arg_conf = NULL;
897  arg_conf_len = asprintf(&arg_conf, "%s\nsend fqdn.fqdn \"%s\";", last_arg_conf, dhcp_fqdn_arg);
898 
899  if ((arg_conf == 0) || (arg_conf_len <= 0))
900  log_fatal("Unable to send -F option fqdn.fqdn");
901 
902  free(last_arg_conf);
903  }
904  }
905 
906  if (timeout_arg) {
907  if (arg_conf == 0) {
908  arg_conf_len = asprintf(&arg_conf, "timeout %d;", timeout_arg);
909 
910  if ((arg_conf == 0) || (arg_conf_len <= 0))
911  log_fatal("Unable to process --timeout timeout argument");
912  } else {
913  char *last_arg_conf = arg_conf;
914  arg_conf = NULL;
915  arg_conf_len = asprintf(&arg_conf, "%s\ntimeout %d;", last_arg_conf, timeout_arg);
916 
917  if ((arg_conf == 0) || (arg_conf_len == 0))
918  log_fatal("Unable to process --timeout timeout argument");
919 
920  free(last_arg_conf);
921  }
922  }
923 
924  if ((dhcp_vendor_class_identifier_arg != NULL) && (*dhcp_vendor_class_identifier_arg != '\0')) {
925  if (arg_conf == 0) {
926  arg_conf_len = asprintf(&arg_conf, "send vendor-class-identifier \"%s\";", dhcp_vendor_class_identifier_arg);
927 
928  if ((arg_conf == 0) || (arg_conf_len <= 0))
929  log_fatal("Unable to send -V option vendor-class-identifier");
930  } else {
931  char *last_arg_conf = arg_conf;
932  arg_conf = NULL;
933  arg_conf_len = asprintf(&arg_conf, "%s\nsend vendor-class-identifier \"%s\";", last_arg_conf, dhcp_vendor_class_identifier_arg);
934 
935  if ((arg_conf == 0) || (arg_conf_len <= 0))
936  log_fatal("Unable to send -V option vendor-class-identifier");
937 
938  free(last_arg_conf);
939  }
940  }
941 
942  if (dhclient_request_options != NULL) {
943  if (arg_conf == 0) {
944  arg_conf_len = asprintf(&arg_conf, "request %s;", dhclient_request_options);
945 
946  if ((arg_conf == 0) || (arg_conf_len <= 0))
947  log_fatal("Unable to parse --request-options <request options list> argument");
948  } else {
949  char *last_arg_conf = arg_conf;
950  arg_conf = NULL;
951  arg_conf_len = asprintf(&arg_conf, "%s\nrequest %s;", last_arg_conf, dhclient_request_options);
952 
953  if ((arg_conf == 0) || (arg_conf_len <= 0))
954  log_fatal("Unable to parse --request-options <request options list> argument");
955 
956  free(last_arg_conf);
957  }
958  }
959 
960  if (arg_conf) {
961  if (arg_conf_len == 0)
962  if ((arg_conf_len = strlen(arg_conf)) == 0)
963  /* huh ? cannot happen ! */
964  log_fatal("Unable to process -C/-H/-F/--timeout/-V/--request-options configuration arguments");
965 
966  /* parse the extra dhclient.conf configuration arguments
967  * into top level config: */
968  struct parse *cfile = (struct parse *)0;
969  const char *val = NULL;
970  int token;
971 
972  status = new_parse(&cfile, -1, arg_conf, arg_conf_len, "extra dhclient -C/-H/-F/--timeout/-V/--request-options configuration arguments", 0);
973 
974  if ((status != ISC_R_SUCCESS) || (cfile -> warnings_occurred))
975  log_fatal("Cannot parse -C/-H/-F/--timeout/-V/--request-options configuration arguments !");
976  /* more detailed parse failures will be logged */
977 
978  do {
979  token = peek_token(&val, (unsigned *)0, cfile);
980  if (token == END_OF_FILE)
981  break;
982 
984  } while (1);
985 
986  if (cfile -> warnings_occurred)
987  log_fatal("Cannot parse -C/-H/-F/--timeout/-V/--request-options configuration arguments !");
988  end_parse(&cfile);
989 
990  if (timeout_arg) {
991  /* we just set the toplevel timeout, but per-client
992  * timeouts may still be at defaults.
993  */
994  for (ip=interfaces; ip; ip = ip->next) {
995  if (ip->client->config->timeout == 60)
996  ip->client->config->timeout = timeout_arg;
997  }
998  }
999 
1000  if ((dhclient_request_options != 0) && (top_level_config.requested_options != default_requested_options)) {
1001  for (ip=interfaces; ip; ip = ip->next) {
1002  if (ip->client->config->requested_options == default_requested_options)
1003  ip->client->config->requested_options = top_level_config.requested_options;
1004  }
1005  }
1006 
1007  free(arg_conf);
1008  arg_conf = NULL;
1009  arg_conf_len = 0;
1010  }
1011 
1012  /* Parse the lease database. */
1014 
1015  /* If desired parse the secondary lease database for a DUID */
1016  if ((default_duid.len == 0) && (path_dhclient_duid != NULL)) {
1017  read_client_duid();
1018  }
1019 
1020  /* Rewrite the lease database... */
1022 
1023  /* XXX */
1024 /* config_counter(&snd_counter, &rcv_counter); */
1025 
1026  /*
1027  * If no broadcast interfaces were discovered, call the script
1028  * and tell it so.
1029  */
1030  if (!interfaces) {
1031  /*
1032  * Call dhclient-script with the NBI flag,
1033  * in case somebody cares.
1034  */
1035  script_init(NULL, "NBI", NULL);
1036  script_go(NULL);
1037 
1038  /*
1039  * If we haven't been asked to persist, waiting for new
1040  * interfaces, then just exit.
1041  */
1042  if (!persist) {
1043  /* Nothing more to do. */
1044  log_info("No broadcast interfaces found - exiting.");
1045  exit(0);
1046  }
1047  } else if (!release_mode && !exit_mode) {
1048  /* Call the script with the list of interfaces. */
1049  for (ip = interfaces; ip; ip = ip->next) {
1050  /*
1051  * If interfaces were specified, don't configure
1052  * interfaces that weren't specified!
1053  */
1054  if ((interfaces_requested > 0) &&
1055  ((ip->flags & (INTERFACE_REQUESTED |
1056  INTERFACE_AUTOMATIC)) !=
1058  continue;
1059 
1060  if (local_family == AF_INET6) {
1061  script_init(ip->client, "PREINIT6", NULL);
1062  } else {
1063  script_init(ip->client, "PREINIT", NULL);
1064  if (ip->client->alias != NULL)
1065  script_write_params(ip->client,
1066  "alias_",
1067  ip->client->alias);
1068  }
1069  script_go(ip->client);
1070  }
1071  }
1072 
1073  /* We create a backup seed before rediscovering interfaces in order to
1074  have a seed built using all of the available interfaces
1075  It's interesting if required interfaces doesn't let us defined
1076  a really unique seed due to a lack of valid HW addr later
1077  (this is the case with DHCP over IB)
1078  We only use the last device as using a sum could broke the
1079  uniqueness of the seed among multiple nodes
1080  */
1081  unsigned backup_seed = 0;
1082  for (ip = interfaces; ip; ip = ip -> next) {
1083  int junk;
1084  if ( ip -> hw_address.hlen <= sizeof seed )
1085  continue;
1086  memcpy (&junk,
1087  &ip -> hw_address.hbuf [ip -> hw_address.hlen -
1088  sizeof seed], sizeof seed);
1089  backup_seed = junk;
1090  }
1091 
1092 
1093  /* At this point, all the interfaces that the script thinks
1094  are relevant should be running, so now we once again call
1095  discover_interfaces(), and this time ask it to actually set
1096  up the interfaces. */
1099  : DISCOVER_RUNNING);
1100 
1101  /* Make up a seed for the random number generator from current
1102  time plus the sum of the last four bytes of each
1103  interface's hardware address interpreted as an integer.
1104  Not much entropy, but we're booting, so we're not likely to
1105  find anything better. */
1106  seed = 0;
1107  int seed_flag = 0;
1108  for (ip = interfaces; ip; ip = ip->next) {
1109  int junk;
1110  if ( ip -> hw_address.hlen <= sizeof seed )
1111  continue;
1112  memcpy(&junk,
1113  &ip->hw_address.hbuf[ip->hw_address.hlen -
1114  sizeof seed], sizeof seed);
1115  seed += junk;
1116  seed_flag = 1;
1117  }
1118  if ( seed_flag == 0 ) {
1119  if ( backup_seed != 0 ) {
1120  seed = backup_seed;
1121  log_info ("xid: rand init seed (0x%x) built using all"
1122  " available interfaces",seed);
1123  }
1124  else {
1125  seed = cur_time^((unsigned) gethostid()) ;
1126  log_info ("xid: warning: no netdev with useable HWADDR found"
1127  " for seed's uniqueness enforcement");
1128  log_info ("xid: rand init seed (0x%x) built using gethostid",
1129  seed);
1130  }
1131  /* we only use seed and no current time as a broadcast reply */
1132  /* will certainly be used by the hwaddrless interface */
1133  srandom(seed + ((unsigned)(cur_tv.tv_usec * 1000000)) + (unsigned)getpid());
1134  }
1135  else
1136  srandom(seed + ((unsigned)(cur_tv.tv_usec * 1000000)) + (unsigned)getpid());
1137 
1138  /* Setup specific Infiniband options */
1139  for (ip = interfaces; ip; ip = ip->next) {
1140  if (ip->client &&
1141  (ip->hw_address.hbuf[0] == HTYPE_INFINIBAND)) {
1142  setup_ib_interface(ip);
1143  }
1144  }
1145 
1146  /*
1147  * Establish a default DUID. We always do so for v6 and
1148  * do so if desired for v4 via the -D or -i options
1149  */
1150  if ((local_family == AF_INET6) ||
1151  ((local_family == AF_INET) && (duid_v4 == 1))) {
1152  if (default_duid.len == 0) {
1153  if (default_duid.buffer != NULL)
1155 
1156  if (form_duid(&default_duid, MDL) == ISC_R_SUCCESS)
1157  write_duid(&default_duid);
1158  }
1159  }
1160 
1161 #if defined(DHCPv6) && defined(DHCP4o6)
1162  if (dhcpv4_over_dhcpv6 && !exit_mode)
1163  dhcp4o6_setup(dhcp4o6_port);
1164 #endif
1165 
1166  /* Start a configuration state machine for each interface. */
1167 #ifdef DHCPv6
1168  if (local_family == AF_INET6) {
1169  for (ip = interfaces ; ip != NULL ; ip = ip->next) {
1170  for (client = ip->client ; client != NULL ;
1171  client = client->next) {
1172  if (release_mode) {
1173  start_release6(client);
1174  continue;
1175  } else if (exit_mode) {
1176  unconfigure6(client, "STOP6");
1177  continue;
1178  }
1179 
1180  /* If we have a previous binding, Confirm
1181  * that we can (or can't) still use it.
1182  */
1183  if ((client->active_lease != NULL) &&
1184  !client->active_lease->released)
1185  start_confirm6(client);
1186  else
1187  start_init6(client);
1188  }
1189  }
1190  } else
1191 #endif /* DHCPv6 */
1192  {
1193  for (ip = interfaces ; ip ; ip = ip->next) {
1194  ip->flags |= INTERFACE_RUNNING;
1195  for (client = ip->client ; client ;
1196  client = client->next) {
1197  if (exit_mode)
1198  state_stop(client);
1199  if (release_mode)
1200  do_release(client);
1201  else {
1202  client->state = S_INIT;
1203 
1205  {
1206  tv.tv_sec = 0;
1207  if (top_level_config.
1208  initial_delay>1)
1209  tv.tv_sec = cur_time
1210  + random()
1211  % (top_level_config.
1212  initial_delay-1);
1213  tv.tv_usec = random()
1214  % 1000000;
1215  /*
1216  * this gives better
1217  * distribution than just
1218  *whole seconds
1219  */
1221  client, 0, 0);
1222  } else {
1223  state_reboot(client);
1224  }
1225  }
1226  }
1227  }
1228  }
1229 
1230  if (exit_mode)
1231  return 0;
1232  if (release_mode) {
1233 #ifndef DHCPv6
1234  return 0;
1235 #else
1236  if ((local_family == AF_INET6) || dhcpv4_over_dhcpv6) {
1237  if (onetry)
1238  return 0;
1239  } else
1240  return 0;
1241 #endif /* DHCPv6 */
1242  }
1243 
1244  /* Start up a listener for the object management API protocol. */
1245  if (top_level_config.omapi_port != -1) {
1246  listener = NULL;
1247  result = omapi_generic_new(&listener, MDL);
1248  if (result != ISC_R_SUCCESS)
1249  log_fatal("Can't allocate new generic object: %s\n",
1250  isc_result_totext(result));
1251  result = omapi_protocol_listen(listener,
1252  (unsigned)
1254  1);
1255  if (result != ISC_R_SUCCESS)
1256  log_fatal("Can't start OMAPI protocol: %s",
1257  isc_result_totext (result));
1258  }
1259 
1260  /* Set up the bootp packet handler... */
1262 #ifdef DHCPv6
1264 #endif /* DHCPv6 */
1265 
1266 #if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \
1267  defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1268  dmalloc_cutoff_generation = dmalloc_generation;
1269  dmalloc_longterm = dmalloc_outstanding;
1270  dmalloc_outstanding = 0;
1271 #endif
1272 
1273 #if defined(ENABLE_GENTLE_SHUTDOWN)
1274  /* no signal handlers until we deal with the side effects */
1275  /* install signal handlers */
1276  signal(SIGINT, dhcp_signal_handler); /* control-c */
1277  signal(SIGTERM, dhcp_signal_handler); /* kill */
1278 #endif
1279 
1280  /* If we're not supposed to wait before getting the address,
1281  don't. */
1282  if (nowait)
1283  go_daemon();
1284 
1285  /* If we're not going to daemonize, write the pid file
1286  now. */
1287  if (no_daemon || nowait)
1289 
1290  /* Start dispatching packets and timeouts... */
1291  dispatch();
1292 
1293  /* In fact dispatch() never returns. */
1294  return 0;
1295 }
1296 
1297 /*
1298  * \brief Run the DHCPv6 stateless client (dhclient -6 -S)
1299  *
1300  * \param exist_mode set to 1 when dhclient was called with -x
1301  * \param port DHCPv4-over-DHCPv6 client inter-process communication
1302  * UDP port pair (port,port+1 with port in network byte order)
1303  */
1304 
1305 void run_stateless(int exit_mode, u_int16_t port)
1306 {
1307 #ifdef DHCPv6
1308  struct client_state *client;
1309  omapi_object_t *listener;
1310  isc_result_t result;
1311 
1312 #ifndef DHCP4o6
1313  IGNORE_UNUSED(port);
1314 #endif
1315 
1316  struct interface_info *ip;
1317 
1318  if (!interfaces)
1319  usage("No interfaces available for stateless command: %s", "-S");
1320 
1321 #ifdef DHCP4o6
1322  if (dhcpv4_over_dhcpv6) {
1323  /* Mark we want to request IRT too! */
1325  }
1326 #endif
1327 
1328  for (ip = interfaces; ip; ip = ip->next) {
1329  if ((interfaces_requested > 0) &&
1330  ((ip->flags & (INTERFACE_REQUESTED |
1331  INTERFACE_AUTOMATIC)) !=
1333  continue;
1334  script_init(ip->client, "PREINIT6", NULL);
1335  script_go(ip->client);
1336  }
1337 
1338  /* Discover the network interface. */
1340 
1341  /* Parse the lease database. */
1343 
1344  /* If desired parse the secondary lease database for a DUID */
1345  if ((default_duid.len == 0) && (path_dhclient_duid != NULL)) {
1346  read_client_duid();
1347  }
1348 
1349  /* Establish a default DUID. */
1350  if (default_duid.len == 0) {
1351  if (default_duid.buffer != NULL)
1353 
1355  if (form_duid(&default_duid, MDL) == ISC_R_SUCCESS &&
1356  duid_type == DUID_LLT)
1357  write_duid(&default_duid);
1358  }
1359 
1360 #ifdef DHCP4o6
1361  if (dhcpv4_over_dhcpv6 && !exit_mode)
1362  dhcp4o6_setup(port);
1363 #endif
1364 
1365  /* Start a configuration state machine. */
1366  for (client = interfaces->client ;
1367  client != NULL ;
1368  client = client->next) {
1369  if (exit_mode) {
1370  unconfigure6(client, "STOP6");
1371  continue;
1372  }
1374  }
1375  if (exit_mode)
1376  return;
1377 
1378  /* Start up a listener for the object management API protocol. */
1379  if (top_level_config.omapi_port != -1) {
1380  listener = NULL;
1381  result = omapi_generic_new(&listener, MDL);
1382  if (result != ISC_R_SUCCESS)
1383  log_fatal("Can't allocate new generic object: %s\n",
1384  isc_result_totext(result));
1385  result = omapi_protocol_listen(listener,
1386  (unsigned)
1388  1);
1389  if (result != ISC_R_SUCCESS)
1390  log_fatal("Can't start OMAPI protocol: %s",
1391  isc_result_totext(result));
1392  }
1393 
1394  /* Set up the packet handler... */
1396 
1397 #if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \
1398  defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1399  dmalloc_cutoff_generation = dmalloc_generation;
1400  dmalloc_longterm = dmalloc_outstanding;
1401  dmalloc_outstanding = 0;
1402 #endif
1403 
1404  /* If we're not supposed to wait before getting the address,
1405  don't. */
1406  if (nowait)
1407  go_daemon();
1408 
1409  /* If we're not going to daemonize, write the pid file
1410  now. */
1411  if (no_daemon || nowait)
1413 
1414  /* Start dispatching packets and timeouts... */
1415  dispatch();
1416 
1417 #endif /* DHCPv6 */
1418  return;
1419 }
1420 #endif /* !UNIT_TEST */
1421 
1422 isc_result_t find_class (struct class **c,
1423  const char *s, const char *file, int line)
1424 {
1425  return 0;
1426 }
1427 
1429  struct packet *packet;
1430  struct lease *lease;
1431  struct collection *collection;
1432 {
1433  return 0;
1434 }
1435 
1436 void classify (packet, class)
1437  struct packet *packet;
1438  struct class *class;
1439 {
1440 }
1441 
1443  struct lease *lease;
1444 {
1445 }
1446 
1447 int find_subnet (struct subnet **sp,
1448  struct iaddr addr, const char *file, int line)
1449 {
1450  return 0;
1451 }
1452 
1453 static void setup_ib_interface(struct interface_info *ip)
1454 {
1455  struct group *g;
1456 
1457  /* Set the broadcast flag */
1458  ip->client->config->bootp_broadcast_always = 1;
1459 
1460  /*
1461  * Find out if a dhcp-client-identifier option was specified either
1462  * in the config file or on the command line
1463  */
1464  for (g = ip->client->config->on_transmission; g != NULL; g = g->next) {
1465  if ((g->statements != NULL) &&
1466  (strcmp(g->statements->data.option->option->name,
1467  "dhcp-client-identifier") == 0)) {
1468  return;
1469  }
1470  }
1471 
1472  /* No client ID specified */
1473  //log_fatal("dhcp-client-identifier must be specified for InfiniBand");
1474 }
1475 
1476 /* Individual States:
1477  *
1478  * Each routine is called from the dhclient_state_machine() in one of
1479  * these conditions:
1480  * -> entering INIT state
1481  * -> recvpacket_flag == 0: timeout in this state
1482  * -> otherwise: received a packet in this state
1483  *
1484  * Return conditions as handled by dhclient_state_machine():
1485  * Returns 1, sendpacket_flag = 1: send packet, reset timer.
1486  * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone).
1487  * Returns 0: finish the nap which was interrupted for no good reason.
1488  *
1489  * Several per-interface variables are used to keep track of the process:
1490  * active_lease: the lease that is being used on the interface
1491  * (null pointer if not configured yet).
1492  * offered_leases: leases corresponding to DHCPOFFER messages that have
1493  * been sent to us by DHCP servers.
1494  * acked_leases: leases corresponding to DHCPACK messages that have been
1495  * sent to us by DHCP servers.
1496  * sendpacket: DHCP packet we're trying to send.
1497  * destination: IP address to send sendpacket to
1498  * In addition, there are several relevant per-lease variables.
1499  * T1_expiry, T2_expiry, lease_expiry: lease milestones
1500  * In the active lease, these control the process of renewing the lease;
1501  * In leases on the acked_leases list, this simply determines when we
1502  * can no longer legitimately use the lease.
1503  */
1504 
1505 void state_reboot (cpp)
1506  void *cpp;
1507 {
1508  struct client_state *client = cpp;
1509 
1510 #if defined(DHCPv6) && defined(DHCP4o6)
1511  if (dhcpv4_over_dhcpv6 && (dhcp4o6_state <= 0)) {
1512  if (dhcp4o6_state < 0)
1513  dhcp4o6_poll(NULL);
1514  client->pending = P_REBOOT;
1515  return;
1516  }
1517 #endif
1518 
1519  client->pending= P_NONE;
1520 
1521  /* If we don't remember an active lease, go straight to INIT. */
1522  if (!client -> active ||
1523  client -> active -> is_bootp ||
1524  client -> active -> expiry <= cur_time) {
1525  state_init (client);
1526  return;
1527  }
1528 
1529  /* We are in the rebooting state. */
1530  client -> state = S_REBOOTING;
1531 
1532  /*
1533  * make_request doesn't initialize xid because it normally comes
1534  * from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
1535  * so pick an xid now.
1536  */
1537  client -> xid = random ();
1538 
1539  /*
1540  * Make a DHCPREQUEST packet, and set
1541  * appropriate per-interface flags.
1542  */
1543  make_request (client, client -> active);
1544  client -> destination = iaddr_broadcast;
1545  client -> first_sending = cur_time;
1546  client -> interval = client -> config -> initial_interval;
1547 
1548  /* Zap the medium list... */
1549  client -> medium = NULL;
1550 
1551  /* Send out the first DHCPREQUEST packet. */
1552  send_request (client);
1553 }
1554 
1555 /* Called when a lease has completely expired and we've been unable to
1556  renew it. */
1557 
1558 void state_init (cpp)
1559  void *cpp;
1560 {
1561  struct client_state *client = cpp;
1562  enum dhcp_state init_state = client->state;
1563  struct timeval tv;
1564 
1565  ASSERT_STATE(state, S_INIT);
1566 
1567  /* Make a DHCPDISCOVER packet, and set appropriate per-interface
1568  flags. */
1569  make_discover (client, client -> active);
1570  client -> xid = client -> packet.xid;
1571  client -> destination = iaddr_broadcast;
1572  client -> state = S_SELECTING;
1573  client -> first_sending = cur_time;
1574  client -> interval = client -> config -> initial_interval;
1575 
1576  if (init_state != S_DECLINED) {
1577  /* Add an immediate timeout to cause the first DHCPDISCOVER packet
1578  to go out. */
1579  send_discover(client);
1580  } else {
1581  /* We've received an OFFER and it has been DECLINEd by dhclient-script.
1582  * wait for a random time between 1 and backoff_cutoff seconds before
1583  * trying again. */
1584  tv . tv_sec = cur_time + ((1 + (random() >> 2)) % client->config->backoff_cutoff);
1585  tv . tv_usec = 0;
1586  add_timeout(&tv, send_discover, client, 0, 0);
1587  }
1588 }
1589 
1590 /*
1591  * state_selecting is called when one or more DHCPOFFER packets have been
1592  * received and a configurable period of time has passed.
1593  */
1594 
1596  void *cpp;
1597 {
1598  struct client_state *client = cpp;
1599  struct client_lease *lp, *next, *picked;
1600 
1601 
1602  ASSERT_STATE(state, S_SELECTING);
1603 
1604  /*
1605  * Cancel state_selecting and send_discover timeouts, since either
1606  * one could have got us here.
1607  */
1608  cancel_timeout (state_selecting, client);
1609  cancel_timeout (send_discover, client);
1610 
1611  /*
1612  * We have received one or more DHCPOFFER packets. Currently,
1613  * the only criterion by which we judge leases is whether or
1614  * not we get a response when we arp for them.
1615  */
1616  picked = NULL;
1617  for (lp = client -> offered_leases; lp; lp = next) {
1618  next = lp -> next;
1619 
1620  /*
1621  * Check to see if we got an ARPREPLY for the address
1622  * in this particular lease.
1623  */
1624  if (!picked) {
1625  picked = lp;
1626  picked -> next = NULL;
1627  } else {
1628  destroy_client_lease (lp);
1629  }
1630  }
1631  client -> offered_leases = NULL;
1632 
1633  /*
1634  * If we just tossed all the leases we were offered, go back
1635  * to square one.
1636  */
1637  if (!picked) {
1638  client -> state = S_INIT;
1639  state_init (client);
1640  return;
1641  }
1642 
1643  /* If it was a BOOTREPLY, we can just take the address right now. */
1644  if (picked -> is_bootp) {
1645  client -> new = picked;
1646 
1647  /* Make up some lease expiry times
1648  XXX these should be configurable. */
1649  client -> new -> expiry = cur_time + 12000;
1650  client -> new -> renewal += cur_time + 8000;
1651  client -> new -> rebind += cur_time + 10000;
1652 
1653  client -> state = S_REQUESTING;
1654 
1655  /* Bind to the address we received. */
1656  bind_lease (client);
1657  return;
1658  }
1659 
1660  /* Go to the REQUESTING state. */
1661  client -> destination = iaddr_broadcast;
1662  client -> state = S_REQUESTING;
1663  client -> first_sending = cur_time;
1664  client -> interval = client -> config -> initial_interval;
1665 
1666  /* Make a DHCPREQUEST packet from the lease we picked. */
1667  make_request (client, picked);
1668  client -> xid = client -> packet.xid;
1669 
1670  /* Toss the lease we picked - we'll get it back in a DHCPACK. */
1671  destroy_client_lease (picked);
1672 
1673  /* Add an immediate timeout to send the first DHCPREQUEST packet. */
1674  send_request (client);
1675 }
1676 
1677 /* state_requesting is called when we receive a DHCPACK message after
1678  having sent out one or more DHCPREQUEST packets. */
1679 
1681  struct packet *packet;
1682 {
1683  struct interface_info *ip = packet -> interface;
1684  struct client_state *client;
1685  struct client_lease *lease;
1686  struct option_cache *oc;
1687  struct data_string ds;
1688 
1689  /* If we're not receptive to an offer right now, or if the offer
1690  has an unrecognizable transaction id, then just drop it. */
1691  for (client = ip -> client; client; client = client -> next) {
1692  if (client -> xid == packet -> raw -> xid)
1693  break;
1694  }
1695  if (!client ||
1696  (packet -> interface -> hw_address.hlen - 1 !=
1697  packet -> raw -> hlen) ||
1698  (memcmp (&packet -> interface -> hw_address.hbuf [1],
1699  packet -> raw -> chaddr, packet -> raw -> hlen))) {
1700 #if defined (DEBUG)
1701  log_debug ("DHCPACK in wrong transaction.");
1702 #endif
1703  return;
1704  }
1705 
1706  if (client -> state != S_REBOOTING &&
1707  client -> state != S_REQUESTING &&
1708  client -> state != S_RENEWING &&
1709  client -> state != S_REBINDING) {
1710 #if defined (DEBUG)
1711  log_debug ("DHCPACK in wrong state.");
1712 #endif
1713  return;
1714  }
1715 
1716  log_info ("DHCPACK from %s (xid=0x%x)", piaddr (packet -> client_addr), ntohl(client -> xid));
1717 
1718  lease = packet_to_lease (packet, client);
1719  if (!lease) {
1720  log_info ("packet_to_lease failed.");
1721  return;
1722  }
1723 
1724  client -> new = lease;
1725 
1726  /* Stop resending DHCPREQUEST. */
1727  cancel_timeout (send_request, client);
1728 
1729  /* Figure out the lease time. */
1730  oc = lookup_option (&dhcp_universe, client -> new -> options,
1732  memset (&ds, 0, sizeof ds);
1733  if (oc &&
1734  evaluate_option_cache (&ds, packet, (struct lease *)0, client,
1735  packet -> options, client -> new -> options,
1736  &global_scope, oc, MDL)) {
1737  if (ds.len > 3)
1738  client -> new -> expiry = getULong (ds.data);
1739  else
1740  client -> new -> expiry = 0;
1741  data_string_forget (&ds, MDL);
1742  } else
1743  client -> new -> expiry = 0;
1744 
1745  if (client->new->expiry == 0) {
1746  struct timeval tv;
1747 
1748  log_error ("no expiry time on offered lease.");
1749 
1750  /* Quench this (broken) server. Return to INIT to reselect. */
1751  add_reject(packet);
1752 
1753  /* 1/2 second delay to restart at INIT. */
1754  tv.tv_sec = cur_tv.tv_sec;
1755  tv.tv_usec = cur_tv.tv_usec + 500000;
1756 
1757  if (tv.tv_usec >= 1000000) {
1758  tv.tv_sec++;
1759  tv.tv_usec -= 1000000;
1760  }
1761 
1762  add_timeout(&tv, state_init, client, 0, 0);
1763  return;
1764  }
1765 
1766  /*
1767  * A number that looks negative here is really just very large,
1768  * because the lease expiry offset is unsigned.
1769  */
1770  if (client->new->expiry < 0)
1771  client->new->expiry = TIME_MAX;
1772 
1773  /* Take the server-provided renewal time if there is one. */
1774  oc = lookup_option (&dhcp_universe, client -> new -> options,
1776  if (oc &&
1777  evaluate_option_cache (&ds, packet, (struct lease *)0, client,
1778  packet -> options, client -> new -> options,
1779  &global_scope, oc, MDL)) {
1780  if (ds.len > 3)
1781  client -> new -> renewal = getULong (ds.data);
1782  else
1783  client -> new -> renewal = 0;
1784  data_string_forget (&ds, MDL);
1785  } else
1786  client -> new -> renewal = 0;
1787 
1788  /*
1789  * If it wasn't specified by the server, calculate it. Also use expiry
1790  * instead of renewal time when it is shorter. This better follows
1791  * RFC 2131 (section 4.4.5) when dealing with some DHCP servers.
1792  */
1793 
1794  if (!client -> new -> renewal ||
1795  client -> new -> renewal > client -> new -> expiry)
1796  client -> new -> renewal = client -> new -> expiry / 2 + 1;
1797 
1798  if (client -> new -> renewal <= 0)
1799  client -> new -> renewal = TIME_MAX;
1800 
1801  /* Now introduce some randomness to the renewal time: */
1802  if (client->new->renewal <= ((TIME_MAX / 3) - 3))
1803  client->new->renewal = (((client->new->renewal * 3) + 3) / 4) +
1804  (((random() % client->new->renewal) + 3) / 4);
1805 
1806  /* Same deal with the rebind time. */
1807  oc = lookup_option (&dhcp_universe, client -> new -> options,
1809  if (oc &&
1810  evaluate_option_cache (&ds, packet, (struct lease *)0, client,
1811  packet -> options, client -> new -> options,
1812  &global_scope, oc, MDL)) {
1813  if (ds.len > 3)
1814  client -> new -> rebind = getULong (ds.data);
1815  else
1816  client -> new -> rebind = 0;
1817  data_string_forget (&ds, MDL);
1818  } else
1819  client -> new -> rebind = 0;
1820 
1821  /* Rebinding time must not be longer than expiry. */
1822  if (client -> new -> rebind <= 0 ||
1823  client -> new -> rebind > client -> new -> expiry) {
1824  if (client -> new -> expiry <= TIME_MAX / 7)
1825  client -> new -> rebind =
1826  client -> new -> expiry * 7 / 8;
1827  else
1828  client -> new -> rebind =
1829  client -> new -> expiry / 8 * 7;
1830  }
1831 
1832  /* Make sure our randomness didn't run the renewal time past the
1833  rebind time. */
1834  if (client -> new -> renewal > client -> new -> rebind) {
1835  if (client -> new -> rebind <= TIME_MAX / 3)
1836  client -> new -> renewal =
1837  client -> new -> rebind * 3 / 4;
1838  else
1839  client -> new -> renewal =
1840  client -> new -> rebind / 4 * 3;
1841  }
1842 
1843  client -> new -> expiry += cur_time;
1844  /* Lease lengths can never be negative. */
1845  if (client -> new -> expiry < cur_time)
1846  client -> new -> expiry = TIME_MAX;
1847  client -> new -> renewal += cur_time;
1848  if (client -> new -> renewal < cur_time)
1849  client -> new -> renewal = TIME_MAX;
1850  client -> new -> rebind += cur_time;
1851  if (client -> new -> rebind < cur_time)
1852  client -> new -> rebind = TIME_MAX;
1853 
1854  bind_lease (client);
1855 }
1856 
1857 void bind_lease (client)
1858  struct client_state *client;
1859 {
1860  struct timeval tv;
1861 
1862  /* Remember the medium. */
1863  client->new->medium = client->medium;
1864 
1865  /* Run the client script with the new parameters. */
1866  script_init(client, (client->state == S_REQUESTING ? "BOUND" :
1867  (client->state == S_RENEWING ? "RENEW" :
1868  (client->state == S_REBOOTING ? "REBOOT" :
1869  "REBIND"))),
1870  client->new->medium);
1871  if (client->active && client->state != S_REBOOTING)
1872  script_write_params(client, "old_", client->active);
1873  script_write_params(client, "new_", client->new);
1874  script_write_requested(client);
1875  if (client->alias)
1876  script_write_params(client, "alias_", client->alias);
1877 
1878  /* If the BOUND/RENEW code detects another machine using the
1879  offered address, it exits nonzero. We need to send a
1880  DHCPDECLINE and toss the lease. */
1881  if (script_go(client)) {
1882  make_decline(client, client->new);
1883  send_decline(client);
1884  destroy_client_lease(client->new);
1885  client->new = NULL;
1886  if (onetry) {
1887  if (!quiet) {
1888  log_info("Unable to obtain a lease on first "
1889  "try (declined). Exiting.");
1890  }
1891 
1892 #if defined (CALL_SCRIPT_ON_ONETRY_FAIL)
1893  /* Let's call a script and we're done */
1894  script_init(client, "FAIL", (struct string_list *)0);
1895  script_go(client);
1896 #endif
1897  exit(2);
1898  } else {
1899  client -> state = S_DECLINED;
1900  state_init(client);
1901  return;
1902  }
1903  }
1904 
1905  /* Write out the new lease if it has been long enough. */
1906  if (!client->last_write ||
1907  (cur_time - client->last_write) >= MIN_LEASE_WRITE)
1908  write_client_lease(client, client->new, 0, 1);
1909 
1910  /* Replace the old active lease with the new one. */
1911  if (client->active)
1912  destroy_client_lease(client->active);
1913  client->active = client->new;
1914  client->new = NULL;
1915 
1916  /* Set up a timeout to start the renewal process. */
1917  tv.tv_sec = client->active->renewal;
1918  tv.tv_usec = ((client->active->renewal - cur_tv.tv_sec) > 1) ?
1919  random() % 1000000 : cur_tv.tv_usec;
1920  add_timeout(&tv, state_bound, client, 0, 0);
1921 
1922  log_info("bound to %s -- renewal in %ld seconds.",
1923  piaddr(client->active->address),
1924  (long)(client->active->renewal - cur_time));
1925  client->state = S_BOUND;
1927  go_daemon();
1928 #if defined (NSUPDATE)
1929  if (client->config->do_forward_update)
1930  dhclient_schedule_updates(client, &client->active->address, 1);
1931 #endif
1932 }
1933 
1934 /* state_bound is called when we've successfully bound to a particular
1935  lease, but the renewal time on that lease has expired. We are
1936  expected to unicast a DHCPREQUEST to the server that gave us our
1937  original lease. */
1938 
1939 void state_bound (cpp)
1940  void *cpp;
1941 {
1942  struct client_state *client = cpp;
1943  struct option_cache *oc;
1944  struct data_string ds;
1945 
1946  ASSERT_STATE(state, S_BOUND);
1947 
1948  /* T1 has expired. */
1949  make_request (client, client -> active);
1950  client -> xid = client -> packet.xid;
1951 
1952  memset (&ds, 0, sizeof ds);
1953  oc = lookup_option (&dhcp_universe, client -> active -> options,
1955  if (oc &&
1956  evaluate_option_cache (&ds, (struct packet *)0, (struct lease *)0,
1957  client, (struct option_state *)0,
1958  client -> active -> options,
1959  &global_scope, oc, MDL)) {
1960  if (ds.len > 3) {
1961  memcpy (client -> destination.iabuf, ds.data, 4);
1962  client -> destination.len = 4;
1963  } else
1964  client -> destination = iaddr_broadcast;
1965 
1966  data_string_forget (&ds, MDL);
1967  } else
1968  client -> destination = iaddr_broadcast;
1969 
1970  client -> first_sending = cur_time;
1971  client -> interval = client -> config -> initial_interval;
1972  client -> state = S_RENEWING;
1973 
1974  /* Send the first packet immediately. */
1975  send_request (client);
1976 }
1977 
1978 /* state_stop is called when we've been told to shut down. We unconfigure
1979  the interfaces, and then stop operating until told otherwise. */
1980 
1981 void state_stop (cpp)
1982  void *cpp;
1983 {
1984  struct client_state *client = cpp;
1985 
1986  client->pending = P_NONE;
1987 
1988  /* Cancel all timeouts. */
1990  cancel_timeout(send_discover, client);
1991  cancel_timeout(send_request, client);
1992  cancel_timeout(state_bound, client);
1993 
1994  /* If we have an address, unconfigure it. */
1995  if (client->active) {
1996  script_init(client, "STOP", client->active->medium);
1997  script_write_params(client, "old_", client->active);
1998  script_write_requested(client);
1999  if (client->alias)
2000  script_write_params(client, "alias_", client->alias);
2001  script_go(client);
2002  }
2003 }
2004 
2006 {
2007  return 0;
2008 }
2009 
2011  struct lease *lease;
2012 {
2013  return 0;
2014 }
2015 
2017  struct host_decl *host;
2018 {
2019  return 0;
2020 }
2021 
2022 void db_startup (testp)
2023  int testp;
2024 {
2025 }
2026 
2028  struct packet *packet;
2029 {
2030  struct iaddrmatchlist *ap;
2031  char addrbuf[4*16];
2032  char maskbuf[4*16];
2033 
2034  if (packet -> raw -> op != BOOTREPLY)
2035  return;
2036 
2037  /* If there's a reject list, make sure this packet's sender isn't
2038  on it. */
2039  for (ap = packet -> interface -> client -> config -> reject_list;
2040  ap; ap = ap -> next) {
2041  if (addr_match(&packet->client_addr, &ap->match)) {
2042 
2043  /* piaddr() returns its result in a static
2044  buffer sized 4*16 (see common/inet.c). */
2045 
2046  strcpy(addrbuf, piaddr(ap->match.addr));
2047  strcpy(maskbuf, piaddr(ap->match.mask));
2048 
2049  log_info("BOOTREPLY from %s rejected by rule %s "
2050  "mask %s.", piaddr(packet->client_addr),
2051  addrbuf, maskbuf);
2052  return;
2053  }
2054  }
2055 
2056  dhcpoffer (packet);
2057 
2058 }
2059 
2060 void dhcp (packet)
2061  struct packet *packet;
2062 {
2063  struct iaddrmatchlist *ap;
2064  void (*handler) (struct packet *);
2065  const char *type;
2066  char addrbuf[4*16];
2067  char maskbuf[4*16];
2068 
2069  switch (packet -> packet_type) {
2070  case DHCPOFFER:
2071  handler = dhcpoffer;
2072  type = "DHCPOFFER";
2073  break;
2074 
2075  case DHCPNAK:
2076  handler = dhcpnak;
2077  type = "DHCPNACK";
2078  break;
2079 
2080  case DHCPACK:
2081  handler = dhcpack;
2082  type = "DHCPACK";
2083  break;
2084 
2085  default:
2086  return;
2087  }
2088 
2089  /* If there's a reject list, make sure this packet's sender isn't
2090  on it. */
2091  for (ap = packet -> interface -> client -> config -> reject_list;
2092  ap; ap = ap -> next) {
2093  if (addr_match(&packet->client_addr, &ap->match)) {
2094 
2095  /* piaddr() returns its result in a static
2096  buffer sized 4*16 (see common/inet.c). */
2097 
2098  strcpy(addrbuf, piaddr(ap->match.addr));
2099  strcpy(maskbuf, piaddr(ap->match.mask));
2100 
2101  log_info("%s from %s rejected by rule %s mask %s.",
2102  type, piaddr(packet->client_addr),
2103  addrbuf, maskbuf);
2104  return;
2105  }
2106  }
2107  (*handler) (packet);
2108 }
2109 
2110 #ifdef DHCPv6
2111 void
2112 dhcpv6(struct packet *packet) {
2113  struct iaddrmatchlist *ap;
2114  struct client_state *client;
2115  char addrbuf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")];
2116 
2117  /* Silently drop bogus messages. */
2119  return;
2120 
2121  /* Discard, with log, packets from quenched sources. */
2122  for (ap = packet->interface->client->config->reject_list ;
2123  ap ; ap = ap->next) {
2124  if (addr_match(&packet->client_addr, &ap->match)) {
2125  strcpy(addrbuf, piaddr(packet->client_addr));
2126  log_info("%s from %s rejected by rule %s",
2128  addrbuf,
2129  piaddrmask(&ap->match.addr, &ap->match.mask));
2130  return;
2131  }
2132  }
2133 
2134  /* Screen out nonsensical messages. */
2135  switch(packet->dhcpv6_msg_type) {
2136 #ifdef DHCP4o6
2138  if (dhcpv4_over_dhcpv6) {
2139  log_info("RCV: %s message on %s from %s.",
2141  packet->interface->name,
2143  forw_dhcpv4_response(packet);
2144  }
2145  return;
2146 #endif
2147  case DHCPV6_ADVERTISE:
2148  case DHCPV6_RECONFIGURE:
2149  if (stateless)
2150  return;
2151  /* Falls through */
2152  case DHCPV6_REPLY:
2153  log_info("RCV: %s message on %s from %s.",
2156  break;
2157 
2158  default:
2159  return;
2160  }
2161 
2162  /* Find a client state that matches the incoming XID. */
2163  for (client = packet->interface->client ; client ;
2164  client = client->next) {
2165  if (memcmp(&client->dhcpv6_transaction_id,
2166  packet->dhcpv6_transaction_id, 3) == 0) {
2167  client->v6_handler(packet, client);
2168  return;
2169  }
2170  }
2171 
2172  /* XXX: temporary log for debugging */
2173  log_info("Packet received, but nothing done with it.");
2174 }
2175 
2176 #ifdef DHCP4o6
2177 /*
2178  * \brief Forward a DHCPv4-response to the DHCPv4 client.
2179  * (DHCPv6 client function)
2180  *
2181  * The DHCPv6 client receives a DHCPv4-response which is forwarded
2182  * to the DHCPv4 client.
2183  * Format: address:16 + DHCPv4 message content
2184  * (we have no state to keep the address so it is transported in
2185  * DHCPv6 <-> DHCPv6 inter-process messages)
2186  *
2187  * \param packet the DHCPv4-response packet
2188  */
2189 static void forw_dhcpv4_response(struct packet *packet)
2190 {
2191  struct option_cache *oc;
2192  struct data_string enc_opt_data;
2193  struct data_string ds;
2194  int cc;
2195 
2196  /*
2197  * Discard if relay is not ready.
2198  */
2199  if (dhcp4o6_state == -1) {
2200  log_info("forw_dhcpv4_response: not ready.");
2201  return;
2202  }
2203 
2204  if (packet->client_addr.len != 16) {
2205  log_error("forw_dhcpv4_response: bad address");
2206  return;
2207  }
2208 
2209  /*
2210  * Get our encapsulated DHCPv4 message.
2211  */
2213  if (oc == NULL) {
2214  log_info("DHCPv4-response from %s missing "
2215  "DHCPv4 Message option.",
2217  return;
2218  }
2219 
2220  memset(&enc_opt_data, 0, sizeof(enc_opt_data));
2221  if (!evaluate_option_cache(&enc_opt_data, NULL, NULL, NULL,
2222  NULL, NULL, &global_scope, oc, MDL)) {
2223  log_error("forw_dhcpv4_response: error evaluating "
2224  "DHCPv4 message.");
2225  data_string_forget(&enc_opt_data, MDL);
2226  return;
2227  }
2228 
2229  if (enc_opt_data.len < DHCP_FIXED_NON_UDP) {
2230  log_error("forw_dhcpv4_response: "
2231  "no memory for encapsulated packet.");
2232  data_string_forget(&enc_opt_data, MDL);
2233  return;
2234  }
2235 
2236  /*
2237  * Append address.
2238  */
2239  memset(&ds, 0, sizeof(ds));
2240  if (!buffer_allocate(&ds.buffer, enc_opt_data.len + 16, MDL)) {
2241  log_error("forw_dhcpv4_response: no memory buffer.");
2242  data_string_forget(&enc_opt_data, MDL);
2243  return;
2244  }
2245  ds.data = ds.buffer->data;
2246  ds.len = enc_opt_data.len + 16;
2247  memcpy(ds.buffer->data, enc_opt_data.data, enc_opt_data.len);
2248  memcpy(ds.buffer->data + enc_opt_data.len,
2249  packet->client_addr.iabuf, 16);
2250  data_string_forget(&enc_opt_data, MDL);
2251 
2252  /*
2253  * Forward them.
2254  */
2255  cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
2256  if (cc < 0)
2257  log_error("forw_dhcpv4_response: send(): %m");
2258 
2259  data_string_forget(&ds, MDL);
2260 }
2261 
2262 /*
2263  * \brief Receive a DHCPv4-response from the DHCPv6 client.
2264  * (DHCPv4 client function)
2265  *
2266  * The DHCPv4 client receives a DHCPv4-response forwarded
2267  * by the DHCPv6 client (using \ref forw_dhcpv4_response())
2268  *
2269  * \param raw the DHCPv4-response raw packet
2270  */
2271 static void recv_dhcpv4_response(struct data_string *raw)
2272 {
2273  struct packet *packet;
2274  struct iaddr from;
2275 
2276  if (interfaces == NULL) {
2277  log_error("recv_dhcpv4_response: no interfaces.");
2278  return;
2279  }
2280 
2281  from.len = 16;
2282  memcpy(from.iabuf, raw->data + (raw->len - 16), 16);
2283 
2284  /*
2285  * Build a packet structure.
2286  */
2287  packet = NULL;
2288  if (!packet_allocate(&packet, MDL)) {
2289  log_error("recv_dhcpv4_response: no memory for packet.");
2290  return;
2291  }
2292 
2293  packet->raw = (struct dhcp_packet *) raw->data;
2294  packet->packet_length = raw->len - 16;
2296  packet->client_addr = from;
2297  interface_reference(&packet->interface, interfaces, MDL);
2298 
2299  /* Allocate packet->options now so it is non-null for all packets */
2301  log_error("recv_dhcpv4_response: no memory for options.");
2303  return;
2304  }
2305 
2306  /* If there's an option buffer, try to parse it. */
2307  if (packet->packet_length >= DHCP_FIXED_NON_UDP + 4) {
2308  struct option_cache *op;
2309  if (!parse_options(packet)) {
2310  if (packet->options)
2312  (&packet->options, MDL);
2314  return;
2315  }
2316 
2317  if (packet->options_valid &&
2319  packet->options,
2321  struct data_string dp;
2322  memset(&dp, 0, sizeof dp);
2323  evaluate_option_cache(&dp, packet, NULL, NULL,
2324  packet->options, NULL,
2325  NULL, op, MDL);
2326  if (dp.len > 0)
2327  packet->packet_type = dp.data[0];
2328  else
2329  packet->packet_type = 0;
2330  data_string_forget(&dp, MDL);
2331  }
2332  }
2333 
2334  if (validate_packet(packet) != 0) {
2335  if (packet->packet_type)
2336  dhcp(packet);
2337  else
2338  bootp(packet);
2339  }
2340 
2341  /* If the caller kept the packet, they'll have upped the refcnt. */
2343 }
2344 #endif /* DHCP4o6 */
2345 #endif /* DHCPv6 */
2346 
2348  struct packet *packet;
2349 {
2350  struct interface_info *ip = packet -> interface;
2351  struct client_state *client;
2352  struct client_lease *lease, *lp;
2353  struct option **req;
2354  int i;
2355  int stop_selecting;
2356  const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY";
2357  char obuf [1024];
2358  struct timeval tv;
2359 
2360 #ifdef DEBUG_PACKET
2361  dump_packet (packet);
2362 #endif
2363 
2364  /* Find a client state that matches the xid... */
2365  for (client = ip -> client; client; client = client -> next)
2366  if (client -> xid == packet -> raw -> xid)
2367  break;
2368 
2369  /* If we're not receptive to an offer right now, or if the offer
2370  has an unrecognizable transaction id, then just drop it. */
2371  if (!client ||
2372  client -> state != S_SELECTING ||
2373  (packet -> interface -> hw_address.hlen - 1 !=
2374  packet -> raw -> hlen) ||
2375  (memcmp (&packet -> interface -> hw_address.hbuf [1],
2376  packet -> raw -> chaddr, packet -> raw -> hlen))) {
2377 #if defined (DEBUG)
2378  log_debug ("%s in wrong transaction.", name);
2379 #endif
2380  return;
2381  }
2382 
2383  sprintf (obuf, "%s from %s", name, piaddr (packet -> client_addr));
2384 
2385 
2386  /* If this lease doesn't supply the minimum required DHCPv4 parameters,
2387  * ignore it.
2388  */
2389  req = client->config->required_options;
2390  if (req != NULL) {
2391  for (i = 0 ; req[i] != NULL ; i++) {
2392  if ((req[i]->universe == &dhcp_universe) &&
2394  req[i]->code)) {
2395  struct option *option = NULL;
2396  unsigned code = req[i]->code;
2397 
2398  option_code_hash_lookup(&option,
2400  &code, 0, MDL);
2401 
2402  if (option)
2403  log_info("%s: no %s option.", obuf,
2404  option->name);
2405  else
2406  log_info("%s: no unknown-%u option.",
2407  obuf, code);
2408 
2410 
2411  return;
2412  }
2413  }
2414  }
2415 
2416  /* If we've already seen this lease, don't record it again. */
2417  for (lease = client -> offered_leases; lease; lease = lease -> next) {
2418  if (lease -> address.len == sizeof packet -> raw -> yiaddr &&
2419  !memcmp (lease -> address.iabuf,
2420  &packet -> raw -> yiaddr, lease -> address.len)) {
2421  log_debug ("%s: already seen.", obuf);
2422  return;
2423  }
2424  }
2425 
2426  lease = packet_to_lease (packet, client);
2427  if (!lease) {
2428  log_info ("%s: packet_to_lease failed.", obuf);
2429  return;
2430  }
2431 
2432  /* If this lease was acquired through a BOOTREPLY, record that
2433  fact. */
2434  if (!packet -> options_valid || !packet -> packet_type)
2435  lease -> is_bootp = 1;
2436 
2437  /* Record the medium under which this lease was offered. */
2438  lease -> medium = client -> medium;
2439 
2440  /* Figure out when we're supposed to stop selecting. */
2441  stop_selecting = (client -> first_sending +
2442  client -> config -> select_interval);
2443 
2444  /* If this is the lease we asked for, put it at the head of the
2445  list, and don't mess with the arp request timeout. */
2446  if (lease -> address.len == client -> requested_address.len &&
2447  !memcmp (lease -> address.iabuf,
2448  client -> requested_address.iabuf,
2449  client -> requested_address.len)) {
2450  lease -> next = client -> offered_leases;
2451  client -> offered_leases = lease;
2452  } else {
2453  /* Put the lease at the end of the list. */
2454  lease -> next = (struct client_lease *)0;
2455  if (!client -> offered_leases)
2456  client -> offered_leases = lease;
2457  else {
2458  for (lp = client -> offered_leases; lp -> next;
2459  lp = lp -> next)
2460  ;
2461  lp -> next = lease;
2462  }
2463  }
2464 
2465  /* If the selecting interval has expired, go immediately to
2466  state_selecting(). Otherwise, time out into
2467  state_selecting at the select interval. */
2468  if (stop_selecting <= cur_tv.tv_sec)
2469  state_selecting (client);
2470  else {
2471  tv.tv_sec = stop_selecting;
2472  tv.tv_usec = cur_tv.tv_usec;
2473  add_timeout(&tv, state_selecting, client, 0, 0);
2474  cancel_timeout(send_discover, client);
2475  }
2476  log_info("%s", obuf);
2477 }
2478 
2479 /* Allocate a client_lease structure and initialize it from the parameters
2480  in the specified packet. */
2481 
2483  struct packet *packet;
2484  struct client_state *client;
2485 {
2486  struct client_lease *lease;
2487  unsigned i;
2488  struct option_cache *oc;
2489  struct option *option = NULL;
2490  struct data_string data;
2491 
2492  lease = (struct client_lease *)new_client_lease (MDL);
2493 
2494  if (!lease) {
2495  log_error("packet_to_lease: no memory to record lease.\n");
2496  return NULL;
2497  }
2498 
2499  memset(lease, 0, sizeof(*lease));
2500 
2501  /* Copy the lease options. */
2503 
2504  lease->address.len = sizeof(packet->raw->yiaddr);
2505  memcpy(lease->address.iabuf, &packet->raw->yiaddr,
2506  lease->address.len);
2507 
2508  lease->next_srv_addr.len = sizeof(packet->raw->siaddr);
2509  memcpy(lease->next_srv_addr.iabuf, &packet->raw->siaddr,
2510  lease->next_srv_addr.len);
2511 
2512  memset(&data, 0, sizeof(data));
2513 
2514  if (client -> config -> vendor_space_name) {
2516 
2517  /* See if there was a vendor encapsulation option. */
2518  oc = lookup_option (&dhcp_universe, lease -> options, i);
2519  if (oc &&
2520  client -> config -> vendor_space_name &&
2521  evaluate_option_cache (&data, packet,
2522  (struct lease *)0, client,
2523  packet -> options, lease -> options,
2524  &global_scope, oc, MDL)) {
2525  if (data.len) {
2526  if (!option_code_hash_lookup(&option,
2528  &i, 0, MDL))
2529  log_fatal("Unable to find VENDOR "
2530  "option (%s:%d).", MDL);
2532  (packet -> options, option,
2533  data.data, data.len, &dhcp_universe,
2534  client -> config -> vendor_space_name
2535  );
2536 
2538  }
2539  data_string_forget (&data, MDL);
2540  }
2541  } else
2542  i = 0;
2543 
2544  /* Figure out the overload flag. */
2547  if (oc &&
2548  evaluate_option_cache (&data, packet, (struct lease *)0, client,
2549  packet -> options, lease -> options,
2550  &global_scope, oc, MDL)) {
2551  if (data.len > 0)
2552  i = data.data [0];
2553  else
2554  i = 0;
2555  data_string_forget (&data, MDL);
2556  } else
2557  i = 0;
2558 
2559  /* If the server name was filled out, copy it. */
2560  if (!(i & 2) && packet -> raw -> sname [0]) {
2561  unsigned len;
2562  /* Don't count on the NUL terminator. */
2563  for (len = 0; len < DHCP_SNAME_LEN; len++)
2564  if (!packet -> raw -> sname [len])
2565  break;
2566  lease -> server_name = dmalloc (len + 1, MDL);
2567  if (!lease -> server_name) {
2568  log_error ("dhcpoffer: no memory for server name.\n");
2570  return (struct client_lease *)0;
2571  } else {
2572  memcpy (lease -> server_name,
2573  packet -> raw -> sname, len);
2574  lease -> server_name [len] = 0;
2575  }
2576  }
2577 
2578  /* Ditto for the filename. */
2579  if (!(i & 1) && packet -> raw -> file [0]) {
2580  unsigned len;
2581  /* Don't count on the NUL terminator. */
2582  for (len = 0; len < DHCP_FILE_LEN; len++)
2583  if (!packet -> raw -> file [len])
2584  break;
2585  lease -> filename = dmalloc (len + 1, MDL);
2586  if (!lease -> filename) {
2587  log_error ("dhcpoffer: no memory for filename.\n");
2589  return (struct client_lease *)0;
2590  } else {
2591  memcpy (lease -> filename,
2592  packet -> raw -> file, len);
2593  lease -> filename [len] = 0;
2594  }
2595  }
2596 
2597  execute_statements_in_scope(NULL, (struct packet *)packet, NULL,
2598  client, lease->options, lease->options,
2599  &global_scope, client->config->on_receipt,
2600  NULL, NULL);
2601 
2602  return lease;
2603 }
2604 
2606  struct packet *packet;
2607 {
2608  struct interface_info *ip = packet -> interface;
2609  struct client_state *client;
2610 
2611  /* Find a client state that matches the xid... */
2612  for (client = ip -> client; client; client = client -> next)
2613  if (client -> xid == packet -> raw -> xid)
2614  break;
2615 
2616  /* If we're not receptive to an offer right now, or if the offer
2617  has an unrecognizable transaction id, then just drop it. */
2618  if (!client ||
2619  (packet -> interface -> hw_address.hlen - 1 !=
2620  packet -> raw -> hlen) ||
2621  (memcmp (&packet -> interface -> hw_address.hbuf [1],
2622  packet -> raw -> chaddr, packet -> raw -> hlen))) {
2623 #if defined (DEBUG)
2624  log_debug ("DHCPNAK in wrong transaction.");
2625 #endif
2626  return;
2627  }
2628 
2629  if (client -> state != S_REBOOTING &&
2630  client -> state != S_REQUESTING &&
2631  client -> state != S_RENEWING &&
2632  client -> state != S_REBINDING) {
2633 #if defined (DEBUG)
2634  log_debug ("DHCPNAK in wrong state.");
2635 #endif
2636  return;
2637  }
2638 
2639  log_info ("DHCPNAK from %s (xid=0x%x)", piaddr (packet -> client_addr), ntohl(client -> xid));
2640 
2641  if (!client -> active) {
2642 #if defined (DEBUG)
2643  log_info ("DHCPNAK with no active lease.\n");
2644 #endif
2645  return;
2646  }
2647 
2648  /* If we get a DHCPNAK, we use the EXPIRE dhclient-script state
2649  * to indicate that we want all old bindings to be removed. (It
2650  * is possible that we may get a NAK while in the RENEW state,
2651  * so we might have bindings active at that time)
2652  */
2653  script_init(client, "EXPIRE", NULL);
2654  script_write_params(client, "old_", client->active);
2655  script_write_requested(client);
2656  if (client->alias)
2657  script_write_params(client, "alias_", client->alias);
2658  script_go(client);
2659 
2660  destroy_client_lease (client -> active);
2661  client -> active = (struct client_lease *)0;
2662 
2663  /* Stop sending DHCPREQUEST packets... */
2664  cancel_timeout (send_request, client);
2665 
2666  /* On some scripts, 'EXPIRE' causes the interface to be ifconfig'd
2667  * down (this expunges any routes and arp cache). This makes the
2668  * interface unusable by state_init(), which we call next. So, we
2669  * need to 'PREINIT' the interface to bring it back up.
2670  */
2671  script_init(client, "PREINIT", NULL);
2672  if (client->alias)
2673  script_write_params(client, "alias_", client->alias);
2674  script_go(client);
2675 
2676  client -> state = S_INIT;
2677  state_init (client);
2678 }
2679 
2680 /* Send out a DHCPDISCOVER packet, and set a timeout to send out another
2681  one after the right interval has expired. If we don't get an offer by
2682  the time we reach the panic interval, call the panic function. */
2683 
2684 void send_discover (cpp)
2685  void *cpp;
2686 {
2687  struct client_state *client = cpp;
2688 
2689  int result;
2690  int interval;
2691  int increase = 1;
2692  struct timeval tv;
2693 
2694  /* Figure out how long it's been since we started transmitting. */
2695  interval = cur_time - client -> first_sending;
2696 
2697  /* If we're past the panic timeout, call the script and tell it
2698  we haven't found anything for this interface yet. */
2699  if (interval > client -> config -> timeout) {
2700  state_panic (client);
2701  return;
2702  }
2703 
2704  /* If we're selecting media, try the whole list before doing
2705  the exponential backoff, but if we've already received an
2706  offer, stop looping, because we obviously have it right. */
2707  if (!client -> offered_leases &&
2708  client -> config -> media) {
2709  int fail = 0;
2710  again:
2711  if (client -> medium) {
2712  client -> medium = client -> medium -> next;
2713  increase = 0;
2714  }
2715  if (!client -> medium) {
2716  if (fail)
2717  log_fatal ("No valid media types for %s!",
2718  client -> interface -> name);
2719  client -> medium =
2720  client -> config -> media;
2721  increase = 1;
2722  }
2723 
2724  log_info ("Trying medium \"%s\" %d",
2725  client -> medium -> string, increase);
2726  script_init(client, "MEDIUM", client -> medium);
2727  if (script_go(client)) {
2728  fail = 1;
2729  goto again;
2730  }
2731  }
2732 
2733  /* If we're supposed to increase the interval, do so. If it's
2734  currently zero (i.e., we haven't sent any packets yet), set
2735  it to initial_interval; otherwise, add to it a random number
2736  between zero and two times itself. On average, this means
2737  that it will double with every transmission. */
2738  if (increase) {
2739  if (!client->interval)
2740  client->interval = client->config->initial_interval;
2741  else
2742  client->interval += random() % (2 * client->interval);
2743 
2744  /* Don't backoff past cutoff. */
2745  if (client->interval > client->config->backoff_cutoff)
2746  client->interval = (client->config->backoff_cutoff / 2)
2747  + (random() % client->config->backoff_cutoff);
2748  } else if (!client->interval)
2749  client->interval = client->config->initial_interval;
2750 
2751  /* If the backoff would take us to the panic timeout, just use that
2752  as the interval. */
2753  if (cur_time + client -> interval >
2754  client -> first_sending + client -> config -> timeout)
2755  client -> interval =
2756  (client -> first_sending +
2757  client -> config -> timeout) - cur_time + 1;
2758 
2759  /* Record the number of seconds since we started sending. */
2760  if (interval < 65536)
2761  client -> packet.secs = htons (interval);
2762  else
2763  client -> packet.secs = htons (65535);
2764  client -> secs = client -> packet.secs;
2765 
2766 #if defined(DHCPv6) && defined(DHCP4o6)
2767  if (dhcpv4_over_dhcpv6) {
2768  log_info ("DHCPDISCOVER interval %ld",
2769  (long)(client -> interval));
2770  } else
2771 #endif
2772  log_info ("DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",
2773  client -> name ? client -> name : client -> interface -> name,
2774  inet_ntoa (sockaddr_broadcast.sin_addr),
2775  ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval), ntohl(client -> xid));
2776 
2777  /* Send out a packet. */
2778 #if defined(DHCPv6) && defined(DHCP4o6)
2779  if (dhcpv4_over_dhcpv6) {
2780  result = send_dhcpv4_query(client, 1);
2781  } else
2782 #endif
2783  result = send_packet(client->interface, NULL, &client->packet,
2784  client->packet_length, inaddr_any,
2785  &sockaddr_broadcast, NULL);
2786  if (result < 0) {
2787 #if defined(DHCPv6) && defined(DHCP4o6)
2788  if (dhcpv4_over_dhcpv6) {
2789  log_error("%s:%d: Failed to send %d byte long packet.",
2790  MDL, client->packet_length);
2791  } else
2792 #endif
2793  log_error("%s:%d: Failed to send %d byte long packet over %s "
2794  "interface.", MDL, client->packet_length,
2795  client->interface->name);
2796  }
2797 
2798  /*
2799  * If we used 0 microseconds here, and there were other clients on the
2800  * same network with a synchronized local clock (ntp), and a similar
2801  * zero-microsecond-scheduler behavior, then we could be participating
2802  * in a sub-second DOS ttck.
2803  */
2804  tv.tv_sec = cur_tv.tv_sec + client->interval;
2805  tv.tv_usec = client->interval > 1 ? random() % 1000000 : cur_tv.tv_usec;
2806  add_timeout(&tv, send_discover, client, 0, 0);
2807 }
2808 
2809 /* state_panic gets called if we haven't received any offers in a preset
2810  amount of time. When this happens, we try to use existing leases that
2811  haven't yet expired, and failing that, we call the client script and
2812  hope it can do something. */
2813 
2814 void state_panic (cpp)
2815  void *cpp;
2816 {
2817  struct client_state *client = cpp;
2818  struct client_lease *loop;
2819  struct client_lease *lp;
2820  struct timeval tv;
2821 
2822  loop = lp = client -> active;
2823 
2824  log_info ("No DHCPOFFERS received.");
2825 
2826  /* We may not have an active lease, but we may have some
2827  predefined leases that we can try. */
2828  if (!client -> active && client -> leases)
2829  goto activate_next;
2830 
2831  /* Run through the list of leases and see if one can be used. */
2832  while (client -> active) {
2833  if (client -> active -> expiry > cur_time) {
2834  log_info ("Trying recorded lease %s",
2835  piaddr (client -> active -> address));
2836  /* Run the client script with the existing
2837  parameters. */
2838  script_init(client, "TIMEOUT",
2839  client -> active -> medium);
2840  script_write_params(client, "new_", client -> active);
2841  script_write_requested(client);
2842  if (client -> alias)
2843  script_write_params(client, "alias_",
2844  client -> alias);
2845 
2846  /* If the old lease is still good and doesn't
2847  yet need renewal, go into BOUND state and
2848  timeout at the renewal time. */
2849  if (!script_go(client)) {
2850  if (cur_time < client -> active -> renewal) {
2851  client -> state = S_BOUND;
2852  log_info ("bound: renewal in %ld %s.",
2853  (long)(client -> active -> renewal -
2854  cur_time), "seconds");
2855  tv.tv_sec = client->active->renewal;
2856  tv.tv_usec = ((client->active->renewal -
2857  cur_time) > 1) ?
2858  random() % 1000000 :
2859  cur_tv.tv_usec;
2860  add_timeout(&tv, state_bound, client, 0, 0);
2861  } else {
2862  client -> state = S_BOUND;
2863  log_info ("bound: immediate renewal.");
2864  state_bound (client);
2865  }
2867  go_daemon ();
2868  return;
2869  }
2870  }
2871 
2872  /* If there are no other leases, give up. */
2873  if (!client -> leases) {
2874  client -> leases = client -> active;
2875  client -> active = (struct client_lease *)0;
2876  break;
2877  }
2878 
2879  activate_next:
2880  /* Otherwise, put the active lease at the end of the
2881  lease list, and try another lease.. */
2882  for (lp = client -> leases; lp -> next; lp = lp -> next)
2883  ;
2884  lp -> next = client -> active;
2885  if (lp -> next) {
2886  lp -> next -> next = (struct client_lease *)0;
2887  }
2888  client -> active = client -> leases;
2889  client -> leases = client -> leases -> next;
2890 
2891  /* If we already tried this lease, we've exhausted the
2892  set of leases, so we might as well give up for
2893  now. */
2894  if (client -> active == loop)
2895  break;
2896  else if (!loop)
2897  loop = client -> active;
2898  }
2899 
2900  /* No leases were available, or what was available didn't work, so
2901  tell the shell script that we failed to allocate an address,
2902  and try again later. */
2903  if (onetry) {
2904  if (!quiet) {
2905  log_info ("Unable to obtain a lease on first try.%s",
2906  " Exiting.");
2907  }
2908 
2909 #if defined (CALL_SCRIPT_ON_ONETRY_FAIL)
2910  /* Let's call a script and we're done */
2911  script_init(client, "FAIL", (struct string_list *)0);
2912  script_go(client);
2913 #endif
2914  exit (2);
2915  }
2916 
2917  log_info ("No working leases in persistent database - sleeping.");
2918  script_init(client, "FAIL", (struct string_list *)0);
2919  if (client -> alias)
2920  script_write_params(client, "alias_", client -> alias);
2921  script_go(client);
2922  client -> state = S_INIT;
2923  tv.tv_sec = cur_tv.tv_sec + ((client->config->retry_interval + 1) / 2 +
2924  (random() % client->config->retry_interval));
2925  tv.tv_usec = ((tv.tv_sec - cur_tv.tv_sec) > 1) ?
2926  random() % 1000000 : cur_tv.tv_usec;
2927  add_timeout(&tv, state_init, client, 0, 0);
2928  go_daemon ();
2929 }
2930 
2931 void send_request (cpp)
2932  void *cpp;
2933 {
2934  struct client_state *client = cpp;
2935 
2936  int result;
2937  int interval;
2938  struct sockaddr_in destination;
2939  struct in_addr from;
2940  struct timeval tv;
2941 
2942  /* Figure out how long it's been since we started transmitting. */
2943  interval = cur_time - client -> first_sending;
2944 
2945  /* If we're in the INIT-REBOOT or REQUESTING state and we're
2946  past the reboot timeout, go to INIT and see if we can
2947  DISCOVER an address... */
2948  /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
2949  means either that we're on a network with no DHCP server,
2950  or that our server is down. In the latter case, assuming
2951  that there is a backup DHCP server, DHCPDISCOVER will get
2952  us a new address, but we could also have successfully
2953  reused our old address. In the former case, we're hosed
2954  anyway. This is not a win-prone situation. */
2955  if ((client -> state == S_REBOOTING ||
2956  client -> state == S_REQUESTING) &&
2957  interval > client -> config -> reboot_timeout) {
2958  cancel:
2959  client -> state = S_INIT;
2960  cancel_timeout (send_request, client);
2961  state_init (client);
2962  return;
2963  }
2964 
2965  /* If we're in the reboot state, make sure the media is set up
2966  correctly. */
2967  if (client -> state == S_REBOOTING &&
2968  !client -> medium &&
2969  client -> active -> medium ) {
2970  script_init(client, "MEDIUM", client -> active -> medium);
2971 
2972  /* If the medium we chose won't fly, go to INIT state. */
2973  if (script_go(client))
2974  goto cancel;
2975 
2976  /* Record the medium. */
2977  client -> medium = client -> active -> medium;
2978  }
2979 
2980  /* If the lease has expired, relinquish the address and go back
2981  to the INIT state. */
2982  if (client -> state != S_REQUESTING &&
2983  cur_time > client -> active -> expiry) {
2984  /* Run the client script with the new parameters. */
2985  script_init(client, "EXPIRE", (struct string_list *)0);
2986  script_write_params(client, "old_", client -> active);
2987  script_write_requested(client);
2988  if (client -> alias)
2989  script_write_params(client, "alias_",
2990  client -> alias);
2991  script_go(client);
2992 
2993  /* Now do a preinit on the interface so that we can
2994  discover a new address. */
2995  script_init(client, "PREINIT", (struct string_list *)0);
2996  if (client -> alias)
2997  script_write_params(client, "alias_",
2998  client -> alias);
2999  script_go(client);
3000 
3001  client -> state = S_INIT;
3002  state_init (client);
3003  return;
3004  }
3005 
3006  /* Do the exponential backoff... */
3007  if (!client -> interval)
3008  client -> interval = client -> config -> initial_interval;
3009  else {
3010  client -> interval += ((random () >> 2) %
3011  (2 * client -> interval));
3012  }
3013 
3014  /* Don't backoff past cutoff. */
3015  if (client -> interval >
3016  client -> config -> backoff_cutoff)
3017  client -> interval =
3018  ((client -> config -> backoff_cutoff / 2)
3019  + ((random () >> 2) %
3020  client -> config -> backoff_cutoff));
3021 
3022  /* If the backoff would take us to the expiry time, just set the
3023  timeout to the expiry time. */
3024  if (client -> state != S_REQUESTING &&
3025  cur_time + client -> interval > client -> active -> expiry)
3026  client -> interval =
3027  client -> active -> expiry - cur_time + 1;
3028 
3029  /* If the lease T2 time has elapsed, or if we're not yet bound,
3030  broadcast the DHCPREQUEST rather than unicasting. */
3031  if (client -> state == S_REQUESTING ||
3032  client -> state == S_REBOOTING ||
3033  cur_time > client -> active -> rebind)
3034  destination.sin_addr = sockaddr_broadcast.sin_addr;
3035  else
3036  memcpy (&destination.sin_addr.s_addr,
3037  client -> destination.iabuf,
3038  sizeof destination.sin_addr.s_addr);
3039  destination.sin_port = remote_port;
3040  destination.sin_family = AF_INET;
3041 #ifdef HAVE_SA_LEN
3042  destination.sin_len = sizeof destination;
3043 #endif
3044 
3045  if (client -> state == S_RENEWING ||
3046  client -> state == S_REBINDING)
3047  memcpy (&from, client -> active -> address.iabuf,
3048  sizeof from);
3049  else
3050  from.s_addr = INADDR_ANY;
3051 
3052  /* Record the number of seconds since we started sending. */
3053  if (client -> state == S_REQUESTING)
3054  client -> packet.secs = client -> secs;
3055  else {
3056  if (interval < 65536)
3057  client -> packet.secs = htons (interval);
3058  else
3059  client -> packet.secs = htons (65535);
3060  }
3061 
3062 #if defined(DHCPv6) && defined(DHCP4o6)
3063  if (dhcpv4_over_dhcpv6) {
3064  log_info ("DHCPREQUEST");
3065  } else
3066 #endif
3067  log_info ("DHCPREQUEST on %s to %s port %d (xid=0x%x)",
3068  client -> name ? client -> name : client -> interface -> name,
3069  inet_ntoa (destination.sin_addr),
3070  ntohs (destination.sin_port), ntohl(client -> xid));
3071 
3072 #if defined(DHCPv6) && defined(DHCP4o6)
3073  if (dhcpv4_over_dhcpv6) {
3074  int broadcast = 0;
3075  if (destination.sin_addr.s_addr == INADDR_BROADCAST)
3076  broadcast = 1;
3077  result = send_dhcpv4_query(client, broadcast);
3078  if (result < 0) {
3079  log_error("%s:%d: Failed to send %d byte long packet.",
3080  MDL, client->packet_length);
3081  }
3082  } else
3083 #endif
3084  if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
3086 #if defined(SO_BINDTODEVICE)
3087  if (setsockopt(fallback_interface -> wfdesc, SOL_SOCKET,
3088  SO_BINDTODEVICE, client->interface->name,
3089  strlen(client->interface->name)) < 0) {
3090  log_error("%s:%d: Failed to bind fallback interface"
3091  " to %s: %m", MDL, client->interface->name);
3092  }
3093 #endif
3094  result = send_packet(fallback_interface, NULL, &client->packet,
3095  client->packet_length, from, &destination,
3096  NULL);
3097  if (result < 0) {
3098  log_error("%s:%d: Failed to send %d byte long packet "
3099  "over %s interface.", MDL,
3100  client->packet_length,
3102  }
3103 #if defined(SO_BINDTODEVICE)
3104  if (setsockopt(fallback_interface -> wfdesc, SOL_SOCKET,
3105  SO_BINDTODEVICE, NULL, 0) < 0) {
3106  log_fatal("%s:%d: Failed to unbind fallback interface:"
3107  " %m", MDL);
3108  }
3109 #endif
3110  }
3111  else {
3112  /* Send out a packet. */
3113  result = send_packet(client->interface, NULL, &client->packet,
3114  client->packet_length, from, &destination,
3115  NULL);
3116  if (result < 0) {
3117  log_error("%s:%d: Failed to send %d byte long packet"
3118  " over %s interface.", MDL,
3119  client->packet_length,
3120  client->interface->name);
3121  }
3122  }
3123 
3124  tv.tv_sec = cur_tv.tv_sec + client->interval;
3125  tv.tv_usec = ((tv.tv_sec - cur_tv.tv_sec) > 1) ?
3126  random() % 1000000 : cur_tv.tv_usec;
3127  add_timeout(&tv, send_request, client, 0, 0);
3128 }
3129 
3130 void send_decline (cpp)
3131  void *cpp;
3132 {
3133  struct client_state *client = cpp;
3134 
3135  int result;
3136 
3137 #if defined(DHCPv6) && defined(DHCP4o6)
3138  if (dhcpv4_over_dhcpv6) {
3139  log_info ("DHCPDECLINE");
3140  } else
3141 #endif
3142  log_info ("DHCPDECLINE on %s to %s port %d (xid=0x%x)",
3143  client->name ? client->name : client->interface->name,
3144  inet_ntoa(sockaddr_broadcast.sin_addr),
3145  ntohs(sockaddr_broadcast.sin_port), ntohl(client -> xid));
3146 
3147  /* Send out a packet. */
3148 #if defined(DHCPv6) && defined(DHCP4o6)
3149  if (dhcpv4_over_dhcpv6) {
3150  result = send_dhcpv4_query(client, 1);
3151  } else
3152 #endif
3153  result = send_packet(client->interface, NULL, &client->packet,
3154  client->packet_length, inaddr_any,
3155  &sockaddr_broadcast, NULL);
3156  if (result < 0) {
3157 #if defined(DHCPv6) && defined(DHCP4o6)
3158  if (dhcpv4_over_dhcpv6) {
3159  log_error("%s:%d: Failed to send %d byte long packet.",
3160  MDL, client->packet_length);
3161  } else
3162 #endif
3163  log_error("%s:%d: Failed to send %d byte long packet over %s"
3164  " interface.", MDL, client->packet_length,
3165  client->interface->name);
3166  }
3167 }
3168 
3169 void send_release (cpp)
3170  void *cpp;
3171 {
3172  struct client_state *client = cpp;
3173 
3174  int result;
3175  struct sockaddr_in destination;
3176  struct in_addr from;
3177 
3178  memcpy (&from, client -> active -> address.iabuf,
3179  sizeof from);
3180  memcpy (&destination.sin_addr.s_addr,
3181  client -> destination.iabuf,
3182  sizeof destination.sin_addr.s_addr);
3183  destination.sin_port = remote_port;
3184  destination.sin_family = AF_INET;
3185 #ifdef HAVE_SA_LEN
3186  destination.sin_len = sizeof destination;
3187 #endif
3188 
3189  /* Set the lease to end now, so that we don't accidentally
3190  reuse it if we restart before the old expiry time. */
3191  client -> active -> expiry =
3192  client -> active -> renewal =
3193  client -> active -> rebind = cur_time;
3194  if (!write_client_lease (client, client -> active, 1, 1)) {
3195  log_error ("Can't release lease: lease write failed.");
3196  return;
3197  }
3198 
3199 #if defined(DHCPv6) && defined(DHCP4o6)
3200  if (dhcpv4_over_dhcpv6) {
3201  log_info ("DHCPRELEASE");
3202  } else
3203 #endif
3204  log_info ("DHCPRELEASE on %s to %s port %d (xid=0x%x)",
3205  client -> name ? client -> name : client -> interface -> name,
3206  inet_ntoa (destination.sin_addr),
3207  ntohs (destination.sin_port), ntohl(client -> xid));
3208 
3209 #if defined(DHCPv6) && defined(DHCP4o6)
3210  if (dhcpv4_over_dhcpv6) {
3211  int broadcast = 0;
3212  if (destination.sin_addr.s_addr == INADDR_BROADCAST)
3213  broadcast = 1;
3214  result = send_dhcpv4_query(client, broadcast);
3215  if (result < 0) {
3216  log_error("%s:%d: Failed to send %d byte long packet.",
3217  MDL, client->packet_length);
3218  }
3219  } else
3220 #endif
3221  if (fallback_interface) {
3222 #if defined(SO_BINDTODEVICE)
3223  if (setsockopt(fallback_interface -> wfdesc, SOL_SOCKET,
3224  SO_BINDTODEVICE, client->interface->name,
3225  strlen(client->interface->name)) < 0) {
3226  log_error("%s:%d: Failed to bind fallback interface"
3227  " to %s: %m", MDL, client->interface->name);
3228  }
3229 #endif
3230  result = send_packet(fallback_interface, NULL, &client->packet,
3231  client->packet_length, from, &destination,
3232  NULL);
3233  if (result < 0) {
3234  log_error("%s:%d: Failed to send %d byte long packet"
3235  " over %s interface.", MDL,
3236  client->packet_length,
3238  }
3239 #if defined(SO_BINDTODEVICE)
3240  if (setsockopt(fallback_interface -> wfdesc, SOL_SOCKET,
3241  SO_BINDTODEVICE, NULL, 0) < 0) {
3242  log_fatal("%s:%d: Failed to unbind fallback interface:"
3243  " %m", MDL);
3244  }
3245 #endif
3246  } else {
3247  /* Send out a packet. */
3248  result = send_packet(client->interface, NULL, &client->packet,
3249  client->packet_length, from, &destination,
3250  NULL);
3251  if (result < 0) {
3252  log_error ("%s:%d: Failed to send %d byte long packet"
3253  " over %s interface.", MDL,
3254  client->packet_length,
3255  client->interface->name);
3256  }
3257 
3258  }
3259 }
3260 
3261 #if defined(DHCPv6) && defined(DHCP4o6)
3262 /*
3263  * \brief Send a DHCPv4-query to the DHCPv6 client
3264  * (DHCPv4 client function)
3265  *
3266  * The DHCPv4 client sends a DHCPv4-query to the DHCPv6 client over
3267  * the inter-process communication socket.
3268  *
3269  * \param client the DHCPv4 client state
3270  * \param broadcast the broadcast flag
3271  * \return the sent byte count (-1 on error)
3272  */
3273 static int send_dhcpv4_query(struct client_state *client, int broadcast) {
3274  struct data_string ds;
3275  struct dhcpv4_over_dhcpv6_packet *query;
3276  int ofs, len, cc;
3277 
3278  if (dhcp4o6_state <= 0) {
3279  log_info("send_dhcpv4_query: not ready.");
3280  return -1;
3281  }
3282 
3283  /*
3284  * Compute buffer length and allocate it.
3285  */
3286  len = ofs = (int)(offsetof(struct dhcpv4_over_dhcpv6_packet, options));
3288  len += client->packet_length;
3289  memset(&ds, 0, sizeof(ds));
3290  if (!buffer_allocate(&ds.buffer, len, MDL)) {
3291  log_error("Unable to allocate memory for DHCPv4-query.");
3292  return -1;
3293  }
3294  ds.data = ds.buffer->data;
3295  ds.len = len;
3296 
3297  /*
3298  * Fill header.
3299  */
3300  query = (struct dhcpv4_over_dhcpv6_packet *)ds.data;
3301  query->msg_type = DHCPV6_DHCPV4_QUERY;
3302  query->flags[0] = query->flags[1] = query->flags[2] = 0;
3303  if (!broadcast)
3304  query->flags[0] |= DHCP4O6_QUERY_UNICAST;
3305 
3306  /*
3307  * Append DHCPv4 message.
3308  */
3309  dhcpv6_universe.store_tag(ds.buffer->data + ofs, D6O_DHCPV4_MSG);
3310  ofs += dhcpv6_universe.tag_size;
3311  dhcpv6_universe.store_length(ds.buffer->data + ofs,
3312  client->packet_length);
3314  memcpy(ds.buffer->data + ofs, &client->packet, client->packet_length);
3315 
3316  /*
3317  * Send DHCPv6 message.
3318  */
3319  cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
3320  if (cc < 0)
3321  log_error("send_dhcpv4_query: send(): %m");
3322 
3323  data_string_forget(&ds, MDL);
3324 
3325  return cc;
3326 }
3327 
3328 /*
3329  * \brief Forward a DHCPv4-query to all DHCPv4 over DHCPv6 server addresses.
3330  * (DHCPv6 client function)
3331  *
3332  * \param raw the DHCPv6 DHCPv4-query message raw content
3333  */
3334 static void forw_dhcpv4_query(struct data_string *raw) {
3335  struct interface_info *ip;
3336  struct client_state *client;
3337  struct dhc6_lease *lease;
3338  struct option_cache *oc;
3339  struct data_string addrs;
3340  struct sockaddr_in6 sin6;
3341  int i, send_ret, attempt, success;
3342 
3343  attempt = success = 0;
3344  memset(&sin6, 0, sizeof(sin6));
3345  sin6.sin6_family = AF_INET6;
3346  sin6.sin6_port = remote_port;
3347 #ifdef HAVE_SA_LEN
3348  sin6.sin6_len = sizeof(sin6);
3349 #endif
3350  memset(&addrs, 0, sizeof(addrs));
3351  for (ip = interfaces; ip != NULL; ip = ip->next) {
3352  for (client = ip->client; client != NULL;
3353  client = client->next) {
3354  if ((client->state != S_BOUND) &&
3355  (client->state != S_RENEWING) &&
3356  (client->state != S_REBINDING))
3357  continue;
3358  lease = client->active_lease;
3359  if ((lease == NULL) || lease->released)
3360  continue;
3362  lease->options,
3364  if ((oc == NULL) ||
3365  !evaluate_option_cache(&addrs, NULL, NULL, NULL,
3366  lease->options, NULL,
3367  &global_scope, oc, MDL) ||
3368  ((addrs.len % sizeof(sin6.sin6_addr)) != 0)) {
3369  data_string_forget(&addrs, MDL);
3370  continue;
3371  }
3372  if (addrs.len == 0) {
3373  /* note there is nothing to forget */
3374  inet_pton(AF_INET6,
3376  &sin6.sin6_addr);
3377  attempt++;
3378  send_ret = send_packet6(ip, raw->data,
3379  raw->len, &sin6);
3380  if (send_ret == raw->len)
3381  success++;
3382  continue;
3383  }
3384  for (i = 0; i < addrs.len;
3385  i += sizeof(sin6.sin6_addr)) {
3386  memcpy(&sin6.sin6_addr, addrs.data + i,
3387  sizeof(sin6.sin6_addr));
3388  attempt++;
3389  send_ret = send_packet6(ip, raw->data,
3390  raw->len, &sin6);
3391  if (send_ret == raw->len)
3392  success++;
3393  }
3394  data_string_forget(&addrs, MDL);
3395  }
3396  }
3397 
3398  log_info("forw_dhcpv4_query: sent(%d): %d/%d",
3399  raw->len, success, attempt);
3400 
3401  if (attempt == 0)
3402  dhcp4o6_stop();
3403 }
3404 #endif
3405 
3406 void
3408  u_int8_t *type, struct option_cache *sid,
3409  struct iaddr *rip, struct option **prl,
3410  struct option_state **op)
3411 {
3412  unsigned i;
3413  struct option_cache *oc;
3414  struct option *option = NULL;
3415  struct buffer *bp = NULL;
3416 
3417  /* If there are any leftover options, get rid of them. */
3418  if (*op)
3420 
3421  /* Allocate space for options. */
3423 
3424  /* Send the server identifier if provided. */
3425  if (sid)
3426  save_option(&dhcp_universe, *op, sid);
3427 
3428  oc = NULL;
3429 
3430  /* Send the requested address if provided. */
3431  if (rip) {
3432  client->requested_address = *rip;
3434  if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash,
3435  &i, 0, MDL) &&
3436  make_const_option_cache(&oc, NULL, rip->iabuf, rip->len,
3437  option, MDL)))
3438  log_error ("can't make requested address cache.");
3439  else {
3440  save_option(&dhcp_universe, *op, oc);
3442  }
3444  } else {
3445  client->requested_address.len = 0;
3446  }
3447 
3449  if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash, &i, 0,
3450  MDL) &&
3451  make_const_option_cache(&oc, NULL, type, 1, option, MDL)))
3452  log_error("can't make message type.");
3453  else {
3454  save_option(&dhcp_universe, *op, oc);
3456  }
3458 
3459  if (prl) {
3460  int len;
3461 
3462  /* Probe the length of the list. */
3463  len = 0;
3464  for (i = 0 ; prl[i] != NULL ; i++)
3465  if (prl[i]->universe == &dhcp_universe)
3466  len++;
3467 
3468  if (!buffer_allocate(&bp, len, MDL))
3469  log_error("can't make parameter list buffer.");
3470  else {
3471  unsigned code = DHO_DHCP_PARAMETER_REQUEST_LIST;
3472 
3473  len = 0;
3474  for (i = 0 ; prl[i] != NULL ; i++)
3475  if (prl[i]->universe == &dhcp_universe)
3476  bp->data[len++] = prl[i]->code;
3477 
3478  if (!(option_code_hash_lookup(&option,
3480  &code, 0, MDL) &&
3481  make_const_option_cache(&oc, &bp, NULL, len,
3482  option, MDL))) {
3483  if (bp != NULL)
3484  buffer_dereference(&bp, MDL);
3485  log_error ("can't make option cache");
3486  } else {
3487  save_option(&dhcp_universe, *op, oc);
3489  }
3491  }
3492  }
3493 
3494  /*
3495  * If requested (duid_v4 == 1) add an RFC4361 compliant client-identifier
3496  * This can be overridden by including a client id in the configuration
3497  * file.
3498  */
3499  if (duid_v4 == 1) {
3500  struct data_string client_identifier;
3501  int hw_idx, hw_len;
3502 
3503  memset(&client_identifier, 0, sizeof(client_identifier));
3504  client_identifier.len = 1 + 4 + default_duid.len;
3505  if (!buffer_allocate(&client_identifier.buffer,
3506  client_identifier.len, MDL))
3507  log_fatal("no memory for default DUID!");
3508  client_identifier.data = client_identifier.buffer->data;
3509 
3511 
3512  /* Client-identifier type : 1 byte */
3513  *client_identifier.buffer->data = 255;
3514 
3515  /* IAID : 4 bytes
3516  * we use the low 4 bytes from the interface address
3517  */
3518  if (client->interface->hw_address.hlen > 4) {
3519  hw_idx = client->interface->hw_address.hlen - 4;
3520  hw_len = 4;
3521  } else {
3522  hw_idx = 0;
3523  hw_len = client->interface->hw_address.hlen;
3524  }
3525  memcpy(&client_identifier.buffer->data + 5 - hw_len,
3526  client->interface->hw_address.hbuf + hw_idx,
3527  hw_len);
3528 
3529  /* Add the default duid */
3530  memcpy(&client_identifier.buffer->data+(1+4),
3532 
3533  /* And save the option */
3534  if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash,
3535  &i, 0, MDL) &&
3536  make_const_option_cache(&oc, NULL,
3537  (u_int8_t *)client_identifier.data,
3538  client_identifier.len,
3539  option, MDL)))
3540  log_error ("can't make requested client id cache..");
3541  else {
3542  save_option (&dhcp_universe, *op, oc);
3544  }
3546  }
3547 
3548  /* Run statements that need to be run on transmission. */
3549  if (client->config->on_transmission)
3550  execute_statements_in_scope(NULL, NULL, NULL, client,
3551  (lease ? lease->options : NULL),
3552  *op, &global_scope,
3553  client->config->on_transmission,
3554  NULL, NULL);
3555 }
3556 
3557 void make_discover (client, lease)
3558  struct client_state *client;
3559  struct client_lease *lease;
3560 {
3561  unsigned char discover = DHCPDISCOVER;
3562  struct option_state *options = (struct option_state *)0;
3563 
3564  memset (&client -> packet, 0, sizeof (client -> packet));
3565 
3566  make_client_options (client,
3567  lease, &discover, (struct option_cache *)0,
3568  lease ? &lease -> address : (struct iaddr *)0,
3569  client -> config -> requested_options,
3570  &options);
3571 
3572  /* Set up the option buffer... */
3573  client -> packet_length =
3574  cons_options ((struct packet *)0, &client -> packet,
3575  (struct lease *)0, client,
3576  /* maximum packet size */1500,
3577  (struct option_state *)0,
3578  options,
3579  /* scope */ &global_scope,
3580  /* overload */ 0,
3581  /* terminate */0,
3582  /* bootpp */0,
3583  (struct data_string *)0,
3584  client -> config -> vendor_space_name);
3585 
3586  option_state_dereference (&options, MDL);
3587  if (client -> packet_length < BOOTP_MIN_LEN)
3588  client -> packet_length = BOOTP_MIN_LEN;
3589 
3590  client -> packet.op = BOOTREQUEST;
3591  client -> packet.htype = client -> interface -> hw_address.hbuf [0];
3592  /* Assumes hw_address is known, otherwise a random value may result */
3593  client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
3594  client -> packet.hops = 0;
3595  client -> packet.xid = random ();
3596  client -> packet.secs = 0; /* filled in by send_discover. */
3597 
3600  client -> packet.flags = 0;
3601  else
3602  client -> packet.flags = htons (BOOTP_BROADCAST);
3603 
3604  memset (&(client -> packet.ciaddr),
3605  0, sizeof client -> packet.ciaddr);
3606  memset (&(client -> packet.yiaddr),
3607  0, sizeof client -> packet.yiaddr);
3608  memset (&(client -> packet.siaddr),
3609  0, sizeof client -> packet.siaddr);
3610  client -> packet.giaddr = giaddr;
3611  if (client -> interface -> hw_address.hlen > 0)
3612  memcpy (client -> packet.chaddr,
3613  &client -> interface -> hw_address.hbuf [1],
3614  (unsigned)(client -> interface -> hw_address.hlen - 1));
3615 
3616 #ifdef DEBUG_PACKET
3617  dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
3618 #endif
3619 }
3620 
3621 
3622 void make_request (client, lease)
3623  struct client_state *client;
3624  struct client_lease *lease;
3625 {
3626  unsigned char request = DHCPREQUEST;
3627  struct option_cache *oc;
3628 
3629  memset (&client -> packet, 0, sizeof (client -> packet));
3630 
3631  if (client -> state == S_REQUESTING)
3632  oc = lookup_option (&dhcp_universe, lease -> options,
3634  else
3635  oc = (struct option_cache *)0;
3636 
3637  if (client -> sent_options)
3638  option_state_dereference (&client -> sent_options, MDL);
3639 
3640  make_client_options (client, lease, &request, oc,
3641  ((client -> state == S_REQUESTING ||
3642  client -> state == S_REBOOTING)
3643  ? &lease -> address
3644  : (struct iaddr *)0),
3645  client -> config -> requested_options,
3646  &client -> sent_options);
3647 
3648  /* Set up the option buffer... */
3649  client -> packet_length =
3650  cons_options ((struct packet *)0, &client -> packet,
3651  (struct lease *)0, client,
3652  /* maximum packet size */1500,
3653  (struct option_state *)0,
3654  client -> sent_options,
3655  /* scope */ &global_scope,
3656  /* overload */ 0,
3657  /* terminate */0,
3658  /* bootpp */0,
3659  (struct data_string *)0,
3660  client -> config -> vendor_space_name);
3661 
3662  if (client -> packet_length < BOOTP_MIN_LEN)
3663  client -> packet_length = BOOTP_MIN_LEN;
3664 
3665  client -> packet.op = BOOTREQUEST;
3666  client -> packet.htype = client -> interface -> hw_address.hbuf [0];
3667  /* Assumes hw_address is known, otherwise a random value may result */
3668  client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
3669  client -> packet.hops = 0;
3670  client -> packet.xid = client -> xid;
3671  client -> packet.secs = 0; /* Filled in by send_request. */
3672 
3673  /* If we own the address we're requesting, put it in ciaddr;
3674  otherwise set ciaddr to zero. */
3675  if (client -> state == S_BOUND ||
3676  client -> state == S_RENEWING ||
3677  client -> state == S_REBINDING) {
3678  memcpy (&client -> packet.ciaddr,
3679  lease -> address.iabuf, lease -> address.len);
3680  client -> packet.flags = 0;
3681  } else {
3682  memset (&client -> packet.ciaddr, 0,
3683  sizeof client -> packet.ciaddr);
3684  if ((!(bootp_broadcast_always ||
3685  client ->config->bootp_broadcast_always)) &&
3686  can_receive_unicast_unconfigured (client -> interface))
3687  client -> packet.flags = 0;
3688  else
3689  client -> packet.flags = htons (BOOTP_BROADCAST);
3690  }
3691 
3692  memset (&client -> packet.yiaddr, 0,
3693  sizeof client -> packet.yiaddr);
3694  memset (&client -> packet.siaddr, 0,
3695  sizeof client -> packet.siaddr);
3696  if (client -> state != S_BOUND &&
3697  client -> state != S_RENEWING)
3698  client -> packet.giaddr = giaddr;
3699  else
3700  memset (&client -> packet.giaddr, 0,
3701  sizeof client -> packet.giaddr);
3702  if (client -> interface -> hw_address.hlen > 0)
3703  memcpy (client -> packet.chaddr,
3704  &client -> interface -> hw_address.hbuf [1],
3705  (unsigned)(client -> interface -> hw_address.hlen - 1));
3706 
3707 #ifdef DEBUG_PACKET
3708  dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
3709 #endif
3710 }
3711 
3712 void make_decline (client, lease)
3713  struct client_state *client;
3714  struct client_lease *lease;
3715 {
3716  unsigned char decline = DHCPDECLINE;
3717  struct option_cache *oc;
3718 
3719  struct option_state *options = (struct option_state *)0;
3720 
3721  /* Create the options cache. */
3722  oc = lookup_option (&dhcp_universe, lease -> options,
3724  make_client_options(client, lease, &decline, oc, &lease->address,
3725  NULL, &options);
3726 
3727  /* Consume the options cache into the option buffer. */
3728  memset (&client -> packet, 0, sizeof (client -> packet));
3729  client -> packet_length =
3730  cons_options ((struct packet *)0, &client -> packet,
3731  (struct lease *)0, client, 0,
3732  (struct option_state *)0, options,
3733  &global_scope, 0, 0, 0, (struct data_string *)0,
3734  client -> config -> vendor_space_name);
3735 
3736  /* Destroy the options cache. */
3737  option_state_dereference (&options, MDL);
3738 
3739  if (client -> packet_length < BOOTP_MIN_LEN)
3740  client -> packet_length = BOOTP_MIN_LEN;
3741 
3742  client -> packet.op = BOOTREQUEST;
3743  client -> packet.htype = client -> interface -> hw_address.hbuf [0];
3744  /* Assumes hw_address is known, otherwise a random value may result */
3745  client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
3746  client -> packet.hops = 0;
3747  client -> packet.xid = client -> xid;
3748  client -> packet.secs = 0; /* Filled in by send_request. */
3751  client -> packet.flags = 0;
3752  else
3753  client -> packet.flags = htons (BOOTP_BROADCAST);
3754 
3755  /* ciaddr must always be zero. */
3756  memset (&client -> packet.ciaddr, 0,
3757  sizeof client -> packet.ciaddr);
3758  memset (&client -> packet.yiaddr, 0,
3759  sizeof client -> packet.yiaddr);
3760  memset (&client -> packet.siaddr, 0,
3761  sizeof client -> packet.siaddr);
3762  client -> packet.giaddr = giaddr;
3763  memcpy (client -> packet.chaddr,
3764  &client -> interface -> hw_address.hbuf [1],
3765  client -> interface -> hw_address.hlen);
3766 
3767 #ifdef DEBUG_PACKET
3768  dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
3769 #endif
3770 }
3771 
3772 void make_release (client, lease)
3773  struct client_state *client;
3774  struct client_lease *lease;
3775 {
3776  unsigned char request = DHCPRELEASE;
3777  struct option_cache *oc;
3778 
3779  struct option_state *options = (struct option_state *)0;
3780 
3781  memset (&client -> packet, 0, sizeof (client -> packet));
3782 
3783  oc = lookup_option (&dhcp_universe, lease -> options,
3785  make_client_options(client, lease, &request, oc, NULL, NULL, &options);
3786 
3787  /* Set up the option buffer... */
3788  client -> packet_length =
3789  cons_options ((struct packet *)0, &client -> packet,
3790  (struct lease *)0, client,
3791  /* maximum packet size */1500,
3792  (struct option_state *)0,
3793  options,
3794  /* scope */ &global_scope,
3795  /* overload */ 0,
3796  /* terminate */0,
3797  /* bootpp */0,
3798  (struct data_string *)0,
3799  client -> config -> vendor_space_name);
3800 
3801  if (client -> packet_length < BOOTP_MIN_LEN)
3802  client -> packet_length = BOOTP_MIN_LEN;
3803  option_state_dereference (&options, MDL);
3804 
3805  client -> packet.op = BOOTREQUEST;
3806  client -> packet.htype = client -> interface -> hw_address.hbuf [0];
3807  /* Assumes hw_address is known, otherwise a random value may result */
3808  client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
3809  client -> packet.hops = 0;
3810  client -> packet.xid = random ();
3811  client -> packet.secs = 0;
3812  client -> packet.flags = 0;
3813  memcpy (&client -> packet.ciaddr,
3814  lease -> address.iabuf, lease -> address.len);
3815  memset (&client -> packet.yiaddr, 0,
3816  sizeof client -> packet.yiaddr);
3817  memset (&client -> packet.siaddr, 0,
3818  sizeof client -> packet.siaddr);
3819  client -> packet.giaddr = giaddr;
3820  memcpy (client -> packet.chaddr,
3821  &client -> interface -> hw_address.hbuf [1],
3822  client -> interface -> hw_address.hlen);
3823 
3824 #ifdef DEBUG_PACKET
3825  dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
3826 #endif
3827 }
3828 
3830  struct client_lease *lease;
3831 {
3832  if (lease -> server_name)
3833  dfree (lease -> server_name, MDL);
3834  if (lease -> filename)
3835  dfree (lease -> filename, MDL);
3838 }
3839 
3840 FILE *leaseFile = NULL;
3842 
3844 {
3845  struct interface_info *ip;
3846  struct client_state *client;
3847  struct client_lease *lp;
3848 
3849  if (leaseFile != NULL)
3850  fclose (leaseFile);
3851  leaseFile = fopen (path_dhclient_db, "we");
3852  if (leaseFile == NULL) {
3853  log_error ("can't create %s: %m", path_dhclient_db);
3854  return;
3855  }
3856 
3857  /* If there is a default duid, write it out. */
3858  if (default_duid.len != 0)
3859  write_duid(&default_duid);
3860 
3861  /* Write out all the leases attached to configured interfaces that
3862  we know about. */
3863  for (ip = interfaces; ip; ip = ip -> next) {
3864  for (client = ip -> client; client; client = client -> next) {
3865  for (lp = client -> leases; lp; lp = lp -> next) {
3866  write_client_lease (client, lp, 1, 0);
3867  }
3868  if (client -> active)
3869  write_client_lease (client,
3870  client -> active, 1, 0);
3871 
3872  if (client->active_lease != NULL)
3873  write_client6_lease(client,
3874  client->active_lease,
3875  1, 0);
3876 
3877  /* Reset last_write after rewrites. */
3878  client->last_write = 0;
3879  }
3880  }
3881 
3882  /* Write out any leases that are attached to interfaces that aren't
3883  currently configured. */
3884  for (ip = dummy_interfaces; ip; ip = ip -> next) {
3885  for (client = ip -> client; client; client = client -> next) {
3886  for (lp = client -> leases; lp; lp = lp -> next) {
3887  write_client_lease (client, lp, 1, 0);
3888  }
3889  if (client -> active)
3890  write_client_lease (client,
3891  client -> active, 1, 0);
3892 
3893  if (client->active_lease != NULL)
3894  write_client6_lease(client,
3895  client->active_lease,
3896  1, 0);
3897 
3898  /* Reset last_write after rewrites. */
3899  client->last_write = 0;
3900  }
3901  }
3902  fflush (leaseFile);
3903 }
3904 
3906  struct packet *packet, struct lease *lease,
3907  struct client_state *client_state,
3908  struct option_state *in_options,
3909  struct option_state *cfg_options,
3910  struct binding_scope **scope,
3911  struct universe *u, void *stuff)
3912 {
3913  const char *name, *dot;
3914  struct data_string ds;
3915  char *preamble = stuff;
3916 
3917  memset (&ds, 0, sizeof ds);
3918 
3919  if (u != &dhcp_universe) {
3920  name = u -> name;
3921  dot = ".";
3922  } else {
3923  name = "";
3924  dot = "";
3925  }
3927  in_options, cfg_options, scope, oc, MDL)) {
3928  /* The option name */
3929  fprintf(leaseFile, "%soption %s%s%s", preamble,
3930  name, dot, oc->option->name);
3931 
3932  /* The option value if there is one */
3933  if ((oc->option->format == NULL) ||
3934  (oc->option->format[0] != 'Z')) {
3935  fprintf(leaseFile, " %s",
3937  ds.len, 1, 1));
3938  }
3939 
3940  /* The closing semi-colon and newline */
3941  fprintf(leaseFile, ";\n");
3942 
3943  data_string_forget (&ds, MDL);
3944  }
3945 }
3946 
3947 /* Write an option cache to the lease store. */
3948 static void
3949 write_options(struct client_state *client, struct option_state *options,
3950  const char *preamble)
3951 {
3952  int i;
3953 
3954  for (i = 0; i < options->universe_count; i++) {
3955  option_space_foreach(NULL, NULL, client, NULL, options,
3956  &global_scope, universes[i],
3957  (char *)preamble, write_lease_option);
3958  }
3959 }
3960 
3961 int unhexchar(char c) {
3962 
3963  if (c >= '0' && c <= '9')
3964  return c - '0';
3965 
3966  if (c >= 'a' && c <= 'f')
3967  return c - 'a' + 10;
3968 
3969  if (c >= 'A' && c <= 'F')
3970  return c - 'A' + 10;
3971 
3972  return -1;
3973 }
3974 
3975 isc_result_t
3976 read_uuid(u_int8_t* uuid) {
3977  const char *id_fname = "/etc/machine-id";
3978  char id[32];
3979  size_t nread;
3980  FILE * file = fopen( id_fname , "r");
3981  if (!file) {
3982  log_debug("Cannot open %s", id_fname);
3983  return ISC_R_IOERROR;
3984  }
3985  nread = fread(id, 1, sizeof id, file);
3986  fclose(file);
3987 
3988  if (nread < 32) {
3989  log_debug("Not enough data in %s", id_fname);
3990  return ISC_R_IOERROR;
3991  }
3992  int j;
3993  for (j = 0; j < 16; j++) {
3994  int a, b;
3995 
3996  a = unhexchar(id[j*2]);
3997  b = unhexchar(id[j*2+1]);
3998 
3999  if (a < 0 || b < 0) {
4000  log_debug("Wrong data in %s", id_fname);
4001  return ISC_R_IOERROR;
4002  }
4003  uuid[j] = a << 4 | b;
4004  }
4005 
4006  /* Set UUID version to 4 --- truly random generation */
4007  uuid[6] = (uuid[6] & 0x0F) | 0x40;
4008  /* Set the UUID variant to DCE */
4009  uuid[8] = (uuid[8] & 0x3F) | 0x80;
4010 
4011  return ISC_R_SUCCESS;
4012 }
4013 
4014 /*
4015  * The "best" default DUID, since we cannot predict any information
4016  * about the system (such as whether or not the hardware addresses are
4017  * integrated into the motherboard or similar), is the "LLT", link local
4018  * plus time, DUID. For real stateless "LL" is better.
4019  *
4020  * Once generated, this duid is stored into the state database, and
4021  * retained across restarts.
4022  *
4023  * For the time being, there is probably a different state database for
4024  * every daemon, so this winds up being a per-interface identifier...which
4025  * is not how it is intended. Upcoming rearchitecting the client should
4026  * address this "one daemon model."
4027  */
4028 isc_result_t
4029 form_duid(struct data_string *duid, const char *file, int line)
4030 {
4031  struct interface_info *ip;
4032  int len;
4033  char *str;
4034  u_int8_t uuid[16];
4035 
4036  /* For now, just use the first interface on the list. */
4037  ip = interfaces;
4038 
4039  if (ip == NULL)
4040  log_fatal("Impossible condition at %s:%d.", MDL);
4041 
4042  while (ip && ip->hw_address.hbuf[0] == HTYPE_RESERVED) {
4043  /* Try the other interfaces */
4044  log_debug("Cannot form default DUID from interface %s.", ip->name);
4045  ip = ip->next;
4046  }
4047  if (ip == NULL) {
4048  return ISC_R_UNEXPECTED;
4049  }
4050 
4051  if ((ip->hw_address.hlen == 0) ||
4052  (ip->hw_address.hlen > sizeof(ip->hw_address.hbuf)))
4053  log_fatal("Impossible hardware address length at %s:%d.", MDL);
4054 
4055  if (duid_type == 0) {
4056  if (read_uuid(uuid) == ISC_R_SUCCESS)
4057  duid_type = DUID_UUID;
4058  else
4060  }
4061 
4062  if (duid_type == DUID_UUID)
4063  len = 2 + sizeof (uuid);
4064  else {
4065  /*
4066  * 2 bytes for the 'duid type' field.
4067  * 2 bytes for the 'htype' field.
4068  * (DUID_LLT) 4 bytes for the 'current time'.
4069  * enough bytes for the hardware address (note that hw_address has
4070  * the 'htype' on byte zero).
4071  */
4072  len = 4 + (ip->hw_address.hlen - 1);
4073  if (duid_type == DUID_LLT)
4074  len += 4;
4075  }
4076  if (!buffer_allocate(&duid->buffer, len, MDL))
4077  log_fatal("no memory for default DUID!");
4078  duid->data = duid->buffer->data;
4079  duid->len = len;
4080 
4081  if (duid_type == DUID_UUID) {
4082  putUShort(duid->buffer->data, DUID_UUID);
4083  memcpy(duid->buffer->data + 2, uuid, sizeof(uuid));
4084  }
4085  /* Basic Link Local Address type of DUID. */
4086  else if (duid_type == DUID_LLT) {
4087  putUShort(duid->buffer->data, DUID_LLT);
4088  putUShort(duid->buffer->data + 2, ip->hw_address.hbuf[0]);
4089  putULong(duid->buffer->data + 4, cur_time - DUID_TIME_EPOCH);
4090  memcpy(duid->buffer->data + 8, ip->hw_address.hbuf + 1,
4091  ip->hw_address.hlen - 1);
4092  } else {
4093  putUShort(duid->buffer->data, DUID_LL);
4094  putUShort(duid->buffer->data + 2, ip->hw_address.hbuf[0]);
4095  memcpy(duid->buffer->data + 4, ip->hw_address.hbuf + 1,
4096  ip->hw_address.hlen - 1);
4097  }
4098 
4099  /* Now format the output based on lease-id-format */
4100  str = format_lease_id(duid->data, duid->len,
4102  if (str == NULL) {
4103  log_info("form_duid: Couldn't allocate memory to log duid!");
4104  } else {
4105  log_info("Created duid %s.", str);
4106  dfree(str, MDL);
4107  }
4108 
4109  return ISC_R_SUCCESS;
4110 }
4111 
4112 /* Write the default DUID to the lease store. */
4113 static isc_result_t
4114 write_duid(struct data_string *duid)
4115 {
4116  char *str;
4117  int stat;
4118 
4119  if ((duid == NULL) || (duid->len <= 2))
4120  return DHCP_R_INVALIDARG;
4121 
4122  if (leaseFile == NULL) { /* XXX? */
4123  leaseFile = fopen(path_dhclient_db, "we");
4124  if (leaseFile == NULL) {
4125  log_error("can't create %s: %m", path_dhclient_db);
4126  return ISC_R_IOERROR;
4127  }
4128  }
4129 
4130  /* Generate a formatted duid string per lease-id-format */
4131  str = format_lease_id(duid->data, duid->len,
4133  if (str == NULL)
4134  return ISC_R_NOMEMORY;
4135 
4136  stat = fprintf(leaseFile, "default-duid %s;\n", str);
4137  dfree(str, MDL);
4138  if (stat <= 0)
4139  return ISC_R_IOERROR;
4140 
4141  if (fflush(leaseFile) != 0)
4142  return ISC_R_IOERROR;
4143 
4144  return ISC_R_SUCCESS;
4145 }
4146 
4147 /* Write a DHCPv6 lease to the store. */
4148 isc_result_t
4150  int rewrite, int sync)
4151 {
4152  struct dhc6_ia *ia;
4153  struct dhc6_addr *addr;
4154  int stat;
4155  const char *ianame;
4156 
4157  /* This should include the current lease. */
4158  if (!rewrite && (leases_written++ > 20)) {
4160  leases_written = 0;
4161  return ISC_R_SUCCESS;
4162  }
4163 
4164  if (client == NULL || lease == NULL)
4165  return DHCP_R_INVALIDARG;
4166 
4167  if (leaseFile == NULL) { /* XXX? */
4168  leaseFile = fopen(path_dhclient_db, "w");
4169  if (leaseFile == NULL) {
4170  log_error("can't create %s: %m", path_dhclient_db);
4171  return ISC_R_IOERROR;
4172  }
4173  }
4174 
4175  stat = fprintf(leaseFile, "lease6 {\n");
4176  if (stat <= 0)
4177  return ISC_R_IOERROR;
4178 
4179  stat = fprintf(leaseFile, " interface \"%s\";\n",
4180  client->interface->name);
4181  if (stat <= 0)
4182  return ISC_R_IOERROR;
4183 
4184  for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
4185  switch (ia->ia_type) {
4186  case D6O_IA_NA:
4187  default:
4188  ianame = "ia-na";
4189  break;
4190  case D6O_IA_TA:
4191  ianame = "ia-ta";
4192  break;
4193  case D6O_IA_PD:
4194  ianame = "ia-pd";
4195  break;
4196  }
4197 
4198  /* For some reason IAID was never octal or hex, but string or
4199  * hex. Go figure. So for compatibilty's sake we will either
4200  * do hex or "legacy" i.e string rather than octal. What a
4201  * cluster. */
4203  case TOKEN_HEX: {
4204  char* iaid_str = format_lease_id(
4205  (const unsigned char *) &ia->iaid, 4,
4207 
4208  if (!iaid_str) {
4209  log_error("Can't format iaid");
4210  return ISC_R_IOERROR;
4211  }
4212 
4213  stat = fprintf(leaseFile, " %s %s {\n",
4214  ianame, iaid_str);
4215  dfree(iaid_str, MDL);
4216  break;
4217  }
4218 
4219  case TOKEN_OCTAL:
4220  default:
4221  stat = fprintf(leaseFile, " %s %s {\n", ianame,
4222  print_hex_1(4, ia->iaid, 12));
4223  break;
4224  }
4225 
4226  if (stat <= 0)
4227  return ISC_R_IOERROR;
4228 
4229  if (ia->ia_type != D6O_IA_TA)
4230  stat = fprintf(leaseFile, " starts %d;\n"
4231  " renew %u;\n"
4232  " rebind %u;\n",
4233  (int)ia->starts, ia->renew, ia->rebind);
4234  else
4235  stat = fprintf(leaseFile, " starts %d;\n",
4236  (int)ia->starts);
4237  if (stat <= 0)
4238  return ISC_R_IOERROR;
4239 
4240  for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
4241  if (ia->ia_type != D6O_IA_PD)
4242  stat = fprintf(leaseFile,
4243  " iaaddr %s {\n",
4244  piaddr(addr->address));
4245  else
4246  stat = fprintf(leaseFile,
4247  " iaprefix %s/%d {\n",
4248  piaddr(addr->address),
4249  (int)addr->plen);
4250  if (stat <= 0)
4251  return ISC_R_IOERROR;
4252 
4253  stat = fprintf(leaseFile, " starts %d;\n"
4254  " preferred-life %u;\n"
4255  " max-life %u;\n",
4256  (int)addr->starts, addr->preferred_life,
4257  addr->max_life);
4258  if (stat <= 0)
4259  return ISC_R_IOERROR;
4260 
4261  if (addr->options != NULL)
4262  write_options(client, addr->options, " ");
4263 
4264  stat = fprintf(leaseFile, " }\n");
4265  if (stat <= 0)
4266  return ISC_R_IOERROR;
4267  }
4268 
4269  if (ia->options != NULL)
4270  write_options(client, ia->options, " ");
4271 
4272  stat = fprintf(leaseFile, " }\n");
4273  if (stat <= 0)
4274  return ISC_R_IOERROR;
4275  }
4276 
4277  if (lease->released) {
4278  stat = fprintf(leaseFile, " released;\n");
4279  if (stat <= 0)
4280  return ISC_R_IOERROR;
4281  }
4282 
4283  if (lease->options != NULL)
4284  write_options(client, lease->options, " ");
4285 
4286  stat = fprintf(leaseFile, "}\n");
4287  if (stat <= 0)
4288  return ISC_R_IOERROR;
4289 
4290  if (fflush(leaseFile) != 0)
4291  return ISC_R_IOERROR;
4292 
4293  if (sync) {
4294  if (fsync(fileno(leaseFile)) < 0) {
4295  log_error("write_client_lease: fsync(): %m");
4296  return ISC_R_IOERROR;
4297  }
4298  }
4299 
4300  return ISC_R_SUCCESS;
4301 }
4302 
4303 int write_client_lease (client, lease, rewrite, makesure)
4304  struct client_state *client;
4305  struct client_lease *lease;
4306  int rewrite;
4307  int makesure;
4308 {
4309  struct data_string ds;
4310  int errors = 0;
4311  char *s;
4312  const char *tval;
4313 
4314  if (!rewrite) {
4315  if (leases_written++ > 20) {
4317  leases_written = 0;
4318  }
4319  }
4320 
4321  /* If the lease came from the config file, we don't need to stash
4322  a copy in the lease database. */
4323  if (lease -> is_static)
4324  return 1;
4325 
4326  if (leaseFile == NULL) { /* XXX */
4327  leaseFile = fopen (path_dhclient_db, "we");
4328  if (leaseFile == NULL) {
4329  log_error ("can't create %s: %m", path_dhclient_db);
4330  return 0;
4331  }
4332  }
4333 
4334  errno = 0;
4335  fprintf (leaseFile, "lease {\n");
4336  if (lease -> is_bootp) {
4337  fprintf (leaseFile, " bootp;\n");
4338  if (errno) {
4339  ++errors;
4340  errno = 0;
4341  }
4342  }
4343  fprintf (leaseFile, " interface \"%s\";\n",
4344  client -> interface -> name);
4345  if (errno) {
4346  ++errors;
4347  errno = 0;
4348  }
4349  if (client -> name) {
4350  fprintf (leaseFile, " name \"%s\";\n", client -> name);
4351  if (errno) {
4352  ++errors;
4353  errno = 0;
4354  }
4355  }
4356  fprintf (leaseFile, " fixed-address %s;\n",
4357  piaddr (lease -> address));
4358  if (errno) {
4359  ++errors;
4360  errno = 0;
4361  }
4362  if (lease -> filename) {
4363  s = quotify_string (lease -> filename, MDL);
4364  if (s) {
4365  fprintf (leaseFile, " filename \"%s\";\n", s);
4366  if (errno) {
4367  ++errors;
4368  errno = 0;
4369  }
4370  dfree (s, MDL);
4371  } else
4372  errors++;
4373 
4374  }
4375  if (lease->server_name != NULL) {
4376  s = quotify_string(lease->server_name, MDL);
4377  if (s != NULL) {
4378  fprintf(leaseFile, " server-name \"%s\";\n", s);
4379  if (errno) {
4380  ++errors;
4381  errno = 0;
4382  }
4383  dfree(s, MDL);
4384  } else
4385  ++errors;
4386  }
4387  if (lease -> medium) {
4388  s = quotify_string (lease -> medium -> string, MDL);
4389  if (s) {
4390  fprintf (leaseFile, " medium \"%s\";\n", s);
4391  if (errno) {
4392  ++errors;
4393  errno = 0;
4394  }
4395  dfree (s, MDL);
4396  } else
4397  errors++;
4398  }
4399  if (errno != 0) {
4400  errors++;
4401  errno = 0;
4402  }
4403 
4404  memset (&ds, 0, sizeof ds);
4405 
4406  write_options(client, lease->options, " ");
4407 
4408  tval = print_time(lease->renewal);
4409  if (tval == NULL ||
4410  fprintf(leaseFile, " renew %s\n", tval) < 0)
4411  errors++;
4412 
4413  tval = print_time(lease->rebind);
4414  if (tval == NULL ||
4415  fprintf(leaseFile, " rebind %s\n", tval) < 0)
4416  errors++;
4417 
4418  tval = print_time(lease->expiry);
4419  if (tval == NULL ||
4420  fprintf(leaseFile, " expire %s\n", tval) < 0)
4421  errors++;
4422 
4423  if (fprintf(leaseFile, "}\n") < 0)
4424  errors++;
4425 
4426  if (fflush(leaseFile) != 0)
4427  errors++;
4428 
4429  client->last_write = cur_time;
4430 
4431  if (!errors && makesure) {
4432  if (fsync (fileno (leaseFile)) < 0) {
4433  log_info ("write_client_lease: %m");
4434  return 0;
4435  }
4436  }
4437 
4438  return errors ? 0 : 1;
4439 }
4440 
4441 /* Variables holding name of script and file pointer for writing to
4442  script. Needless to say, this is not reentrant - only one script
4443  can be invoked at a time. */
4444 char scriptName [256];
4446 
4459 void script_init(struct client_state *client, const char *reason,
4460  struct string_list *medium)
4461 {
4462  struct string_list *sl, *next;
4463 
4464  if (client) {
4465  for (sl = client -> env; sl; sl = next) {
4466  next = sl -> next;
4467  dfree (sl, MDL);
4468  }
4469  client -> env = (struct string_list *)0;
4470  client -> envc = 0;
4471 
4472  if (client -> interface) {
4473  client_envadd (client, "", "interface", "%s",
4474  client -> interface -> name);
4475  }
4476  if (client -> name)
4477  client_envadd (client,
4478  "", "client", "%s", client -> name);
4479  if (medium)
4480  client_envadd (client,
4481  "", "medium", "%s", medium -> string);
4482 
4483  client_envadd (client, "", "reason", "%s", reason);
4484  client_envadd (client, "", "pid", "%ld", (long int)getpid ());
4485  client_envadd (client, "", "dad_wait_time", "%ld",
4486  (long int)dad_wait_time);
4487  }
4488 }
4489 
4491  struct packet *packet, struct lease *lease,
4492  struct client_state *client_state,
4493  struct option_state *in_options,
4494  struct option_state *cfg_options,
4495  struct binding_scope **scope,
4496  struct universe *u, void *stuff)
4497 {
4498  struct envadd_state *es = stuff;
4499  struct data_string data;
4500  memset (&data, 0, sizeof data);
4501 
4503  in_options, cfg_options, scope, oc, MDL)) {
4504  if (data.len) {
4505  char name [256];
4506  if (dhcp_option_ev_name (name, sizeof name,
4507  oc->option)) {
4508  const char *value;
4509  size_t length;
4510  value = pretty_print_option(oc->option,
4511  data.data,
4512  data.len, 0, 0);
4513  length = strlen(value);
4514 
4515  if (check_option_values(oc->option->universe,
4516  oc->option->code,
4517  value, length) == 0) {
4518  client_envadd(es->client, es->prefix,
4519  name, "%s", value);
4520  } else {
4521  log_error("suspect value in %s "
4522  "option - discarded",
4523  name);
4524  }
4526  }
4527  }
4528  }
4529 }
4530 
4550 void script_write_params(struct client_state *client, const char *prefix,
4551  struct client_lease *lease)
4552 {
4553  int i;
4554  struct data_string data;
4555  struct option_cache *oc;
4556  struct envadd_state es;
4557 
4558  es.client = client;
4559  es.prefix = prefix;
4560 
4562  prefix, "ip_address", "%s", piaddr (lease -> address));
4563 
4564  /* If we've set the next server address in the lease structure
4565  put it into an environment variable for the script */
4566  if (lease->next_srv_addr.len != 0) {
4567  client_envadd(client, prefix, "next_server", "%s",
4568  piaddr(lease->next_srv_addr));
4569  }
4570 
4571  /* For the benefit of Linux (and operating systems which may
4572  have similar needs), compute the network address based on
4573  the supplied ip address and netmask, if provided. Also
4574  compute the broadcast address (the host address all ones
4575  broadcast address, not the host address all zeroes
4576  broadcast address). */
4577 
4578  memset (&data, 0, sizeof data);
4579  oc = lookup_option (&dhcp_universe, lease -> options, DHO_SUBNET_MASK);
4580  if (oc && evaluate_option_cache (&data, (struct packet *)0,
4581  (struct lease *)0, client,
4582  (struct option_state *)0,
4583  lease -> options,
4584  &global_scope, oc, MDL)) {
4585  if (data.len > 3) {
4586  struct iaddr netmask, subnet, broadcast;
4587 
4588  /*
4589  * No matter the length of the subnet-mask option,
4590  * use only the first four octets. Note that
4591  * subnet-mask options longer than 4 octets are not
4592  * in conformance with RFC 2132, but servers with this
4593  * flaw do exist.
4594  */
4595  memcpy(netmask.iabuf, data.data, 4);
4596  netmask.len = 4;
4597  data_string_forget (&data, MDL);
4598 
4599  subnet = subnet_number (lease -> address, netmask);
4600  if (subnet.len) {
4601  client_envadd (client, prefix, "network_number",
4602  "%s", piaddr (subnet));
4603 
4605  lease -> options,
4607  if (!oc ||
4609  (&data, (struct packet *)0,
4610  (struct lease *)0, client,
4611  (struct option_state *)0,
4612  lease -> options,
4613  &global_scope, oc, MDL))) {
4614  broadcast = broadcast_addr (subnet, netmask);
4615  if (broadcast.len) {
4616  client_envadd (client,
4617  prefix, "broadcast_address",
4618  "%s", piaddr (broadcast));
4619  }
4620  }
4621  }
4622  }
4623  data_string_forget (&data, MDL);
4624  }
4625 
4626  if (lease->filename) {
4627  if (check_option_values(NULL, DHO_ROOT_PATH,
4628  lease->filename,
4629  strlen(lease->filename)) == 0) {
4630  client_envadd(client, prefix, "filename",
4631  "%s", lease->filename);
4632  } else {
4633  log_error("suspect value in %s "
4634  "option - discarded",
4635  lease->filename);
4636  }
4637  }
4638 
4639  if (lease->server_name) {
4640  if (check_option_values(NULL, DHO_HOST_NAME,
4641  lease->server_name,
4642  strlen(lease->server_name)) == 0 ) {
4643  client_envadd (client, prefix, "server_name",
4644  "%s", lease->server_name);
4645  } else {
4646  log_error("suspect value in %s "
4647  "option - discarded",
4648  lease->server_name);
4649  }
4650  }
4651 
4652  for (i = 0; i < lease -> options -> universe_count; i++) {
4653  option_space_foreach ((struct packet *)0, (struct lease *)0,
4654  client, (struct option_state *)0,
4655  lease -> options, &global_scope,
4656  universes [i],
4657  &es, client_option_envadd);
4658  }
4659 
4660  client_envadd (client, prefix, "expiry", "%lu",
4661  (unsigned long)(lease -> expiry));
4662 }
4663 
4674 {
4675  int i;
4676  struct option **req;
4677  char name[256];
4678  req = client->config->requested_options;
4679 
4680  if (req == NULL)
4681  return;
4682 
4683  for (i = 0 ; req[i] != NULL ; i++) {
4684  if ((req[i]->universe == &dhcp_universe) &&
4685  dhcp_option_ev_name(name, sizeof(name), req[i])) {
4686  client_envadd(client, "requested_", name, "%d", 1);
4687  }
4688  }
4689 }
4690 
4703 int script_go(struct client_state *client)
4704 {
4705  char *scriptName;
4706  char *argv [2];
4707  char **envp;
4708  char reason [] = "REASON=NBI";
4709  static char client_path [] = CLIENT_PATH;
4710  int i;
4711  struct string_list *sp, *next;
4712  int pid, wpid, wstatus;
4713 
4714  if (client)
4715  scriptName = client -> config -> script_name;
4716  else
4718 
4719  envp = dmalloc (((client ? client -> envc : 2) +
4720  client_env_count + 2) * sizeof (char *), MDL);
4721  if (!envp) {
4722  log_error ("No memory for client script environment.");
4723  return 0;
4724  }
4725  i = 0;
4726  /* Copy out the environment specified on the command line,
4727  if any. */
4728  for (sp = client_env; sp; sp = sp -> next) {
4729  envp [i++] = sp -> string;
4730  }
4731  /* Copy out the environment specified by dhclient. */
4732  if (client) {
4733  for (sp = client -> env; sp; sp = sp -> next) {
4734  envp [i++] = sp -> string;
4735  }
4736  } else {
4737  envp [i++] = reason;
4738  }
4739  /* Set $PATH. */
4740  envp [i++] = client_path;
4741  envp [i] = (char *)0;
4742 
4743  argv [0] = scriptName;
4744  argv [1] = (char *)0;
4745 
4746  pid = fork ();
4747  if (pid < 0) {
4748  log_error ("fork: %m");
4749  wstatus = 0;
4750  } else if (pid) {
4751  do {
4752  wpid = wait (&wstatus);
4753  } while (wpid != pid && wpid > 0);
4754  if (wpid < 0) {
4755  log_error ("wait: %m");
4756  wstatus = 0;
4757  }
4758  } else {
4759  /* We don't want to pass an open file descriptor for
4760  * dhclient.leases when executing dhclient-script.
4761  */
4762  if (leaseFile != NULL)
4763  fclose(leaseFile);
4764  execve (scriptName, argv, envp);
4765  log_error ("execve (%s, ...): %m", scriptName);
4766  exit (0);
4767  }
4768 
4769  if (client) {
4770  for (sp = client -> env; sp; sp = next) {
4771  next = sp -> next;
4772  dfree (sp, MDL);
4773  }
4774  client -> env = (struct string_list *)0;
4775  client -> envc = 0;
4776  }
4777  dfree (envp, MDL);
4778  gettimeofday(&cur_tv, NULL);
4779  return (WIFEXITED (wstatus) ?
4780  WEXITSTATUS (wstatus) : -WTERMSIG (wstatus));
4781 }
4782 
4783 void client_envadd (struct client_state *client,
4784  const char *prefix, const char *name, const char *fmt, ...)
4785 {
4786  char spbuf [1024];
4787  char *s;
4788  unsigned len;
4789  struct string_list *val;
4790  va_list list;
4791 
4792  va_start (list, fmt);
4793  len = vsnprintf (spbuf, sizeof spbuf, fmt, list);
4794  va_end (list);
4795 
4796  val = dmalloc (strlen (prefix) + strlen (name) + 1 /* = */ +
4797  len + sizeof *val, MDL);
4798  if (!val) {
4799  log_error ("client_envadd: cannot allocate space for variable");
4800  return;
4801  }
4802 
4803  s = val -> string;
4804  strcpy (s, prefix);
4805  strcat (s, name);
4806  s += strlen (s);
4807  *s++ = '=';
4808  if (len >= sizeof spbuf) {
4809  va_start (list, fmt);
4810  vsnprintf (s, len + 1, fmt, list);
4811  va_end (list);
4812  } else {
4813  strcpy (s, spbuf);
4814  }
4815 
4816  val -> next = client -> env;
4817  client -> env = val;
4818  client -> envc++;
4819 }
4820 
4821 int dhcp_option_ev_name (buf, buflen, option)
4822  char *buf;
4823  size_t buflen;
4824  struct option *option;
4825 {
4826  int i, j;
4827  const char *s;
4828 
4829  j = 0;
4830  if (option -> universe != &dhcp_universe) {
4831  s = option -> universe -> name;
4832  i = 0;
4833  } else {
4834  s = option -> name;
4835  i = 1;
4836  }
4837 
4838  do {
4839  while (*s) {
4840  if (j + 1 == buflen)
4841  return 0;
4842  if (*s == '-')
4843  buf [j++] = '_';
4844  else
4845  buf [j++] = *s;
4846  ++s;
4847  }
4848  if (!i) {
4849  s = option -> name;
4850  if (j + 1 == buflen)
4851  return 0;
4852  buf [j++] = '_';
4853  }
4854  ++i;
4855  } while (i != 2);
4856 
4857  buf [j] = 0;
4858  return 1;
4859 }
4860 
4861 void go_daemon ()
4862 {
4863  static int state = 0;
4864  int pid;
4865 
4866  /* Don't become a daemon if the user requested otherwise. */
4867  if (no_daemon) {
4869  return;
4870  }
4871 
4872  /* Only do it once. */
4873  if (state)
4874  return;
4875  state = 1;
4876 
4877  /* Stop logging to stderr... */
4878  log_perror = 0;
4879 
4880  /* Become a daemon... */
4881  if ((pid = fork ()) < 0)
4882  log_fatal ("Can't fork daemon: %m");
4883  else if (pid)
4884  exit (0);
4885  /* Become session leader and get pid... */
4886  (void) setsid ();
4887 
4888  /* Close standard I/O descriptors. */
4889  (void) close(0);
4890  (void) close(1);
4891  (void) close(2);
4892 
4893  /* Reopen them on /dev/null. */
4894  (void) open("/dev/null", O_RDWR | O_CLOEXEC);
4895  (void) open("/dev/null", O_RDWR | O_CLOEXEC);
4896  (void) open("/dev/null", O_RDWR | O_CLOEXEC);
4897 
4899 
4900  IGNORE_RET (chdir("/"));
4901 }
4902 
4904 {
4905  FILE *pf;
4906  int pfdesc;
4907 
4908  /* nothing to do if the user doesn't want a pid file */
4909  if (no_pid_file == ISC_TRUE) {
4910  return;
4911  }
4912 
4913  pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
4914 
4915  if (pfdesc < 0) {
4916  log_error ("Can't create %s: %m", path_dhclient_pid);
4917  return;
4918  }
4919 
4920  pf = fdopen (pfdesc, "we");
4921  if (!pf) {
4922  close(pfdesc);
4923  log_error ("Can't fdopen %s: %m", path_dhclient_pid);
4924  } else {
4925  fprintf (pf, "%ld\n", (long)getpid ());
4926  fclose (pf);
4927  }
4928 }
4929 
4931 {
4932  struct interface_info *ip;
4933  struct client_state *client;
4934 
4935  for (ip = interfaces; ip; ip = ip -> next) {
4936  for (client = ip -> client; client; client = client -> next) {
4937  switch (client -> state) {
4938  case S_SELECTING:
4939  cancel_timeout (send_discover, client);
4940  break;
4941 
4942  case S_BOUND:
4943  cancel_timeout (state_bound, client);
4944  break;
4945 
4946  case S_REBOOTING:
4947  case S_REQUESTING:
4948  case S_RENEWING:
4949  cancel_timeout (send_request, client);
4950  break;
4951 
4952  case S_INIT:
4953  case S_REBINDING:
4954  case S_STOPPED:
4955  case S_DECLINED:
4956  break;
4957  }
4958  client -> state = S_INIT;
4959  state_reboot (client);
4960  }
4961  }
4962 }
4963 
4964 void do_release(client)
4965  struct client_state *client;
4966 {
4967  struct data_string ds;
4968  struct option_cache *oc;
4969 
4970 #if defined(DHCPv6) && defined(DHCP4o6)
4971  if (dhcpv4_over_dhcpv6 && (dhcp4o6_state <= 0)) {
4972  if (dhcp4o6_state < 0)
4973  dhcp4o6_poll(NULL);
4974  client->pending = P_RELEASE;
4975  return;
4976  }
4977 #endif
4978 
4979  /* Pick a random xid. */
4980  client -> xid = random ();
4981 
4982  /* is there even a lease to release? */
4983  if (client -> active) {
4984  /* Make a DHCPRELEASE packet, and set appropriate per-interface
4985  flags. */
4986  make_release (client, client -> active);
4987 
4988  memset (&ds, 0, sizeof ds);
4990  client -> active -> options,
4992  if (oc &&
4993  evaluate_option_cache (&ds, (struct packet *)0,
4994  (struct lease *)0, client,
4995  (struct option_state *)0,
4996  client -> active -> options,
4997  &global_scope, oc, MDL)) {
4998  if (ds.len > 3) {
4999  memcpy (client -> destination.iabuf,
5000  ds.data, 4);
5001  client -> destination.len = 4;
5002  } else
5003  client -> destination = iaddr_broadcast;
5004 
5005  data_string_forget (&ds, MDL);
5006  } else
5007  client -> destination = iaddr_broadcast;
5008  client -> first_sending = cur_time;
5009  client -> interval = client -> config -> initial_interval;
5010 
5011  /* Zap the medium list... */
5012  client -> medium = (struct string_list *)0;
5013 
5014  /* Send out the first and only DHCPRELEASE packet. */
5015  send_release (client);
5016 
5017  /* Do the client script RELEASE operation. */
5018  script_init (client,
5019  "RELEASE", (struct string_list *)0);
5020  if (client -> alias)
5021  script_write_params(client, "alias_",
5022  client -> alias);
5023  script_write_params(client, "old_", client -> active);
5024  script_write_requested(client);
5025  script_go(client);
5026  }
5027 
5028  /* Cancel any timeouts. */
5029  cancel_timeout (state_bound, client);
5030  cancel_timeout (send_discover, client);
5031  cancel_timeout (state_init, client);
5032  cancel_timeout (send_request, client);
5033  cancel_timeout (state_reboot, client);
5034  client -> state = S_STOPPED;
5035 
5036 #if defined(DHCPv6) && defined(DHCP4o6)
5037  if (dhcpv4_over_dhcpv6)
5038  exit(0);
5039 #endif
5040 }
5041 
5043 {
5044  do_release (interface -> client);
5045 
5046  return 1;
5047 }
5048 
5050 {
5051  struct interface_info *last, *ip;
5052  /* See if we can find the client from dummy_interfaces */
5053  last = 0;
5054  for (ip = dummy_interfaces; ip; ip = ip -> next) {
5055  if (!strcmp (ip -> name, tmp -> name)) {
5056  /* Remove from dummy_interfaces */
5057  if (last) {
5058  ip = (struct interface_info *)0;
5059  interface_reference (&ip, last -> next, MDL);
5060  interface_dereference (&last -> next, MDL);
5061  if (ip -> next) {
5062  interface_reference (&last -> next,
5063  ip -> next, MDL);
5064  interface_dereference (&ip -> next,
5065  MDL);
5066  }
5067  } else {
5068  ip = (struct interface_info *)0;
5069  interface_reference (&ip,
5071  interface_dereference (&dummy_interfaces, MDL);
5072  if (ip -> next) {
5073  interface_reference (&dummy_interfaces,
5074  ip -> next, MDL);
5075  interface_dereference (&ip -> next,
5076  MDL);
5077  }
5078  }
5079  /* Copy "client" to tmp */
5080  if (ip -> client) {
5081  tmp -> client = ip -> client;
5082  tmp -> client -> interface = tmp;
5083  }
5084  interface_dereference (&ip, MDL);
5085  break;
5086  }
5087  last = ip;
5088  }
5089  return 1;
5090 }
5091 
5092 isc_result_t dhclient_interface_startup_hook (struct interface_info *interface)
5093 {
5094  struct interface_info *ip;
5095  struct client_state *client;
5096 
5097  /* This code needs some rethinking. It doesn't test against
5098  a signal name, and it just kind of bulls into doing something
5099  that may or may not be appropriate. */
5100 
5101  if (interfaces) {
5102  interface_reference (&interface -> next, interfaces, MDL);
5103  interface_dereference (&interfaces, MDL);
5104  }
5105  interface_reference (&interfaces, interface, MDL);
5106 
5108 
5109  for (ip = interfaces; ip; ip = ip -> next) {
5110  /* If interfaces were specified, don't configure
5111  interfaces that weren't specified! */
5112  if (ip -> flags & INTERFACE_RUNNING ||
5113  (ip -> flags & (INTERFACE_REQUESTED |
5114  INTERFACE_AUTOMATIC)) !=
5116  continue;
5117  script_init (ip -> client,
5118  "PREINIT", (struct string_list *)0);
5119  if (ip -> client -> alias)
5120  script_write_params(ip -> client, "alias_",
5121  ip -> client -> alias);
5122  script_go(ip -> client);
5123  }
5124 
5127  : DISCOVER_RUNNING);
5128 
5129  for (ip = interfaces; ip; ip = ip -> next) {
5130  if (ip -> flags & INTERFACE_RUNNING)
5131  continue;
5132  ip -> flags |= INTERFACE_RUNNING;
5133  for (client = ip->client ; client ; client = client->next) {
5134  client->state = S_INIT;
5135  state_reboot(client);
5136  }
5137  }
5138  return ISC_R_SUCCESS;
5139 }
5140 
5141 /* The client should never receive a relay agent information option,
5142  so if it does, log it and discard it. */
5143 
5145  struct packet *packet;
5146  int len;
5147  u_int8_t *data;
5148 {
5149  return 1;
5150 }
5151 
5152 /* The client never sends relay agent information options. */
5153 
5154 unsigned cons_agent_information_options (cfg_options, outpacket,
5155  agentix, length)
5156  struct option_state *cfg_options;
5157  struct dhcp_packet *outpacket;
5158  unsigned agentix;
5159  unsigned length;
5160 {
5161  return length;
5162 }
5163 
5164 static void shutdown_exit (void *foo)
5165 {
5166  /* get rid of the pid if we can */
5167  if (no_pid_file == ISC_FALSE)
5168  (void) unlink(path_dhclient_pid);
5169  exit (0);
5170 }
5171 
5172 #if defined (NSUPDATE)
5173 /*
5174  * If the first query fails, the updater MUST NOT delete the DNS name. It
5175  * may be that the host whose lease on the server has expired has moved
5176  * to another network and obtained a lease from a different server,
5177  * which has caused the client's A RR to be replaced. It may also be
5178  * that some other client has been configured with a name that matches
5179  * the name of the DHCP client, and the policy was that the last client
5180  * to specify the name would get the name. In this case, the DHCID RR
5181  * will no longer match the updater's notion of the client-identity of
5182  * the host pointed to by the DNS name.
5183  * -- "Interaction between DHCP and DNS"
5184  */
5185 
5186 /* The first and second stages are pretty similar so we combine them */
5187 void
5188 client_dns_remove_action(dhcp_ddns_cb_t *ddns_cb,
5189  isc_result_t eresult)
5190 {
5191 
5192  isc_result_t result;
5193 
5194  if ((eresult == ISC_R_SUCCESS) &&
5195  (ddns_cb->state == DDNS_STATE_REM_FW_YXDHCID)) {
5196  /* Do the second stage of the FWD removal */
5197  ddns_cb->state = DDNS_STATE_REM_FW_NXRR;
5198 
5199  result = ddns_modify_fwd(ddns_cb, MDL);
5200  if (result == ISC_R_SUCCESS) {
5201  return;
5202  }
5203  }
5204 
5205  /* If we are done or have an error clean up */
5206  dhclient_ddns_cb_free(ddns_cb, MDL);
5207  return;
5208 }
5209 
5210 void
5211 client_dns_remove(struct client_state *client,
5212  struct iaddr *addr)
5213 {
5214  dhcp_ddns_cb_t *ddns_cb;
5215  isc_result_t result;
5216 
5217  /* if we have an old ddns request for this client, cancel it */
5218  if (client->ddns_cb != NULL) {
5219  ddns_cancel(client->ddns_cb, MDL);
5220  client->ddns_cb = NULL;
5221  }
5222 
5223  ddns_cb = ddns_cb_alloc(MDL);
5224  if (ddns_cb != NULL) {
5225  ddns_cb->address = *addr;
5226  ddns_cb->timeout = 0;
5227 
5228  ddns_cb->state = DDNS_STATE_REM_FW_YXDHCID;
5229  ddns_cb->flags = DDNS_UPDATE_ADDR;
5230  ddns_cb->cur_func = client_dns_remove_action;
5231 
5232  result = client_dns_update(client, ddns_cb);
5233 
5234  if (result != ISC_R_TIMEDOUT) {
5235  dhclient_ddns_cb_free(ddns_cb, MDL);
5236  }
5237  }
5238 }
5239 #endif
5240 
5242  control_object_state_t newstate)
5243 {
5244  struct interface_info *ip;
5245  struct client_state *client;
5246  struct timeval tv;
5247 
5248  if (newstate == server_shutdown) {
5249  /* Re-entry */
5250  if (shutdown_signal == SIGUSR1)
5251  return ISC_R_SUCCESS;
5252  /* Log shutdown on signal. */
5253  if ((shutdown_signal == SIGINT) ||
5254  (shutdown_signal == SIGTERM)) {
5255  log_info("Received signal %d, initiating shutdown.",
5256  shutdown_signal);
5257  }
5258  /* Mark it was called. */
5259  shutdown_signal = SIGUSR1;
5260  }
5261 
5262  /* Do the right thing for each interface. */
5263  for (ip = interfaces; ip; ip = ip -> next) {
5264  for (client = ip -> client; client; client = client -> next) {
5265  switch (newstate) {
5266  case server_startup:
5267  return ISC_R_SUCCESS;
5268 
5269  case server_running:
5270  return ISC_R_SUCCESS;
5271 
5272  case server_shutdown:
5273  if (client -> active &&
5274  client -> active -> expiry > cur_time) {
5275 #if defined (NSUPDATE)
5276  if (client->config->do_forward_update) {
5277  client_dns_remove(client,
5278  &client->active->address);
5279  }
5280 #endif
5281  do_release (client);
5282  }
5283  break;
5284 
5285  case server_hibernate:
5286  state_stop (client);
5287  break;
5288 
5289  case server_awaken:
5290  state_reboot (client);
5291  break;
5292  }
5293  }
5294  }
5295 
5296  if (newstate == server_shutdown) {
5297  tv.tv_sec = cur_tv.tv_sec;
5298  tv.tv_usec = cur_tv.tv_usec + 1;
5299  add_timeout(&tv, shutdown_exit, 0, 0, 0);
5300  }
5301  return ISC_R_SUCCESS;
5302 }
5303 
5304 #if defined (NSUPDATE)
5305 /*
5306  * Called after a timeout if the DNS update failed on the previous try.
5307  * Starts the retry process. If the retry times out it will schedule
5308  * this routine to run again after a 10x wait.
5309  */
5310 void
5311 client_dns_update_timeout (void *cp)
5312 {
5313  dhcp_ddns_cb_t *ddns_cb = (dhcp_ddns_cb_t *)cp;
5314  struct client_state *client = (struct client_state *)ddns_cb->lease;
5315  isc_result_t status = ISC_R_FAILURE;
5316 
5317  if ((client != NULL) &&
5318  ((client->active != NULL) ||
5319  (client->active_lease != NULL)))
5320  status = client_dns_update(client, ddns_cb);
5321 
5322  /*
5323  * A status of timedout indicates that we started the update and
5324  * have released control of the control block. Any other status
5325  * indicates that we should clean up the control block. We either
5326  * got a success which indicates that we didn't really need to
5327  * send an update or some other error in which case we weren't able
5328  * to start the update process. In both cases we still own
5329  * the control block and should free it.
5330  */
5331  if (status != ISC_R_TIMEDOUT) {
5332  dhclient_ddns_cb_free(ddns_cb, MDL);
5333  }
5334 }
5335 
5336 /*
5337  * If the first query succeeds, the updater can conclude that it
5338  * has added a new name whose only RRs are the A and DHCID RR records.
5339  * The A RR update is now complete (and a client updater is finished,
5340  * while a server might proceed to perform a PTR RR update).
5341  * -- "Interaction between DHCP and DNS"
5342  *
5343  * If the second query succeeds, the updater can conclude that the current
5344  * client was the last client associated with the domain name, and that
5345  * the name now contains the updated A RR. The A RR update is now
5346  * complete (and a client updater is finished, while a server would
5347  * then proceed to perform a PTR RR update).
5348  * -- "Interaction between DHCP and DNS"
5349  *
5350  * If the second query fails with NXRRSET, the updater must conclude
5351  * that the client's desired name is in use by another host. At this
5352  * juncture, the updater can decide (based on some administrative
5353  * configuration outside of the scope of this document) whether to let
5354  * the existing owner of the name keep that name, and to (possibly)
5355  * perform some name disambiguation operation on behalf of the current
5356  * client, or to replace the RRs on the name with RRs that represent
5357  * the current client. If the configured policy allows replacement of
5358  * existing records, the updater submits a query that deletes the
5359  * existing A RR and the existing DHCID RR, adding A and DHCID RRs that
5360  * represent the IP address and client-identity of the new client.
5361  * -- "Interaction between DHCP and DNS"
5362  */
5363 
5364 /* The first and second stages are pretty similar so we combine them */
5365 void
5366 client_dns_update_action(dhcp_ddns_cb_t *ddns_cb,
5367  isc_result_t eresult)
5368 {
5369  isc_result_t result;
5370  struct timeval tv;
5371 
5372  switch(eresult) {
5373  case ISC_R_SUCCESS:
5374  default:
5375  /* Either we succeeded or broke in a bad way, clean up */
5376  break;
5377 
5378  case DNS_R_YXRRSET:
5379  /*
5380  * This is the only difference between the two stages,
5381  * check to see if it is the first stage, in which case
5382  * start the second stage
5383  */
5384  if (ddns_cb->state == DDNS_STATE_ADD_FW_NXDOMAIN) {
5385  ddns_cb->state = DDNS_STATE_ADD_FW_YXDHCID;
5386  ddns_cb->cur_func = client_dns_update_action;
5387 
5388  result = ddns_modify_fwd(ddns_cb, MDL);
5389  if (result == ISC_R_SUCCESS) {
5390  return;
5391  }
5392  }
5393  break;
5394 
5395  case ISC_R_TIMEDOUT:
5396  /*
5397  * We got a timeout response from the DNS module. Schedule
5398  * another attempt for later. We forget the name, dhcid and
5399  * zone so if it gets changed we will get the new information.
5400  */
5401  data_string_forget(&ddns_cb->fwd_name, MDL);
5402  data_string_forget(&ddns_cb->dhcid, MDL);
5403  if (ddns_cb->zone != NULL) {
5404  forget_zone((struct dns_zone **)&ddns_cb->zone);
5405  }
5406 
5407  /* Reset to doing the first stage */
5408  ddns_cb->state = DDNS_STATE_ADD_FW_NXDOMAIN;
5409  ddns_cb->cur_func = client_dns_update_action;
5410 
5411  /* and update our timer */
5412  if (ddns_cb->timeout < 3600)
5413  ddns_cb->timeout *= 10;
5414  tv.tv_sec = cur_tv.tv_sec + ddns_cb->timeout;
5415  tv.tv_usec = cur_tv.tv_usec;
5417  ddns_cb, NULL, NULL);
5418  return;
5419  }
5420 
5421  dhclient_ddns_cb_free(ddns_cb, MDL);
5422  return;
5423 }
5424 
5425 /* See if we should do a DNS update, and if so, do it. */
5426 
5427 isc_result_t
5428 client_dns_update(struct client_state *client, dhcp_ddns_cb_t *ddns_cb)
5429 {
5430  struct data_string client_identifier;
5431  struct option_cache *oc;
5432  int ignorep;
5433  int result;
5434  int ddns_v4_type;
5435  isc_result_t rcode;
5436 
5437  /* If we didn't send an FQDN option, we certainly aren't going to
5438  be doing an update. */
5439  if (!client -> sent_options)
5440  return ISC_R_SUCCESS;
5441 
5442  /* If we don't have a lease, we can't do an update. */
5443  if ((client->active == NULL) && (client->active_lease == NULL))
5444  return ISC_R_SUCCESS;
5445 
5446  /* If we set the no client update flag, don't do the update. */
5447  if ((oc = lookup_option (&fqdn_universe, client -> sent_options,
5449  evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
5450  (struct lease *)0, client,
5451  client -> sent_options,
5452  (struct option_state *)0,
5453  &global_scope, oc, MDL))
5454  return ISC_R_SUCCESS;
5455 
5456  /* If we set the "server, please update" flag, or didn't set it
5457  to false, don't do the update. */
5458  if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
5459  FQDN_SERVER_UPDATE)) ||
5460  evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
5461  (struct lease *)0, client,
5462  client -> sent_options,
5463  (struct option_state *)0,
5464  &global_scope, oc, MDL))
5465  return ISC_R_SUCCESS;
5466 
5467  /* If no FQDN option was supplied, don't do the update. */
5468  if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
5469  FQDN_FQDN)) ||
5470  !evaluate_option_cache (&ddns_cb->fwd_name, (struct packet *)0,
5471  (struct lease *)0, client,
5472  client -> sent_options,
5473  (struct option_state *)0,
5474  &global_scope, oc, MDL))
5475  return ISC_R_SUCCESS;
5476 
5477  /*
5478  * Construct the DHCID value for use in the DDNS update process
5479  * We have the newer standard version and the older interim version
5480  * chosen by the '-I' option. The interim version is left as is
5481  * for backwards compatibility. The standard version is based on
5482  * RFC 4701 section 3.3
5483  */
5484 
5485  result = 0;
5486  POST(result);
5487  memset(&client_identifier, 0, sizeof(client_identifier));
5488 
5489  if (std_dhcid == 1) {
5490  /* standard style */
5491  ddns_cb->dhcid_class = dns_rdatatype_dhcid;
5492  ddns_v4_type = 1;
5493  } else {
5494  /* interim style */
5495  ddns_cb->dhcid_class = dns_rdatatype_txt;
5496  /* for backwards compatibility */
5497  ddns_v4_type = DHO_DHCP_CLIENT_IDENTIFIER;
5498  }
5499  if (client->active_lease != NULL) {
5500  /* V6 request, get the client identifier, then
5501  * construct the dhcid for either standard
5502  * or interim */
5503  if (((oc = lookup_option(&dhcpv6_universe,
5504  client->sent_options,
5505  D6O_CLIENTID)) != NULL) &&
5506  evaluate_option_cache(&client_identifier, NULL,
5507  NULL, client,
5508  client->sent_options, NULL,
5509  &global_scope, oc, MDL)) {
5510  result = get_dhcid(ddns_cb, 2,
5511  client_identifier.data,
5512  client_identifier.len);
5513  data_string_forget(&client_identifier, MDL);
5514  } else
5515  log_fatal("Impossible condition at %s:%d.", MDL);
5516  } else {
5517  /*
5518  * V4 request, use the client id if there is one or the
5519  * mac address if there isn't. If we have a client id
5520  * we check to see if it is an embedded DUID.
5521  */
5522  if (((oc = lookup_option(&dhcp_universe,
5523  client->sent_options,
5524  DHO_DHCP_CLIENT_IDENTIFIER)) != NULL) &&
5525  evaluate_option_cache(&client_identifier, NULL,
5526  NULL, client,
5527  client->sent_options, NULL,
5528  &global_scope, oc, MDL)) {
5529  if ((std_dhcid == 1) && (duid_v4 == 1) &&
5530  (client_identifier.data[0] == 255)) {
5531  /*
5532  * This appears to be an embedded DUID,
5533  * extract it and treat it as such
5534  */
5535  if (client_identifier.len <= 5)
5536  log_fatal("Impossible condition at %s:%d.",
5537  MDL);
5538  result = get_dhcid(ddns_cb, 2,
5539  client_identifier.data + 5,
5540  client_identifier.len - 5);
5541  } else {
5542  result = get_dhcid(ddns_cb, ddns_v4_type,
5543  client_identifier.data,
5544  client_identifier.len);
5545  }
5546  data_string_forget(&client_identifier, MDL);
5547  } else
5548  result = get_dhcid(ddns_cb, 0,
5549  client->interface->hw_address.hbuf,
5550  client->interface->hw_address.hlen);
5551  }
5552 
5553  if (!result) {
5554  return ISC_R_SUCCESS;
5555  }
5556 
5557  /*
5558  * Perform updates.
5559  */
5560  if (ddns_cb->fwd_name.len && ddns_cb->dhcid.len) {
5561  rcode = ddns_modify_fwd(ddns_cb, MDL);
5562  } else
5563  rcode = ISC_R_FAILURE;
5564 
5565  /*
5566  * A success from the modify routine means we are performing
5567  * async processing, for which we use the timedout error message.
5568  */
5569  if (rcode == ISC_R_SUCCESS) {
5570  rcode = ISC_R_TIMEDOUT;
5571  }
5572 
5573  return rcode;
5574 }
5575 
5576 
5577 /*
5578  * Schedule the first update. They will continue to retry occasionally
5579  * until they no longer time out (or fail).
5580  */
5581 void
5583  struct iaddr *addr,
5584  int offset)
5585 {
5586  dhcp_ddns_cb_t *ddns_cb;
5587  struct timeval tv;
5588 
5589  if (!client->config->do_forward_update)
5590  return;
5591 
5592  /* cancel any outstanding ddns requests */
5593  if (client->ddns_cb != NULL) {
5594  ddns_cancel(client->ddns_cb, MDL);
5595  client->ddns_cb = NULL;
5596  }
5597 
5598  ddns_cb = ddns_cb_alloc(MDL);
5599 
5600  if (ddns_cb != NULL) {
5601  ddns_cb->lease = (void *)client;
5602  ddns_cb->address = *addr;
5603  ddns_cb->timeout = 1;
5604 
5605  /*
5606  * XXX: DNS TTL is a problem we need to solve properly.
5607  * Until that time, 300 is a placeholder default for
5608  * something that is less insane than a value scaled
5609  * by lease timeout.
5610  */
5611  ddns_cb->ttl = 300;
5612 
5613  ddns_cb->state = DDNS_STATE_ADD_FW_NXDOMAIN;
5614  ddns_cb->cur_func = client_dns_update_action;
5616 
5617  client->ddns_cb = ddns_cb;
5618  tv.tv_sec = cur_tv.tv_sec + offset;
5619  tv.tv_usec = cur_tv.tv_usec;
5621  ddns_cb, NULL, NULL);
5622  } else {
5623  log_error("Unable to allocate dns update state for %s",
5624  piaddr(*addr));
5625  }
5626 }
5627 #endif
5628 
5629 void
5631 {
5632  struct servent *ent;
5633 
5634  if (path_dhclient_pid == NULL)
5636  if (path_dhclient_db == NULL)
5638 
5639  /* Default to the DHCP/BOOTP port. */
5640  if (!local_port) {
5641  /* If we're faking a relay agent, and we're not using loopback,
5642  use the server port, not the client port. */
5643  if (mockup_relay && giaddr.s_addr != htonl(INADDR_LOOPBACK)) {
5644  local_port = htons(67);
5645  } else {
5646  ent = getservbyname("dhcpc", "udp");
5647  if (ent == NULL)
5648  ent = getservbyname("bootpc", "udp");
5649  if (ent == NULL)
5650  local_port = htons(68);
5651  else
5652  local_port = ent->s_port;
5653 #ifndef __CYGWIN32__
5654  endservent ();
5655 #endif
5656  }
5657  }
5658 
5659  /* If we're faking a relay agent, and we're not using loopback,
5660  we're using the server port, not the client port. */
5661  if (mockup_relay && giaddr.s_addr != htonl(INADDR_LOOPBACK)) {
5663  } else
5664  remote_port = htons(ntohs(local_port) - 1); /* XXX */
5665 }
5666 
5667 /*
5668  * The following routines are used to check that certain
5669  * strings are reasonable before we pass them to the scripts.
5670  * This avoids some problems with scripts treating the strings
5671  * as commands - see ticket 23722
5672  * The domain checking code should be done as part of assembling
5673  * the string but we are doing it here for now due to time
5674  * constraints.
5675  */
5676 
5677 static int check_domain_name(const char *ptr, size_t len, int dots)
5678 {
5679  const char *p;
5680 
5681  /* not empty or complete length not over 255 characters */
5682  if ((len == 0) || (len > 256))
5683  return(-1);
5684 
5685  /* consists of [[:alnum:]-]+ labels separated by [.] */
5686  /* a [_] is against RFC but seems to be "widely used"... */
5687  for (p=ptr; (*p != 0) && (len-- > 0); p++) {
5688  if ((*p == '-') || (*p == '_')) {
5689  /* not allowed at begin or end of a label */
5690  if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
5691  return(-1);
5692  } else if (*p == '.') {
5693  /* each label has to be 1-63 characters;
5694  we allow [.] at the end ('foo.bar.') */
5695  size_t d = p - ptr;
5696  if ((d <= 0) || (d >= 64))
5697  return(-1);
5698  ptr = p + 1; /* jump to the next label */
5699  if ((dots > 0) && (len > 0))
5700  dots--;
5701  } else if (isalnum((unsigned char)*p) == 0) {
5702  /* also numbers at the begin are fine */
5703  return(-1);
5704  }
5705  }
5706  return(dots ? -1 : 0);
5707 }
5708 
5709 static int check_domain_name_list(const char *ptr, size_t len, int dots)
5710 {
5711  const char *p;
5712  int ret = -1; /* at least one needed */
5713 
5714  if ((ptr == NULL) || (len == 0))
5715  return(-1);
5716 
5717  for (p=ptr; (*p != 0) && (len > 0); p++, len--) {
5718  if (*p != ' ')
5719  continue;
5720  if (p > ptr) {
5721  if (check_domain_name(ptr, p - ptr, dots) != 0)
5722  return(-1);
5723  ret = 0;
5724  }
5725  ptr = p + 1;
5726  }
5727  if (p > ptr)
5728  return(check_domain_name(ptr, p - ptr, dots));
5729  else
5730  return(ret);
5731 }
5732 
5733 static int check_option_values(struct universe *universe,
5734  unsigned int opt,
5735  const char *ptr,
5736  size_t len)
5737 {
5738  if (ptr == NULL)
5739  return(-1);
5740 
5741  /* just reject options we want to protect, will be escaped anyway */
5742  if ((universe == NULL) || (universe == &dhcp_universe)) {
5743  switch(opt) {
5744  case DHO_DOMAIN_NAME:
5745 #ifdef ACCEPT_LIST_IN_DOMAIN_NAME
5746  return check_domain_name_list(ptr, len, 0);
5747 #else
5748  return check_domain_name(ptr, len, 0);
5749 #endif
5750  case DHO_HOST_NAME:
5751  case DHO_NIS_DOMAIN:
5752  case DHO_NETBIOS_SCOPE:
5753  return check_domain_name(ptr, len, 0);
5754  break;
5755  case DHO_DOMAIN_SEARCH:
5756  return check_domain_name_list(ptr, len, 0);
5757  break;
5758  case DHO_ROOT_PATH:
5759  if (len == 0)
5760  return(-1);
5761  for (; (*ptr != 0) && (len-- > 0); ptr++) {
5762  if(!(isalnum((unsigned char)*ptr) ||
5763  *ptr == '#' || *ptr == '%' ||
5764  *ptr == '+' || *ptr == '-' ||
5765  *ptr == '_' || *ptr == ':' ||
5766  *ptr == '.' || *ptr == ',' ||
5767  *ptr == '@' || *ptr == '~' ||
5768  *ptr == '\\' || *ptr == '/' ||
5769  *ptr == '[' || *ptr == ']' ||
5770  *ptr == '=' || *ptr == ' '))
5771  return(-1);
5772  }
5773  return(0);
5774  break;
5775  }
5776  }
5777 
5778 #ifdef DHCPv6
5779  if (universe == &dhcpv6_universe) {
5780  switch(opt) {
5781  case D6O_SIP_SERVERS_DNS:
5782  case D6O_DOMAIN_SEARCH:
5783  case D6O_NIS_DOMAIN_NAME:
5784  case D6O_NISP_DOMAIN_NAME:
5785  return check_domain_name_list(ptr, len, 0);
5786  break;
5787  }
5788  }
5789 #endif
5790 
5791  return(0);
5792 }
5793 
5794 static void
5795 add_reject(struct packet *packet) {
5796  struct iaddrmatchlist *list;
5797 
5798  list = dmalloc(sizeof(struct iaddrmatchlist), MDL);
5799  if (!list)
5800  log_fatal ("no memory for reject list!");
5801 
5802  /*
5803  * client_addr is misleading - it is set to source address in common
5804  * code.
5805  */
5806  list->match.addr = packet->client_addr;
5807  /* Set mask to indicate host address. */
5808  list->match.mask.len = list->match.addr.len;
5809  memset(list->match.mask.iabuf, 0xff, sizeof(list->match.mask.iabuf));
5810 
5811  /* Append to reject list for the source interface. */
5814 
5815  /*
5816  * We should inform user that we won't be accepting this server
5817  * anymore.
5818  */
5819  log_info("Server added to list of rejected servers.");
5820 }
5821 
5822 /* Wrapper function around common ddns_cb_free function that ensures
5823  * we set the client_state pointer to the control block to NULL. */
5824 static void
5825 dhclient_ddns_cb_free(dhcp_ddns_cb_t *ddns_cb, char* file, int line) {
5826  if (ddns_cb) {
5827  struct client_state *client = (struct client_state *)ddns_cb->lease;
5828  if (client != NULL) {
5829  client->ddns_cb = NULL;
5830  }
5831 
5833  }
5834 }
5835 
5836 #if defined(DHCPv6) && defined(DHCP4o6)
5837 /*
5838  * \brief Omapi I/O handler
5839  *
5840  * The inter-process communication receive handler.
5841  *
5842  * On the DHCPv6 side, the message is either a POLL (which is answered
5843  * by a START or a STOP) or a DHCPv4-QUERY (which is forwarded to
5844  * DHCPv4 over DHCPv6 servers by forw_dhcpv4_query()).
5845  *
5846  * On the DHCPv4 side, the message is either a START, a STOP
5847  * (both for the DHCP4 over DHCPv6 state machine) or a DHCPv4-RESPONSE
5848  * (which is processed by recv_dhcpv4_response()).
5849  *
5850  * \param h the OMAPI object
5851  * \return a result for I/O success or error (used by the I/O subsystem)
5852  */
5853 isc_result_t dhcpv4o6_handler(omapi_object_t *h) {
5854  char buf[65536];
5855  char start_msg[5] = { 'S', 'T', 'A', 'R', 'T' };
5856  char stop_msg[4] = { 'S', 'T', 'O', 'P' };
5857  char poll_msg[4] = { 'P', 'O', 'L', 'L' };
5858  struct data_string raw;
5859  int cc;
5860 
5861  if (h->type != dhcp4o6_type)
5862  return DHCP_R_INVALIDARG;
5863 
5864  cc = recv(dhcp4o6_fd, buf, sizeof(buf), 0);
5865  if (cc <= 0)
5866  return ISC_R_UNEXPECTED;
5867 
5868  if (local_family == AF_INET6) {
5869  if ((cc == 4) &&
5870  (memcmp(buf, poll_msg, sizeof(poll_msg)) == 0)) {
5871  log_info("RCV: POLL");
5872  if (dhcp4o6_state < 0)
5873  cc = send(dhcp4o6_fd, stop_msg,
5874  sizeof(stop_msg), 0);
5875  else
5876  cc = send(dhcp4o6_fd, start_msg,
5877  sizeof(start_msg), 0);
5878  if (cc < 0) {
5879  log_error("dhcpv4o6_handler: send(): %m");
5880  return ISC_R_IOERROR;
5881  }
5882  } else {
5883  if (cc < DHCP_FIXED_NON_UDP + 8)
5884  return ISC_R_UNEXPECTED;
5885  memset(&raw, 0, sizeof(raw));
5886  if (!buffer_allocate(&raw.buffer, cc, MDL)) {
5887  log_error("dhcpv4o6_handler: "
5888  "no memory buffer.");
5889  return ISC_R_NOMEMORY;
5890  }
5891  raw.data = raw.buffer->data;
5892  raw.len = cc;
5893  memcpy(raw.buffer->data, buf, cc);
5894 
5895  forw_dhcpv4_query(&raw);
5896 
5897  data_string_forget(&raw, MDL);
5898  }
5899  } else {
5900  if ((cc == 4) &&
5901  (memcmp(buf, stop_msg, sizeof(stop_msg)) == 0)) {
5902  log_info("RCV: STOP");
5903  if (dhcp4o6_state > 0) {
5904  dhcp4o6_state = 0;
5905  dhcp4o6_poll(NULL);
5906  }
5907  } else if ((cc == 5) &&
5908  (memcmp(buf, start_msg, sizeof(start_msg)) == 0)) {
5909  log_info("RCV: START");
5910  if (dhcp4o6_state == 0)
5911  cancel_timeout(dhcp4o6_poll, NULL);
5912  dhcp4o6_state = 1;
5913  dhcp4o6_resume();
5914  } else {
5915  if (cc < DHCP_FIXED_NON_UDP + 16)
5916  return ISC_R_UNEXPECTED;
5917  memset(&raw, 0, sizeof(raw));
5918  if (!buffer_allocate(&raw.buffer, cc, MDL)) {
5919  log_error("dhcpv4o6_handler: "
5920  "no memory buffer.");
5921  return ISC_R_NOMEMORY;
5922  }
5923  raw.data = raw.buffer->data;
5924  raw.len = cc;
5925  memcpy(raw.buffer->data, buf, cc);
5926 
5927  recv_dhcpv4_response(&raw);
5928 
5929  data_string_forget(&raw, MDL);
5930  }
5931  }
5932 
5933  return ISC_R_SUCCESS;
5934 }
5935 
5936 /*
5937  * \brief Poll the DHCPv6 client
5938  * (DHCPv4 client function)
5939  *
5940  * A POLL message is sent to the DHCPv6 client periodically to check
5941  * if the DHCPv6 is ready (i.e., has a valid DHCPv4-over-DHCPv6 server
5942  * address option).
5943  */
5944 static void dhcp4o6_poll(void *dummy) {
5945  char msg[4] = { 'P', 'O', 'L', 'L' };
5946  struct timeval tv;
5947  int cc;
5948 
5949  IGNORE_UNUSED(dummy);
5950 
5951  if (dhcp4o6_state < 0)
5952  dhcp4o6_state = 0;
5953 
5954  log_info("POLL");
5955 
5956  cc = send(dhcp4o6_fd, msg, sizeof(msg), 0);
5957  if (cc < 0)
5958  log_error("dhcp4o6_poll: send(): %m");
5959 
5960  tv.tv_sec = cur_time + 60;
5961  tv.tv_usec = random() % 1000000;
5962 
5963  add_timeout(&tv, dhcp4o6_poll, NULL, 0, 0);
5964 }
5965 
5966 /*
5967  * \brief Resume pending operations
5968  * (DHCPv4 client function)
5969  *
5970  * A START message was received from the DHCPv6 client so pending
5971  * operations (RELEASE or REBOOT) must be resumed.
5972  */
5973 static void dhcp4o6_resume() {
5974  struct interface_info *ip;
5975  struct client_state *client;
5976 
5977  for (ip = interfaces; ip != NULL; ip = ip->next) {
5978  for (client = ip->client; client != NULL;
5979  client = client->next) {
5980  if (client->pending == P_RELEASE)
5981  do_release(client);
5982  else if (client->pending == P_REBOOT)
5983  state_reboot(client);
5984  }
5985  }
5986 }
5987 
5988 /*
5989  * \brief Send a START to the DHCPv4 client
5990  * (DHCPv6 client function)
5991  *
5992  * First check if there is a valid DHCPv4-over-DHCPv6 server address option,
5993  * and when found go UP and on a transition from another state send
5994  * a START message to the DHCPv4 client.
5995  */
5996 void dhcp4o6_start() {
5997  struct interface_info *ip;
5998  struct client_state *client;
5999  struct dhc6_lease *lease;
6000  struct option_cache *oc;
6001  struct data_string addrs;
6002  char msg[5] = { 'S', 'T', 'A', 'R', 'T' };
6003  int cc;
6004 
6005  memset(&addrs, 0, sizeof(addrs));
6006  for (ip = interfaces; ip != NULL; ip = ip->next) {
6007  for (client = ip->client; client != NULL;
6008  client = client->next) {
6009  if ((client->state != S_BOUND) &&
6010  (client->state != S_RENEWING) &&
6011  (client->state != S_REBINDING))
6012  continue;
6013  lease = client->active_lease;
6014  if ((lease == NULL) || lease->released)
6015  continue;
6017  lease->options,
6019  if ((oc == NULL) ||
6020  !evaluate_option_cache(&addrs, NULL, NULL, NULL,
6021  lease->options, NULL,
6022  &global_scope, oc, MDL))
6023  continue;
6024  if ((addrs.len % 16) != 0) {
6025  data_string_forget(&addrs, MDL);
6026  continue;
6027  }
6028  data_string_forget(&addrs, MDL);
6029  goto found;
6030  }
6031  }
6032  log_info("dhcp4o6_start: failed");
6033  dhcp4o6_stop();
6034  return;
6035 
6036 found:
6037  if (dhcp4o6_state == 1)
6038  return;
6039  log_info("dhcp4o6_start: go to UP");
6040  dhcp4o6_state = 1;
6041 
6042  cc = send(dhcp4o6_fd, msg, sizeof(msg), 0);
6043  if (cc < 0)
6044  log_info("dhcp4o6_start: send(): %m");
6045 }
6046 
6047 /*
6048  * Send a STOP to the DHCPv4 client
6049  * (DHCPv6 client function)
6050  *
6051  * Go DOWN and on a transition from another state send a STOP message
6052  * to the DHCPv4 client.
6053  */
6054 static void dhcp4o6_stop() {
6055  char msg[4] = { 'S', 'T', 'O', 'P' };
6056  int cc;
6057 
6058  if (dhcp4o6_state == -1)
6059  return;
6060 
6061  log_info("dhcp4o6_stop: go to DOWN");
6062  dhcp4o6_state = -1;
6063 
6064  cc = send(dhcp4o6_fd, msg, sizeof(msg), 0);
6065  if (cc < 0)
6066  log_error("dhcp4o6_stop: send(): %m");
6067 }
6068 #endif /* DHCPv6 && DHCP4o6 */
#define BOOTREPLY
Definition: dhcp.h:70
void do_packet6(struct interface_info *, const char *, int, int, const struct iaddr *, isc_boolean_t)
void state_selecting(void *cpp)
Definition: dhclient.c:1595
#define DHCP_FIXED_NON_UDP
Definition: dhcp.h:37
#define _PATH_DHCLIENT_CONF
Definition: dhcpd.h:1557
void(* dhcpv6_packet_handler)(struct interface_info *, const char *, int, int, const struct iaddr *, isc_boolean_t)
void send_discover(void *cpp)
Definition: dhclient.c:2684
void unbill_class(struct lease *lease)
Definition: dhclient.c:1442
struct client_lease * alias
Definition: dhcpd.h:1284
#define IGNORE_UNUSED(x)
Definition: cdefs.h:68
int parse_encapsulated_suboptions(struct option_state *options, struct option *eopt, const unsigned char *buffer, unsigned len, struct universe *eu, const char *uname)
Definition: options.c:318
isc_result_t omapi_protocol_listen(omapi_object_t *, unsigned, int)
Definition: protocol.c:998
TIME interval
Definition: dhcpd.h:1290
const char int line
Definition: dhcpd.h:3724
u_int8_t plen
Definition: dhcpd.h:1132
struct binding_scope * global_scope
Definition: tree.c:38
struct dns_zone * zone
Definition: dhcpd.h:1786
#define _PATH_DHCLIENT_PID
Definition: config.h:250
struct universe * universe
Definition: tree.h:349
int interfaces_requested
Definition: dhclient.c:69
void make_client_options(struct client_state *client, struct client_lease *lease, u_int8_t *type, struct option_cache *sid, struct iaddr *rip, struct option **prl, struct option_state **op)
Definition: dhclient.c:3407
struct group * on_receipt
Definition: dhcpd.h:1203
unsigned char dhcpv6_transaction_id[3]
Definition: dhcpd.h:1298
Definition: dhcpd.h:556
#define _PATH_DHCLIENT_SCRIPT
Definition: dhcpd.h:1561
void save_option(struct universe *universe, struct option_state *options, struct option_cache *oc)
Definition: options.c:2764
unsigned len
Definition: tree.h:80
struct client_lease * new
Definition: dhcpd.h:1281
void do_release(struct client_state *client)
Definition: dhclient.c:4964
const char * piaddr(const struct iaddr addr)
Definition: inet.c:579
u_int8_t hlen
Definition: dhcpd.h:489
void rewrite_client_leases()
Definition: dhclient.c:3843
#define FQDN_NO_CLIENT_UPDATE
Definition: dhcp.h:193
#define DHO_DOMAIN_SEARCH
Definition: dhcp.h:164
int do_forward_update
Definition: dhcpd.h:1252
#define DDNS_STATE_ADD_FW_NXDOMAIN
Definition: dhcpd.h:1754
dhcp_state
Definition: dhcpd.h:1174
void dhcpoffer(struct packet *packet)
Definition: dhclient.c:2347
int no_daemon
Definition: dhclient.c:97
u_int32_t renew
Definition: dhcpd.h:1152
unsigned char dhcpv6_transaction_id[3]
Definition: dhcpd.h:414
char name[IFNAMSIZ]
Definition: dhcpd.h:1375
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:149
void dhcpnak(struct packet *packet)
Definition: dhclient.c:2605
int get_dhcid(dhcp_ddns_cb_t *, int, const u_int8_t *, unsigned)
isc_result_t end_parse(struct parse **cfile)
Definition: conflex.c:103
const char * path_dhclient_db
Definition: dhclient.c:58
void(* bootp_packet_handler)(struct interface_info *, struct dhcp_packet *, unsigned, unsigned int, struct iaddr, struct hardware *)
Definition: discover.c:58
#define All_DHCP_Relay_Agents_and_Servers
Definition: dhcp6.h:187
Definition: dhcpd.h:1188
#define DDNS_UPDATE_ADDR
Definition: dhcpd.h:1739
int tag_size
Definition: tree.h:335
void start_release6(struct client_state *client)
char * piaddrmask(struct iaddr *addr, struct iaddr *mask)
Definition: inet.c:606
int option_cache_dereference(struct option_cache **ptr, const char *file, int line)
Definition: options.c:2899
enum dhcp_token token
Definition: dhcpd.h:320
int stateless
Definition: dhclient.c:103
int duid_type
Definition: dhclient.c:77
void start_info_request6(struct client_state *client)
Definition: dhcpd.h:1044
TIME first_sending
Definition: dhcpd.h:1289
void send_decline(void *cpp)
Definition: dhclient.c:3130
#define STDERR_FILENO
Definition: osdep.h:288
#define HTYPE_RESERVED
Definition: dhcp.h:84
void client_dns_update_timeout(void *cp)
#define MDL
Definition: omapip.h:568
void cancel_timeout(void(*)(void *) where, void *what)
Definition: dispatch.c:381
unsigned char iabuf[16]
Definition: inet.h:33
#define print_hex_1(len, data, limit)
Definition: dhcpd.h:2576
Definition: dhcpd.h:1176
#define DHO_DHCP_PARAMETER_REQUEST_LIST
Definition: dhcp.h:147
FILE * leaseFile
Definition: dhclient.c:3840
int lease_id_format
Definition: dhcpd.h:1256
int dhcp_max_agent_option_packet_length
Definition: dhclient.c:67
struct client_lease * packet_to_lease(struct packet *packet, struct client_state *client)
Definition: dhclient.c:2482
#define DHCP_R_INVALIDARG
Definition: result.h:48
struct group * on_transmission
Definition: dhcpd.h:1208
#define DISCOVER_REQUESTED
Definition: dhcpd.h:697
#define DHCP_SNAME_LEN
Definition: dhcp.h:35
#define DHO_NIS_DOMAIN
Definition: dhcp.h:132
int script_go(struct client_state *client)
Calls external script.
Definition: dhclient.c:4703
struct iaddr requested_address
Definition: dhcpd.h:1295
const char * dhcpv6_type_names[]
Definition: tables.c:656
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
int write_client_lease(struct client_state *client, struct client_lease *lease, int rewrite, int makesure)
Definition: dhclient.c:4303
struct client_state * client
Definition: dhcpd.h:1398
#define DHCPV6_REPLY
Definition: dhcp6.h:144
int can_receive_unicast_unconfigured(struct interface_info *)
struct iaddr iaddr_broadcast
Definition: dhclient.c:71
void reinitialize_interfaces()
Definition: discover.c:1024
FILE * scriptFile
Definition: dhclient.c:4445
unsigned char msg_type
Definition: dhcp6.h:250
#define DHCPV6_RECONFIGURE
Definition: dhcp6.h:147
struct client_state * next
Definition: dhcpd.h:1266
#define DHCP_CONTEXT_PRE_DB
Definition: isclib.h:130
#define DHO_DHCP_LEASE_TIME
Definition: dhcp.h:143
void dhcpack(struct packet *packet)
Definition: dhclient.c:1680
unsigned cons_agent_information_options(struct option_state *cfg_options, struct dhcp_packet *outpacket, unsigned agentix, unsigned length)
Definition: dhclient.c:5154
struct universe dhcp_universe
int wanted_ia_pd
Definition: dhclient.c:106
struct option_state * options
Definition: dhcpd.h:1143
int dhcpv4_over_dhcpv6
Definition: discover.c:47
dhcp_ddns_cb_t * ddns_cb_alloc(const char *file, int line)
void data_string_forget(struct data_string *data, const char *file, int line)
Definition: alloc.c:1339
void bootp(struct packet *packet)
Definition: dhclient.c:2027
#define DHCPACK
Definition: dhcp.h:176
int duid_v4
Definition: dhclient.c:78
const char * pretty_print_option(struct option *option, const unsigned char *data, unsigned len, int emit_commas, int emit_quotes)
Definition: options.c:1769
#define DHO_SUBNET_MASK
Definition: dhcp.h:93
#define INTERFACE_RUNNING
Definition: dhcpd.h:1392
struct dhc6_ia * next
Definition: dhcpd.h:1147
#define DHO_ROOT_PATH
Definition: dhcp.h:109
#define DUID_LL
Definition: dhcp6.h:167
#define BOOTP_BROADCAST
Definition: dhcp.h:73
TIME last_write
Definition: dhcpd.h:1276
void send_release(void *cpp)
Definition: dhclient.c:3169
int log_error(const char *,...) __attribute__((__format__(__printf__
int address_prefix_len
Definition: dhclient.c:117
struct string_list * client_env
Definition: dhclient.c:98
#define DDNS_INCLUDE_RRSET
Definition: dhcpd.h:1741
struct in_addr siaddr
Definition: dhcp.h:58
void client_envadd(struct client_state *client, const char *prefix, const char *name, const char *fmt,...)
Definition: dhclient.c:4783
void add_timeout(struct timeval *when, void(*)(void *) where, void *what, tvref_t ref, tvunref_t unref)
Definition: dispatch.c:197
void dump_packet(struct packet *)
TIME initial_delay
Definition: dhcpd.h:1216
#define DDNS_STATE_REM_FW_YXDHCID
Definition: dhcpd.h:1758
#define DHO_DHCP_REBINDING_TIME
Definition: dhcp.h:151
#define DHO_NETBIOS_SCOPE
Definition: dhcp.h:139
unsigned len
Definition: inet.h:32
struct iaddr destination
Definition: dhcpd.h:1286
TIME backoff_cutoff
Definition: dhcpd.h:1230
#define DHCPV6_DHCPV4_QUERY
Definition: dhcp6.h:157
char scriptName[256]
Definition: dhclient.c:4444
#define D6O_DHCPV4_MSG
Definition: dhcp6.h:116
void dhcp4o6_start(void)
unsigned char flags[3]
Definition: dhcp6.h:251
const char * path_dhclient_duid
Definition: dhclient.c:62
enum dhcp_token peek_token(const char **rval, unsigned *rlen, struct parse *cfile)
Definition: conflex.c:443
struct data_string fwd_name
Definition: dhcpd.h:1774
void write_client_pid_file()
Definition: dhclient.c:4903
#define D6O_CLIENTID
Definition: dhcp6.h:30
void state_panic(void *cpp)
Definition: dhclient.c:2814
#define DHO_DOMAIN_NAME
Definition: dhcp.h:107
#define DHCPRELEASE
Definition: dhcp.h:178
void forget_zone(struct dns_zone **)
struct data_string default_duid
Definition: dhclient.c:76
char * filename
Definition: dhcpd.h:1117
struct option_state * options
Definition: dhcpd.h:449
#define BOOTP_MIN_LEN
Definition: dhcp.h:40
Definition: dhcpd.h:288
void ddns_cb_free(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
struct iaddr address
Definition: dhcpd.h:1777
unsigned long ttl
Definition: dhcpd.h:1780
Definition: tree.h:302
void do_packet(struct interface_info *interface, struct dhcp_packet *packet, unsigned len, unsigned int from_port, struct iaddr from, struct hardware *hfrom)
Definition: options.c:3993
void dispatch(void)
Definition: dispatch.c:109
#define DHCP_LOG_OPTIONS
Definition: dhcpd.h:1602
#define D6O_NIS_DOMAIN_NAME
Definition: dhcp6.h:58
void * lease
Definition: dhcpd.h:1796
unsigned char dhcpv6_msg_type
Definition: dhcpd.h:411
unsigned char iaid[4]
Definition: dhcpd.h:1148
#define DHO_DHCP_SERVER_IDENTIFIER
Definition: dhcp.h:146
void log_fatal(const char *,...) __attribute__((__format__(__printf__
int client_port
Definition: dhcpd.h:431
void(* v6_handler)(struct packet *, struct client_state *)
Definition: dhcpd.h:1324
#define D6O_IA_TA
Definition: dhcp6.h:33
#define DHCP_CONTEXT_POST_DB
Definition: isclib.h:131
enum dhcp_pending pending
Definition: dhcpd.h:1277
isc_result_t form_duid(struct data_string *duid, const char *file, int line)
Definition: dhclient.c:4029
struct executable_statement * statements
Definition: dhcpd.h:939
void state_init(void *cpp)
Definition: dhclient.c:1558
#define INTERFACE_AUTOMATIC
Definition: dhcpd.h:1391
struct data_string dhcid
Definition: dhcpd.h:1776
int option_state_reference(struct option_state **ptr, struct option_state *bp, const char *file, int line)
Definition: alloc.c:883
struct dhcp_packet * raw
Definition: dhcpd.h:406
#define MIN_LEASE_WRITE
Definition: dhcpd.h:850
struct option * default_requested_options[]
Definition: clparse.c:36
void read_client_leases()
Definition: clparse.c:366
struct iaddr subnet_number(struct iaddr addr, struct iaddr mask)
Definition: inet.c:34
u_int16_t validate_port(char *port)
Definition: inet.c:659
void dhcp_signal_handler(int signal)
Definition: isclib.c:337
int find_subnet(struct subnet **sp, struct iaddr addr, const char *file, int line)
Definition: dhclient.c:1447
void execute_statements_in_scope(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct group *group, struct group *limiting_group, struct on_star *on_star)
Definition: execute.c:563
void make_request(struct client_state *client, struct client_lease *lease)
Definition: dhclient.c:3622
char * name
Definition: dhcpd.h:1268
#define DUID_TIME_EPOCH
Definition: dhcp6.h:273
struct interface_info * fallback_interface
Definition: discover.c:42
isc_result_t dhclient_interface_startup_hook(struct interface_info *interface)
Definition: dhclient.c:5092
unsigned packet_length
Definition: dhcpd.h:1293
int option_state_allocate(struct option_state **ptr, const char *file, int line)
Definition: alloc.c:846
const char * path_dhclient_pid
Definition: dhclient.c:59
struct iaddrmatchlist * next
Definition: inet.h:61
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:4490
isc_result_t dhcp_context_create(int flags, struct in_addr *local4, struct in6_addr *local6)
Definition: isclib.c:138
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:2699
TIME expiry
Definition: dhcpd.h:1114
#define DHCPV6_DHCPV4_RESPONSE
Definition: dhcp6.h:158
Definition: tree.h:346
int write_host(struct host_decl *host)
Definition: dhclient.c:2016
struct option_state * options
Definition: dhcpd.h:1124
#define DHCPNAK
Definition: dhcp.h:177
struct option ** requested_options
Definition: dhcpd.h:1211
void classify(struct packet *packet, struct class *class)
Definition: dhclient.c:1436
int require_all_ias
Definition: dhclient.c:107
void script_init(struct client_state *client, const char *reason, struct string_list *medium)
Initializes basic variables for a script.
Definition: dhclient.c:4459
#define DHCP_MAX_OPTION_LEN
Definition: dhcp.h:45
int main(int argc, char **argv)
Definition: dhclient.c:210
int options_valid
Definition: dhcpd.h:430
void(* store_length)(unsigned char *, u_int32_t)
Definition: tree.h:334
dns_rdataclass_t dhcid_class
Definition: dhcpd.h:1802
void make_decline(struct client_state *client, struct client_lease *lease)
Definition: dhclient.c:3712
#define HTYPE_INFINIBAND
Definition: dhcp.h:79
#define DHCP_DNS_CLIENT_LAZY_INIT
Definition: isclib.h:132
void bind_lease(struct client_state *client)
Definition: dhclient.c:1857
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
Definition: alloc.c:679
#define DHO_BROADCAST_ADDRESS
Definition: dhcp.h:120
TIME timeout
Definition: dhcpd.h:1789
struct option_cache * option
Definition: statement.h:66
struct interface_info * interface
Definition: dhcpd.h:433
isc_result_t read_uuid(u_int8_t *uuid)
Definition: dhclient.c:3976
unsigned code
Definition: tree.h:350
ssize_t send_packet6(struct interface_info *, const unsigned char *, size_t, struct sockaddr_in6 *)
int write_lease(struct lease *lease)
Definition: dhclient.c:2010
struct group * next
Definition: dhcpd.h:932
void putULong(unsigned char *, u_int32_t)
Definition: convert.c:70
const char * prefix
Definition: dhcpd.h:1337
u_int16_t local_port
Definition: dhclient.c:92
Definition: dhcpd.h:405
void run_stateless(int exit_mode, u_int16_t port)
Definition: dhclient.c:1305
void send_request(void *cpp)
Definition: dhclient.c:2931
isc_result_t omapi_generic_new(omapi_object_t **, const char *, int)
#define D6O_DOMAIN_SEARCH
Definition: dhcp6.h:53
struct in_addr yiaddr
Definition: dhcp.h:57
#define cur_time
Definition: dhcpd.h:2078
struct iaddr iaddr_any
Definition: dhclient.c:72
int quiet
Definition: dhclient.c:101
Definition: ip.h:47
ssize_t send_packet(struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)
int cons_options(struct packet *inpacket, struct dhcp_packet *outpacket, struct lease *lease, struct client_state *client_state, int mms, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, int overload_avail, int terminate, int bootpp, struct data_string *prl, const char *vuname)
Definition: options.c:519
void start_confirm6(struct client_state *client)
struct in_addr giaddr
Definition: dhclient.c:75
void dfree(void *, const char *, int)
Definition: alloc.c:145
isc_boolean_t no_pid_file
Definition: dhclient.c:65
u_int32_t max_life
Definition: dhcpd.h:1141
struct client_lease * next
Definition: dhcpd.h:1113
void ddns_cancel(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
#define FQDN_FQDN
Definition: dhcp.h:200
const char * name
Definition: tree.h:347
struct option_state * sent_options
Definition: dhcpd.h:1274
#define DISCOVER_RUNNING
Definition: dhcpd.h:692
const char * path_dhclient_conf
Definition: dhclient.c:57
#define BOOTREQUEST
Definition: dhcp.h:69
struct hardware hw_address
Definition: dhcpd.h:1353
int packet_type
Definition: dhcpd.h:409
char * mockup_relay
Definition: dhclient.c:111
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
Definition: options.c:2449
#define DHCPDECLINE
Definition: dhcp.h:175
int dhclient_interface_discovery_hook(struct interface_info *tmp)
Definition: dhclient.c:5049
struct client_state * client
Definition: dhcpd.h:1336
struct option_state * options
Definition: dhcpd.h:1156
int omapi_port
Definition: dhcpd.h:1249
struct option * option
Definition: dhcpd.h:389
int unhexchar(char c)
Definition: dhclient.c:3961
int asprintf(char **strp, const char *fmt,...)
control_object_state_t
Definition: dhcpd.h:519
int int log_info(const char *,...) __attribute__((__format__(__printf__
int bootp_broadcast_always
Definition: dhclient.c:115
enum dhcp_state state
Definition: dhcpd.h:1275
u_int16_t validate_port_pair(char *port)
Definition: inet.c:685
void * dmalloc(size_t, const char *, int)
Definition: alloc.c:57
int parse_options(struct packet *packet)
Definition: options.c:47
struct interface_info * interfaces
Definition: discover.c:42
void free_client_lease(struct client_lease *lease, const char *file, int line)
Definition: alloc.c:369
#define _PATH_DHCLIENT_DB
Definition: config.h:247
u_int32_t flags
Definition: dhcpd.h:1389
u_int32_t getULong(const unsigned char *)
int validate_packet(struct packet *packet)
Definition: options.c:4429
struct client_config top_level_config
Definition: clparse.c:32
struct iaddr broadcast_addr(struct iaddr subnet, struct iaddr mask)
Definition: inet.c:112
#define DHCPDISCOVER
Definition: dhcp.h:172
u_int32_t rebind
Definition: dhcpd.h:1153
struct option ** required_options
Definition: dhcpd.h:1210
struct dhc6_addr * addrs
Definition: dhcpd.h:1154
union executable_statement::@7 data
void state_reboot(void *cpp)
Definition: dhclient.c:1505
int check_collection(struct packet *packet, struct lease *lease, struct collection *collection)
Definition: dhclient.c:1428
void destroy_client_lease(struct client_lease *lease)
Definition: dhclient.c:3829
void db_startup(int testp)
Definition: dhclient.c:2022
int parse_agent_information_option(struct packet *packet, int len, u_int8_t *data)
Definition: dhclient.c:5144
TIME retry_interval
Definition: dhcpd.h:1220
#define ASSERT_STATE(state_is, state_shouldbe)
Definition: dhclient.c:83
int std_dhcid
Definition: dhclient.c:79
char * path_dhclient_script
Definition: dhclient.c:61
void parse_client_statement(struct parse *cfile, struct interface_info *ip, struct client_config *config)
Definition: clparse.c:435
struct universe ** universes
Definition: tables.c:963
Definition: inet.h:31
#define DHCP4O6_QUERY_UNICAST
Definition: dhcp6.h:254
TIME max_lease_time
Definition: dhclient.c:55
int local_family
Definition: discover.c:55
int shutdown_signal
Definition: isclib.c:34
int quiet_interface_discovery
Definition: discover.c:44
isc_result_t(* dhcp_interface_startup_hook)(struct interface_info *)
Definition: discover.c:50
#define DISCOVER_UNCONFIGURED
Definition: dhcpd.h:694
struct client_lease * active
Definition: dhcpd.h:1280
isc_result_t client_dns_update(struct client_state *client, dhcp_ddns_cb_t *ddns_cb)
const char * format
Definition: tree.h:348
u_int32_t preferred_life
Definition: dhcpd.h:1140
int option_state_dereference(struct option_state **ptr, const char *file, int line)
Definition: alloc.c:911
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:3737
Definition: dhcpd.h:931
struct dhc6_addr * next
Definition: dhcpd.h:1130
void initialize_common_option_spaces()
Definition: tables.c:1049
void make_discover(struct client_state *client, struct client_lease *lease)
Definition: dhclient.c:3557
int leases_written
Definition: dhclient.c:3841
void dhcpv6(struct packet *)
struct timeval cur_tv
Definition: dispatch.c:35
ddns_action_t cur_func
Definition: dhcpd.h:1791
void unconfigure6(struct client_state *client, const char *reason)
void client_dns_remove(struct client_state *client, struct iaddr *addr)
const int dhcpv6_type_name_max
Definition: tables.c:680
int addr_match(struct iaddr *addr, struct iaddrmatch *match)
Definition: inet.c:184
struct dhcp_packet packet
Definition: dhcpd.h:1292
void state_bound(void *cpp)
Definition: dhclient.c:1939
struct interface_info * next
Definition: dhcpd.h:1350
struct universe dhcpv6_universe
Definition: tables.c:343
struct iaddr addr
Definition: inet.h:54
int evaluate_boolean_option_cache(int *ignorep, 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:2733
#define D6O_IA_NA
Definition: dhcp6.h:32
#define DHCLIENT_DEFAULT_PREFIX_LEN
Definition: site.h:289
#define TIME_MAX
Definition: osdep.h:83
int packet_dereference(struct packet **ptr, const char *file, int line)
Definition: alloc.c:1081
int packet_allocate(struct packet **ptr, const char *file, int line)
Definition: alloc.c:1015
int warnings_occurred
Definition: dhcpd.h:326
struct host_decl * host
Definition: dhcpd.h:572
void make_release(struct client_state *client, struct client_lease *lease)
Definition: dhclient.c:3772
struct string_list * next
Definition: dhcpd.h:348
TIME initial_interval
Definition: dhcpd.h:1218
const char int
Definition: omapip.h:443
#define DHCPV6_ADVERTISE
Definition: dhcp6.h:139
int onetry
Definition: dhclient.c:100
void read_client_duid()
Definition: clparse.c:330
isc_result_t read_client_conf()
Definition: clparse.c:55
struct interface_info * dummy_interfaces
Definition: discover.c:42
isc_result_t find_class(struct class **c, const char *s, const char *file, int line)
Definition: dhclient.c:1422
void script_write_requested(struct client_state *client)
Write out the environent variable the client requested. Write out the environment variables for the o...
Definition: dhclient.c:4673
int universe_count
Definition: dhcpd.h:398
char * progname
Definition: dhclient.c:113
time_t TIME
Definition: dhcpd.h:85
char string[1]
Definition: dhcpd.h:349
#define FQDN_SERVER_UPDATE
Definition: dhcp.h:194
char * script_name
Definition: dhcpd.h:1236
struct client_lease * new_client_lease(char *file, int line) const
Definition: alloc.c:361
int commit_leases()
Definition: dhclient.c:2005
unsigned char data[1]
Definition: tree.h:63
Definition: tree.h:61
#define DHCP_FILE_LEN
Definition: dhcp.h:36
u_int32_t xid
Definition: dhcpd.h:1287
int length_size
Definition: tree.h:335
int state
Definition: dhcpd.h:1790
#define DDNS_STATE_ADD_FW_YXDHCID
Definition: dhcpd.h:1755
#define D6O_DHCP4_O_DHCP6_SERVER
Definition: dhcp6.h:117
void dhcpv4_client_assignments(void)
Definition: dhclient.c:5630
TIME renewal
Definition: dhcpd.h:1114
struct iaddr address
Definition: dhcpd.h:1131
struct iaddr mask
Definition: inet.h:55
void dhcpv6_client_assignments(void)
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
Definition: dhcpd.h:490
struct iaddrmatchlist * reject_list
Definition: dhcpd.h:1247
struct string_list * medium
Definition: dhcpd.h:1118
int wanted_ia_na
Definition: dhclient.c:104
struct client_config * config
Definition: dhcpd.h:1271
int wanted_ia_ta
Definition: dhclient.c:105
u_int16_t flags
Definition: dhcpd.h:1788
struct iaddrmatch match
Definition: inet.h:62
#define D6O_SIP_SERVERS_DNS
Definition: dhcp6.h:50
struct sockaddr_in sockaddr_broadcast
Definition: dhclient.c:74
struct iaddr client_addr
Definition: dhcpd.h:432
void dhclient_schedule_updates(struct client_state *client, struct iaddr *addr, int offset)
#define DHCPREQUEST
Definition: dhcp.h:174
TIME rebind
Definition: dhcpd.h:1114
#define PACKAGE_VERSION
Definition: config.h:168
int dhcp_option_ev_name(char *buf, size_t buflen, struct option *option)
Definition: dhclient.c:4821
#define D6O_IA_PD
Definition: dhcp6.h:54
int(* dhcp_interface_discovery_hook)(struct interface_info *)
Definition: discover.c:49
void go_daemon()
Definition: dhclient.c:4861
struct in_addr inaddr_any
Definition: dhclient.c:73
struct universe fqdn_universe
Definition: tables.c:310
#define DUID_LLT
Definition: dhcp6.h:165
void dhcp(struct packet *packet)
Definition: dhclient.c:2060
#define DHO_DHCP_OPTION_OVERLOAD
Definition: dhcp.h:144
#define D6O_NISP_DOMAIN_NAME
Definition: dhcp6.h:59
option_code_hash_t * code_hash
Definition: tree.h:338
int nowait
Definition: dhclient.c:102
u_int16_t remote_port
Definition: dhclient.c:93
#define DHO_DHCP_RENEWAL_TIME
Definition: dhcp.h:150
struct iaddr address
Definition: dhcpd.h:1115
struct string_list * medium
Definition: dhcpd.h:1291
unsigned int is_bootp
Definition: dhcpd.h:1122
const char * file
Definition: dhcpd.h:3724
#define DHO_DHCP_CLIENT_IDENTIFIER
Definition: dhcp.h:153
struct dhcp_ddns_cb * ddns_cb
Definition: dhcpd.h:1332
void putUShort(unsigned char *, u_int32_t)
Definition: convert.c:86
TIME default_lease_time
Definition: dhclient.c:54
int client_env_count
Definition: dhclient.c:99
isc_result_t dhcp_set_control_state(control_object_state_t oldstate, control_object_state_t newstate)
Definition: dhclient.c:5241
unsigned char options[FLEXIBLE_ARRAY_MEMBER]
Definition: dhcp6.h:252
Definition: dhcpd.h:1071
const unsigned char * data
Definition: tree.h:79
struct interface_info * interface
Definition: dhcpd.h:1267
#define DHO_DHCP_MESSAGE_TYPE
Definition: dhcp.h:145
void dhcp_common_objects_setup(void)
#define DHCPv6
Definition: config.h:24
u_int16_t ia_type
Definition: dhcpd.h:1149
isc_boolean_t released
Definition: dhcpd.h:1163
unsigned packet_length
Definition: dhcpd.h:408
void(* store_tag)(unsigned char *, u_int32_t)
Definition: tree.h:332
void write_lease_option(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:3905
#define DDNS_STATE_REM_FW_NXRR
Definition: dhcpd.h:1759
int(* dhcp_interface_shutdown_hook)(struct interface_info *)
Definition: discover.c:51
#define DHCPOFFER
Definition: dhcp.h:173
TIME starts
Definition: dhcpd.h:1151
void discover_interfaces(int state)
Definition: discover.c:559
isc_result_t new_parse(struct parse **cfile, int file, char *inbuf, unsigned buflen, const char *name, int eolp)
Definition: conflex.c:41
#define DUID_UUID
Definition: dhcp6.h:168
struct dhc6_lease * active_lease
Definition: dhcpd.h:1301
#define INTERFACE_REQUESTED
Definition: dhcpd.h:1390
#define DHO_HOST_NAME
Definition: dhcp.h:104
int universe_count
Definition: tables.c:964
int dhclient_interface_shutdown_hook(struct interface_info *interface)
Definition: dhclient.c:5042
TIME starts
Definition: dhcpd.h:1139
struct buffer * buffer
Definition: tree.h:78
void script_write_params(struct client_state *client, const char *prefix, struct client_lease *lease)
Adds parameters to environment variables for a script.
Definition: dhclient.c:4550
int option_dereference(struct option **dest, const char *file, int line)
Definition: tables.c:1002
#define DHO_VENDOR_ENCAPSULATED_OPTIONS
Definition: dhcp.h:135
void client_location_changed()
Definition: dhclient.c:4930
void state_stop(void *cpp)
Definition: dhclient.c:1981
int dad_wait_time
Definition: dhclient.c:110
isc_result_t omapi_init(void)
Definition: support.c:62
#define DHO_DHCP_REQUESTED_ADDRESS
Definition: dhcp.h:142
int buffer_dereference(struct buffer **ptr, const char *file, int line)
Definition: alloc.c:726
#define IGNORE_RET(x)
Definition: cdefs.h:55
int log_perror
Definition: errwarn.c:43
char * server_name
Definition: dhcpd.h:1116
isc_result_t ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
isc_result_t write_client6_lease(struct client_state *client, struct dhc6_lease *lease, int rewrite, int sync)
Definition: dhclient.c:4149
int bootp_broadcast_always
Definition: dhcpd.h:1259