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