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