ISC DHCP  4.3.1
A reference DHCPv4 and DHCPv6 implementation
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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", DHCP_LOG_OPTIONS, 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  const char vstring[] = "isc-dhcpd-";
318  IGNORE_RET(write(STDERR_FILENO, vstring,
319  strlen(vstring)));
322  strlen(PACKAGE_VERSION)));
323  IGNORE_RET(write(STDERR_FILENO, "\n", 1));
324  exit (0);
325 #if defined (TRACING)
326  } else if (!strcmp (argv [i], "-tf")) {
327  if (++i == argc)
328  usage ();
329  traceoutfile = argv [i];
330  } else if (!strcmp (argv [i], "-play")) {
331  if (++i == argc)
332  usage ();
333  traceinfile = argv [i];
335 #endif /* TRACING */
336  } else if (argv [i][0] == '-') {
337  usage ();
338  } else {
339  struct interface_info *tmp =
340  (struct interface_info *)0;
341  if (strlen(argv[i]) >= sizeof(tmp->name))
342  log_fatal("%s: interface name too long "
343  "(is %ld)",
344  argv[i], (long)strlen(argv[i]));
345  result = interface_allocate (&tmp, MDL);
346  if (result != ISC_R_SUCCESS)
347  log_fatal ("Insufficient memory to %s %s: %s",
348  "record interface", argv [i],
349  isc_result_totext (result));
350  strcpy (tmp -> name, argv [i]);
351  if (interfaces) {
352  interface_reference (&tmp -> next,
353  interfaces, MDL);
354  interface_dereference (&interfaces, MDL);
355  }
356  interface_reference (&interfaces, tmp, MDL);
357  tmp -> flags = INTERFACE_REQUESTED;
358  }
359  }
360 
361  if (!no_dhcpd_conf && (s = getenv ("PATH_DHCPD_CONF"))) {
362  path_dhcpd_conf = s;
363  }
364 
365 #ifdef DHCPv6
366  if (local_family == AF_INET6) {
367  /* DHCPv6: override DHCPv4 lease and pid filenames */
368  if (!no_dhcpd_db) {
369  if ((s = getenv ("PATH_DHCPD6_DB")))
370  path_dhcpd_db = s;
371  else
373  }
374  if (!no_dhcpd_pid) {
375  if ((s = getenv ("PATH_DHCPD6_PID")))
376  path_dhcpd_pid = s;
377  else
379  }
380  } else
381 #else /* !DHCPv6 */
382  {
383  if (!no_dhcpd_db && (s = getenv ("PATH_DHCPD_DB"))) {
384  path_dhcpd_db = s;
385  }
386  if (!no_dhcpd_pid && (s = getenv ("PATH_DHCPD_PID"))) {
387  path_dhcpd_pid = s;
388  }
389  }
390 #endif /* DHCPv6 */
391 
392  /*
393  * convert relative path names to absolute, for files that need
394  * to be reopened after chdir() has been called
395  */
396  if (path_dhcpd_db[0] != '/') {
397  const char *path = path_dhcpd_db;
398  path_dhcpd_db = realpath(path_dhcpd_db, NULL);
399  if (path_dhcpd_db == NULL)
400  log_fatal("Failed to get realpath for %s: %s", path,
401  strerror(errno));
402  }
403 
404  if (!quiet) {
405  log_info("%s %s", message, PACKAGE_VERSION);
406  log_info (copyright);
407  log_info (arr);
408  log_info (url);
409  log_info ("Config file: %s", path_dhcpd_conf);
410  log_info ("Database file: %s", path_dhcpd_db);
411  log_info ("PID file: %s", path_dhcpd_pid);
412  } else {
413  quiet = 0;
414  log_perror = 0;
415  }
416 
417 #if defined (TRACING)
419  if (traceoutfile) {
420  result = trace_begin (traceoutfile, MDL);
421  if (result != ISC_R_SUCCESS)
422  log_fatal ("Unable to begin trace: %s",
423  isc_result_totext (result));
424  }
427  trace_srandom = trace_type_register ("random-seed", (void *)0,
430 #if defined (NSUPDATE)
431  trace_ddns_init();
432 #endif /* NSUPDATE */
433 #endif
434 
435 #if defined (PARANOIA)
436  /* get user and group info if those options were given */
437  if (set_user) {
438  struct passwd *tmp_pwd;
439 
440  if (geteuid())
441  log_fatal ("you must be root to set user");
442 
443  if (!(tmp_pwd = getpwnam(set_user)))
444  log_fatal ("no such user: %s", set_user);
445 
446  set_uid = tmp_pwd->pw_uid;
447 
448  /* use the user's group as the default gid */
449  if (!set_group)
450  set_gid = tmp_pwd->pw_gid;
451  }
452 
453  if (set_group) {
454 /* get around the ISC declaration of group */
455 #define group real_group
456  struct group *tmp_grp;
457 
458  if (geteuid())
459  log_fatal ("you must be root to set group");
460 
461  if (!(tmp_grp = getgrnam(set_group)))
462  log_fatal ("no such group: %s", set_group);
463 
464  set_gid = tmp_grp->gr_gid;
465 #undef group
466  }
467 
468 # if defined (EARLY_CHROOT)
469  if (set_chroot) setup_chroot (set_chroot);
470 # endif /* EARLY_CHROOT */
471 #endif /* PARANOIA */
472 
473  /* Default to the DHCP/BOOTP port. */
474  if (!local_port)
475  {
476  if ((s = getenv ("DHCPD_PORT"))) {
478  log_debug ("binding to environment-specified port %d",
479  ntohs (local_port));
480  } else {
481  if (local_family == AF_INET) {
482  ent = getservbyname("dhcp", "udp");
483  if (ent == NULL) {
484  local_port = htons(67);
485  } else {
486  local_port = ent->s_port;
487  }
488  } else {
489  /* INSIST(local_family == AF_INET6); */
490  ent = getservbyname("dhcpv6-server", "udp");
491  if (ent == NULL) {
492  local_port = htons(547);
493  } else {
494  local_port = ent->s_port;
495  }
496  }
497 #ifndef __CYGWIN32__ /* XXX */
498  endservent ();
499 #endif
500  }
501  }
502 
503  if (local_family == AF_INET) {
504  remote_port = htons(ntohs(local_port) + 1);
505  } else {
506  /* INSIST(local_family == AF_INET6); */
507  ent = getservbyname("dhcpv6-client", "udp");
508  if (ent == NULL) {
509  remote_port = htons(546);
510  } else {
511  remote_port = ent->s_port;
512  }
513  }
514 
515  if (server) {
516  if (local_family != AF_INET) {
517  log_fatal("You can only specify address to send "
518  "replies to when running an IPv4 server.");
519  }
520  if (!inet_aton (server, &limited_broadcast)) {
521  struct hostent *he;
522  he = gethostbyname (server);
523  if (he) {
524  memcpy (&limited_broadcast,
525  he -> h_addr_list [0],
526  sizeof limited_broadcast);
527  } else
528  limited_broadcast.s_addr = INADDR_BROADCAST;
529  }
530  } else {
531  limited_broadcast.s_addr = INADDR_BROADCAST;
532  }
533 
534  /* Get the current time... */
535  gettimeofday(&cur_tv, NULL);
536 
537  /* Set up the initial dhcp option universe. */
540 
541  /* Add the ddns update style enumeration prior to parsing. */
544 #if defined (LDAP_CONFIGURATION)
545  add_enumeration (&ldap_methods);
546 #if defined (LDAP_USE_SSL)
547  add_enumeration (&ldap_ssl_usage_enum);
548  add_enumeration (&ldap_tls_reqcert_enum);
549  add_enumeration (&ldap_tls_crlcheck_enum);
550 #endif
551 #endif
552 
553  if (!group_allocate (&root_group, MDL))
554  log_fatal ("Can't allocate root group!");
555  root_group -> authoritative = 0;
556 
557  /* Set up various hooks. */
560 #ifdef DHCPv6
562 #endif /* DHCPv6 */
563 
564 #if defined (NSUPDATE)
565  /* Set up the standard name service updater routine. */
566  parse = NULL;
567  status = new_parse(&parse, -1, std_nsupdate, sizeof(std_nsupdate) - 1,
568  "standard name service update routine", 0);
569  if (status != ISC_R_SUCCESS)
570  log_fatal ("can't begin parsing name service updater!");
571 
572  if (parse != NULL) {
573  lose = 0;
575  parse, &lose, context_any))) {
576  end_parse(&parse);
577  log_fatal("can't parse standard name service updater!");
578  }
579  end_parse(&parse);
580  }
581 #endif
582 
583  /* Initialize icmp support... */
584  if (!cftest && !lftest)
586 
587 #if defined (TRACING)
588  if (traceinfile) {
589  if (!no_dhcpd_db) {
590  log_error ("%s", "");
591  log_error ("** You must specify a lease file with -lf.");
592  log_error (" Dhcpd will not overwrite your default");
593  log_fatal (" lease file when playing back a trace. **");
594  }
595  trace_file_replay (traceinfile);
596 
597 #if defined (DEBUG_MEMORY_LEAKAGE) && \
598  defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
599  free_everything ();
601 #endif
602 
603  exit (0);
604  }
605 #endif
606 
607 #ifdef DHCPv6
608  /* set up DHCPv6 hashes */
609  if (!ia_new_hash(&ia_na_active, DEFAULT_HASH_SIZE, MDL)) {
610  log_fatal("Out of memory creating hash for active IA_NA.");
611  }
612  if (!ia_new_hash(&ia_ta_active, DEFAULT_HASH_SIZE, MDL)) {
613  log_fatal("Out of memory creating hash for active IA_TA.");
614  }
615  if (!ia_new_hash(&ia_pd_active, DEFAULT_HASH_SIZE, MDL)) {
616  log_fatal("Out of memory creating hash for active IA_PD.");
617  }
618 #endif /* DHCPv6 */
619 
620  /* Read the dhcpd.conf file... */
621  if (readconf () != ISC_R_SUCCESS)
622  log_fatal ("Configuration file errors encountered -- exiting");
623 
624  postconf_initialization (quiet);
625 
626 #if defined (PARANOIA) && !defined (EARLY_CHROOT)
627  if (set_chroot) setup_chroot (set_chroot);
628 #endif /* PARANOIA && !EARLY_CHROOT */
629 
630  /* test option should cause an early exit */
631  if (cftest && !lftest)
632  exit(0);
633 
635 
636  /* Start up the database... */
637 #if defined (PARANOIA)
638  db_startup (lftest, set_uid, set_gid);
639 #else
640  db_startup (lftest);
641 #endif /* PARANOIA */
642 
643  if (lftest)
644  exit (0);
645 
646  /* Discover all the network interfaces and initialize them. */
648 
649 #ifdef DHCPv6
650  /*
651  * Remove addresses from our pools that we should not issue
652  * to clients.
653  *
654  * We currently have no support for this in IPv4. It is not
655  * as important in IPv4, as making pools with ranges that
656  * leave out interfaces and hosts is fairly straightforward
657  * using range notation, but not so handy with CIDR notation.
658  */
659  if (local_family == AF_INET6) {
663  }
664 #endif /* DHCPv6 */
665 
666 
667  /* Make up a seed for the random number generator from current
668  time plus the sum of the last four bytes of each
669  interface's hardware address interpreted as an integer.
670  Not much entropy, but we're booting, so we're not likely to
671  find anything better. */
672  seed = 0;
673  for (ip = interfaces; ip; ip = ip -> next) {
674  int junk;
675  memcpy (&junk,
676  &ip -> hw_address.hbuf [ip -> hw_address.hlen -
677  sizeof seed], sizeof seed);
678  seed += junk;
679  }
680  srandom (seed + cur_time);
681 #if defined (TRACING)
682  trace_seed_stash (trace_srandom, seed + cur_time);
683 #endif
684  postdb_startup ();
685 
686 #ifdef DHCPv6
687  /*
688  * Set server DHCPv6 identifier.
689  * See dhcpv6.c for discussion of setting DUID.
690  */
691  if (set_server_duid_from_option() == ISC_R_SUCCESS) {
693  } else {
694  if (!server_duid_isset()) {
695  if (generate_new_server_duid() != ISC_R_SUCCESS) {
696  log_fatal("Unable to set server identifier.");
697  }
699  }
700  }
701 #endif /* DHCPv6 */
702 
703 #ifndef DEBUG
704  if (daemon) {
705  /* First part of becoming a daemon... */
706  if ((pid = fork ()) < 0)
707  log_fatal ("Can't fork daemon: %m");
708  else if (pid)
709  exit (0);
710  }
711 
712  /*
713  * Deal with pid files. If the user told us
714  * not to write a file we don't read one either
715  */
716  if (no_pid_file == ISC_FALSE) {
717  /*Read previous pid file. */
718  if ((i = open (path_dhcpd_pid, O_RDONLY | O_CLOEXEC)) >= 0) {
719  status = read(i, pbuf, (sizeof pbuf) - 1);
720  close (i);
721  if (status > 0) {
722  pbuf[status] = 0;
723  pid = atoi(pbuf);
724 
725  /*
726  * If there was a previous server process and
727  * it is still running, abort
728  */
729  if (!pid ||
730  (pid != getpid() && kill(pid, 0) == 0))
731  log_fatal("There's already a "
732  "DHCP server running.");
733  }
734  }
735 
736  /* Write new pid file. */
737  i = open(path_dhcpd_pid, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644);
738  if (i >= 0) {
739  sprintf(pbuf, "%d\n", (int) getpid());
740  IGNORE_RET (write(i, pbuf, strlen(pbuf)));
741  close(i);
742  } else {
743  log_error("Can't create PID file %s: %m.",
745  }
746  }
747 
748 #if defined (PARANOIA)
749  /* change uid to the specified one */
750 
751  if (set_gid) {
752  if (setgroups (0, (void *)0))
753  log_fatal ("setgroups: %m");
754  if (setgid (set_gid))
755  log_fatal ("setgid(%d): %m", (int) set_gid);
756  }
757 
758  if (set_uid) {
759  if (setuid (set_uid))
760  log_fatal ("setuid(%d): %m", (int) set_uid);
761  }
762 #endif /* PARANOIA */
763 
764  /* If we were requested to log to stdout on the command line,
765  keep doing so; otherwise, stop. */
766  if (log_perror == -1)
767  log_perror = 1;
768  else
769  log_perror = 0;
770 
771  if (daemon) {
772  /* Become session leader and get pid... */
773  (void) setsid();
774 
775  /* Close standard I/O descriptors. */
776  (void) close(0);
777  (void) close(1);
778  (void) close(2);
779 
780  /* Reopen them on /dev/null. */
781  (void) open("/dev/null", O_RDWR | O_CLOEXEC);
782  (void) open("/dev/null", O_RDWR | O_CLOEXEC);
783  (void) open("/dev/null", O_RDWR | O_CLOEXEC);
784  log_perror = 0; /* No sense logging to /dev/null. */
785 
786  IGNORE_RET (chdir("/"));
787  }
788 #endif /* !DEBUG */
789 
790 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
791  defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
792  dmalloc_cutoff_generation = dmalloc_generation;
793  dmalloc_longterm = dmalloc_outstanding;
794  dmalloc_outstanding = 0;
795 #endif
796 
798  (omapi_object_t *)0, "state", server_running);
799 
800 #if defined(ENABLE_GENTLE_SHUTDOWN)
801  /* no signal handlers until we deal with the side effects */
802  /* install signal handlers */
803  signal(SIGINT, dhcp_signal_handler); /* control-c */
804  signal(SIGTERM, dhcp_signal_handler); /* kill */
805 #endif
806 
807  /* Log that we are about to start working */
808  log_info("Server starting service.");
809 
810  TRACE(DHCPD_MAIN());
811 
812 #ifdef HAVE_LIBSYSTEMD
813  /* We are ready to process incomming packets. Let's notify systemd */
814  sd_notifyf(0, "READY=1\n"
815  "STATUS=Dispatching packets...\n"
816  "MAINPID=%lu",
817  (unsigned long) getpid());
818 #endif
819  /*
820  * Receive packets and dispatch them...
821  * dispatch() will never return.
822  */
823  dispatch ();
824 
825  /* Let's return status code */
826  return 0;
827 }
828 #endif /* !UNIT_TEST */
829 
831 {
832  struct option_state *options = NULL;
833  struct data_string db;
834  struct option_cache *oc;
835  char *s;
836  isc_result_t result;
837  int tmp;
838 #if defined (NSUPDATE)
839  struct in_addr local4, *local4_ptr = NULL;
840  struct in6_addr local6, *local6_ptr = NULL;
841 #endif
842 
843  /* Now try to get the lease file name. */
844  option_state_allocate(&options, MDL);
845 
846  execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL,
847  options, &global_scope, root_group,
848  NULL, NULL);
849  memset(&db, 0, sizeof db);
851  if (oc &&
852  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
853  &global_scope, oc, MDL)) {
854  s = dmalloc(db.len + 1, MDL);
855  if (!s)
856  log_fatal("no memory for lease db filename.");
857  memcpy(s, db.data, db.len);
858  s[db.len] = 0;
859  data_string_forget(&db, MDL);
860  path_dhcpd_db = s;
861  }
862 
864  if (oc &&
865  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
866  &global_scope, oc, MDL)) {
867  s = dmalloc(db.len + 1, MDL);
868  if (!s)
869  log_fatal("no memory for pid filename.");
870  memcpy(s, db.data, db.len);
871  s[db.len] = 0;
872  data_string_forget(&db, MDL);
873  path_dhcpd_pid = s;
874  }
875 
876 #ifdef DHCPv6
877  if (local_family == AF_INET6) {
878  /*
879  * Override lease file name with dhcpv6 lease file name,
880  * if it was set; then, do the same with the pid file name
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 lease db filename.");
890  memcpy(s, db.data, db.len);
891  s[db.len] = 0;
892  data_string_forget(&db, MDL);
893  path_dhcpd_db = s;
894  }
895 
896  oc = lookup_option(&server_universe, options,
898  if (oc &&
899  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
900  &global_scope, oc, MDL)) {
901  s = dmalloc(db.len + 1, MDL);
902  if (!s)
903  log_fatal("no memory for pid filename.");
904  memcpy(s, db.data, db.len);
905  s[db.len] = 0;
906  data_string_forget(&db, MDL);
907  path_dhcpd_pid = s;
908  }
909  }
910 #endif /* DHCPv6 */
911 
912  omapi_port = -1;
914  if (oc &&
915  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
916  &global_scope, oc, MDL)) {
917  if (db.len == 2) {
918  omapi_port = getUShort(db.data);
919  } else
920  log_fatal("invalid omapi port data length");
921  data_string_forget(&db, MDL);
922  }
923 
924  oc = lookup_option(&server_universe, options, SV_OMAPI_KEY);
925  if (oc &&
926  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
927  &global_scope, oc, MDL)) {
928  s = dmalloc(db.len + 1, MDL);
929  if (!s)
930  log_fatal("no memory for OMAPI key filename.");
931  memcpy(s, db.data, db.len);
932  s[db.len] = 0;
933  data_string_forget(&db, MDL);
934  result = omapi_auth_key_lookup_name(&omapi_key, s);
935  dfree(s, MDL);
936  if (result != ISC_R_SUCCESS)
937  log_fatal("OMAPI key %s: %s",
938  s, isc_result_totext (result));
939  }
940 
942  if (oc &&
943  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
944  &global_scope, oc, MDL)) {
945  if (db.len == 2) {
946  local_port = htons(getUShort (db.data));
947  } else
948  log_fatal("invalid local port data length");
949  data_string_forget(&db, MDL);
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  remote_port = htons(getUShort (db.data));
958  } else
959  log_fatal("invalid remote port data length");
960  data_string_forget(&db, MDL);
961  }
962 
963  oc = lookup_option(&server_universe, options,
965  if (oc &&
966  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
967  &global_scope, oc, MDL)) {
968  if (db.len == 4) {
969  memcpy(&limited_broadcast, db.data, 4);
970  } else
971  log_fatal("invalid broadcast address data length");
972  data_string_forget(&db, MDL);
973  }
974 
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(&local_address, db.data, 4);
981  } else
982  log_fatal("invalid local address data length");
983  data_string_forget(&db, MDL);
984  }
985 
987  if (oc) {
988  if (evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
989  &global_scope, oc, MDL)) {
990  if (db.len == 1) {
991  ddns_update_style = db.data[0];
992  } else
993  log_fatal("invalid dns update type");
994  data_string_forget(&db, MDL);
995  }
996  } else {
998  }
999 #if defined (NSUPDATE)
1000  /* We no longer support ad_hoc, tell the user */
1002  log_fatal("ddns-update-style ad_hoc no longer supported");
1003  }
1004 
1006  if (oc) {
1007  if (evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1008  &global_scope, oc, MDL)) {
1009  if (db.len == 4) {
1010  memcpy(&local4, db.data, 4);
1011  local4_ptr = &local4;
1012  }
1013  data_string_forget(&db, MDL);
1014  }
1015  }
1016 
1018  if (oc) {
1019  if (evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1020  &global_scope, oc, MDL)) {
1021  if (db.len == 16) {
1022  memcpy(&local6, db.data, 16);
1023  local6_ptr = &local6;
1024  }
1025  data_string_forget(&db, MDL);
1026  }
1027  }
1028 
1029  if (dhcp_context_create(DHCP_CONTEXT_POST_DB, local4_ptr, local6_ptr)
1030  != ISC_R_SUCCESS)
1031  log_fatal("Unable to complete ddns initialization");
1032 
1033 #else
1034  /* If we don't have support for updates compiled in tell the user */
1036  log_fatal("Support for ddns-update-style not compiled in");
1037  }
1038 #endif
1039 
1041  if (oc) {
1042  if (evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1043  &global_scope, oc, MDL)) {
1044  if (db.len == 1) {
1045  closelog ();
1046  openlog("dhcpd", DHCP_LOG_OPTIONS, db.data[0]);
1047  /* Log the startup banner into the new
1048  log file. */
1049  if (!quiet) {
1050  /* Don't log to stderr twice. */
1051  tmp = log_perror;
1052  log_perror = 0;
1053  log_info("%s %s",
1054  message, PACKAGE_VERSION);
1055  log_info(copyright);
1056  log_info(arr);
1057  log_info(url);
1058  log_perror = tmp;
1059  }
1060  } else
1061  log_fatal("invalid log facility");
1062  data_string_forget(&db, MDL);
1063  }
1064  }
1065 
1066  oc = lookup_option(&server_universe, options, SV_DELAYED_ACK);
1067  if (oc &&
1068  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1069  &global_scope, oc, MDL)) {
1070  if (db.len == 2) {
1071  max_outstanding_acks = htons(getUShort(db.data));
1072  } else {
1073  log_fatal("invalid max delayed ACK count ");
1074  }
1075  data_string_forget(&db, MDL);
1076  }
1077 
1079  if (oc &&
1080  evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
1081  &global_scope, oc, MDL)) {
1082  u_int32_t timeval;
1083 
1084  if (db.len != 4)
1085  log_fatal("invalid max ack delay configuration");
1086 
1087  timeval = getULong(db.data);
1088  max_ack_delay_secs = timeval / 1000000;
1089  max_ack_delay_usecs = timeval % 1000000;
1090 
1091  data_string_forget(&db, MDL);
1092  }
1093 
1095  if ((oc != NULL) &&
1096  evaluate_boolean_option_cache(NULL, NULL, NULL, NULL, options, NULL,
1097  &global_scope, oc, MDL)) {
1098  dont_use_fsync = 1;
1099  log_error("Not using fsync() to flush lease writes");
1100  }
1101 
1102  /* Don't need the options anymore. */
1103  option_state_dereference(&options, MDL);
1104 }
1105 
1106 void postdb_startup (void)
1107 {
1108  /* Initialize the omapi listener state. */
1109  if (omapi_port != -1) {
1110  omapi_listener_start (0);
1111  }
1112 
1113 #if defined (FAILOVER_PROTOCOL)
1114  /* Initialize the failover listener state. */
1116 #endif
1117 
1118  /*
1119  * Begin our lease timeout background task.
1120  */
1122 }
1123 
1124 /* Print usage message. */
1125 #ifndef UNIT_TEST
1126 static void
1127 usage(void) {
1128  log_info("%s %s", message, PACKAGE_VERSION);
1129  log_info(copyright);
1130  log_info(arr);
1131 
1132  log_fatal("Usage: dhcpd [-p <UDP port #>] [-f] [-d] [-q] [-t|-T]\n"
1133 #ifdef DHCPv6
1134  " [-4|-6] [-cf config-file] [-lf lease-file]\n"
1135 #else /* !DHCPv6 */
1136  " [-cf config-file] [-lf lease-file]\n"
1137 #endif /* DHCPv6 */
1138 #if defined (PARANOIA)
1139  /* meld into the following string */
1140  " [-user user] [-group group] [-chroot dir]\n"
1141 #endif /* PARANOIA */
1142 #if defined (TRACING)
1143  " [-tf trace-output-file]\n"
1144  " [-play trace-input-file]\n"
1145 #endif /* TRACING */
1146  " [-pf pid-file] [--no-pid] [-s server]\n"
1147  " [if0 [...ifN]]");
1148 }
1149 #endif
1150 
1151 void lease_pinged (from, packet, length)
1152  struct iaddr from;
1153  u_int8_t *packet;
1154  int length;
1155 {
1156  struct lease *lp;
1157 
1158  /* Don't try to look up a pinged lease if we aren't trying to
1159  ping one - otherwise somebody could easily make us churn by
1160  just forging repeated ICMP EchoReply packets for us to look
1161  up. */
1162  if (!outstanding_pings)
1163  return;
1164 
1165  lp = (struct lease *)0;
1166  if (!find_lease_by_ip_addr (&lp, from, MDL)) {
1167  log_debug ("unexpected ICMP Echo Reply from %s",
1168  piaddr (from));
1169  return;
1170  }
1171 
1172  if (!lp -> state) {
1173 #if defined (FAILOVER_PROTOCOL)
1174  if (!lp -> pool ||
1175  !lp -> pool -> failover_peer)
1176 #endif
1177  log_debug ("ICMP Echo Reply for %s late or spurious.",
1178  piaddr (from));
1179  goto out;
1180  }
1181 
1182  if (lp -> ends > cur_time) {
1183  log_debug ("ICMP Echo reply while lease %s valid.",
1184  piaddr (from));
1185  }
1186 
1187  /* At this point it looks like we pinged a lease and got a
1188  response, which shouldn't have happened. */
1189  data_string_forget (&lp -> state -> parameter_request_list, MDL);
1190  free_lease_state (lp -> state, MDL);
1191  lp -> state = (struct lease_state *)0;
1192 
1193  abandon_lease (lp, "pinged before offer");
1196  out:
1197  lease_dereference (&lp, MDL);
1198 }
1199 
1201  void *vlp;
1202 {
1203  struct lease *lp = vlp;
1204 
1205 #if defined (DEBUG_MEMORY_LEAKAGE)
1206  unsigned long previous_outstanding = dmalloc_outstanding;
1207 #endif
1208 
1210  dhcp_reply (lp);
1211 
1212 #if defined (DEBUG_MEMORY_LEAKAGE)
1213  log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term",
1214  dmalloc_generation,
1215  dmalloc_outstanding - previous_outstanding,
1216  dmalloc_outstanding, dmalloc_longterm);
1217 #endif
1218 #if defined (DEBUG_MEMORY_LEAKAGE)
1219  dmalloc_dump_outstanding ();
1220 #endif
1221 }
1222 
1224 {
1225  struct subnet *subnet;
1226  struct shared_network *share;
1227  isc_result_t status;
1228 
1229  /* Special case for fallback network - not sure why this is
1230  necessary. */
1231  if (!ia) {
1232  const char *fnn = "fallback-net";
1233  status = shared_network_allocate (&ip -> shared_network, MDL);
1234  if (status != ISC_R_SUCCESS)
1235  log_fatal ("No memory for shared subnet: %s",
1236  isc_result_totext (status));
1237  ip -> shared_network -> name = dmalloc (strlen (fnn) + 1, MDL);
1238  strcpy (ip -> shared_network -> name, fnn);
1239  return 1;
1240  }
1241 
1242  /* If there's a registered subnet for this address,
1243  connect it together... */
1244  subnet = (struct subnet *)0;
1245  if (find_subnet (&subnet, *ia, MDL)) {
1246  /* If this interface has multiple aliases on the same
1247  subnet, ignore all but the first we encounter. */
1248  if (!subnet -> interface) {
1249  interface_reference (&subnet -> interface, ip, MDL);
1250  subnet -> interface_address = *ia;
1251  } else if (subnet -> interface != ip) {
1252  log_error ("Multiple interfaces match the %s: %s %s",
1253  "same subnet",
1254  subnet -> interface -> name, ip -> name);
1255  }
1256  share = subnet -> shared_network;
1257  if (ip -> shared_network &&
1258  ip -> shared_network != share) {
1259  log_fatal ("Interface %s matches multiple shared %s",
1260  ip -> name, "networks");
1261  } else {
1262  if (!ip -> shared_network)
1263  shared_network_reference
1264  (&ip -> shared_network, share, MDL);
1265  }
1266 
1267  if (!share -> interface) {
1268  interface_reference (&share -> interface, ip, MDL);
1269  } else if (share -> interface != ip) {
1270  log_error ("Multiple interfaces match the %s: %s %s",
1271  "same shared network",
1272  share -> interface -> name, ip -> name);
1273  }
1274  subnet_dereference (&subnet, MDL);
1275  }
1276  return 1;
1277 }
1278 
1279 static TIME shutdown_time;
1280 static int omapi_connection_count;
1282 
1283 isc_result_t dhcp_io_shutdown (omapi_object_t *obj, void *foo)
1284 {
1285  /* Shut down all listeners. */
1286  if (shutdown_state == shutdown_listeners &&
1287  obj -> type == omapi_type_listener &&
1288  obj -> inner &&
1289  obj -> inner -> type == omapi_type_protocol_listener) {
1290  omapi_listener_destroy (obj, MDL);
1291  return ISC_R_SUCCESS;
1292  }
1293 
1294  /* Shut down all existing omapi connections. */
1295  if (obj -> type == omapi_type_connection &&
1296  obj -> inner &&
1297  obj -> inner -> type == omapi_type_protocol) {
1298  if (shutdown_state == shutdown_drop_omapi_connections) {
1299  omapi_disconnect (obj, 1);
1300  }
1301  omapi_connection_count++;
1302  if (shutdown_state == shutdown_omapi_connections) {
1303  omapi_disconnect (obj, 0);
1304  return ISC_R_SUCCESS;
1305  }
1306  }
1307 
1308  /* Shutdown all DHCP interfaces. */
1309  if (obj -> type == dhcp_type_interface &&
1310  shutdown_state == shutdown_dhcp) {
1312  return ISC_R_SUCCESS;
1313  }
1314  return ISC_R_SUCCESS;
1315 }
1316 
1317 static isc_result_t dhcp_io_shutdown_countdown (void *vlp)
1318 {
1319 #if defined (FAILOVER_PROTOCOL)
1320  dhcp_failover_state_t *state;
1321  int failover_connection_count = 0;
1322 #endif
1323  struct timeval tv;
1324 
1325  oncemore:
1326  if (shutdown_state == shutdown_listeners ||
1327  shutdown_state == shutdown_omapi_connections ||
1328  shutdown_state == shutdown_drop_omapi_connections ||
1329  shutdown_state == shutdown_dhcp) {
1330  omapi_connection_count = 0;
1332  }
1333 
1334  if ((shutdown_state == shutdown_listeners ||
1335  shutdown_state == shutdown_omapi_connections ||
1336  shutdown_state == shutdown_drop_omapi_connections) &&
1337  omapi_connection_count == 0) {
1338  shutdown_state = shutdown_dhcp;
1339  shutdown_time = cur_time;
1340  goto oncemore;
1341  } else if (shutdown_state == shutdown_listeners &&
1342  cur_time - shutdown_time > 4) {
1343  shutdown_state = shutdown_omapi_connections;
1344  shutdown_time = cur_time;
1345  } else if (shutdown_state == shutdown_omapi_connections &&
1346  cur_time - shutdown_time > 4) {
1347  shutdown_state = shutdown_drop_omapi_connections;
1348  shutdown_time = cur_time;
1349  } else if (shutdown_state == shutdown_drop_omapi_connections &&
1350  cur_time - shutdown_time > 4) {
1351  shutdown_state = shutdown_dhcp;
1352  shutdown_time = cur_time;
1353  goto oncemore;
1354  } else if (shutdown_state == shutdown_dhcp &&
1355  cur_time - shutdown_time > 4) {
1356  shutdown_state = shutdown_done;
1357  shutdown_time = cur_time;
1358  }
1359 
1360 #if defined (FAILOVER_PROTOCOL)
1361  /* Set all failover peers into the shutdown state. */
1362  if (shutdown_state == shutdown_dhcp) {
1363  for (state = failover_states; state; state = state -> next) {
1364  if (state -> me.state == normal) {
1366  failover_connection_count++;
1367  }
1368  if (state -> me.state == shut_down &&
1369  state -> partner.state != partner_down)
1370  failover_connection_count++;
1371  }
1372  }
1373 
1374  if (shutdown_state == shutdown_done) {
1375  for (state = failover_states; state; state = state -> next) {
1376  if (state -> me.state == shut_down) {
1377  if (state -> link_to_peer)
1378  dhcp_failover_link_dereference (&state -> link_to_peer,
1379  MDL);
1381  }
1382  }
1383 #if defined (DEBUG_MEMORY_LEAKAGE) && \
1384  defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1385  free_everything ();
1387 #endif
1388  if (no_pid_file == ISC_FALSE)
1389  (void) unlink(path_dhcpd_pid);
1390  exit (0);
1391  }
1392 #else
1393  if (shutdown_state == shutdown_done) {
1394 #if defined (DEBUG_MEMORY_LEAKAGE) && \
1395  defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1396  free_everything ();
1398 #endif
1399  if (no_pid_file == ISC_FALSE)
1400  (void) unlink(path_dhcpd_pid);
1401  exit (0);
1402  }
1403 #endif
1404  if (shutdown_state == shutdown_dhcp &&
1405 #if defined(FAILOVER_PROTOCOL)
1406  !failover_connection_count &&
1407 #endif
1408  ISC_TRUE) {
1409  shutdown_state = shutdown_done;
1410  shutdown_time = cur_time;
1411  goto oncemore;
1412  }
1413  tv.tv_sec = cur_tv.tv_sec + 1;
1414  tv.tv_usec = cur_tv.tv_usec;
1415  add_timeout (&tv,
1416  (void (*)(void *))dhcp_io_shutdown_countdown, 0, 0, 0);
1417  return ISC_R_SUCCESS;
1418 }
1419 
1421  control_object_state_t newstate)
1422 {
1423  struct timeval tv;
1424 
1425  if (newstate != server_shutdown)
1426  return DHCP_R_INVALIDARG;
1427  /* Re-entry. */
1428  if (shutdown_signal == SIGUSR1)
1429  return ISC_R_SUCCESS;
1430  shutdown_time = cur_time;
1431  shutdown_state = shutdown_listeners;
1432  /* Called by user. */
1433  if (shutdown_signal == 0) {
1434  shutdown_signal = SIGUSR1;
1435  dhcp_io_shutdown_countdown (0);
1436  return ISC_R_SUCCESS;
1437  }
1438  /* Called on signal. */
1439  log_info("Received signal %d, initiating shutdown.", shutdown_signal);
1440  shutdown_signal = SIGUSR1;
1441 
1442  /*
1443  * Prompt the shutdown event onto the timer queue
1444  * and return to the dispatch loop.
1445  */
1446  tv.tv_sec = cur_tv.tv_sec;
1447  tv.tv_usec = cur_tv.tv_usec + 1;
1448  add_timeout(&tv,
1449  (void (*)(void *))dhcp_io_shutdown_countdown, 0, 0, 0);
1450  return ISC_R_SUCCESS;
1451 }
#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:413
int dhcpd_interface_setup_hook(struct interface_info *ip, struct iaddr *ia)
Definition: dhcpd.c:1223
void mark_hosts_unavailable(void)
Definition: mdb6.c:2257
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:154
struct binding_scope * global_scope
Definition: tree.c:39
omapi_object_type_t * omapi_type_connection
Definition: support.c:34
void(* dhcpv6_packet_handler)(struct interface_info *, const char *, int, int, const struct iaddr *, isc_boolean_t)
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:1272
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:1200
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:952
struct universe server_universe
Definition: stables.c:175
int max_outstanding_acks
Definition: dhcp.c:45
#define STDERR_FILENO
Definition: osdep.h:288
#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: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: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:233
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:2312
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:3843
void dispatch(void)
Definition: dispatch.c:109
#define _PATH_DHCPD_DB
Definition: config.h:236
#define DHCP_LOG_OPTIONS
Definition: dhcpd.h:1498
#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:859
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:316
void postconf_initialization(int quiet)
Definition: dhcpd.c:830
int find_subnet(struct subnet **sp, struct iaddr addr, const char *file, int line)
Definition: dhclient.c:1278
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:1490
void mark_phosts_unavailable(void)
Definition: mdb6.c:2307
struct iaddr interface_address
Definition: dhcpd.h:958
int max_ack_delay_secs
Definition: dhcp.c:46
Definition: dhcpd.h:906
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:1420
int group_allocate(struct group **ptr, const char *file, int line)
Definition: alloc.c:146
void(* bootp_packet_handler)(struct interface_info *, struct dhcp_packet *, unsigned, unsigned int, struct iaddr, struct hardware *)
Definition: discover.c:58
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: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:230
isc_result_t omapi_generic_new(omapi_object_t **, const char *, int)
#define cur_time
Definition: dhcpd.h:1946
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:701
dhcp_failover_state_t * failover_states
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
Definition: options.c:2303
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:53
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:43
u_int32_t flags
Definition: dhcpd.h:1286
u_int32_t getULong(const unsigned char *)
struct shared_network * shared_network
Definition: dhcpd.h:956
void trace_replay_init(void)
void lease_pinged(struct iaddr from, u_int8_t *packet, int length)
Definition: dhcpd.c:1151
dhcp_control_object_t * dhcp_control_object
isc_result_t dhcp_io_shutdown(omapi_object_t *obj, void *foo)
Definition: dhcpd.c:1283
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(* dhcp_interface_setup_hook)(struct interface_info *, struct iaddr *)
Definition: discover.c:48
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: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:851
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:1247
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:1994
#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:56
#define PACKAGE_VERSION
Definition: config.h:151
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:89
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:3504
char * name
Definition: dhcpd.h:937
struct enumeration syslog_enum
Definition: stables.c:407
#define TRACING
Definition: config.h:166
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:1281
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:239
struct enumeration ddns_styles
Definition: stables.c:337
void discover_interfaces(int state)
Definition: discover.c:555
struct interface_info * interface
Definition: dhcpd.h:957
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:1287
#define _PATH_DHCPD_CONF
Definition: dhcpd.h:1432
void postdb_startup(void)
Definition: dhcpd.c:1106
#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