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