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