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