ISC DHCP  4.3.2
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-2015 by Internet Systems Consortium, Inc. ("ISC")
7  * Copyright (c) 1996-2003 by Internet Software Consortium
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  *
21  * Internet Systems Consortium, Inc.
22  * 950 Charter Street
23  * Redwood City, CA 94063
24  * <info@isc.org>
25  * https://www.isc.org/
26  *
27  */
28 
29 static const char copyright[] =
30 "Copyright 2004-2015 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 
45 #if defined (PARANOIA)
46 # include <sys/types.h>
47 # include <unistd.h>
48 # include <pwd.h>
49 /* get around the ISC declaration of group */
50 # define group real_group
51 # include <grp.h>
52 # undef group
53 #endif /* PARANOIA */
54 
55 #include "trace.h"
56 
57 #ifdef HAVE_LIBSYSTEMD
58 #include <systemd/sd-daemon.h>
59 #endif
60 
61 #ifndef UNIT_TEST
62 static void usage(void);
63 #endif
64 
67 
68 #if defined (NSUPDATE)
69 
70 /* This stuff is always executed to figure the default values for certain
71  ddns variables. */
72 char std_nsupdate [] = " \n\
73 option server.ddns-hostname = \n\
74  pick (option fqdn.hostname, option host-name, config-option host-name); \n\
75 option server.ddns-domainname = config-option domain-name; \n\
76 option server.ddns-rev-domainname = \"in-addr.arpa.\";";
77 
78 #endif /* NSUPDATE */
80 int dont_use_fsync = 0; /* 0 = default, use fsync, 1 = don't use fsync */
81 int server_id_check = 0; /* 0 = default, don't check server id, 1 = do check */
83 
87 /* False (default) => we write and use a pid file */
88 isc_boolean_t no_pid_file = ISC_FALSE;
89 
91 
92 static omapi_auth_key_t *omapi_key = (omapi_auth_key_t *)0;
94 
95 #if defined (TRACING)
96 trace_type_t *trace_srandom;
97 #endif
98 
99 static isc_result_t verify_addr (omapi_object_t *l, omapi_addr_t *addr) {
100  return ISC_R_SUCCESS;
101 }
102 
103 static isc_result_t verify_auth (omapi_object_t *p, omapi_auth_key_t *a) {
104  if (a != omapi_key)
105  return DHCP_R_INVALIDKEY;
106  return ISC_R_SUCCESS;
107 }
108 
109 static void omapi_listener_start (void *foo)
110 {
111  omapi_object_t *listener;
112  isc_result_t result;
113  struct timeval tv;
114 
115  listener = (omapi_object_t *)0;
116  result = omapi_generic_new (&listener, MDL);
117  if (result != ISC_R_SUCCESS)
118  log_fatal ("Can't allocate new generic object: %s",
119  isc_result_totext (result));
120  result = omapi_protocol_listen (listener,
121  (unsigned)omapi_port, 1);
122  if (result == ISC_R_SUCCESS && omapi_key)
124  (listener, verify_addr, verify_auth);
125  if (result != ISC_R_SUCCESS) {
126  log_error ("Can't start OMAPI protocol: %s",
127  isc_result_totext (result));
128  tv.tv_sec = cur_tv.tv_sec + 5;
129  tv.tv_usec = cur_tv.tv_usec;
130  add_timeout (&tv, omapi_listener_start, 0, 0, 0);
131  }
132  omapi_object_dereference (&listener, MDL);
133 }
134 
135 #if defined (PARANOIA)
136 /* to be used in one of two possible scenarios */
137 static void setup_chroot (char *chroot_dir) {
138  if (geteuid())
139  log_fatal ("you must be root to use chroot");
140 
141  if (chroot(chroot_dir)) {
142  log_fatal ("chroot(\"%s\"): %m", chroot_dir);
143  }
144  if (chdir ("/")) {
145  /* probably permission denied */
146  log_fatal ("chdir(\"/\"): %m");
147  }
148 }
149 #endif /* PARANOIA */
150 
151 #ifndef UNIT_TEST
152 int
153 main(int argc, char **argv) {
154  int fd;
155  int i, status;
156  struct servent *ent;
157  char *s;
158  int cftest = 0;
159  int lftest = 0;
160  int pid;
161  char pbuf [20];
162 #ifndef DEBUG
163  int daemon = 1;
164 #endif
165  int quiet = 0;
166  char *server = (char *)0;
167  isc_result_t result;
168  unsigned seed;
169  struct interface_info *ip;
170 #if defined (NSUPDATE)
171  struct parse *parse;
172  int lose;
173 #endif
174  int no_dhcpd_conf = 0;
175  int no_dhcpd_db = 0;
176  int no_dhcpd_pid = 0;
177 #ifdef DHCPv6
178  int local_family_set = 0;
179 #endif /* DHCPv6 */
180 #if defined (TRACING)
181  char *traceinfile = (char *)0;
182  char *traceoutfile = (char *)0;
183 #endif
184 
185 #if defined (PARANOIA)
186  char *set_user = 0;
187  char *set_group = 0;
188  char *set_chroot = 0;
189 
190  uid_t set_uid = 0;
191  gid_t set_gid = 0;
192 #endif /* PARANOIA */
193 
194  /* Make sure that file descriptors 0 (stdin), 1, (stdout), and
195  2 (stderr) are open. To do this, we assume that when we
196  open a file the lowest available file descriptor is used. */
197  fd = open("/dev/null", O_RDWR | O_CLOEXEC);
198  if (fd == 0)
199  fd = open("/dev/null", O_RDWR | O_CLOEXEC);
200  if (fd == 1)
201  fd = open("/dev/null", O_RDWR | O_CLOEXEC);
202  if (fd == 2)
203  log_perror = 0; /* No sense logging to /dev/null. */
204  else if (fd != -1)
205  close(fd);
206 
207  /* Set up the isc and dns library managers */
209  NULL, NULL);
210  if (status != ISC_R_SUCCESS)
211  log_fatal("Can't initialize context: %s",
212  isc_result_totext(status));
213 
214  /* Set up the client classification system. */
216 
217  /* Initialize the omapi system. */
218  result = omapi_init ();
219  if (result != ISC_R_SUCCESS)
220  log_fatal ("Can't initialize OMAPI: %s",
221  isc_result_totext (result));
222 
223  /* Set up the OMAPI wrappers for common objects. */
225  /* Set up the OMAPI wrappers for various server database internal
226  objects. */
228 
229  /* Initially, log errors to stderr as well as to syslogd. */
230  openlog ("dhcpd", DHCP_LOG_OPTIONS, DHCPD_LOG_FACILITY);
231 
232  for (i = 1; i < argc; i++) {
233  if (!strcmp (argv [i], "-p")) {
234  if (++i == argc)
235  usage ();
236  local_port = validate_port (argv [i]);
237  log_debug ("binding to user-specified port %d",
238  ntohs (local_port));
239  } else if (!strcmp (argv [i], "-f")) {
240 #ifndef DEBUG
241  daemon = 0;
242 #endif
243  } else if (!strcmp (argv [i], "-d")) {
244 #ifndef DEBUG
245  daemon = 0;
246 #endif
247  log_perror = -1;
248  } else if (!strcmp (argv [i], "-s")) {
249  if (++i == argc)
250  usage ();
251  server = argv [i];
252 #if defined (PARANOIA)
253  } else if (!strcmp (argv [i], "-user")) {
254  if (++i == argc)
255  usage ();
256  set_user = argv [i];
257  } else if (!strcmp (argv [i], "-group")) {
258  if (++i == argc)
259  usage ();
260  set_group = argv [i];
261  } else if (!strcmp (argv [i], "-chroot")) {
262  if (++i == argc)
263  usage ();
264  set_chroot = argv [i];
265 #endif /* PARANOIA */
266  } else if (!strcmp (argv [i], "-cf")) {
267  if (++i == argc)
268  usage ();
269  path_dhcpd_conf = argv [i];
270  no_dhcpd_conf = 1;
271  } else if (!strcmp (argv [i], "-lf")) {
272  if (++i == argc)
273  usage ();
274  path_dhcpd_db = argv [i];
275  no_dhcpd_db = 1;
276  } else if (!strcmp (argv [i], "-pf")) {
277  if (++i == argc)
278  usage ();
279  path_dhcpd_pid = argv [i];
280  no_dhcpd_pid = 1;
281  } else if (!strcmp(argv[i], "--no-pid")) {
282  no_pid_file = ISC_TRUE;
283  } else if (!strcmp (argv [i], "-t")) {
284  /* test configurations only */
285 #ifndef DEBUG
286  daemon = 0;
287 #endif
288  cftest = 1;
289  log_perror = -1;
290  } else if (!strcmp (argv [i], "-T")) {
291  /* test configurations and lease file only */
292 #ifndef DEBUG
293  daemon = 0;
294 #endif
295  cftest = 1;
296  lftest = 1;
297  log_perror = -1;
298  } else if (!strcmp (argv [i], "-q")) {
299  quiet = 1;
301 #ifdef DHCPv6
302  } else if (!strcmp(argv[i], "-4")) {
303  if (local_family_set && (local_family != AF_INET)) {
304  log_fatal("Server cannot run in both IPv4 and "
305  "IPv6 mode at the same time.");
306  }
307  local_family = AF_INET;
308  local_family_set = 1;
309  } else if (!strcmp(argv[i], "-6")) {
310  if (local_family_set && (local_family != AF_INET6)) {
311  log_fatal("Server cannot run in both IPv4 and "
312  "IPv6 mode at the same time.");
313  }
314  local_family = AF_INET6;
315  local_family_set = 1;
316 #endif /* DHCPv6 */
317  } else if (!strcmp (argv [i], "--version")) {
318  const char vstring[] = "isc-dhcpd-";
319  IGNORE_RET(write(STDERR_FILENO, vstring,
320  strlen(vstring)));
323  strlen(PACKAGE_VERSION)));
324  IGNORE_RET(write(STDERR_FILENO, "\n", 1));
325  exit (0);
326 #if defined (TRACING)
327  } else if (!strcmp (argv [i], "-tf")) {
328  if (++i == argc)
329  usage ();
330  traceoutfile = argv [i];
331  } else if (!strcmp (argv [i], "-play")) {
332  if (++i == argc)
333  usage ();
334  traceinfile = argv [i];
336 #endif /* TRACING */
337  } else if (argv [i][0] == '-') {
338  usage ();
339  } else {
340  struct interface_info *tmp =
341  (struct interface_info *)0;
342  if (strlen(argv[i]) >= sizeof(tmp->name))
343  log_fatal("%s: interface name too long "
344  "(is %ld)",
345  argv[i], (long)strlen(argv[i]));
346  result = interface_allocate (&tmp, MDL);
347  if (result != ISC_R_SUCCESS)
348  log_fatal ("Insufficient memory to %s %s: %s",
349  "record interface", argv [i],
350  isc_result_totext (result));
351  strcpy (tmp -> name, argv [i]);
352  if (interfaces) {
353  interface_reference (&tmp -> next,
354  interfaces, MDL);
355  interface_dereference (&interfaces, MDL);
356  }
357  interface_reference (&interfaces, tmp, MDL);
358  tmp -> flags = INTERFACE_REQUESTED;
359  }
360  }
361 
362  if (!no_dhcpd_conf && (s = getenv ("PATH_DHCPD_CONF"))) {
363  path_dhcpd_conf = s;
364  }
365 
366 #ifdef DHCPv6
367  if (local_family == AF_INET6) {
368  /* DHCPv6: override DHCPv4 lease and pid filenames */
369  if (!no_dhcpd_db) {
370  if ((s = getenv ("PATH_DHCPD6_DB")))
371  path_dhcpd_db = s;
372  else
374  }
375  if (!no_dhcpd_pid) {
376  if ((s = getenv ("PATH_DHCPD6_PID")))
377  path_dhcpd_pid = s;
378  else
380  }
381  } else
382 #else /* !DHCPv6 */
383  {
384  if (!no_dhcpd_db && (s = getenv ("PATH_DHCPD_DB"))) {
385  path_dhcpd_db = s;
386  }
387  if (!no_dhcpd_pid && (s = getenv ("PATH_DHCPD_PID"))) {
388  path_dhcpd_pid = s;
389  }
390  }
391 #endif /* DHCPv6 */
392 
393  /*
394  * convert relative path names to absolute, for files that need
395  * to be reopened after chdir() has been called
396  */
397  if (path_dhcpd_db[0] != '/') {
398  const char *path = path_dhcpd_db;
399  path_dhcpd_db = realpath(path_dhcpd_db, NULL);
400  if (path_dhcpd_db == NULL)
401  log_fatal("Failed to get realpath for %s: %s", path,
402  strerror(errno));
403  }
404 
405  if (!quiet) {
406  log_info("%s %s", message, PACKAGE_VERSION);
407  log_info (copyright);
408  log_info (arr);
409  log_info (url);
410  } else {
411  log_perror = 0;
412  }
413 
414 #if defined (TRACING)
416  if (traceoutfile) {
417  result = trace_begin (traceoutfile, MDL);
418  if (result != ISC_R_SUCCESS)
419  log_fatal ("Unable to begin trace: %s",
420  isc_result_totext (result));
421  }
424  trace_srandom = trace_type_register ("random-seed", (void *)0,
427 #if defined (NSUPDATE)
428  trace_ddns_init();
429 #endif /* NSUPDATE */
430 #endif
431 
432 #if defined (PARANOIA)
433  /* get user and group info if those options were given */
434  if (set_user) {
435  struct passwd *tmp_pwd;
436 
437  if (geteuid())
438  log_fatal ("you must be root to set user");
439 
440  if (!(tmp_pwd = getpwnam(set_user)))
441  log_fatal ("no such user: %s", set_user);
442 
443  set_uid = tmp_pwd->pw_uid;
444 
445  /* use the user's group as the default gid */
446  if (!set_group)
447  set_gid = tmp_pwd->pw_gid;
448  }
449 
450  if (set_group) {
451 /* get around the ISC declaration of group */
452 #define group real_group
453  struct group *tmp_grp;
454 
455  if (geteuid())
456  log_fatal ("you must be root to set group");
457 
458  if (!(tmp_grp = getgrnam(set_group)))
459  log_fatal ("no such group: %s", set_group);
460 
461  set_gid = tmp_grp->gr_gid;
462 #undef group
463  }
464 
465 # if defined (EARLY_CHROOT)
466  if (set_chroot) setup_chroot (set_chroot);
467 # endif /* EARLY_CHROOT */
468 #endif /* PARANOIA */
469 
470  /* Default to the DHCP/BOOTP port. */
471  if (!local_port)
472  {
473  if ((s = getenv ("DHCPD_PORT"))) {
475  log_debug ("binding to environment-specified port %d",
476  ntohs (local_port));
477  } else {
478  if (local_family == AF_INET) {
479  ent = getservbyname("dhcp", "udp");
480  if (ent == NULL) {
481  local_port = htons(67);
482  } else {
483  local_port = ent->s_port;
484  }
485  } else {
486  /* INSIST(local_family == AF_INET6); */
487  ent = getservbyname("dhcpv6-server", "udp");
488  if (ent == NULL) {
489  local_port = htons(547);
490  } else {
491  local_port = ent->s_port;
492  }
493  }
494 #ifndef __CYGWIN32__ /* XXX */
495  endservent ();
496 #endif
497  }
498  }
499 
500  if (local_family == AF_INET) {
501  remote_port = htons(ntohs(local_port) + 1);
502  } else {
503  /* INSIST(local_family == AF_INET6); */
504  ent = getservbyname("dhcpv6-client", "udp");
505  if (ent == NULL) {
506  remote_port = htons(546);
507  } else {
508  remote_port = ent->s_port;
509  }
510  }
511 
512  if (server) {
513  if (local_family != AF_INET) {
514  log_fatal("You can only specify address to send "
515  "replies to when running an IPv4 server.");
516  }
517  if (!inet_aton (server, &limited_broadcast)) {
518  struct hostent *he;
519  he = gethostbyname (server);
520  if (he) {
521  memcpy (&limited_broadcast,
522  he -> h_addr_list [0],
523  sizeof limited_broadcast);
524  } else
525  limited_broadcast.s_addr = INADDR_BROADCAST;
526  }
527  } else {
528  limited_broadcast.s_addr = INADDR_BROADCAST;
529  }
530 
531  /* Get the current time... */
532  gettimeofday(&cur_tv, NULL);
533 
534  /* Set up the initial dhcp option universe. */
537 
538  /* Add the ddns update style enumeration prior to parsing. */
541 #if defined (LDAP_CONFIGURATION)
542  add_enumeration (&ldap_methods);
543 #if defined (LDAP_USE_SSL)
544  add_enumeration (&ldap_ssl_usage_enum);
545  add_enumeration (&ldap_tls_reqcert_enum);
546  add_enumeration (&ldap_tls_crlcheck_enum);
547 #endif
548 #endif
549 
550  if (!group_allocate (&root_group, MDL))
551  log_fatal ("Can't allocate root group!");
552  root_group -> authoritative = 0;
553 
554  /* Set up various hooks. */
557 #ifdef DHCPv6
560 #endif /* DHCPv6 */
561 
562 #if defined (NSUPDATE)
563  /* Set up the standard name service updater routine. */
564  parse = NULL;
565  status = new_parse(&parse, -1, std_nsupdate, sizeof(std_nsupdate) - 1,
566  "standard name service update routine", 0);
567  if (status != ISC_R_SUCCESS)
568  log_fatal ("can't begin parsing name service updater!");
569 
570  if (parse != NULL) {
571  lose = 0;
573  parse, &lose, context_any))) {
574  end_parse(&parse);
575  log_fatal("can't parse standard name service updater!");
576  }
577  end_parse(&parse);
578  }
579 #endif
580 
581  /* Initialize icmp support... */
582  if (!cftest && !lftest)
584 
585 #if defined (TRACING)
586  if (traceinfile) {
587  if (!no_dhcpd_db) {
588  log_error ("%s", "");
589  log_error ("** You must specify a lease file with -lf.");
590  log_error (" Dhcpd will not overwrite your default");
591  log_fatal (" lease file when playing back a trace. **");
592  }
593  trace_file_replay (traceinfile);
594 
595 #if defined (DEBUG_MEMORY_LEAKAGE) && \
596  defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
597  free_everything ();
599 #endif
600 
601  exit (0);
602  }
603 #endif
604 
605 #ifdef DHCPv6
606  /* set up DHCPv6 hashes */
607  if (!ia_new_hash(&ia_na_active, DEFAULT_HASH_SIZE, MDL)) {
608  log_fatal("Out of memory creating hash for active IA_NA.");
609  }
610  if (!ia_new_hash(&ia_ta_active, DEFAULT_HASH_SIZE, MDL)) {
611  log_fatal("Out of memory creating hash for active IA_TA.");
612  }
613  if (!ia_new_hash(&ia_pd_active, DEFAULT_HASH_SIZE, MDL)) {
614  log_fatal("Out of memory creating hash for active IA_PD.");
615  }
616 #endif /* DHCPv6 */
617 
618  /* Read the dhcpd.conf file... */
619  if (readconf () != ISC_R_SUCCESS)
620  log_fatal ("Configuration file errors encountered -- exiting");
621 
622  postconf_initialization (quiet);
623 
624 #if defined (PARANOIA) && !defined (EARLY_CHROOT)
625  if (set_chroot) setup_chroot (set_chroot);
626 #endif /* PARANOIA && !EARLY_CHROOT */
627 
628 #ifdef DHCPv6
629  /* log info about ipv6_ponds with large address ranges */
631 #endif
632 
633  /* test option should cause an early exit */
634  if (cftest && !lftest)
635  exit(0);
636 
637  /*
638  * First part of dealing with pid files. Check to see if
639  * we should continue running or not. We run if:
640  * - we are testing the lease file out
641  * - we don't have a pid file to check
642  * - there is no other process running
643  */
644  if ((lftest == 0) && (no_pid_file == ISC_FALSE)) {
645  /*Read previous pid file. */
646  if ((i = open(path_dhcpd_pid, O_RDONLY)) >= 0) {
647  status = read(i, pbuf, (sizeof pbuf) - 1);
648  close(i);
649  if (status > 0) {
650  pbuf[status] = 0;
651  pid = atoi(pbuf);
652 
653  /*
654  * If there was a previous server process and
655  * it is still running, abort
656  */
657  if (!pid ||
658  (pid != getpid() && kill(pid, 0) == 0))
659  log_fatal("There's already a "
660  "DHCP server running.");
661  }
662  }
663  }
664 
666 
667  /* Start up the database... */
668 #if defined (PARANOIA)
669  db_startup (lftest, set_uid, set_gid);
670 #else
671  db_startup (lftest);
672 #endif /* PARANOIA */
673 
674  if (lftest)
675  exit (0);
676 
677  /* Discover all the network interfaces and initialize them. */
679 
680 #ifdef DHCPv6
681  /*
682  * Remove addresses from our pools that we should not issue
683  * to clients.
684  *
685  * We currently have no support for this in IPv4. It is not
686  * as important in IPv4, as making pools with ranges that
687  * leave out interfaces and hosts is fairly straightforward
688  * using range notation, but not so handy with CIDR notation.
689  */
690  if (local_family == AF_INET6) {
694  }
695 #endif /* DHCPv6 */
696 
697  /* Make up a seed for the random number generator from current
698  time plus the sum of the last four bytes of each
699  interface's hardware address interpreted as an integer.
700  Not much entropy, but we're booting, so we're not likely to
701  find anything better. */
702  seed = 0;
703  for (ip = interfaces; ip; ip = ip -> next) {
704  int junk;
705  memcpy (&junk,
706  &ip -> hw_address.hbuf [ip -> hw_address.hlen -
707  sizeof seed], sizeof seed);
708  seed += junk;
709  }
710  srandom (seed + cur_time);
711 #if defined (TRACING)
712  trace_seed_stash (trace_srandom, seed + cur_time);
713 #endif
714  postdb_startup ();
715 
716 #ifdef DHCPv6
717  /*
718  * Set server DHCPv6 identifier.
719  * See dhcpv6.c for discussion of setting DUID.
720  */
721  if (set_server_duid_from_option() == ISC_R_SUCCESS) {
723  } else {
724  if (!server_duid_isset()) {
725  if (generate_new_server_duid() != ISC_R_SUCCESS) {
726  log_fatal("Unable to set server identifier.");
727  }
729  }
730  }
731 #endif /* DHCPv6 */
732 
733 #ifndef DEBUG
734  if (daemon) {
735  /* First part of becoming a daemon... */
736  if ((pid = fork ()) < 0)
737  log_fatal ("Can't fork daemon: %m");
738  else if (pid)
739  exit (0);
740  }
741 
742  /*
743  * Second part of dealing with pid files. Now
744  * that we have forked we can write our pid if
745  * appropriate.
746  */
747  if (no_pid_file == ISC_FALSE) {
748  i = open(path_dhcpd_pid, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644);
749  if (i >= 0) {
750  sprintf(pbuf, "%d\n", (int) getpid());
751  IGNORE_RET(write(i, pbuf, strlen(pbuf)));
752  close(i);
753  } else {
754  log_error("Can't create PID file %s: %m.",
756  }
757  }
758 
759 #if defined (PARANOIA)
760  /* change uid to the specified one */
761 
762  if (set_gid) {
763  if (setgroups (0, (void *)0))
764  log_fatal ("setgroups: %m");
765  if (setgid (set_gid))
766  log_fatal ("setgid(%d): %m", (int) set_gid);
767  }
768 
769  if (set_uid) {
770  if (setuid (set_uid))
771  log_fatal ("setuid(%d): %m", (int) set_uid);
772  }
773 #endif /* PARANOIA */
774 
775  /* If we were requested to log to stdout on the command line,
776  keep doing so; otherwise, stop. */
777  if (log_perror == -1)
778  log_perror = 1;
779  else
780  log_perror = 0;
781 
782  if (daemon) {
783  /* Become session leader and get pid... */
784  (void) setsid();
785 
786  /* Close standard I/O descriptors. */
787  (void) close(0);
788  (void) close(1);
789  (void) close(2);
790 
791  /* Reopen them on /dev/null. */
792  (void) open("/dev/null", O_RDWR | O_CLOEXEC);
793  (void) open("/dev/null", O_RDWR | O_CLOEXEC);
794  (void) open("/dev/null", O_RDWR | O_CLOEXEC);
795  log_perror = 0; /* No sense logging to /dev/null. */
796 
797  IGNORE_RET (chdir("/"));
798  }
799 #endif /* !DEBUG */
800 
801 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
802  defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
803  dmalloc_cutoff_generation = dmalloc_generation;
804  dmalloc_longterm = dmalloc_outstanding;
805  dmalloc_outstanding = 0;
806 #endif
807 
809  (omapi_object_t *)0, "state", server_running);
810 
811 #if defined(ENABLE_GENTLE_SHUTDOWN)
812  /* no signal handlers until we deal with the side effects */
813  /* install signal handlers */
814  signal(SIGINT, dhcp_signal_handler); /* control-c */
815  signal(SIGTERM, dhcp_signal_handler); /* kill */
816 #endif
817 
818  /* Log that we are about to start working */
819  log_info("Server starting service.");
820 
821  TRACE(DHCPD_MAIN());
822 
823 #ifdef HAVE_LIBSYSTEMD
824  /* We are ready to process incomming packets. Let's notify systemd */
825  sd_notifyf(0, "READY=1\n"
826  "STATUS=Dispatching packets...\n"
827  "MAINPID=%lu",
828  (unsigned long) getpid());
829 #endif
830  /*
831  * Receive packets and dispatch them...
832  * dispatch() will never return.
833  */
834  dispatch ();
835 
836  /* Let's return status code */
837  return 0;
838 }
839 #endif /* !UNIT_TEST */
840 
842 {
843  struct option_state *options = NULL;
844  struct data_string db;
845  struct option_cache *oc;
846  char *s;
847  isc_result_t result;
848  int tmp;
849 #if defined (NSUPDATE)
850  struct in_addr local4, *local4_ptr = NULL;
851  struct in6_addr local6, *local6_ptr = NULL;
852 #endif
853 
854  /* Now try to get the lease file name. */
855  option_state_allocate(&options, MDL);
856 
857  execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL,
858  options, &global_scope, root_group,
859  NULL, NULL);
860  memset(&db, 0, sizeof db);
862  if (oc &&
863  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
864  &global_scope, oc, MDL)) {
865  s = dmalloc(db.len + 1, MDL);
866  if (!s)
867  log_fatal("no memory for lease db filename.");
868  memcpy(s, db.data, db.len);
869  s[db.len] = 0;
870  data_string_forget(&db, MDL);
871  path_dhcpd_db = s;
872  }
873 
875  if (oc &&
876  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
877  &global_scope, oc, MDL)) {
878  s = dmalloc(db.len + 1, MDL);
879  if (!s)
880  log_fatal("no memory for pid filename.");
881  memcpy(s, db.data, db.len);
882  s[db.len] = 0;
883  data_string_forget(&db, MDL);
884  path_dhcpd_pid = s;
885  }
886 
887 #ifdef DHCPv6
888  if (local_family == AF_INET6) {
889  /*
890  * Override lease file name with dhcpv6 lease file name,
891  * if it was set; then, do the same with the pid file name
892  */
893  oc = lookup_option(&server_universe, options,
895  if (oc &&
896  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
897  &global_scope, oc, MDL)) {
898  s = dmalloc(db.len + 1, MDL);
899  if (!s)
900  log_fatal("no memory for lease db filename.");
901  memcpy(s, db.data, db.len);
902  s[db.len] = 0;
903  data_string_forget(&db, MDL);
904  path_dhcpd_db = s;
905  }
906 
907  oc = lookup_option(&server_universe, options,
909  if (oc &&
910  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
911  &global_scope, oc, MDL)) {
912  s = dmalloc(db.len + 1, MDL);
913  if (!s)
914  log_fatal("no memory for pid filename.");
915  memcpy(s, db.data, db.len);
916  s[db.len] = 0;
917  data_string_forget(&db, MDL);
918  path_dhcpd_pid = s;
919  }
920  }
921 #endif /* DHCPv6 */
922 
923  omapi_port = -1;
925  if (oc &&
926  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
927  &global_scope, oc, MDL)) {
928  if (db.len == 2) {
929  omapi_port = getUShort(db.data);
930  } else
931  log_fatal("invalid omapi port data length");
932  data_string_forget(&db, MDL);
933  }
934 
935  oc = lookup_option(&server_universe, options, SV_OMAPI_KEY);
936  if (oc &&
937  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
938  &global_scope, oc, MDL)) {
939  s = dmalloc(db.len + 1, MDL);
940  if (!s)
941  log_fatal("no memory for OMAPI key filename.");
942  memcpy(s, db.data, db.len);
943  s[db.len] = 0;
944  data_string_forget(&db, MDL);
945  result = omapi_auth_key_lookup_name(&omapi_key, s);
946  dfree(s, MDL);
947  if (result != ISC_R_SUCCESS)
948  log_fatal("OMAPI key %s: %s",
949  s, isc_result_totext (result));
950  }
951 
953  if (oc &&
954  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
955  &global_scope, oc, MDL)) {
956  if (db.len == 2) {
957  local_port = htons(getUShort (db.data));
958  } else
959  log_fatal("invalid local port data length");
960  data_string_forget(&db, MDL);
961  }
962 
964  if (oc &&
965  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
966  &global_scope, oc, MDL)) {
967  if (db.len == 2) {
968  remote_port = htons(getUShort (db.data));
969  } else
970  log_fatal("invalid remote port data length");
971  data_string_forget(&db, MDL);
972  }
973 
974  oc = lookup_option(&server_universe, options,
976  if (oc &&
977  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
978  &global_scope, oc, MDL)) {
979  if (db.len == 4) {
980  memcpy(&limited_broadcast, db.data, 4);
981  } else
982  log_fatal("invalid broadcast address data length");
983  data_string_forget(&db, MDL);
984  }
985 
987  if (oc &&
988  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
989  &global_scope, oc, MDL)) {
990  if (db.len == 4) {
991  memcpy(&local_address, db.data, 4);
992  } else
993  log_fatal("invalid local address data length");
994  data_string_forget(&db, MDL);
995  }
996 
998  if (oc) {
999  if (evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1000  &global_scope, oc, MDL)) {
1001  if (db.len == 1) {
1002  ddns_update_style = db.data[0];
1003  } else
1004  log_fatal("invalid dns update type");
1005  data_string_forget(&db, MDL);
1006  }
1007  } else {
1009  }
1010 #if defined (NSUPDATE)
1011  /* We no longer support ad_hoc, tell the user */
1013  log_fatal("ddns-update-style ad_hoc no longer supported");
1014  }
1015 
1017  if (oc) {
1018  if (evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1019  &global_scope, oc, MDL)) {
1020  if (db.len == 4) {
1021  memcpy(&local4, db.data, 4);
1022  local4_ptr = &local4;
1023  }
1024  data_string_forget(&db, MDL);
1025  }
1026  }
1027 
1029  if (oc) {
1030  if (evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1031  &global_scope, oc, MDL)) {
1032  if (db.len == 16) {
1033  memcpy(&local6, db.data, 16);
1034  local6_ptr = &local6;
1035  }
1036  data_string_forget(&db, MDL);
1037  }
1038  }
1039 
1040  if (dhcp_context_create(DHCP_CONTEXT_POST_DB, local4_ptr, local6_ptr)
1041  != ISC_R_SUCCESS)
1042  log_fatal("Unable to complete ddns initialization");
1043 
1044 #else
1045  /* If we don't have support for updates compiled in tell the user */
1047  log_fatal("Support for ddns-update-style not compiled in");
1048  }
1049 #endif
1050 
1051  if (!quiet) {
1052  log_info ("Config file: %s", path_dhcpd_conf);
1053  log_info ("Database file: %s", path_dhcpd_db);
1054  log_info ("PID file: %s", path_dhcpd_pid);
1055  }
1056 
1058  if (oc) {
1059  if (evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1060  &global_scope, oc, MDL)) {
1061  if (db.len == 1) {
1062  closelog ();
1063  openlog("dhcpd", DHCP_LOG_OPTIONS, db.data[0]);
1064  /* Log the startup banner into the new
1065  log file. */
1066  /* Don't log to stderr twice. */
1067  tmp = log_perror;
1068  log_perror = 0;
1069  log_info("%s %s", message, PACKAGE_VERSION);
1070  log_info(copyright);
1071  log_info(arr);
1072  log_info(url);
1073  log_perror = tmp;
1074  } else
1075  log_fatal("invalid log facility");
1076  data_string_forget(&db, MDL);
1077  }
1078  }
1079 
1080  oc = lookup_option(&server_universe, options, SV_DELAYED_ACK);
1081  if (oc &&
1082  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1083  &global_scope, oc, MDL)) {
1084  if (db.len == 2) {
1085  max_outstanding_acks = htons(getUShort(db.data));
1086  } else {
1087  log_fatal("invalid max delayed ACK count ");
1088  }
1089  data_string_forget(&db, MDL);
1090  }
1091 
1093  if (oc &&
1094  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1095  &global_scope, oc, MDL)) {
1096  u_int32_t timeval;
1097 
1098  if (db.len != 4)
1099  log_fatal("invalid max ack delay configuration");
1100 
1101  timeval = getULong(db.data);
1102  max_ack_delay_secs = timeval / 1000000;
1103  max_ack_delay_usecs = timeval % 1000000;
1104 
1105  data_string_forget(&db, MDL);
1106  }
1107 
1109  if ((oc != NULL) &&
1110  evaluate_boolean_option_cache(NULL, NULL, NULL, NULL, options, NULL,
1111  &global_scope, oc, MDL)) {
1112  dont_use_fsync = 1;
1113  log_error("Not using fsync() to flush lease writes");
1114  }
1115 
1117  if ((oc != NULL) &&
1118  evaluate_boolean_option_cache(NULL, NULL, NULL, NULL, options, NULL,
1119  &global_scope, oc, MDL)) {
1120  log_info("Setting server-id-check true");
1121  server_id_check = 1;
1122  }
1123 
1125  if ((oc != NULL) &&
1126  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1127  &global_scope, oc, MDL)) {
1128  if (db.len == 1) {
1129  prefix_length_mode = db.data[0];
1130  } else {
1131  log_fatal("invalid prefix-len-mode");
1132  }
1133 
1134  data_string_forget(&db, MDL);
1135  }
1136 
1137  /* Don't need the options anymore. */
1138  option_state_dereference(&options, MDL);
1139 }
1140 
1141 void postdb_startup (void)
1142 {
1143  /* Initialize the omapi listener state. */
1144  if (omapi_port != -1) {
1145  omapi_listener_start (0);
1146  }
1147 
1148 #if defined (FAILOVER_PROTOCOL)
1149  /* Initialize the failover listener state. */
1151 #endif
1152 
1153  /*
1154  * Begin our lease timeout background task.
1155  */
1157 }
1158 
1159 /* Print usage message. */
1160 #ifndef UNIT_TEST
1161 static void
1162 usage(void) {
1163  log_info("%s %s", message, PACKAGE_VERSION);
1164  log_info(copyright);
1165  log_info(arr);
1166 
1167  log_fatal("Usage: dhcpd [-p <UDP port #>] [-f] [-d] [-q] [-t|-T]\n"
1168 #ifdef DHCPv6
1169  " [-4|-6] [-cf config-file] [-lf lease-file]\n"
1170 #else /* !DHCPv6 */
1171  " [-cf config-file] [-lf lease-file]\n"
1172 #endif /* DHCPv6 */
1173 #if defined (PARANOIA)
1174  /* meld into the following string */
1175  " [-user user] [-group group] [-chroot dir]\n"
1176 #endif /* PARANOIA */
1177 #if defined (TRACING)
1178  " [-tf trace-output-file]\n"
1179  " [-play trace-input-file]\n"
1180 #endif /* TRACING */
1181  " [-pf pid-file] [--no-pid] [-s server]\n"
1182  " [if0 [...ifN]]");
1183 }
1184 #endif
1185 
1186 void lease_pinged (from, packet, length)
1187  struct iaddr from;
1188  u_int8_t *packet;
1189  int length;
1190 {
1191  struct lease *lp;
1192 
1193  /* Don't try to look up a pinged lease if we aren't trying to
1194  ping one - otherwise somebody could easily make us churn by
1195  just forging repeated ICMP EchoReply packets for us to look
1196  up. */
1197  if (!outstanding_pings)
1198  return;
1199 
1200  lp = (struct lease *)0;
1201  if (!find_lease_by_ip_addr (&lp, from, MDL)) {
1202  log_debug ("unexpected ICMP Echo Reply from %s",
1203  piaddr (from));
1204  return;
1205  }
1206 
1207  if (!lp -> state) {
1208 #if defined (FAILOVER_PROTOCOL)
1209  if (!lp -> pool ||
1210  !lp -> pool -> failover_peer)
1211 #endif
1212  log_debug ("ICMP Echo Reply for %s late or spurious.",
1213  piaddr (from));
1214  goto out;
1215  }
1216 
1217  if (lp -> ends > cur_time) {
1218  log_debug ("ICMP Echo reply while lease %s valid.",
1219  piaddr (from));
1220  }
1221 
1222  /* At this point it looks like we pinged a lease and got a
1223  response, which shouldn't have happened. */
1224  data_string_forget (&lp -> state -> parameter_request_list, MDL);
1225  free_lease_state (lp -> state, MDL);
1226  lp -> state = (struct lease_state *)0;
1227 
1228  abandon_lease (lp, "pinged before offer");
1231  out:
1232  lease_dereference (&lp, MDL);
1233 }
1234 
1236  void *vlp;
1237 {
1238  struct lease *lp = vlp;
1239 
1240 #if defined (DEBUG_MEMORY_LEAKAGE)
1241  unsigned long previous_outstanding = dmalloc_outstanding;
1242 #endif
1243 
1245  dhcp_reply (lp);
1246 
1247 #if defined (DEBUG_MEMORY_LEAKAGE)
1248  log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term",
1249  dmalloc_generation,
1250  dmalloc_outstanding - previous_outstanding,
1251  dmalloc_outstanding, dmalloc_longterm);
1252 #endif
1253 #if defined (DEBUG_MEMORY_LEAKAGE)
1254  dmalloc_dump_outstanding ();
1255 #endif
1256 }
1257 
1259 {
1260  struct subnet *subnet;
1261  struct shared_network *share;
1262  isc_result_t status;
1263 
1264  /* Special case for fallback network - not sure why this is
1265  necessary. */
1266  if (!ia) {
1267  const char *fnn = "fallback-net";
1268  status = shared_network_allocate (&ip -> shared_network, MDL);
1269  if (status != ISC_R_SUCCESS)
1270  log_fatal ("No memory for shared subnet: %s",
1271  isc_result_totext (status));
1272  ip -> shared_network -> name = dmalloc (strlen (fnn) + 1, MDL);
1273  strcpy (ip -> shared_network -> name, fnn);
1274  return 1;
1275  }
1276 
1277  /* If there's a registered subnet for this address,
1278  connect it together... */
1279  subnet = (struct subnet *)0;
1280  if (find_subnet (&subnet, *ia, MDL)) {
1281  /* If this interface has multiple aliases on the same
1282  subnet, ignore all but the first we encounter. */
1283  if (!subnet -> interface) {
1284  interface_reference (&subnet -> interface, ip, MDL);
1285  subnet -> interface_address = *ia;
1286  } else if (subnet -> interface != ip) {
1287  log_error ("Multiple interfaces match the %s: %s %s",
1288  "same subnet",
1289  subnet -> interface -> name, ip -> name);
1290  }
1291  share = subnet -> shared_network;
1292  if (ip -> shared_network &&
1293  ip -> shared_network != share) {
1294  log_fatal ("Interface %s matches multiple shared %s",
1295  ip -> name, "networks");
1296  } else {
1297  if (!ip -> shared_network)
1298  shared_network_reference
1299  (&ip -> shared_network, share, MDL);
1300  }
1301 
1302  if (!share -> interface) {
1303  interface_reference (&share -> interface, ip, MDL);
1304  } else if (share -> interface != ip) {
1305  log_error ("Multiple interfaces match the %s: %s %s",
1306  "same shared network",
1307  share -> interface -> name, ip -> name);
1308  }
1309  subnet_dereference (&subnet, MDL);
1310  }
1311  return 1;
1312 }
1313 
1314 static TIME shutdown_time;
1315 static int omapi_connection_count;
1317 
1318 isc_result_t dhcp_io_shutdown (omapi_object_t *obj, void *foo)
1319 {
1320  /* Shut down all listeners. */
1321  if (shutdown_state == shutdown_listeners &&
1322  obj -> type == omapi_type_listener &&
1323  obj -> inner &&
1324  obj -> inner -> type == omapi_type_protocol_listener) {
1325  omapi_listener_destroy (obj, MDL);
1326  return ISC_R_SUCCESS;
1327  }
1328 
1329  /* Shut down all existing omapi connections. */
1330  if (obj -> type == omapi_type_connection &&
1331  obj -> inner &&
1332  obj -> inner -> type == omapi_type_protocol) {
1333  if (shutdown_state == shutdown_drop_omapi_connections) {
1334  omapi_disconnect (obj, 1);
1335  }
1336  omapi_connection_count++;
1337  if (shutdown_state == shutdown_omapi_connections) {
1338  omapi_disconnect (obj, 0);
1339  return ISC_R_SUCCESS;
1340  }
1341  }
1342 
1343  /* Shutdown all DHCP interfaces. */
1344  if (obj -> type == dhcp_type_interface &&
1345  shutdown_state == shutdown_dhcp) {
1347  return ISC_R_SUCCESS;
1348  }
1349  return ISC_R_SUCCESS;
1350 }
1351 
1352 static isc_result_t dhcp_io_shutdown_countdown (void *vlp)
1353 {
1354 #if defined (FAILOVER_PROTOCOL)
1355  dhcp_failover_state_t *state;
1356  int failover_connection_count = 0;
1357 #endif
1358  struct timeval tv;
1359 
1360  oncemore:
1361  if (shutdown_state == shutdown_listeners ||
1362  shutdown_state == shutdown_omapi_connections ||
1363  shutdown_state == shutdown_drop_omapi_connections ||
1364  shutdown_state == shutdown_dhcp) {
1365  omapi_connection_count = 0;
1367  }
1368 
1369  if ((shutdown_state == shutdown_listeners ||
1370  shutdown_state == shutdown_omapi_connections ||
1371  shutdown_state == shutdown_drop_omapi_connections) &&
1372  omapi_connection_count == 0) {
1373  shutdown_state = shutdown_dhcp;
1374  shutdown_time = cur_time;
1375  goto oncemore;
1376  } else if (shutdown_state == shutdown_listeners &&
1377  cur_time - shutdown_time > 4) {
1378  shutdown_state = shutdown_omapi_connections;
1379  shutdown_time = cur_time;
1380  } else if (shutdown_state == shutdown_omapi_connections &&
1381  cur_time - shutdown_time > 4) {
1382  shutdown_state = shutdown_drop_omapi_connections;
1383  shutdown_time = cur_time;
1384  } else if (shutdown_state == shutdown_drop_omapi_connections &&
1385  cur_time - shutdown_time > 4) {
1386  shutdown_state = shutdown_dhcp;
1387  shutdown_time = cur_time;
1388  goto oncemore;
1389  } else if (shutdown_state == shutdown_dhcp &&
1390  cur_time - shutdown_time > 4) {
1391  shutdown_state = shutdown_done;
1392  shutdown_time = cur_time;
1393  }
1394 
1395 #if defined (FAILOVER_PROTOCOL)
1396  /* Set all failover peers into the shutdown state. */
1397  if (shutdown_state == shutdown_dhcp) {
1398  for (state = failover_states; state; state = state -> next) {
1399  if (state -> me.state == normal) {
1401  failover_connection_count++;
1402  }
1403  if (state -> me.state == shut_down &&
1404  state -> partner.state != partner_down)
1405  failover_connection_count++;
1406  }
1407  }
1408 
1409  if (shutdown_state == shutdown_done) {
1410  for (state = failover_states; state; state = state -> next) {
1411  if (state -> me.state == shut_down) {
1412  if (state -> link_to_peer)
1413  dhcp_failover_link_dereference (&state -> link_to_peer,
1414  MDL);
1416  }
1417  }
1418 #if defined (DEBUG_MEMORY_LEAKAGE) && \
1419  defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1420  free_everything ();
1422 #endif
1423  if (no_pid_file == ISC_FALSE)
1424  (void) unlink(path_dhcpd_pid);
1425  exit (0);
1426  }
1427 #else
1428  if (shutdown_state == shutdown_done) {
1429 #if defined (DEBUG_MEMORY_LEAKAGE) && \
1430  defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1431  free_everything ();
1433 #endif
1434  if (no_pid_file == ISC_FALSE)
1435  (void) unlink(path_dhcpd_pid);
1436  exit (0);
1437  }
1438 #endif
1439  if (shutdown_state == shutdown_dhcp &&
1440 #if defined(FAILOVER_PROTOCOL)
1441  !failover_connection_count &&
1442 #endif
1443  ISC_TRUE) {
1444  shutdown_state = shutdown_done;
1445  shutdown_time = cur_time;
1446  goto oncemore;
1447  }
1448  tv.tv_sec = cur_tv.tv_sec + 1;
1449  tv.tv_usec = cur_tv.tv_usec;
1450  add_timeout (&tv,
1451  (void (*)(void *))dhcp_io_shutdown_countdown, 0, 0, 0);
1452  return ISC_R_SUCCESS;
1453 }
1454 
1456  control_object_state_t newstate)
1457 {
1458  struct timeval tv;
1459 
1460  if (newstate != server_shutdown)
1461  return DHCP_R_INVALIDARG;
1462  /* Re-entry. */
1463  if (shutdown_signal == SIGUSR1)
1464  return ISC_R_SUCCESS;
1465  shutdown_time = cur_time;
1466  shutdown_state = shutdown_listeners;
1467  /* Called by user. */
1468  if (shutdown_signal == 0) {
1469  shutdown_signal = SIGUSR1;
1470  dhcp_io_shutdown_countdown (0);
1471  return ISC_R_SUCCESS;
1472  }
1473  /* Called on signal. */
1474  log_info("Received signal %d, initiating shutdown.", shutdown_signal);
1475  shutdown_signal = SIGUSR1;
1476 
1477  /*
1478  * Prompt the shutdown event onto the timer queue
1479  * and return to the dispatch loop.
1480  */
1481  tv.tv_sec = cur_tv.tv_sec;
1482  tv.tv_usec = cur_tv.tv_usec + 1;
1483  add_timeout(&tv,
1484  (void (*)(void *))dhcp_io_shutdown_countdown, 0, 0, 0);
1485  return ISC_R_SUCCESS;
1486 }
#define SV_LOCAL_ADDRESS
Definition: dhcpd.h:698
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:722
const char * path_dhcpd_db
Definition: dhcpd.c:85
void initialize_server_option_spaces(void)
Definition: stables.c:435
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:1258
void mark_hosts_unavailable(void)
Definition: mdb6.c:2292
isc_result_t omapi_protocol_listen(omapi_object_t *, unsigned, int)
Definition: protocol.c:998
void add_enumeration(struct enumeration *enumeration)
Definition: parse.c:37
void parse_trace_setup(void)
#define PARANOIA
Definition: config.h:157
struct binding_scope * global_scope
Definition: tree.c:39
omapi_object_type_t * omapi_type_connection
Definition: support.c:34
Definition: dhcpd.h:521
unsigned len
Definition: tree.h:80
#define SV_DDNS_UPDATE_STYLE
Definition: dhcpd.h:702
const char * piaddr(const struct iaddr addr)
Definition: inet.c:581
char name[IFNAMSIZ]
Definition: dhcpd.h:1305
isc_boolean_t server_duid_isset(void)
isc_result_t end_parse(struct parse **cfile)
Definition: conflex.c:103
void lease_ping_timeout(void *vlp)
Definition: dhcpd.c:1235
void(* bootp_packet_handler)(struct interface_info *, struct dhcp_packet *, unsigned, unsigned int, struct iaddr, struct hardware *)
Definition: discover.c:58
int outstanding_pings
Definition: dhcp.c:41
void * dmalloc(unsigned, const char *, int)
Definition: alloc.c:56
struct lease_state * state
Definition: dhcpd.h:582
#define PLM_EXACT
Definition: dhcpd.h:812
Definition: dhcpd.h:985
struct universe server_universe
Definition: stables.c:175
int max_outstanding_acks
Definition: dhcp.c:48
#define STDERR_FILENO
Definition: osdep.h:288
#define SV_DONT_USE_FSYNC
Definition: dhcpd.h:746
#define MDL
Definition: omapip.h:568
void cancel_timeout(void(*)(void *) where, void *what)
Definition: dispatch.c:390
void icmp_startup(int routep, void *handler)
Definition: icmp.c:48
#define DHCP_R_INVALIDARG
Definition: result.h:48
#define DDNS_UPDATE_STYLE_AD_HOC
Definition: dhcpd.h:658
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
#define SV_DDNS_LOCAL_ADDRESS4
Definition: dhcpd.h:747
void db_startup(int, uid_t, gid_t)
isc_result_t dhcp_interface_remove(omapi_object_t *lp, omapi_object_t *id)
Definition: discover.c:1385
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:126
isc_boolean_t no_pid_file
Definition: dhcpd.c:88
#define SV_DELAYED_ACK
Definition: dhcpd.h:721
#define SV_LEASE_FILE_NAME
Definition: dhcpd.h:689
void data_string_forget(struct data_string *data, const char *file, int line)
Definition: alloc.c:1340
struct group * root_group
Definition: memory.c:31
int server_id_check
Definition: dhcpd.c:81
int log_error(const char *,...) __attribute__((__format__(__printf__
trace_type_t * trace_type_register(const char *, void *, void(*)(trace_type_t *, unsigned, char *), void(*)(trace_type_t *), const char *, int)
#define _PATH_DHCPD6_PID
Definition: config.h:239
void add_timeout(struct timeval *when, void(*)(void *) where, void *what, tvref_t ref, tvunref_t unref)
Definition: dispatch.c:198
#define DHCP_R_INVALIDKEY
Definition: result.h:56
void omapi_print_dmalloc_usage_by_caller(void)
void mark_interfaces_unavailable(void)
Definition: mdb6.c:2347
Definition: dhcpd.h:259
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:3888
void dispatch(void)
Definition: dispatch.c:109
#define _PATH_DHCPD_DB
Definition: config.h:242
#define DHCP_LOG_OPTIONS
Definition: dhcpd.h:1531
#define SV_LOG_FACILITY
Definition: dhcpd.h:707
void log_fatal(const char *,...) __attribute__((__format__(__printf__
#define SV_SERVER_ID_CHECK
Definition: dhcpd.h:753
int dont_use_fsync
Definition: dhcpd.c:80
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:905
#define DHCP_CONTEXT_POST_DB
Definition: isclib.h:127
struct executable_statement * statements
Definition: dhcpd.h:892
void interface_trace_setup(void)
int ddns_update_style
Definition: dhcpd.c:79
void free_lease_state(struct lease_state *, const char *, int)
Definition: salloc.c:196
omapi_object_type_t * omapi_type_listener
Definition: support.c:35
int server_identifier_matched
Definition: dhcpd.c:66
omapi_object_type_t * omapi_type_protocol
Definition: support.c:39
u_int16_t validate_port(char *port)
Definition: inet.c:661
void dhcp_signal_handler(int signal)
Definition: isclib.c:347
void postconf_initialization(int quiet)
Definition: dhcpd.c:841
int find_subnet(struct subnet **sp, struct iaddr addr, const char *file, int line)
Definition: dhclient.c:1280
void execute_statements_in_scope(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct group *group, struct group *limiting_group, struct on_star *on_star)
Definition: execute.c:555
isc_result_t readconf(void)
Definition: confpars.c:57
#define FAILOVER_PROTOCOL
Definition: config.h:27
int option_state_allocate(struct option_state **ptr, const char *file, int line)
Definition: alloc.c:847
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:2688
isc_result_t dhcp_failover_set_state(dhcp_failover_state_t *, enum failover_state)
#define DISCOVER_SERVER
Definition: dhcpd.h:651
void trace_seed_stop(trace_type_t *)
#define DHCPD_LOG_FACILITY
Definition: dhcpd.h:1523
void mark_phosts_unavailable(void)
Definition: mdb6.c:2342
struct iaddr interface_address
Definition: dhcpd.h:991
int max_ack_delay_secs
Definition: dhcp.c:49
Definition: dhcpd.h:939
void abandon_lease(struct lease *, const char *)
Definition: mdb.c:1793
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:1455
int group_allocate(struct group **ptr, const char *file, int line)
Definition: alloc.c:146
isc_result_t omapi_listener_destroy(omapi_object_t *, const char *, int)
Definition: listener.c:437
u_int16_t local_port
Definition: dhclient.c:88
Definition: dhcpd.h:376
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:579
void trace_file_replay(const char *)
void set_time(TIME t)
Definition: dispatch.c:36
dhcp_shutdown_state
Definition: dhcpd.h:240
#define _PATH_DHCPD6_DB
Definition: config.h:236
isc_result_t omapi_generic_new(omapi_object_t **, const char *, int)
#define cur_time
Definition: dhcpd.h:1988
int quiet
Definition: dhclient.c:94
Definition: ip.h:47
omapi_object_type_t * omapi_type_protocol_listener
Definition: support.c:40
u_int32_t getUShort(const unsigned char *)
isc_result_t trace_begin(const char *, const char *, int)
void dfree(void *, const char *, int)
Definition: alloc.c:131
omapi_object_type_t * dhcp_type_interface
Definition: discover.c:71
#define SV_DHCPV6_PID_FILE_NAME
Definition: dhcpd.h:718
dhcp_failover_state_t * failover_states
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
Definition: options.c:2348
int max_ack_delay_usecs
Definition: dhcp.c:50
control_object_state_t
Definition: dhcpd.h:484
void dhcp_db_objects_setup(void)
Definition: omapi.c:55
struct in_addr limited_broadcast
Definition: discover.c:53
int int log_info(const char *,...) __attribute__((__format__(__printf__
int main(int argc, char **argv)
Definition: dhcpd.c:153
void trace_seed_stash(trace_type_t *, unsigned)
struct interface_info * interfaces
Definition: discover.c:43
u_int32_t flags
Definition: dhcpd.h:1319
u_int32_t getULong(const unsigned char *)
struct shared_network * shared_network
Definition: dhcpd.h:989
void trace_replay_init(void)
void lease_pinged(struct iaddr from, u_int8_t *packet, int length)
Definition: dhcpd.c:1186
dhcp_control_object_t * dhcp_control_object
int(* dhcp_interface_setup_hook)(struct interface_info *, struct iaddr *)
Definition: discover.c:48
isc_result_t dhcp_io_shutdown(omapi_object_t *obj, void *foo)
Definition: dhcpd.c:1318
Definition: inet.h:31
#define DEFAULT_HASH_SIZE
Definition: hash.h:33
void dhcp_failover_startup(void)
int local_family
Definition: discover.c:55
int shutdown_signal
Definition: isclib.c:34
int quiet_interface_discovery
Definition: discover.c:45
isc_result_t trace_init(void(*set_time)(time_t), const char *, int)
#define SV_REMOTE_PORT
Definition: dhcpd.h:697
int option_state_dereference(struct option_state **ptr, const char *file, int line)
Definition: alloc.c:912
ia_hash_t * ia_pd_active
Definition: dhcpd.h:884
void initialize_common_option_spaces()
Definition: tables.c:1004
struct timeval cur_tv
Definition: dispatch.c:35
void trace_ddns_init(void)
struct interface_info * next
Definition: dhcpd.h:1280
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:2722
void schedule_all_ipv6_lease_timeouts()
Definition: mdb6.c:2029
#define SV_OMAPI_PORT
Definition: dhcpd.h:694
void report_jumbo_ranges()
Definition: mdb6.c:2510
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:967
#define DDNS_UPDATE_STYLE_NONE
Definition: dhcpd.h:657
int omapi_port
Definition: dhcpd.c:93
#define SV_DHCPV6_LEASE_FILE_NAME
Definition: dhcpd.h:717
struct in_addr local_address
Definition: discover.c:56
#define PACKAGE_VERSION
Definition: config.h:154
int dhcp_max_agent_option_packet_length
Definition: dhcpd.c:90
#define SV_DDNS_LOCAL_ADDRESS6
Definition: dhcpd.h:748
#define SV_PID_FILE_NAME
Definition: dhcpd.h:690
#define SV_PREFIX_LEN_MODE
Definition: dhcpd.h:754
void classification_setup(void)
Definition: class.c:45
isc_result_t omapi_set_int_value(omapi_object_t *, omapi_object_t *, const char *, int)
Definition: support.c:396
#define SV_LIMITED_BROADCAST_ADDRESS
Definition: dhcpd.h:696
u_int16_t remote_port
Definition: dhclient.c:89
int group_writer(struct group_object *)
Definition: db.c:1237
const char * path_dhcpd_conf
Definition: dhcpd.c:84
void dhcp_reply(struct lease *)
Definition: dhcp.c:3569
char * name
Definition: dhcpd.h:970
struct enumeration syslog_enum
Definition: stables.c:429
#define TRACING
Definition: config.h:169
int parse_executable_statements(struct executable_statement **statements, struct parse *cfile, int *lose, enum expression_context case_context)
Definition: parse.c:2105
int prefix_length_mode
Definition: dhcpd.c:82
isc_result_t omapi_disconnect(omapi_object_t *, int)
Definition: connection.c:454
const unsigned char * data
Definition: tree.h:79
void dhcp_common_objects_setup(void)
isc_result_t generate_new_server_duid(void)
TIME ends
Definition: dhcpd.h:527
#define DHCPv6
Definition: config.h:18
enum dhcp_shutdown_state shutdown_state
Definition: dhcpd.c:1316
struct iaddr server_identifier
Definition: dhcpd.c:65
struct enumeration prefix_length_modes
Definition: stables.c:359
const char * path_dhcpd_pid
Definition: dhcpd.c:86
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:2003
#define DHCPD_MAIN()
Definition: probes.h:20
#define _PATH_DHCPD_PID
Definition: config.h:245
struct enumeration ddns_styles
Definition: stables.c:344
void discover_interfaces(int state)
Definition: discover.c:555
struct interface_info * interface
Definition: dhcpd.h:990
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:699
#define DHCP_MTU_MAX
Definition: dhcp.h:42
#define INTERFACE_REQUESTED
Definition: dhcpd.h:1320
#define _PATH_DHCPD_CONF
Definition: dhcpd.h:1465
void postdb_startup(void)
Definition: dhcpd.c:1141
#define TRACE(probe)
Definition: trace.h:10
isc_result_t omapi_init(void)
Definition: support.c:62
#define IGNORE_RET(x)
Definition: cdefs.h:55
int log_perror
Definition: errwarn.c:44
#define SV_LOCAL_PORT
Definition: dhcpd.h:695