ISC DHCP  4.4.1
A reference DHCPv4 and DHCPv6 implementation
dhcpd.c
Go to the documentation of this file.
1 /* dhcpd.c
2 
3  DHCP Server Daemon. */
4 
5 /*
6  * Copyright (c) 2004-2018 by Internet Systems Consortium, Inc. ("ISC")
7  * Copyright (c) 1996-2003 by Internet Software Consortium
8  *
9  * This Source Code Form is subject to the terms of the Mozilla Public
10  * License, v. 2.0. If a copy of the MPL was not distributed with this
11  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  *
21  * Internet Systems Consortium, Inc.
22  * 950 Charter Street
23  * Redwood City, CA 94063
24  * <info@isc.org>
25  * https://www.isc.org/
26  *
27  */
28 
29 static const char copyright[] =
30 "Copyright 2004-2018 Internet Systems Consortium.";
31 static const char arr [] = "All rights reserved.";
32 static const char message [] = "Internet Systems Consortium DHCP Server";
33 static const char url [] =
34 "For info, please visit https://www.isc.org/software/dhcp/";
35 
36 #include "dhcpd.h"
37 #include <omapip/omapip_p.h>
38 #include <syslog.h>
39 #include <signal.h>
40 #include <errno.h>
41 #include <limits.h>
42 #include <sys/types.h>
43 #include <sys/time.h>
44 #include <isc/file.h>
45 
46 #if defined (PARANOIA)
47 # include <sys/types.h>
48 # include <unistd.h>
49 # include <pwd.h>
50 /* get around the ISC declaration of group */
51 # define group real_group
52 # include <grp.h>
53 # undef group
54 
55 /* global values so db.c can look at them */
56 uid_t set_uid = 0;
57 gid_t set_gid = 0;
58 #endif /* PARANOIA */
59 
62 
65 
66 #if defined (NSUPDATE)
67 
68 /* This stuff is always executed to figure the default values for certain
69  ddns variables. */
70 char std_nsupdate [] = " \n\
71 option server.ddns-hostname = \n\
72  pick (option fqdn.hostname, option host-name, config-option host-name); \n\
73 option server.ddns-domainname = config-option domain-name; \n\
74 option server.ddns-rev-domainname = \"in-addr.arpa.\";";
75 
76 /* Stores configured DDNS conflict detection flags */
77 u_int16_t ddns_conflict_mask;
78 #endif /* NSUPDATE */
79 
81 int dont_use_fsync = 0; /* 0 = default, use fsync, 1 = don't use fsync */
82 int server_id_check = 0; /* 0 = default, don't check server id, 1 = do check */
83 
84 #ifdef DHCPv6
86 int do_release_on_roam = 0; /* 0 = default, do not release v6 leases on roam */
87 #endif
88 
89 #ifdef EUI_64
90 int persist_eui64 = 1; /* 1 = write EUI64 leases to disk, 0 = don't */
91 #endif
92 
93 int authoring_byte_order = 0; /* 0 = not set */
94 int lease_id_format = TOKEN_OCTAL; /* octal by default */
96 
100 /* False (default) => we write and use a pid file */
101 isc_boolean_t no_pid_file = ISC_FALSE;
102 
104 
105 static omapi_auth_key_t *omapi_key = (omapi_auth_key_t *)0;
107 
108 #if defined (TRACING)
109 trace_type_t *trace_srandom;
110 #endif
111 
112 char *progname;
113 
114 static isc_result_t verify_addr (omapi_object_t *l, omapi_addr_t *addr) {
115  return ISC_R_SUCCESS;
116 }
117 
118 static isc_result_t verify_auth (omapi_object_t *p, omapi_auth_key_t *a) {
119  if (a != omapi_key)
120  return DHCP_R_INVALIDKEY;
121  return ISC_R_SUCCESS;
122 }
123 
124 static void omapi_listener_start (void *foo)
125 {
126  omapi_object_t *listener;
127  isc_result_t result;
128  struct timeval tv;
129 
130  listener = (omapi_object_t *)0;
131  result = omapi_generic_new (&listener, MDL);
132  if (result != ISC_R_SUCCESS)
133  log_fatal ("Can't allocate new generic object: %s",
134  isc_result_totext (result));
135  result = omapi_protocol_listen (listener,
136  (unsigned)omapi_port, 1);
137  if (result == ISC_R_SUCCESS && omapi_key)
139  (listener, verify_addr, verify_auth);
140  if (result != ISC_R_SUCCESS) {
141  log_error ("Can't start OMAPI protocol: %s",
142  isc_result_totext (result));
143  tv.tv_sec = cur_tv.tv_sec + 5;
144  tv.tv_usec = cur_tv.tv_usec;
145  add_timeout (&tv, omapi_listener_start, 0, 0, 0);
146  }
147  omapi_object_dereference (&listener, MDL);
148 }
149 
150 #ifndef UNIT_TEST
151 
152 #define DHCPD_USAGE0 \
153 "[-p <UDP port #>] [-f] [-d] [-q] [-t|-T]\n"
154 
155 #ifdef DHCPv6
156 #ifdef DHCP4o6
157 #define DHCPD_USAGE1 \
158 " [-4|-6] [-4o6 <port>]\n" \
159 " [-cf config-file] [-lf lease-file]\n"
160 #else /* DHCP4o6 */
161 #define DHCPD_USAGE1 \
162 " [-4|-6] [-cf config-file] [-lf lease-file]\n"
163 #endif /* DHCP4o6 */
164 #else /* !DHCPv6 */
165 #define DHCPD_USAGE1 \
166 " [-cf config-file] [-lf lease-file]\n"
167 #endif /* DHCPv6 */
168 
169 #if defined (PARANOIA)
170 #define DHCPD_USAGEP \
171 " [-user user] [-group group] [-chroot dir]\n"
172 #else
173 #define DHCPD_USAGEP ""
174 #endif /* PARANOIA */
175 
176 #if defined (TRACING)
177 #define DHCPD_USAGET \
178 " [-tf trace-output-file]\n" \
179 " [-play trace-input-file]\n"
180 #else
181 #define DHCPD_USAGET ""
182 #endif /* TRACING */
183 
184 #define DHCPD_USAGEC \
185 " [-pf pid-file] [--no-pid] [-s server]\n" \
186 " [if0 [...ifN]]"
187 
188 #define DHCPD_USAGEH "{--version|--help|-h}"
189 
205 static char use_noarg[] = "No argument for command: %s ";
206 
207 static void
208 usage(const char *sfmt, const char *sarg) {
209  log_info("%s %s", message, PACKAGE_VERSION);
210  log_info(copyright);
211  log_info(arr);
212  log_info(url);
213 
214  /* If desired print out the specific error message */
215 #ifdef PRINT_SPECIFIC_CL_ERRORS
216  if (sfmt != NULL)
217  log_error(sfmt, sarg);
218 #endif
219 
220  log_fatal("Usage: %s %s%s%s%s%s\n %s %s",
221  isc_file_basename(progname),
222  DHCPD_USAGE0,
223  DHCPD_USAGE1,
224  DHCPD_USAGEP,
225  DHCPD_USAGET,
226  DHCPD_USAGEC,
227  isc_file_basename(progname),
228  DHCPD_USAGEH);
229 }
230 
231 /* Note: If we add unit tests to test setup_chroot it will
232  * need to be moved to be outside the ifndef UNIT_TEST block.
233  */
234 
235 #if defined (PARANOIA)
236 /* to be used in one of two possible scenarios */
237 static void setup_chroot (char *chroot_dir) {
238  if (geteuid())
239  log_fatal ("you must be root to use chroot");
240 
241  if (chroot(chroot_dir)) {
242  log_fatal ("chroot(\"%s\"): %m", chroot_dir);
243  }
244  if (chdir ("/")) {
245  /* probably permission denied */
246  log_fatal ("chdir(\"/\"): %m");
247  }
248 }
249 #endif /* PARANOIA */
250 
251 int
252 main(int argc, char **argv) {
253  int fd;
254  int i, status;
255  struct servent *ent;
256  char *s;
257  int cftest = 0;
258  int lftest = 0;
259  int pid;
260  char pbuf [20];
261 #ifndef DEBUG
262  int daemon = 1;
263  int dfd[2] = { -1, -1 };
264 #endif
265  int quiet = 0;
266  char *server = (char *)0;
267  isc_result_t result;
268  unsigned seed;
269  struct interface_info *ip;
270 #if defined (NSUPDATE)
271  struct parse *parse;
272  int lose;
273 #endif
274  int have_dhcpd_conf = 0;
275  int have_dhcpd_db = 0;
276  int have_dhcpd_pid = 0;
277 #ifdef DHCPv6
278  int local_family_set = 0;
279 #ifdef DHCP4o6
280  u_int16_t dhcp4o6_port = 0;
281 #endif /* DHCP4o6 */
282 #endif /* DHCPv6 */
283 #if defined (TRACING)
284  char *traceinfile = (char *)0;
285  char *traceoutfile = (char *)0;
286 #endif
287 
288 #if defined (PARANOIA)
289  char *set_user = 0;
290  char *set_group = 0;
291  char *set_chroot = 0;
292 #endif /* PARANOIA */
293 
294 #ifdef OLD_LOG_NAME
295  progname = "dhcpd";
296 #else
297  progname = argv[0];
298 #endif
299 
300  /* Make sure that file descriptors 0 (stdin), 1, (stdout), and
301  2 (stderr) are open. To do this, we assume that when we
302  open a file the lowest available file descriptor is used. */
303  fd = open("/dev/null", O_RDWR | O_CLOEXEC);
304  if (fd == 0)
305  fd = open("/dev/null", O_RDWR | O_CLOEXEC);
306  if (fd == 1)
307  fd = open("/dev/null", O_RDWR | O_CLOEXEC);
308  if (fd == 2)
309  log_perror = 0; /* No sense logging to /dev/null. */
310  else if (fd != -1)
311  close(fd);
312 
313  /* Parse arguments changing daemon */
314  for (i = 1; i < argc; i++) {
315  if (!strcmp (argv [i], "-f")) {
316 #ifndef DEBUG
317  daemon = 0;
318 #endif
319  } else if (!strcmp (argv [i], "-d")) {
320 #ifndef DEBUG
321  daemon = 0;
322 #endif
323  } else if (!strcmp (argv [i], "-t")) {
324 #ifndef DEBUG
325  daemon = 0;
326 #endif
327  } else if (!strcmp (argv [i], "-T")) {
328 #ifndef DEBUG
329  daemon = 0;
330 #endif
331  } else if (!strcmp (argv [i], "--version")) {
332  const char vstring[] = "isc-dhcpd-";
333  IGNORE_RET(write(STDERR_FILENO, vstring,
334  strlen(vstring)));
337  strlen(PACKAGE_VERSION)));
338  IGNORE_RET(write(STDERR_FILENO, "\n", 1));
339  exit (0);
340  } else if (!strcmp(argv[i], "--help") ||
341  !strcmp(argv[i], "-h")) {
342  const char *pname = isc_file_basename(progname);
343  IGNORE_RET(write(STDERR_FILENO, "Usage: ", 7));
344  IGNORE_RET(write(STDERR_FILENO, pname, strlen(pname)));
345  IGNORE_RET(write(STDERR_FILENO, " ", 1));
347  strlen(DHCPD_USAGE0)));
349  strlen(DHCPD_USAGE1)));
350 #if defined (PARANOIA)
352  strlen(DHCPD_USAGEP)));
353 #endif
354 #if defined (TRACING)
356  strlen(DHCPD_USAGET)));
357 #endif
359  strlen(DHCPD_USAGEC)));
360  IGNORE_RET(write(STDERR_FILENO, "\n", 1));
361  IGNORE_RET(write(STDERR_FILENO, " ", 7));
362  IGNORE_RET(write(STDERR_FILENO, pname, strlen(pname)));
363  IGNORE_RET(write(STDERR_FILENO, " ", 1));
365  strlen(DHCPD_USAGEH)));
366  IGNORE_RET(write(STDERR_FILENO, "\n", 1));
367  exit(0);
368 #ifdef TRACING
369  } else if (!strcmp (argv [i], "-play")) {
370 #ifndef DEBUG
371  daemon = 0;
372 #endif
373 #endif
374  }
375  }
376 
377 #ifndef DEBUG
378  /* When not forbidden prepare to become a daemon */
379  if (daemon) {
380  if (pipe(dfd) == -1)
381  log_fatal("Can't get pipe: %m");
382  if ((pid = fork ()) < 0)
383  log_fatal("Can't fork daemon: %m");
384  if (pid != 0) {
385  /* Parent: wait for the child to start */
386  int n;
387 
388  (void) close(dfd[1]);
389  do {
390  char buf;
391 
392  n = read(dfd[0], &buf, 1);
393  if (n == 1)
394  _exit((int)buf);
395  } while (n == -1 && errno == EINTR);
396  _exit(1);
397  }
398  /* Child */
399  (void) close(dfd[0]);
400  }
401 #endif
402 
403  /* Set up the isc and dns library managers */
405  NULL, NULL);
406  if (status != ISC_R_SUCCESS)
407  log_fatal("Can't initialize context: %s",
408  isc_result_totext(status));
409 
410  /* Set up the client classification system. */
412 
413  /* Initialize the omapi system. */
414  result = omapi_init ();
415  if (result != ISC_R_SUCCESS)
416  log_fatal ("Can't initialize OMAPI: %s",
417  isc_result_totext (result));
418 
419  /* Set up the OMAPI wrappers for common objects. */
421  /* Set up the OMAPI wrappers for various server database internal
422  objects. */
424 
425  /* Initially, log errors to stderr as well as to syslogd. */
426  openlog (isc_file_basename(progname),
428 
429  for (i = 1; i < argc; i++) {
430  if (!strcmp (argv [i], "-p")) {
431  if (++i == argc)
432  usage(use_noarg, argv[i-1]);
433  local_port = validate_port (argv [i]);
434  log_debug ("binding to user-specified port %d",
435  ntohs (local_port));
436  } else if (!strcmp (argv [i], "-f")) {
437 #ifndef DEBUG
438  /* daemon = 0; */
439 #endif
440  } else if (!strcmp (argv [i], "-d")) {
441 #ifndef DEBUG
442  /* daemon = 0; */
443 #endif
444  log_perror = -1;
445  } else if (!strcmp (argv [i], "-s")) {
446  if (++i == argc)
447  usage(use_noarg, argv[i-1]);
448  server = argv [i];
449 #if defined (PARANOIA)
450  } else if (!strcmp (argv [i], "-user")) {
451  if (++i == argc)
452  usage(use_noarg, argv[i-1]);
453  set_user = argv [i];
454  } else if (!strcmp (argv [i], "-group")) {
455  if (++i == argc)
456  usage(use_noarg, argv[i-1]);
457  set_group = argv [i];
458  } else if (!strcmp (argv [i], "-chroot")) {
459  if (++i == argc)
460  usage(use_noarg, argv[i-1]);
461  set_chroot = argv [i];
462 #endif /* PARANOIA */
463  } else if (!strcmp (argv [i], "-cf")) {
464  if (++i == argc)
465  usage(use_noarg, argv[i-1]);
466  path_dhcpd_conf = argv [i];
467  have_dhcpd_conf = 1;
468  } else if (!strcmp (argv [i], "-lf")) {
469  if (++i == argc)
470  usage(use_noarg, argv[i-1]);
471  path_dhcpd_db = argv [i];
472  have_dhcpd_db = 1;
473  } else if (!strcmp (argv [i], "-pf")) {
474  if (++i == argc)
475  usage(use_noarg, argv[i-1]);
476  path_dhcpd_pid = argv [i];
477  have_dhcpd_pid = 1;
478  } else if (!strcmp(argv[i], "--no-pid")) {
479  no_pid_file = ISC_TRUE;
480  } else if (!strcmp (argv [i], "-t")) {
481  /* test configurations only */
482 #ifndef DEBUG
483  /* daemon = 0; */
484 #endif
485  cftest = 1;
486  log_perror = -1;
487  } else if (!strcmp (argv [i], "-T")) {
488  /* test configurations and lease file only */
489 #ifndef DEBUG
490  /* daemon = 0; */
491 #endif
492  cftest = 1;
493  lftest = 1;
494  log_perror = -1;
495  } else if (!strcmp (argv [i], "-q")) {
496  quiet = 1;
498 #ifdef DHCPv6
499  } else if (!strcmp(argv[i], "-4")) {
500  if (local_family_set && (local_family != AF_INET)) {
501  log_fatal("Server cannot run in both IPv4 and "
502  "IPv6 mode at the same time.");
503  }
504  local_family = AF_INET;
505  local_family_set = 1;
506  } else if (!strcmp(argv[i], "-6")) {
507  if (local_family_set && (local_family != AF_INET6)) {
508  log_fatal("Server cannot run in both IPv4 and "
509  "IPv6 mode at the same time.");
510  }
511  local_family = AF_INET6;
512  local_family_set = 1;
513 #ifdef DHCP4o6
514  } else if (!strcmp(argv[i], "-4o6")) {
515  if (++i == argc)
516  usage(use_noarg, argv[i-1]);
517  dhcp4o6_port = validate_port_pair(argv[i]);
518 
519  log_debug("DHCPv4 over DHCPv6 over ::1 port %d and %d",
520  ntohs(dhcp4o6_port),
521  ntohs(dhcp4o6_port) + 1);
522  dhcpv4_over_dhcpv6 = 1;
523 #endif /* DHCP4o6 */
524 #endif /* DHCPv6 */
525 #if defined (TRACING)
526  } else if (!strcmp (argv [i], "-tf")) {
527  if (++i == argc)
528  usage(use_noarg, argv[i-1]);
529  traceoutfile = argv [i];
530  } else if (!strcmp (argv [i], "-play")) {
531  if (++i == argc)
532  usage(use_noarg, argv[i-1]);
533  traceinfile = argv [i];
535 #endif /* TRACING */
536  } else if (argv [i][0] == '-') {
537  usage("Unknown command %s", argv[i]);
538  } else {
539  struct interface_info *tmp =
540  (struct interface_info *)0;
541  if (strlen(argv[i]) >= sizeof(tmp->name))
542  log_fatal("%s: interface name too long "
543  "(is %ld)",
544  argv[i], (long)strlen(argv[i]));
545  result = interface_allocate (&tmp, MDL);
546  if (result != ISC_R_SUCCESS)
547  log_fatal ("Insufficient memory to %s %s: %s",
548  "record interface", argv [i],
549  isc_result_totext (result));
550  strcpy (tmp -> name, argv [i]);
551  if (interfaces) {
552  interface_reference (&tmp -> next,
553  interfaces, MDL);
554  interface_dereference (&interfaces, MDL);
555  }
556  interface_reference (&interfaces, tmp, MDL);
557  tmp -> flags = INTERFACE_REQUESTED;
558  }
559  }
560 
561 #if defined(DHCPv6) && defined(DHCP4o6)
562  if (dhcpv4_over_dhcpv6) {
563  if (!local_family_set)
564  log_error("please specify the address family "
565  "with DHPv4 over DHCPv6 [-4|-6].");
566  if ((local_family == AF_INET) && (interfaces != NULL))
567  log_fatal("DHCPv4 server in DHPv4 over DHCPv6 "
568  "mode with command line specified "
569  "interfaces.");
570  }
571 #endif /* DHCPv6 && DHCP4o6 */
572 
573  if (!have_dhcpd_conf && (s = getenv ("PATH_DHCPD_CONF"))) {
574  path_dhcpd_conf = s;
575  }
576 
577 #ifdef DHCPv6
578  if (local_family == AF_INET6) {
579  /* DHCPv6: override DHCPv4 lease and pid filenames */
580  if (!have_dhcpd_db) {
581  if ((s = getenv ("PATH_DHCPD6_DB")))
582  path_dhcpd_db = s;
583  else
585  }
586  if (!have_dhcpd_pid) {
587  if ((s = getenv ("PATH_DHCPD6_PID")))
588  path_dhcpd_pid = s;
589  else
591  }
592  } else
593 #endif /* DHCPv6 */
594  {
595  if (!have_dhcpd_db && (s = getenv ("PATH_DHCPD_DB"))) {
596  path_dhcpd_db = s;
597  have_dhcpd_db = 1;
598  }
599  if (!have_dhcpd_pid && (s = getenv ("PATH_DHCPD_PID"))) {
600  path_dhcpd_pid = s;
601  have_dhcpd_pid = 1;
602  }
603  }
604 
605  /*
606  * convert relative path names to absolute, for files that need
607  * to be reopened after chdir() has been called
608  */
609  if (have_dhcpd_db && path_dhcpd_db[0] != '/') {
611  }
612 
613  if (!quiet) {
614  log_info("%s %s", message, PACKAGE_VERSION);
615  log_info (copyright);
616  log_info (arr);
617  log_info (url);
618  } else {
619  log_perror = 0;
620  }
621 
622 #if defined (TRACING)
624  if (traceoutfile) {
625  result = trace_begin (traceoutfile, MDL);
626  if (result != ISC_R_SUCCESS)
627  log_fatal ("Unable to begin trace: %s",
628  isc_result_totext (result));
629  }
632  trace_srandom = trace_type_register ("random-seed", (void *)0,
635 #if defined (NSUPDATE)
636  trace_ddns_init();
637 #endif /* NSUPDATE */
638 #endif
639 
640 #if defined (PARANOIA)
641  /* get user and group info if those options were given */
642  if (set_user) {
643  struct passwd *tmp_pwd;
644 
645  if (geteuid())
646  log_fatal ("you must be root to set user");
647 
648  if (!(tmp_pwd = getpwnam(set_user)))
649  log_fatal ("no such user: %s", set_user);
650 
651  set_uid = tmp_pwd->pw_uid;
652 
653  /* use the user's group as the default gid */
654  if (!set_group)
655  set_gid = tmp_pwd->pw_gid;
656  }
657 
658  if (set_group) {
659 /* get around the ISC declaration of group */
660 #define group real_group
661  struct group *tmp_grp;
662 
663  if (geteuid())
664  log_fatal ("you must be root to set group");
665 
666  if (!(tmp_grp = getgrnam(set_group)))
667  log_fatal ("no such group: %s", set_group);
668 
669  set_gid = tmp_grp->gr_gid;
670 #undef group
671  }
672 
673 # if defined (EARLY_CHROOT)
674  if (set_chroot) setup_chroot (set_chroot);
675 # endif /* EARLY_CHROOT */
676 #endif /* PARANOIA */
677 
678  /* Default to the DHCP/BOOTP port. */
679  if (!local_port)
680  {
681  if ((s = getenv ("DHCPD_PORT"))) {
683  log_debug ("binding to environment-specified port %d",
684  ntohs (local_port));
685  } else {
686  if (local_family == AF_INET) {
687  ent = getservbyname("dhcp", "udp");
688  if (ent == NULL) {
689  local_port = htons(67);
690  } else {
691  local_port = ent->s_port;
692  }
693  } else {
694  /* INSIST(local_family == AF_INET6); */
695  ent = getservbyname("dhcpv6-server", "udp");
696  if (ent == NULL) {
697  local_port = htons(547);
698  } else {
699  local_port = ent->s_port;
700  }
701  }
702 #ifndef __CYGWIN32__ /* XXX */
703  endservent ();
704 #endif
705  }
706  }
707 
708  if (local_family == AF_INET) {
709  remote_port = htons(ntohs(local_port) + 1);
710  } else {
711  /* INSIST(local_family == AF_INET6); */
712  ent = getservbyname("dhcpv6-client", "udp");
713  if (ent == NULL) {
714  remote_port = htons(546);
715  } else {
716  remote_port = ent->s_port;
717  }
718  }
719 
720  if (server) {
721  if (local_family != AF_INET) {
722  log_fatal("You can only specify address to send "
723  "replies to when running an IPv4 server.");
724  }
725  if (!inet_aton (server, &limited_broadcast)) {
726  struct hostent *he;
727  he = gethostbyname (server);
728  if (he) {
729  memcpy (&limited_broadcast,
730  he -> h_addr_list [0],
731  sizeof limited_broadcast);
732  } else
733  limited_broadcast.s_addr = INADDR_BROADCAST;
734  }
735  } else {
736  limited_broadcast.s_addr = INADDR_BROADCAST;
737  }
738 
739  /* Get the current time... */
740  gettimeofday(&cur_tv, NULL);
741 
742  /* Set up the initial dhcp option universe. */
745 
746  /* Add the ddns update style enumeration prior to parsing. */
749 #if defined (LDAP_CONFIGURATION)
750  add_enumeration (&ldap_methods);
751 #if defined (LDAP_USE_SSL)
752  add_enumeration (&ldap_ssl_usage_enum);
753  add_enumeration (&ldap_tls_reqcert_enum);
754  add_enumeration (&ldap_tls_crlcheck_enum);
755 #endif
756 #endif
757 
758  if (!group_allocate (&root_group, MDL))
759  log_fatal ("Can't allocate root group!");
760  root_group -> authoritative = 0;
761 
762  /* Set up various hooks. */
765 #ifdef DHCPv6
768 #endif /* DHCPv6 */
769 
770 #if defined (NSUPDATE)
771  /* Set up the standard name service updater routine. */
772  parse = NULL;
773  status = new_parse(&parse, -1, std_nsupdate, sizeof(std_nsupdate) - 1,
774  "standard name service update routine", 0);
775  if (status != ISC_R_SUCCESS)
776  log_fatal ("can't begin parsing name service updater!");
777 
778  if (parse != NULL) {
779  lose = 0;
781  parse, &lose, context_any))) {
782  end_parse(&parse);
783  log_fatal("can't parse standard name service updater!");
784  }
785  end_parse(&parse);
786  }
787 #endif
788 
789  /* Initialize icmp support... */
790  if (!cftest && !lftest)
792 
793 #if defined (TRACING)
794  if (traceinfile) {
795  if (!have_dhcpd_db) {
796  log_error ("%s", "");
797  log_error ("** You must specify a lease file with -lf.");
798  log_error (" Dhcpd will not overwrite your default");
799  log_fatal (" lease file when playing back a trace. **");
800  }
801  trace_file_replay (traceinfile);
802 
803 #if defined (DEBUG_MEMORY_LEAKAGE) && \
804  defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
805  free_everything ();
807 #endif
808 
809  exit (0);
810  }
811 #endif
812 
813 #ifdef DHCPv6
814  /* set up DHCPv6 hashes */
815  if (!ia_new_hash(&ia_na_active, DEFAULT_HASH_SIZE, MDL)) {
816  log_fatal("Out of memory creating hash for active IA_NA.");
817  }
818  if (!ia_new_hash(&ia_ta_active, DEFAULT_HASH_SIZE, MDL)) {
819  log_fatal("Out of memory creating hash for active IA_TA.");
820  }
821  if (!ia_new_hash(&ia_pd_active, DEFAULT_HASH_SIZE, MDL)) {
822  log_fatal("Out of memory creating hash for active IA_PD.");
823  }
824 #endif /* DHCPv6 */
825 
826  /* Read the dhcpd.conf file... */
827  if (readconf () != ISC_R_SUCCESS)
828  log_fatal ("Configuration file errors encountered -- exiting");
829 
831 
832 #if defined (FAILOVER_PROTOCOL)
834 #endif
835 
836 #if defined(DHCPv6) && defined(DHCP4o6)
837  if (dhcpv4_over_dhcpv6) {
838  if ((local_family == AF_INET) && (interfaces != NULL))
839  log_fatal("DHCPv4 server in DHPv4 over DHCPv6 "
840  "mode with config file specified "
841  "interfaces.");
842  }
843 #endif /* DHCPv6 && DHCP4o6 */
844 
845 #if defined (PARANOIA) && !defined (EARLY_CHROOT)
846  if (set_chroot) setup_chroot (set_chroot);
847 #endif /* PARANOIA && !EARLY_CHROOT */
848 
849 #ifdef DHCPv6
850  /* log info about ipv6_ponds with large address ranges */
852 #endif
853 
854  /* test option should cause an early exit */
855  if (cftest && !lftest) {
856  exit(0);
857  }
858 
859  /*
860  * First part of dealing with pid files. Check to see if
861  * we should continue running or not. We run if:
862  * - we are testing the lease file out
863  * - we don't have a pid file to check
864  * - there is no other process running
865  */
866  if ((lftest == 0) && (no_pid_file == ISC_FALSE)) {
867  /*Read previous pid file. */
868  if ((i = open(path_dhcpd_pid, O_RDONLY)) >= 0) {
869  status = read(i, pbuf, (sizeof pbuf) - 1);
870  close(i);
871  if (status > 0) {
872  pbuf[status] = 0;
873  pid = atoi(pbuf);
874 
875  /*
876  * If there was a previous server process and
877  * it is still running, abort
878  */
879  if (!pid ||
880  (pid != getpid() && kill(pid, 0) == 0))
881  log_fatal("There's already a "
882  "DHCP server running.");
883  }
884  }
885  }
886 
888 
889  /* Start up the database... */
890  db_startup (lftest);
891 
892  if (lftest)
893  exit (0);
894 
895  /* Discover all the network interfaces and initialize them. */
896 #if defined(DHCPv6) && defined(DHCP4o6)
897  if (dhcpv4_over_dhcpv6) {
898  int real_family = local_family;
899  local_family = AF_INET6;
900  /* The DHCPv4 side of DHCPv4-over-DHCPv6 service
901  uses a specific discovery which doesn't register
902  DHCPv6 sockets. */
903  if (real_family == AF_INET)
905  else
907  local_family = real_family;
908  } else
909 #endif /* DHCPv6 && DHCP4o6 */
911 
912 #ifdef DHCPv6
913  /*
914  * Remove addresses from our pools that we should not issue
915  * to clients.
916  *
917  * We currently have no support for this in IPv4. It is not
918  * as important in IPv4, as making pools with ranges that
919  * leave out interfaces and hosts is fairly straightforward
920  * using range notation, but not so handy with CIDR notation.
921  */
922  if (local_family == AF_INET6) {
926  }
927 #endif /* DHCPv6 */
928 
929  /* Make up a seed for the random number generator from current
930  time plus the sum of the last four bytes of each
931  interface's hardware address interpreted as an integer.
932  Not much entropy, but we're booting, so we're not likely to
933  find anything better. */
934  seed = 0;
935  for (ip = interfaces; ip; ip = ip -> next) {
936  int junk;
937  memcpy (&junk,
938  &ip -> hw_address.hbuf [ip -> hw_address.hlen -
939  sizeof seed], sizeof seed);
940  seed += junk;
941  }
942  srandom (seed + cur_time);
943 #if defined (TRACING)
944  trace_seed_stash (trace_srandom, seed + cur_time);
945 #endif
946  postdb_startup ();
947 
948 #ifdef DHCPv6
949  /*
950  * Set server DHCPv6 identifier - we go in order:
951  * dhcp6.server-id in the config file
952  * server-duid from the lease file
953  * server-duid from the config file (the config file is read first
954  * and the lease file overwrites the config file information)
955  * generate a new one from the interface hardware addresses.
956  * In all cases we write it out to the lease file.
957  * See dhcpv6.c for discussion of setting DUID.
958  */
959  if ((set_server_duid_from_option() != ISC_R_SUCCESS) &&
960  (!server_duid_isset()) &&
961  (generate_new_server_duid() != ISC_R_SUCCESS)) {
962  log_fatal("Unable to set server identifier.");
963  }
965 #ifdef DHCP4o6
966  if (dhcpv4_over_dhcpv6)
967  dhcp4o6_setup(dhcp4o6_port);
968 #endif /* DHCP4o6 */
969 #endif /* DHCPv6 */
970 
971 #ifndef DEBUG
972  /*
973  * Second part of dealing with pid files. Now
974  * that we have forked we can write our pid if
975  * appropriate.
976  */
977  if (no_pid_file == ISC_FALSE) {
978  i = open(path_dhcpd_pid, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644);
979  if (i >= 0) {
980  sprintf(pbuf, "%d\n", (int) getpid());
981  IGNORE_RET(write(i, pbuf, strlen(pbuf)));
982  close(i);
983  } else {
984  log_error("Can't create PID file %s: %m.",
986  }
987  }
988 
989 #if defined (PARANOIA)
990  /* change uid to the specified one */
991 
992  if (set_gid) {
993  if (setgroups (0, (void *)0))
994  log_fatal ("setgroups: %m");
995  if (setgid (set_gid))
996  log_fatal ("setgid(%d): %m", (int) set_gid);
997  }
998 
999  if (set_uid) {
1000  if (setuid (set_uid))
1001  log_fatal ("setuid(%d): %m", (int) set_uid);
1002  }
1003 #endif /* PARANOIA */
1004 
1005  /* If we were requested to log to stdout on the command line,
1006  keep doing so; otherwise, stop. */
1007  if (log_perror == -1)
1008  log_perror = 1;
1009  else
1010  log_perror = 0;
1011 
1012  if (daemon) {
1013  if (dfd[0] != -1 && dfd[1] != -1) {
1014  char buf = 0;
1015 
1016  if (write(dfd[1], &buf, 1) != 1)
1017  log_fatal("write to parent: %m");
1018  (void) close(dfd[1]);
1019  dfd[0] = dfd[1] = -1;
1020  }
1021 
1022  /* Become session leader and get pid... */
1023  (void) setsid();
1024 
1025  /* Close standard I/O descriptors. */
1026  (void) close(0);
1027  (void) close(1);
1028  (void) close(2);
1029 
1030  /* Reopen them on /dev/null. */
1031  (void) open("/dev/null", O_RDWR | O_CLOEXEC);
1032  (void) open("/dev/null", O_RDWR | O_CLOEXEC);
1033  (void) open("/dev/null", O_RDWR | O_CLOEXEC);
1034  log_perror = 0; /* No sense logging to /dev/null. */
1035 
1036  IGNORE_RET (chdir("/"));
1037  }
1038 #endif /* !DEBUG */
1039 
1040 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
1041  defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1042  dmalloc_cutoff_generation = dmalloc_generation;
1043  dmalloc_longterm = dmalloc_outstanding;
1044  dmalloc_outstanding = 0;
1045 #endif
1046 
1048  (omapi_object_t *)0, "state", server_running);
1049 
1050 #if defined(ENABLE_GENTLE_SHUTDOWN)
1051  /* no signal handlers until we deal with the side effects */
1052  /* install signal handlers */
1053  signal(SIGINT, dhcp_signal_handler); /* control-c */
1054  signal(SIGTERM, dhcp_signal_handler); /* kill */
1055 #endif
1056 
1057  /* Log that we are about to start working */
1058  log_info("Server starting service.");
1059 
1060  /*
1061  * Receive packets and dispatch them...
1062  * dispatch() will never return.
1063  */
1064  dispatch ();
1065 
1066  /* Let's return status code */
1067  return 0;
1068 }
1069 #endif /* !UNIT_TEST */
1070 
1072 {
1073  struct option_state *options = NULL;
1074  struct data_string db;
1075  struct option_cache *oc;
1076  char *s;
1077  isc_result_t result;
1078  int tmp;
1079 #if defined (NSUPDATE)
1080  struct in_addr local4, *local4_ptr = NULL;
1081  struct in6_addr local6, *local6_ptr = NULL;
1082 #endif
1083 
1084  /* Now try to get the lease file name. */
1085  option_state_allocate(&options, MDL);
1086 
1087  execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL,
1088  options, &global_scope, root_group,
1089  NULL, NULL);
1090  memset(&db, 0, sizeof db);
1092  if (oc &&
1093  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1094  &global_scope, oc, MDL)) {
1095  s = dmalloc(db.len + 1, MDL);
1096  if (!s)
1097  log_fatal("no memory for lease db filename.");
1098  memcpy(s, db.data, db.len);
1099  s[db.len] = 0;
1100  data_string_forget(&db, MDL);
1101  path_dhcpd_db = s;
1102  }
1103 
1105  if (oc &&
1106  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1107  &global_scope, oc, MDL)) {
1108  s = dmalloc(db.len + 1, MDL);
1109  if (!s)
1110  log_fatal("no memory for pid filename.");
1111  memcpy(s, db.data, db.len);
1112  s[db.len] = 0;
1113  data_string_forget(&db, MDL);
1114  path_dhcpd_pid = s;
1115  }
1116 
1117 #ifdef DHCPv6
1118  if (local_family == AF_INET6) {
1119  /*
1120  * Override lease file name with dhcpv6 lease file name,
1121  * if it was set; then, do the same with the pid file name
1122  */
1123  oc = lookup_option(&server_universe, options,
1125  if (oc &&
1126  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1127  &global_scope, oc, MDL)) {
1128  s = dmalloc(db.len + 1, MDL);
1129  if (!s)
1130  log_fatal("no memory for lease db filename.");
1131  memcpy(s, db.data, db.len);
1132  s[db.len] = 0;
1133  data_string_forget(&db, MDL);
1134  path_dhcpd_db = s;
1135  }
1136 
1137  oc = lookup_option(&server_universe, options,
1139  if (oc &&
1140  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1141  &global_scope, oc, MDL)) {
1142  s = dmalloc(db.len + 1, MDL);
1143  if (!s)
1144  log_fatal("no memory for pid filename.");
1145  memcpy(s, db.data, db.len);
1146  s[db.len] = 0;
1147  data_string_forget(&db, MDL);
1148  path_dhcpd_pid = s;
1149  }
1150 
1151  oc = lookup_option(&server_universe, options,
1153  if (oc &&
1154  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1155  &global_scope, oc, MDL)) {
1156  if (db.len == 16) {
1157  memcpy(&local_address6, db.data, 16);
1158  } else
1159  log_fatal("invalid local address "
1160  "data length");
1161  data_string_forget(&db, MDL);
1162  }
1163 
1164  oc = lookup_option(&server_universe, options,
1166  if (oc &&
1167  evaluate_boolean_option_cache(NULL, NULL, NULL,
1168  NULL, options, NULL,
1169  &global_scope, oc, MDL)) {
1170  bind_local_address6 = 1;
1171  }
1172 
1173  }
1174 #endif /* DHCPv6 */
1175 
1176  omapi_port = -1;
1177  oc = lookup_option(&server_universe, options, SV_OMAPI_PORT);
1178  if (oc &&
1179  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1180  &global_scope, oc, MDL)) {
1181  if (db.len == 2) {
1182  omapi_port = getUShort(db.data);
1183  } else
1184  log_fatal("invalid omapi port data length");
1185  data_string_forget(&db, MDL);
1186  }
1187 
1188  oc = lookup_option(&server_universe, options, SV_OMAPI_KEY);
1189  if (oc &&
1190  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1191  &global_scope, oc, MDL)) {
1192  s = dmalloc(db.len + 1, MDL);
1193  if (!s)
1194  log_fatal("no memory for OMAPI key filename.");
1195  memcpy(s, db.data, db.len);
1196  s[db.len] = 0;
1197  data_string_forget(&db, MDL);
1198  result = omapi_auth_key_lookup_name(&omapi_key, s);
1199  dfree(s, MDL);
1200  if (result != ISC_R_SUCCESS)
1201  log_fatal("OMAPI key %s: %s",
1202  s, isc_result_totext (result));
1203  }
1204 
1205  oc = lookup_option(&server_universe, options, SV_LOCAL_PORT);
1206  if (oc &&
1207  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1208  &global_scope, oc, MDL)) {
1209  if (db.len == 2) {
1210  local_port = htons(getUShort (db.data));
1211  } else
1212  log_fatal("invalid local port data length");
1213  data_string_forget(&db, MDL);
1214  }
1215 
1216  oc = lookup_option(&server_universe, options, SV_REMOTE_PORT);
1217  if (oc &&
1218  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1219  &global_scope, oc, MDL)) {
1220  if (db.len == 2) {
1221  remote_port = htons(getUShort (db.data));
1222  } else
1223  log_fatal("invalid remote port data length");
1224  data_string_forget(&db, MDL);
1225  }
1226 
1227  oc = lookup_option(&server_universe, options,
1229  if (oc &&
1230  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1231  &global_scope, oc, MDL)) {
1232  if (db.len == 4) {
1233  memcpy(&limited_broadcast, db.data, 4);
1234  } else
1235  log_fatal("invalid broadcast address data length");
1236  data_string_forget(&db, MDL);
1237  }
1238 
1240  if (oc &&
1241  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1242  &global_scope, oc, MDL)) {
1243  if (db.len == 4) {
1244  memcpy(&local_address, db.data, 4);
1245  } else
1246  log_fatal("invalid local address data length");
1247  data_string_forget(&db, MDL);
1248  }
1249 
1251  if (oc) {
1252  if (evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1253  &global_scope, oc, MDL)) {
1254  if (db.len == 1) {
1255  ddns_update_style = db.data[0];
1256  } else
1257  log_fatal("invalid dns update type");
1258  data_string_forget(&db, MDL);
1259  }
1260  } else {
1262  }
1263 #if defined (NSUPDATE)
1264  /* We no longer support ad_hoc, tell the user */
1266  log_fatal("ddns-update-style ad_hoc no longer supported");
1267  }
1268 
1270  if (oc) {
1271  if (evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1272  &global_scope, oc, MDL)) {
1273  if (db.len == 4) {
1274  memcpy(&local4, db.data, 4);
1275  local4_ptr = &local4;
1276  }
1277  data_string_forget(&db, MDL);
1278  }
1279  }
1280 
1282  if (oc) {
1283  if (evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1284  &global_scope, oc, MDL)) {
1285  if (db.len == 16) {
1286  memcpy(&local6, db.data, 16);
1287  local6_ptr = &local6;
1288  }
1289  data_string_forget(&db, MDL);
1290  }
1291  }
1292 
1293  /* Don't init DNS client if update style is none. This avoids
1294  * listening ports that aren't needed. We don't use ddns-udpates
1295  * as that has multiple levels of scope. */
1298  local4_ptr, local6_ptr)
1299  != ISC_R_SUCCESS) {
1300  log_fatal("Unable to complete ddns initialization");
1301  }
1302  }
1303 
1304  /* Set the conflict detection flag mask based on globally
1305  * defined DDNS configuration params. This mask should be
1306  * to init ddns_cb::flags before for every DDNS transaction. */
1308 
1309 #else
1310  /* If we don't have support for updates compiled in tell the user */
1312  log_fatal("Support for ddns-update-style not compiled in");
1313  }
1314 #endif
1315 
1316  if (!quiet) {
1317  log_info ("Config file: %s", path_dhcpd_conf);
1318  log_info ("Database file: %s", path_dhcpd_db);
1319  log_info ("PID file: %s", path_dhcpd_pid);
1320  }
1321 
1323  if (oc) {
1324  if (evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1325  &global_scope, oc, MDL)) {
1326  if (db.len == 1) {
1327  closelog ();
1328  openlog(isc_file_basename(progname),
1329  DHCP_LOG_OPTIONS, db.data[0]);
1330  /* Log the startup banner into the new
1331  log file. */
1332  /* Don't log to stderr twice. */
1333  tmp = log_perror;
1334  log_perror = 0;
1335  log_info("%s %s", message, PACKAGE_VERSION);
1336  log_info(copyright);
1337  log_info(arr);
1338  log_info(url);
1339  log_perror = tmp;
1340  } else
1341  log_fatal("invalid log facility");
1342  data_string_forget(&db, MDL);
1343  }
1344  }
1345 
1346 #if defined(DELAYED_ACK)
1347  oc = lookup_option(&server_universe, options, SV_DELAYED_ACK);
1348  if (oc &&
1349  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1350  &global_scope, oc, MDL)) {
1351  if (db.len == 2) {
1352  max_outstanding_acks = htons(getUShort(db.data));
1353  } else {
1354  log_fatal("invalid max delayed ACK count ");
1355  }
1356  data_string_forget(&db, MDL);
1357  }
1358 #if defined(DHCP4o6)
1359  /* Delayed acks and DHCPv4-over-DHCPv6 are incompatible */
1360  if (dhcpv4_over_dhcpv6) {
1361  if (max_outstanding_acks > 0) {
1362  log_debug("DHCP4o6 enabled, "
1363  "setting delayed-ack to zero (incompatible)");
1364  }
1365 
1367  }
1368 #endif
1369 
1371  if (oc &&
1372  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1373  &global_scope, oc, MDL)) {
1374  u_int32_t timeval;
1375 
1376  if (db.len != 4)
1377  log_fatal("invalid max ack delay configuration");
1378 
1379  timeval = getULong(db.data);
1380  max_ack_delay_secs = timeval / 1000000;
1381  max_ack_delay_usecs = timeval % 1000000;
1382 
1383  data_string_forget(&db, MDL);
1384  }
1385 #endif
1386 
1388  if ((oc != NULL) &&
1389  evaluate_boolean_option_cache(NULL, NULL, NULL, NULL, options, NULL,
1390  &global_scope, oc, MDL)) {
1391  dont_use_fsync = 1;
1392  log_error("Not using fsync() to flush lease writes");
1393  }
1394 
1396  if ((oc != NULL) &&
1397  evaluate_boolean_option_cache(NULL, NULL, NULL, NULL, options, NULL,
1398  &global_scope, oc, MDL)) {
1399  log_info("Setting server-id-check true");
1400  server_id_check = 1;
1401  }
1402 
1403 #ifdef DHCPv6
1405  if ((oc != NULL) &&
1406  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1407  &global_scope, oc, MDL)) {
1408  if (db.len == 1) {
1409  prefix_length_mode = db.data[0];
1410  } else {
1411  log_fatal("invalid prefix-len-mode");
1412  }
1413 
1414  data_string_forget(&db, MDL);
1415  }
1416 #endif
1417 
1418  // Set global abandon-lease-time option.
1420  if ((oc != NULL) &&
1421  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1422  &global_scope, oc, MDL)) {
1423  if (db.len == sizeof (u_int32_t)) {
1425  } else {
1426  log_fatal("invalid abandon-lease-time");
1427  }
1428 
1429  data_string_forget (&db, MDL);
1430  }
1431 
1432 #if defined (FAILOVER_PROTOCOL)
1434  if ((oc != NULL) &&
1435  evaluate_boolean_option_cache(NULL, NULL, NULL, NULL, options, NULL,
1436  &global_scope, oc, MDL)) {
1437  check_secs_byte_order = 1;
1438  }
1439 #endif
1440 
1441 #ifdef EUI_64
1442  oc = lookup_option(&server_universe, options, SV_PERSIST_EUI_64_LEASES);
1443  if (oc != NULL) {
1444  persist_eui64 = evaluate_boolean_option_cache(NULL, NULL, NULL,
1445  NULL, options,
1446  NULL,
1447  &global_scope,
1448  oc, MDL);
1449  }
1450 
1451  if (!persist_eui64) {
1452  log_info("EUI64 leases will not be written to lease file");
1453  }
1454 #endif
1455 
1456 #ifdef DHCPv6
1458  if (oc != NULL) {
1460  evaluate_boolean_option_cache(NULL, NULL, NULL, NULL,
1461  options, NULL,
1462  &global_scope, oc, MDL);
1463  }
1464 #endif
1465 
1466 #if defined (BINARY_LEASES)
1467  if (local_family == AF_INET) {
1468  log_info("Source compiled to use binary-leases");
1469  }
1470 #endif
1471 
1472  /* Don't need the options anymore. */
1473  option_state_dereference(&options, MDL);
1474 }
1475 
1476 void postdb_startup (void)
1477 {
1478  /* Initialize the omapi listener state. */
1479  if (omapi_port != -1) {
1480  omapi_listener_start (0);
1481  }
1482 
1483 #if defined (FAILOVER_PROTOCOL)
1484  /* Initialize the failover listener state. */
1486 #endif
1487 
1488  /*
1489  * Begin our lease timeout background task.
1490  */
1492 }
1493 
1494 void lease_pinged (from, packet, length)
1495  struct iaddr from;
1496  u_int8_t *packet;
1497  int length;
1498 {
1499  struct lease *lp;
1500 
1501  /* Don't try to look up a pinged lease if we aren't trying to
1502  ping one - otherwise somebody could easily make us churn by
1503  just forging repeated ICMP EchoReply packets for us to look
1504  up. */
1505  if (!outstanding_pings)
1506  return;
1507 
1508  lp = (struct lease *)0;
1509  if (!find_lease_by_ip_addr (&lp, from, MDL)) {
1510  log_debug ("unexpected ICMP Echo Reply from %s",
1511  piaddr (from));
1512  return;
1513  }
1514 
1515  if (!lp -> state) {
1516 #if defined (FAILOVER_PROTOCOL)
1517  if (!lp -> pool ||
1518  !lp -> pool -> failover_peer)
1519 #endif
1520  log_debug ("ICMP Echo Reply for %s late or spurious.",
1521  piaddr (from));
1522  goto out;
1523  }
1524 
1525  if (lp -> ends > cur_time) {
1526  log_debug ("ICMP Echo reply while lease %s valid.",
1527  piaddr (from));
1528  }
1529 
1530  /* At this point it looks like we pinged a lease and got a
1531  response, which shouldn't have happened. */
1532  data_string_forget (&lp -> state -> parameter_request_list, MDL);
1533  free_lease_state (lp -> state, MDL);
1534  lp -> state = (struct lease_state *)0;
1535 
1536  abandon_lease (lp, "pinged before offer");
1539  out:
1540  lease_dereference (&lp, MDL);
1541 }
1542 
1544  void *vlp;
1545 {
1546  struct lease *lp = vlp;
1547 
1548 #if defined (DEBUG_MEMORY_LEAKAGE)
1549  unsigned long previous_outstanding = dmalloc_outstanding;
1550 #endif
1551 
1553  dhcp_reply (lp);
1554 
1555 #if defined (DEBUG_MEMORY_LEAKAGE)
1556  log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term",
1557  dmalloc_generation,
1558  dmalloc_outstanding - previous_outstanding,
1559  dmalloc_outstanding, dmalloc_longterm);
1560 #endif
1561 #if defined (DEBUG_MEMORY_LEAKAGE)
1562  dmalloc_dump_outstanding ();
1563 #endif
1564 }
1565 
1567 {
1568  struct subnet *subnet;
1569  struct shared_network *share;
1570  isc_result_t status;
1571 
1572  /* Special case for fallback network - not sure why this is
1573  necessary. */
1574  if (!ia) {
1575  const char *fnn = "fallback-net";
1576  status = shared_network_allocate (&ip -> shared_network, MDL);
1577  if (status != ISC_R_SUCCESS)
1578  log_fatal ("No memory for shared subnet: %s",
1579  isc_result_totext (status));
1580  ip -> shared_network -> name = dmalloc (strlen (fnn) + 1, MDL);
1581  if (!ip -> shared_network -> name)
1582  log_fatal("no memory for shared network");
1583  strcpy (ip -> shared_network -> name, fnn);
1584  return 1;
1585  }
1586 
1587  /* If there's a registered subnet for this address,
1588  connect it together... */
1589  subnet = (struct subnet *)0;
1590  if (find_subnet (&subnet, *ia, MDL)) {
1591  /* If this interface has multiple aliases on the same
1592  subnet, ignore all but the first we encounter. */
1593  if (!subnet -> interface) {
1594  interface_reference (&subnet -> interface, ip, MDL);
1595  subnet -> interface_address = *ia;
1596  } else if (subnet -> interface != ip) {
1597  log_error ("Multiple interfaces match the %s: %s %s",
1598  "same subnet",
1599  subnet -> interface -> name, ip -> name);
1600  }
1601  share = subnet -> shared_network;
1602  if (ip -> shared_network &&
1603  ip -> shared_network != share) {
1604  log_fatal ("Interface %s matches multiple shared %s",
1605  ip -> name, "networks");
1606  } else {
1607  if (!ip -> shared_network)
1608  shared_network_reference
1609  (&ip -> shared_network, share, MDL);
1610  }
1611 
1612  if (!share -> interface) {
1613  interface_reference (&share -> interface, ip, MDL);
1614  } else if (share -> interface != ip) {
1615  log_error ("Multiple interfaces match the %s: %s %s",
1616  "same shared network",
1617  share -> interface -> name, ip -> name);
1618  }
1619  subnet_dereference (&subnet, MDL);
1620  }
1621  return 1;
1622 }
1623 
1624 static TIME shutdown_time;
1625 static int omapi_connection_count;
1627 
1628 isc_result_t dhcp_io_shutdown (omapi_object_t *obj, void *foo)
1629 {
1630  /* Shut down all listeners. */
1632  obj -> type == omapi_type_listener &&
1633  obj -> inner &&
1634  obj -> inner -> type == omapi_type_protocol_listener) {
1635  omapi_listener_destroy (obj, MDL);
1636  return ISC_R_SUCCESS;
1637  }
1638 
1639  /* Shut down all existing omapi connections. */
1640  if (obj -> type == omapi_type_connection &&
1641  obj -> inner &&
1642  obj -> inner -> type == omapi_type_protocol) {
1644  omapi_disconnect (obj, 1);
1645  }
1646  omapi_connection_count++;
1648  omapi_disconnect (obj, 0);
1649  return ISC_R_SUCCESS;
1650  }
1651  }
1652 
1653  /* Shutdown all DHCP interfaces. */
1654  if (obj -> type == dhcp_type_interface &&
1657  return ISC_R_SUCCESS;
1658  }
1659  return ISC_R_SUCCESS;
1660 }
1661 
1662 static isc_result_t dhcp_io_shutdown_countdown (void *vlp)
1663 {
1664 #if defined (FAILOVER_PROTOCOL)
1665  dhcp_failover_state_t *state;
1666  int failover_connection_count = 0;
1667 #endif
1668  struct timeval tv;
1669 
1670  oncemore:
1675  omapi_connection_count = 0;
1677  }
1678 
1682  omapi_connection_count == 0) {
1684  shutdown_time = cur_time;
1685  goto oncemore;
1686  } else if (shutdown_state == shutdown_listeners &&
1687  cur_time - shutdown_time > 4) {
1689  shutdown_time = cur_time;
1691  cur_time - shutdown_time > 4) {
1693  shutdown_time = cur_time;
1695  cur_time - shutdown_time > 4) {
1697  shutdown_time = cur_time;
1698  goto oncemore;
1699  } else if (shutdown_state == shutdown_dhcp &&
1700  cur_time - shutdown_time > 4) {
1702  shutdown_time = cur_time;
1703  }
1704 
1705 #if defined (FAILOVER_PROTOCOL)
1706  /* Set all failover peers into the shutdown state. */
1707  if (shutdown_state == shutdown_dhcp) {
1708  for (state = failover_states; state; state = state -> next) {
1709  if (state -> me.state == normal) {
1711  failover_connection_count++;
1712  }
1713  if (state -> me.state == shut_down &&
1714  state -> partner.state != partner_down)
1715  failover_connection_count++;
1716  }
1717  }
1718 
1719  if (shutdown_state == shutdown_done) {
1720  for (state = failover_states; state; state = state -> next) {
1721  if (state -> me.state == shut_down) {
1722  if (state -> link_to_peer)
1723  dhcp_failover_link_dereference (&state -> link_to_peer,
1724  MDL);
1726  }
1727  }
1728 #if defined (DEBUG_MEMORY_LEAKAGE) && \
1729  defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1730  free_everything ();
1732 #endif
1733  if (no_pid_file == ISC_FALSE)
1734  (void) unlink(path_dhcpd_pid);
1735  exit (0);
1736  }
1737 #else
1738  if (shutdown_state == shutdown_done) {
1739 #if defined (DEBUG_MEMORY_LEAKAGE) && \
1740  defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1741  free_everything ();
1743 #endif
1744  if (no_pid_file == ISC_FALSE)
1745  (void) unlink(path_dhcpd_pid);
1746  exit (0);
1747  }
1748 #endif
1749  if (shutdown_state == shutdown_dhcp &&
1750 #if defined(FAILOVER_PROTOCOL)
1751  !failover_connection_count &&
1752 #endif
1753  ISC_TRUE) {
1755  shutdown_time = cur_time;
1756  goto oncemore;
1757  }
1758  tv.tv_sec = cur_tv.tv_sec + 1;
1759  tv.tv_usec = cur_tv.tv_usec;
1760  add_timeout (&tv,
1761  (void (*)(void *))dhcp_io_shutdown_countdown, 0, 0, 0);
1762  return ISC_R_SUCCESS;
1763 }
1764 
1766  control_object_state_t newstate)
1767 {
1768  struct timeval tv;
1769 
1770  if (newstate != server_shutdown)
1771  return DHCP_R_INVALIDARG;
1772  /* Re-entry. */
1773  if (shutdown_signal == SIGUSR1)
1774  return ISC_R_SUCCESS;
1775  shutdown_time = cur_time;
1777  /* Called by user. */
1778  if (shutdown_signal == 0) {
1779  shutdown_signal = SIGUSR1;
1780  dhcp_io_shutdown_countdown (0);
1781  return ISC_R_SUCCESS;
1782  }
1783  /* Called on signal. */
1784  log_info("Received signal %d, initiating shutdown.", shutdown_signal);
1785  shutdown_signal = SIGUSR1;
1786 
1787  /*
1788  * Prompt the shutdown event onto the timer queue
1789  * and return to the dispatch loop.
1790  */
1791  tv.tv_sec = cur_tv.tv_sec;
1792  tv.tv_usec = cur_tv.tv_usec + 1;
1793  add_timeout(&tv,
1794  (void (*)(void *))dhcp_io_shutdown_countdown, 0, 0, 0);
1795  return ISC_R_SUCCESS;
1796 }
#define SV_LOCAL_ADDRESS
Definition: dhcpd.h:744
void do_packet6(struct interface_info *, const char *, int, int, const struct iaddr *, isc_boolean_t)
ia_hash_t * ia_ta_active
#define SV_MAX_ACK_DELAY
Definition: dhcpd.h:768
const char * path_dhcpd_db
Definition: dhcpd.c:98
void initialize_server_option_spaces(void)
Definition: stables.c:452
void(* dhcpv6_packet_handler)(struct interface_info *, const char *, int, int, const struct iaddr *, isc_boolean_t)
int dhcpd_interface_setup_hook(struct interface_info *ip, struct iaddr *ia)
Definition: dhcpd.c:1566
void mark_hosts_unavailable(void)
Definition: mdb6.c:2469
isc_result_t omapi_protocol_listen(omapi_object_t *, unsigned, int)
Definition: protocol.c:997
void add_enumeration(struct enumeration *enumeration)
Definition: parse.c:41
void parse_trace_setup(void)
struct binding_scope * global_scope
Definition: tree.c:38
#define DHCPD_USAGE1
Definition: dhcpd.c:165
omapi_object_type_t * omapi_type_connection
Definition: support.c:33
Definition: dhcpd.h:559
unsigned len
Definition: tree.h:79
#define SV_DDNS_UPDATE_STYLE
Definition: dhcpd.h:748
const char * piaddr(const struct iaddr addr)
Definition: inet.c:579
char name[IFNAMSIZ]
Definition: dhcpd.h:1392
isc_boolean_t server_duid_isset(void)
isc_result_t end_parse(struct parse **cfile)
Definition: conflex.c:103
#define SV_BIND_LOCAL_ADDRESS6
Definition: dhcpd.h:820
void lease_ping_timeout(void *vlp)
Definition: dhcpd.c:1543
void(* bootp_packet_handler)(struct interface_info *, struct dhcp_packet *, unsigned, unsigned int, struct iaddr, struct hardware *)
Definition: discover.c:67
int outstanding_pings
Definition: dhcp.c:43
int prefix_length_mode
int dfd[2]
Definition: dhclient.c:100
struct lease_state * state
Definition: dhcpd.h:627
Definition: dhcpd.h:1060
struct universe server_universe
Definition: stables.c:176
int max_outstanding_acks
#define STDERR_FILENO
Definition: osdep.h:287
char * progname
Definition: dhcpd.c:112
#define SV_DONT_USE_FSYNC
Definition: dhcpd.h:797
#define MDL
Definition: omapip.h:567
void cancel_timeout(void(*)(void *) where, void *what)
Definition: dispatch.c:381
void icmp_startup(int routep, void *handler)
Definition: icmp.c:47
#define DHCP_R_INVALIDARG
Definition: result.h:48
#define DDNS_UPDATE_STYLE_AD_HOC
Definition: dhcpd.h:704
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
#define DHCPD_USAGEP
Definition: dhcpd.c:173
#define SV_DDNS_LOCAL_ADDRESS4
Definition: dhcpd.h:798
isc_result_t dhcp_interface_remove(omapi_object_t *lp, omapi_object_t *id)
Definition: discover.c:1464
isc_result_t omapi_auth_key_lookup_name(omapi_auth_key_t **, const char *)
Definition: auth.c:121
#define DHCP_CONTEXT_PRE_DB
Definition: isclib.h:130
isc_boolean_t no_pid_file
Definition: dhcpd.c:101
#define SV_DELAYED_ACK
Definition: dhcpd.h:767
#define PLM_PREFER
Definition: dhcpd.h:874
#define SV_LEASE_FILE_NAME
Definition: dhcpd.h:735
int dhcpv4_over_dhcpv6
Definition: discover.c:48
void data_string_forget(struct data_string *data, const char *file, int line)
Definition: alloc.c:1339
struct group * root_group
Definition: memory.c:31
int server_id_check
Definition: dhcpd.c:82
#define SV_RELEASE_ON_ROAM
Definition: dhcpd.h:818
int log_error(const char *,...) __attribute__((__format__(__printf__
#define _PATH_DHCPD6_PID
Definition: config.h:247
void add_timeout(struct timeval *when, void(*)(void *) where, void *what, tvref_t ref, tvunref_t unref)
Definition: dispatch.c:197
#define DHCP_R_INVALIDKEY
Definition: result.h:56
void omapi_print_dmalloc_usage_by_caller(void)
void mark_interfaces_unavailable(void)
Definition: mdb6.c:2524
Definition: dhcpd.h:288
void do_packet(struct interface_info *interface, struct dhcp_packet *packet, unsigned len, unsigned int from_port, struct iaddr from, struct hardware *hfrom)
Definition: options.c:4009
void dispatch(void)
Definition: dispatch.c:109
#define _PATH_DHCPD_DB
Definition: config.h:253
#define DHCP_LOG_OPTIONS
Definition: dhcpd.h:1619
#define SV_LOG_FACILITY
Definition: dhcpd.h:753
void log_fatal(const char *,...) __attribute__((__format__(__printf__
#define SV_SERVER_ID_CHECK
Definition: dhcpd.h:804
int dont_use_fsync
Definition: dhcpd.c:81
isc_result_t omapi_io_state_foreach(isc_result_t(*func)(omapi_object_t *, void *), void *p)
calls a given function on every object
Definition: dispatch.c:904
#define DHCP_CONTEXT_POST_DB
Definition: isclib.h:131
struct executable_statement * statements
Definition: dhcpd.h:955
u_int32_t abandon_lease_time
Definition: dhcpd.c:95
void interface_trace_setup(void)
int bind_local_address6
int ddns_update_style
Definition: dhcpd.c:80
void free_lease_state(struct lease_state *, const char *, int)
Definition: salloc.c:198
omapi_object_type_t * omapi_type_listener
Definition: support.c:34
int server_identifier_matched
Definition: dhcpd.c:64
omapi_object_type_t * omapi_type_protocol
Definition: support.c:38
u_int16_t validate_port(char *port)
Definition: inet.c:659
void dhcp_signal_handler(int signal)
Definition: isclib.c:337
void postconf_initialization(int quiet)
Definition: dhcpd.c:1071
int find_subnet(struct subnet **sp, struct iaddr addr, const char *file, int line)
Definition: dhclient.c:1536
void execute_statements_in_scope(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct group *group, struct group *limiting_group, struct on_star *on_star)
Definition: execute.c:563
isc_result_t readconf(void)
Definition: confpars.c:64
u_int16_t ddns_conflict_mask
#define FAILOVER_PROTOCOL
Definition: config.h:33
int option_state_allocate(struct option_state **ptr, const char *file, int line)
Definition: alloc.c:846
#define DHCPD_USAGEH
Definition: dhcpd.c:188
isc_result_t dhcp_context_create(int flags, struct in_addr *local4, struct in6_addr *local6)
Definition: isclib.c:138
int evaluate_option_cache(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
Definition: tree.c:2699
isc_result_t dhcp_failover_set_state(dhcp_failover_state_t *, enum failover_state)
#define DISCOVER_SERVER
Definition: dhcpd.h:696
void trace_seed_stop(trace_type_t *)
#define DHCPD_LOG_FACILITY
Definition: dhcpd.h:1610
void mark_phosts_unavailable(void)
Definition: mdb6.c:2519
struct iaddr interface_address
Definition: dhcpd.h:1066
int max_ack_delay_secs
Definition: dhcpd.h:1014
void abandon_lease(struct lease *, const char *)
Definition: mdb.c:1807
uid_t set_uid
gid_t set_gid
ia_hash_t * ia_na_active
isc_result_t dhcp_set_control_state(control_object_state_t oldstate, control_object_state_t newstate)
Definition: dhcpd.c:1765
trace_type_t * trace_type_register(const char *, void *, void(*)(trace_type_t *, unsigned, char *), void(*)(trace_type_t *), const char *, int)
int group_allocate(struct group **ptr, const char *file, int line)
Definition: alloc.c:145
isc_result_t omapi_listener_destroy(omapi_object_t *, const char *, int)
Definition: listener.c:441
u_int16_t local_port
Definition: dhclient.c:94
Definition: dhcpd.h:405
int write_server_duid(void)
int(* group_write_hook)(struct group_object *)
Definition: memory.c:33
isc_result_t omapi_object_dereference(omapi_object_t **, const char *, int)
Definition: alloc.c:593
void set_time(TIME t)
Definition: dispatch.c:36
dhcp_shutdown_state
Definition: dhcpd.h:269
#define _PATH_DHCPD6_DB
Definition: config.h:244
isc_result_t omapi_generic_new(omapi_object_t **, const char *, int)
#define cur_time
Definition: dhcpd.h:2109
int quiet
Definition: dhclient.c:104
Definition: ip.h:47
omapi_object_type_t * omapi_type_protocol_listener
Definition: support.c:39
u_int32_t getUShort(const unsigned char *)
void dfree(void *, const char *, int)
Definition: alloc.c:145
omapi_object_type_t * dhcp_type_interface
Definition: discover.c:80
void trace_file_replay(const char *)
#define SV_DHCPV6_PID_FILE_NAME
Definition: dhcpd.h:764
dhcp_failover_state_t * failover_states
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
Definition: options.c:2465
#define DHCPD_USAGEC
Definition: dhcpd.c:184
int max_ack_delay_usecs
control_object_state_t
Definition: dhcpd.h:522
void dhcp_db_objects_setup(void)
Definition: omapi.c:57
struct in_addr limited_broadcast
Definition: discover.c:54
int int log_info(const char *,...) __attribute__((__format__(__printf__
int main(int argc, char **argv)
Definition: dhcpd.c:252
void trace_seed_stash(trace_type_t *, unsigned)
u_int16_t validate_port_pair(char *port)
Definition: inet.c:685
void * dmalloc(size_t, const char *, int)
Definition: alloc.c:57
struct interface_info * interfaces
Definition: discover.c:42
u_int32_t flags
Definition: dhcpd.h:1406
u_int32_t getULong(const unsigned char *)
struct shared_network * shared_network
Definition: dhcpd.h:1064
void db_startup(int testp)
Definition: dhclient.c:2096
void lease_pinged(struct iaddr from, u_int8_t *packet, int length)
Definition: dhcpd.c:1494
dhcp_control_object_t * dhcp_control_object
int(* dhcp_interface_setup_hook)(struct interface_info *, struct iaddr *)
Definition: discover.c:49
isc_result_t dhcp_io_shutdown(omapi_object_t *obj, void *foo)
Definition: dhcpd.c:1628
Definition: inet.h:31
#define DEFAULT_HASH_SIZE
Definition: hash.h:33
void dhcp_failover_startup(void)
int local_family
Definition: discover.c:56
int shutdown_signal
Definition: isclib.c:34
int quiet_interface_discovery
Definition: discover.c:44
#define DEFAULT_ABANDON_LEASE_TIME
Definition: dhcpd.h:870
#define SV_REMOTE_PORT
Definition: dhcpd.h:743
int option_state_dereference(struct option_state **ptr, const char *file, int line)
Definition: alloc.c:911
ia_hash_t * ia_pd_active
Definition: dhcpd.h:947
void initialize_common_option_spaces()
Definition: tables.c:1053
struct timeval cur_tv
Definition: dispatch.c:35
void trace_ddns_init(void)
struct interface_info * next
Definition: dhcpd.h:1367
int evaluate_boolean_option_cache(int *ignorep, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
Definition: tree.c:2733
int do_release_on_roam
#define DHCPD_USAGET
Definition: dhcpd.c:181
void schedule_all_ipv6_lease_timeouts()
Definition: mdb6.c:2206
#define SV_ABANDON_LEASE_TIME
Definition: dhcpd.h:807
#define SV_OMAPI_PORT
Definition: dhcpd.h:740
void report_jumbo_ranges()
Definition: mdb6.c:2737
isc_result_t trace_begin(const char *, const char *, int)
isc_result_t set_server_duid_from_option(void)
time_t TIME
Definition: dhcpd.h:85
isc_result_t omapi_protocol_configure_security(omapi_object_t *, isc_result_t(*)(omapi_object_t *, omapi_addr_t *), isc_result_t(*)(omapi_object_t *, omapi_auth_key_t *))
Definition: protocol.c:966
#define DISCOVER_SERVER46
Definition: dhcpd.h:699
void dhcp_failover_sanity_check(void)
u_int16_t get_conflict_mask(struct option_state *input_options)
struct class known_class
Definition: dhcpd.c:61
int lease_id_format
Definition: dhcpd.c:94
#define DDNS_UPDATE_STYLE_NONE
Definition: dhcpd.h:703
isc_result_t trace_init(void(*set_time)(time_t), const char *, int)
int omapi_port
Definition: dhcpd.c:106
#define SV_DHCPV6_LEASE_FILE_NAME
Definition: dhcpd.h:763
struct class unknown_class
Definition: dhcpd.c:60
struct in_addr local_address
Definition: discover.c:57
#define PACKAGE_VERSION
Definition: config.h:159
int dhcp_max_agent_option_packet_length
Definition: dhcpd.c:103
#define SV_DDNS_LOCAL_ADDRESS6
Definition: dhcpd.h:799
#define SV_PID_FILE_NAME
Definition: dhcpd.h:736
#define SV_LOCAL_ADDRESS6
Definition: dhcpd.h:819
#define SV_PREFIX_LEN_MODE
Definition: dhcpd.h:805
void classification_setup(void)
Definition: class.c:37
isc_result_t omapi_set_int_value(omapi_object_t *, omapi_object_t *, const char *, int)
Definition: support.c:395
#define SV_LIMITED_BROADCAST_ADDRESS
Definition: dhcpd.h:742
u_int16_t remote_port
Definition: dhclient.c:95
int group_writer(struct group_object *)
Definition: db.c:1280
const char * path_dhcpd_conf
Definition: dhcpd.c:97
void dhcp_reply(struct lease *)
Definition: dhcp.c:3800
char * name
Definition: dhcpd.h:1045
struct enumeration syslog_enum
Definition: stables.c:446
int authoring_byte_order
Definition: dhcpd.c:93
int parse_executable_statements(struct executable_statement **statements, struct parse *cfile, int *lose, enum expression_context case_context)
Definition: parse.c:2117
isc_result_t omapi_disconnect(omapi_object_t *, int)
Definition: connection.c:455
Definition: dhcpd.h:1087
const unsigned char * data
Definition: tree.h:78
void dhcp_common_objects_setup(void)
isc_result_t generate_new_server_duid(void)
TIME ends
Definition: dhcpd.h:569
enum dhcp_shutdown_state shutdown_state
Definition: dhcpd.c:1626
struct iaddr server_identifier
Definition: dhcpd.c:63
struct in6_addr local_address6
struct enumeration prefix_length_modes
Definition: stables.c:376
const char * path_dhcpd_pid
Definition: dhcpd.c:99
void trace_seed_input(trace_type_t *, unsigned, char *)
int find_lease_by_ip_addr(struct lease **, struct iaddr, const char *, int)
Definition: mdb.c:2029
#define _PATH_DHCPD_PID
Definition: config.h:256
struct enumeration ddns_styles
Definition: stables.c:361
void discover_interfaces(int state)
Definition: discover.c:568
#define DHCPD_USAGE0
Definition: dhcpd.c:152
struct interface_info * interface
Definition: dhcpd.h:1065
isc_result_t new_parse(struct parse **cfile, int file, char *inbuf, unsigned buflen, const char *name, int eolp)
Definition: conflex.c:41
#define SV_OMAPI_KEY
Definition: dhcpd.h:745
#define DHCP_MTU_MAX
Definition: dhcp.h:41
#define SV_CHECK_SECS_BYTE_ORDER
Definition: dhcpd.h:813
void trace_replay_init(void)
#define INTERFACE_REQUESTED
Definition: dhcpd.h:1407
#define _PATH_DHCPD_CONF
Definition: dhcpd.h:1552
void postdb_startup(void)
Definition: dhcpd.c:1476
isc_result_t omapi_init(void)
Definition: support.c:61
#define IGNORE_RET(x)
Definition: cdefs.h:54
int log_perror
Definition: errwarn.c:43
#define SV_LOCAL_PORT
Definition: dhcpd.h:741