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