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