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