6 * Copyright (c) 2004-2015 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1996-2003 by Internet Software Consortium
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.
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.
21 * Internet Systems Consortium, Inc.
23 * Redwood City, CA 94063
25 * https://www.isc.org/
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/";
37 #include <omapip/omapip_p.h>
42 #include <sys/types.h>
45 #if defined (PARANOIA)
46 # include <sys/types.h>
49 /* get around the ISC declaration of group */
50 # define group real_group
56 static void usage(void);
59 struct iaddr server_identifier
;
60 int server_identifier_matched
;
62 #if defined (NSUPDATE)
64 /* This stuff is always executed to figure the default values for certain
66 char std_nsupdate
[] = " \n\
67 option server.ddns-hostname = \n\
68 pick (option fqdn.hostname, option host-name, config-option host-name); \n\
69 option server.ddns-domainname = config-option domain-name; \n\
70 option server.ddns-rev-domainname = \"in-addr.arpa.\";";
73 int ddns_update_style
;
74 int dont_use_fsync
= 0; /* 0 = default, use fsync, 1 = don't use fsync */
75 int server_id_check
= 0; /* 0 = default, don't check server id, 1 = do check */
76 int prefix_length_mode
= PLM_EXACT
;
78 const char *path_dhcpd_conf
= _PATH_DHCPD_CONF
;
79 const char *path_dhcpd_db
= _PATH_DHCPD_DB
;
80 const char *path_dhcpd_pid
= _PATH_DHCPD_PID
;
81 /* False (default) => we write and use a pid file */
82 isc_boolean_t no_pid_file
= ISC_FALSE
;
84 int dhcp_max_agent_option_packet_length
= DHCP_MTU_MAX
;
86 static omapi_auth_key_t
*omapi_key
= (omapi_auth_key_t
*)0;
90 trace_type_t
*trace_srandom
;
93 static isc_result_t
verify_addr (omapi_object_t
*l
, omapi_addr_t
*addr
) {
97 static isc_result_t
verify_auth (omapi_object_t
*p
, omapi_auth_key_t
*a
) {
99 return DHCP_R_INVALIDKEY
;
100 return ISC_R_SUCCESS
;
103 static void omapi_listener_start (void *foo
)
105 omapi_object_t
*listener
;
109 listener
= (omapi_object_t
*)0;
110 result
= omapi_generic_new (&listener
, MDL
);
111 if (result
!= ISC_R_SUCCESS
)
112 log_fatal ("Can't allocate new generic object: %s",
113 isc_result_totext (result
));
114 result
= omapi_protocol_listen (listener
,
115 (unsigned)omapi_port
, 1);
116 if (result
== ISC_R_SUCCESS
&& omapi_key
)
117 result
= omapi_protocol_configure_security
118 (listener
, verify_addr
, verify_auth
);
119 if (result
!= ISC_R_SUCCESS
) {
120 log_error ("Can't start OMAPI protocol: %s",
121 isc_result_totext (result
));
122 tv
.tv_sec
= cur_tv
.tv_sec
+ 5;
123 tv
.tv_usec
= cur_tv
.tv_usec
;
124 add_timeout (&tv
, omapi_listener_start
, 0, 0, 0);
126 omapi_object_dereference (&listener
, MDL
);
129 #if defined (PARANOIA)
130 /* to be used in one of two possible scenarios */
131 static void setup_chroot (char *chroot_dir
) {
133 log_fatal ("you must be root to use chroot");
135 if (chroot(chroot_dir
)) {
136 log_fatal ("chroot(\"%s\"): %m", chroot_dir
);
139 /* probably permission denied */
140 log_fatal ("chdir(\"/\"): %m");
143 #endif /* PARANOIA */
147 main(int argc
, char **argv
) {
160 char *server
= (char *)0;
163 struct interface_info
*ip
;
164 #if defined (NSUPDATE)
168 int no_dhcpd_conf
= 0;
170 int no_dhcpd_pid
= 0;
172 int local_family_set
= 0;
174 #if defined (TRACING)
175 char *traceinfile
= (char *)0;
176 char *traceoutfile
= (char *)0;
179 #if defined (PARANOIA)
182 char *set_chroot
= 0;
186 #endif /* PARANOIA */
188 /* Make sure that file descriptors 0 (stdin), 1, (stdout), and
189 2 (stderr) are open. To do this, we assume that when we
190 open a file the lowest available file descriptor is used. */
191 fd
= open("/dev/null", O_RDWR
);
193 fd
= open("/dev/null", O_RDWR
);
195 fd
= open("/dev/null", O_RDWR
);
197 log_perror
= 0; /* No sense logging to /dev/null. */
201 /* Set up the isc and dns library managers */
202 status
= dhcp_context_create(DHCP_CONTEXT_PRE_DB
,
204 if (status
!= ISC_R_SUCCESS
)
205 log_fatal("Can't initialize context: %s",
206 isc_result_totext(status
));
208 /* Set up the client classification system. */
209 classification_setup ();
211 /* Initialize the omapi system. */
212 result
= omapi_init ();
213 if (result
!= ISC_R_SUCCESS
)
214 log_fatal ("Can't initialize OMAPI: %s",
215 isc_result_totext (result
));
217 /* Set up the OMAPI wrappers for common objects. */
218 dhcp_db_objects_setup ();
219 /* Set up the OMAPI wrappers for various server database internal
221 dhcp_common_objects_setup ();
223 /* Initially, log errors to stderr as well as to syslogd. */
224 openlog ("dhcpd", DHCP_LOG_OPTIONS
, DHCPD_LOG_FACILITY
);
226 for (i
= 1; i
< argc
; i
++) {
227 if (!strcmp (argv
[i
], "-p")) {
230 local_port
= validate_port (argv
[i
]);
231 log_debug ("binding to user-specified port %d",
233 } else if (!strcmp (argv
[i
], "-f")) {
237 } else if (!strcmp (argv
[i
], "-d")) {
242 } else if (!strcmp (argv
[i
], "-s")) {
246 #if defined (PARANOIA)
247 } else if (!strcmp (argv
[i
], "-user")) {
251 } else if (!strcmp (argv
[i
], "-group")) {
254 set_group
= argv
[i
];
255 } else if (!strcmp (argv
[i
], "-chroot")) {
258 set_chroot
= argv
[i
];
259 #endif /* PARANOIA */
260 } else if (!strcmp (argv
[i
], "-cf")) {
263 path_dhcpd_conf
= argv
[i
];
265 } else if (!strcmp (argv
[i
], "-lf")) {
268 path_dhcpd_db
= argv
[i
];
270 } else if (!strcmp (argv
[i
], "-pf")) {
273 path_dhcpd_pid
= argv
[i
];
275 } else if (!strcmp(argv
[i
], "--no-pid")) {
276 no_pid_file
= ISC_TRUE
;
277 } else if (!strcmp (argv
[i
], "-t")) {
278 /* test configurations only */
284 } else if (!strcmp (argv
[i
], "-T")) {
285 /* test configurations and lease file only */
292 } else if (!strcmp (argv
[i
], "-q")) {
294 quiet_interface_discovery
= 1;
296 } else if (!strcmp(argv
[i
], "-4")) {
297 if (local_family_set
&& (local_family
!= AF_INET
)) {
298 log_fatal("Server cannot run in both IPv4 and "
299 "IPv6 mode at the same time.");
301 local_family
= AF_INET
;
302 local_family_set
= 1;
303 } else if (!strcmp(argv
[i
], "-6")) {
304 if (local_family_set
&& (local_family
!= AF_INET6
)) {
305 log_fatal("Server cannot run in both IPv4 and "
306 "IPv6 mode at the same time.");
308 local_family
= AF_INET6
;
309 local_family_set
= 1;
311 } else if (!strcmp (argv
[i
], "--version")) {
312 const char vstring
[] = "isc-dhcpd-";
313 IGNORE_RET(write(STDERR_FILENO
, vstring
,
315 IGNORE_RET(write(STDERR_FILENO
,
317 strlen(PACKAGE_VERSION
)));
318 IGNORE_RET(write(STDERR_FILENO
, "\n", 1));
320 #if defined (TRACING)
321 } else if (!strcmp (argv
[i
], "-tf")) {
324 traceoutfile
= argv
[i
];
325 } else if (!strcmp (argv
[i
], "-play")) {
328 traceinfile
= argv
[i
];
329 trace_replay_init ();
331 } else if (argv
[i
][0] == '-') {
334 struct interface_info
*tmp
=
335 (struct interface_info
*)0;
336 if (strlen(argv
[i
]) >= sizeof(tmp
->name
))
337 log_fatal("%s: interface name too long "
339 argv
[i
], (long)strlen(argv
[i
]));
340 result
= interface_allocate (&tmp
, MDL
);
341 if (result
!= ISC_R_SUCCESS
)
342 log_fatal ("Insufficient memory to %s %s: %s",
343 "record interface", argv
[i
],
344 isc_result_totext (result
));
345 strcpy (tmp
-> name
, argv
[i
]);
347 interface_reference (&tmp
-> next
,
349 interface_dereference (&interfaces
, MDL
);
351 interface_reference (&interfaces
, tmp
, MDL
);
352 tmp
-> flags
= INTERFACE_REQUESTED
;
356 if (!no_dhcpd_conf
&& (s
= getenv ("PATH_DHCPD_CONF"))) {
361 if (local_family
== AF_INET6
) {
362 /* DHCPv6: override DHCPv4 lease and pid filenames */
364 if ((s
= getenv ("PATH_DHCPD6_DB")))
367 path_dhcpd_db
= _PATH_DHCPD6_DB
;
370 if ((s
= getenv ("PATH_DHCPD6_PID")))
373 path_dhcpd_pid
= _PATH_DHCPD6_PID
;
378 if (!no_dhcpd_db
&& (s
= getenv ("PATH_DHCPD_DB"))) {
381 if (!no_dhcpd_pid
&& (s
= getenv ("PATH_DHCPD_PID"))) {
388 * convert relative path names to absolute, for files that need
389 * to be reopened after chdir() has been called
391 if (path_dhcpd_db
[0] != '/') {
392 const char *path
= path_dhcpd_db
;
393 path_dhcpd_db
= realpath(path_dhcpd_db
, NULL
);
394 if (path_dhcpd_db
== NULL
)
395 log_fatal("Failed to get realpath for %s: %s", path
,
400 log_info("%s %s", message
, PACKAGE_VERSION
);
401 log_info (copyright
);
408 #if defined (TRACING)
409 trace_init (set_time
, MDL
);
411 result
= trace_begin (traceoutfile
, MDL
);
412 if (result
!= ISC_R_SUCCESS
)
413 log_fatal ("Unable to begin trace: %s",
414 isc_result_totext (result
));
416 interface_trace_setup ();
417 parse_trace_setup ();
418 trace_srandom
= trace_type_register ("random-seed", (void *)0,
420 trace_seed_stop
, MDL
);
421 #if defined (NSUPDATE)
423 #endif /* NSUPDATE */
426 #if defined (PARANOIA)
427 /* get user and group info if those options were given */
429 struct passwd
*tmp_pwd
;
432 log_fatal ("you must be root to set user");
434 if (!(tmp_pwd
= getpwnam(set_user
)))
435 log_fatal ("no such user: %s", set_user
);
437 set_uid
= tmp_pwd
->pw_uid
;
439 /* use the user's group as the default gid */
441 set_gid
= tmp_pwd
->pw_gid
;
445 /* get around the ISC declaration of group */
446 #define group real_group
447 struct group
*tmp_grp
;
450 log_fatal ("you must be root to set group");
452 if (!(tmp_grp
= getgrnam(set_group
)))
453 log_fatal ("no such group: %s", set_group
);
455 set_gid
= tmp_grp
->gr_gid
;
459 # if defined (EARLY_CHROOT)
460 if (set_chroot
) setup_chroot (set_chroot
);
461 # endif /* EARLY_CHROOT */
462 #endif /* PARANOIA */
464 /* Default to the DHCP/BOOTP port. */
467 if ((s
= getenv ("DHCPD_PORT"))) {
468 local_port
= validate_port (s
);
469 log_debug ("binding to environment-specified port %d",
472 if (local_family
== AF_INET
) {
473 ent
= getservbyname("dhcp", "udp");
475 local_port
= htons(67);
477 local_port
= ent
->s_port
;
480 /* INSIST(local_family == AF_INET6); */
481 ent
= getservbyname("dhcpv6-server", "udp");
483 local_port
= htons(547);
485 local_port
= ent
->s_port
;
488 #ifndef __CYGWIN32__ /* XXX */
494 if (local_family
== AF_INET
) {
495 remote_port
= htons(ntohs(local_port
) + 1);
497 /* INSIST(local_family == AF_INET6); */
498 ent
= getservbyname("dhcpv6-client", "udp");
500 remote_port
= htons(546);
502 remote_port
= ent
->s_port
;
507 if (local_family
!= AF_INET
) {
508 log_fatal("You can only specify address to send "
509 "replies to when running an IPv4 server.");
511 if (!inet_aton (server
, &limited_broadcast
)) {
513 he
= gethostbyname (server
);
515 memcpy (&limited_broadcast
,
516 he
-> h_addr_list
[0],
517 sizeof limited_broadcast
);
519 limited_broadcast
.s_addr
= INADDR_BROADCAST
;
522 limited_broadcast
.s_addr
= INADDR_BROADCAST
;
525 /* Get the current time... */
526 gettimeofday(&cur_tv
, NULL
);
528 /* Set up the initial dhcp option universe. */
529 initialize_common_option_spaces ();
530 initialize_server_option_spaces ();
532 /* Add the ddns update style enumeration prior to parsing. */
533 add_enumeration (&ddns_styles
);
534 add_enumeration (&syslog_enum
);
535 #if defined (LDAP_CONFIGURATION)
536 add_enumeration (&ldap_methods
);
537 #if defined (LDAP_USE_SSL)
538 add_enumeration (&ldap_ssl_usage_enum
);
539 add_enumeration (&ldap_tls_reqcert_enum
);
540 add_enumeration (&ldap_tls_crlcheck_enum
);
544 if (!group_allocate (&root_group
, MDL
))
545 log_fatal ("Can't allocate root group!");
546 root_group
-> authoritative
= 0;
548 /* Set up various hooks. */
549 dhcp_interface_setup_hook
= dhcpd_interface_setup_hook
;
550 bootp_packet_handler
= do_packet
;
552 add_enumeration (&prefix_length_modes
);
553 dhcpv6_packet_handler
= do_packet6
;
556 #if defined (NSUPDATE)
557 /* Set up the standard name service updater routine. */
559 status
= new_parse(&parse
, -1, std_nsupdate
, sizeof(std_nsupdate
) - 1,
560 "standard name service update routine", 0);
561 if (status
!= ISC_R_SUCCESS
)
562 log_fatal ("can't begin parsing name service updater!");
566 if (!(parse_executable_statements(&root_group
->statements
,
567 parse
, &lose
, context_any
))) {
569 log_fatal("can't parse standard name service updater!");
575 /* Initialize icmp support... */
576 if (!cftest
&& !lftest
)
577 icmp_startup (1, lease_pinged
);
579 #if defined (TRACING)
582 log_error ("%s", "");
583 log_error ("** You must specify a lease file with -lf.");
584 log_error (" Dhcpd will not overwrite your default");
585 log_fatal (" lease file when playing back a trace. **");
587 trace_file_replay (traceinfile
);
589 #if defined (DEBUG_MEMORY_LEAKAGE) && \
590 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
592 omapi_print_dmalloc_usage_by_caller ();
600 /* set up DHCPv6 hashes */
601 if (!ia_new_hash(&ia_na_active
, DEFAULT_HASH_SIZE
, MDL
)) {
602 log_fatal("Out of memory creating hash for active IA_NA.");
604 if (!ia_new_hash(&ia_ta_active
, DEFAULT_HASH_SIZE
, MDL
)) {
605 log_fatal("Out of memory creating hash for active IA_TA.");
607 if (!ia_new_hash(&ia_pd_active
, DEFAULT_HASH_SIZE
, MDL
)) {
608 log_fatal("Out of memory creating hash for active IA_PD.");
612 /* Read the dhcpd.conf file... */
613 if (readconf () != ISC_R_SUCCESS
)
614 log_fatal ("Configuration file errors encountered -- exiting");
616 postconf_initialization (quiet
);
618 #if defined (PARANOIA) && !defined (EARLY_CHROOT)
619 if (set_chroot
) setup_chroot (set_chroot
);
620 #endif /* PARANOIA && !EARLY_CHROOT */
623 /* log info about ipv6_ponds with large address ranges */
624 report_jumbo_ranges();
627 /* test option should cause an early exit */
628 if (cftest
&& !lftest
)
632 * First part of dealing with pid files. Check to see if
633 * we should continue running or not. We run if:
634 * - we are testing the lease file out
635 * - we don't have a pid file to check
636 * - there is no other process running
638 if ((lftest
== 0) && (no_pid_file
== ISC_FALSE
)) {
639 /*Read previous pid file. */
640 if ((i
= open(path_dhcpd_pid
, O_RDONLY
)) >= 0) {
641 status
= read(i
, pbuf
, (sizeof pbuf
) - 1);
648 * If there was a previous server process and
649 * it is still running, abort
652 (pid
!= getpid() && kill(pid
, 0) == 0))
653 log_fatal("There's already a "
654 "DHCP server running.");
659 group_write_hook
= group_writer
;
661 /* Start up the database... */
667 /* Discover all the network interfaces and initialize them. */
668 discover_interfaces(DISCOVER_SERVER
);
672 * Remove addresses from our pools that we should not issue
675 * We currently have no support for this in IPv4. It is not
676 * as important in IPv4, as making pools with ranges that
677 * leave out interfaces and hosts is fairly straightforward
678 * using range notation, but not so handy with CIDR notation.
680 if (local_family
== AF_INET6
) {
681 mark_hosts_unavailable();
682 mark_phosts_unavailable();
683 mark_interfaces_unavailable();
687 /* Make up a seed for the random number generator from current
688 time plus the sum of the last four bytes of each
689 interface's hardware address interpreted as an integer.
690 Not much entropy, but we're booting, so we're not likely to
691 find anything better. */
693 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
696 &ip
-> hw_address
.hbuf
[ip
-> hw_address
.hlen
-
697 sizeof seed
], sizeof seed
);
700 srandom (seed
+ cur_time
);
701 #if defined (TRACING)
702 trace_seed_stash (trace_srandom
, seed
+ cur_time
);
708 * Set server DHCPv6 identifier.
709 * See dhcpv6.c for discussion of setting DUID.
711 if (set_server_duid_from_option() == ISC_R_SUCCESS
) {
714 if (!server_duid_isset()) {
715 if (generate_new_server_duid() != ISC_R_SUCCESS
) {
716 log_fatal("Unable to set server identifier.");
725 /* First part of becoming a daemon... */
726 if ((pid
= fork ()) < 0)
727 log_fatal ("Can't fork daemon: %m");
733 * Second part of dealing with pid files. Now
734 * that we have forked we can write our pid if
737 if (no_pid_file
== ISC_FALSE
) {
738 i
= open(path_dhcpd_pid
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0644);
740 sprintf(pbuf
, "%d\n", (int) getpid());
741 IGNORE_RET(write(i
, pbuf
, strlen(pbuf
)));
744 log_error("Can't create PID file %s: %m.",
749 #if defined (PARANOIA)
750 /* change uid to the specified one */
753 if (setgroups (0, (void *)0))
754 log_fatal ("setgroups: %m");
755 if (setgid (set_gid
))
756 log_fatal ("setgid(%d): %m", (int) set_gid
);
760 if (setuid (set_uid
))
761 log_fatal ("setuid(%d): %m", (int) set_uid
);
763 #endif /* PARANOIA */
765 /* If we were requested to log to stdout on the command line,
766 keep doing so; otherwise, stop. */
767 if (log_perror
== -1)
773 /* Become session leader and get pid... */
776 /* Close standard I/O descriptors. */
781 /* Reopen them on /dev/null. */
782 (void) open("/dev/null", O_RDWR
);
783 (void) open("/dev/null", O_RDWR
);
784 (void) open("/dev/null", O_RDWR
);
785 log_perror
= 0; /* No sense logging to /dev/null. */
787 IGNORE_RET (chdir("/"));
791 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
792 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
793 dmalloc_cutoff_generation
= dmalloc_generation
;
794 dmalloc_longterm
= dmalloc_outstanding
;
795 dmalloc_outstanding
= 0;
798 omapi_set_int_value ((omapi_object_t
*)dhcp_control_object
,
799 (omapi_object_t
*)0, "state", server_running
);
801 #if defined(ENABLE_GENTLE_SHUTDOWN)
802 /* no signal handlers until we deal with the side effects */
803 /* install signal handlers */
804 signal(SIGINT
, dhcp_signal_handler
); /* control-c */
805 signal(SIGTERM
, dhcp_signal_handler
); /* kill */
808 /* Log that we are about to start working */
809 log_info("Server starting service.");
812 * Receive packets and dispatch them...
813 * dispatch() will never return.
817 /* Let's return status code */
820 #endif /* !UNIT_TEST */
822 void postconf_initialization (int quiet
)
824 struct option_state
*options
= NULL
;
825 struct data_string db
;
826 struct option_cache
*oc
;
830 #if defined (NSUPDATE)
831 struct in_addr local4
, *local4_ptr
= NULL
;
832 struct in6_addr local6
, *local6_ptr
= NULL
;
835 /* Now try to get the lease file name. */
836 option_state_allocate(&options
, MDL
);
838 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
,
839 options
, &global_scope
, root_group
,
841 memset(&db
, 0, sizeof db
);
842 oc
= lookup_option(&server_universe
, options
, SV_LEASE_FILE_NAME
);
844 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
845 &global_scope
, oc
, MDL
)) {
846 s
= dmalloc(db
.len
+ 1, MDL
);
848 log_fatal("no memory for lease db filename.");
849 memcpy(s
, db
.data
, db
.len
);
851 data_string_forget(&db
, MDL
);
855 oc
= lookup_option(&server_universe
, options
, SV_PID_FILE_NAME
);
857 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
858 &global_scope
, oc
, MDL
)) {
859 s
= dmalloc(db
.len
+ 1, MDL
);
861 log_fatal("no memory for pid filename.");
862 memcpy(s
, db
.data
, db
.len
);
864 data_string_forget(&db
, MDL
);
869 if (local_family
== AF_INET6
) {
871 * Override lease file name with dhcpv6 lease file name,
872 * if it was set; then, do the same with the pid file name
874 oc
= lookup_option(&server_universe
, options
,
875 SV_DHCPV6_LEASE_FILE_NAME
);
877 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
878 &global_scope
, oc
, MDL
)) {
879 s
= dmalloc(db
.len
+ 1, MDL
);
881 log_fatal("no memory for lease db filename.");
882 memcpy(s
, db
.data
, db
.len
);
884 data_string_forget(&db
, MDL
);
888 oc
= lookup_option(&server_universe
, options
,
889 SV_DHCPV6_PID_FILE_NAME
);
891 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
892 &global_scope
, oc
, MDL
)) {
893 s
= dmalloc(db
.len
+ 1, MDL
);
895 log_fatal("no memory for pid filename.");
896 memcpy(s
, db
.data
, db
.len
);
898 data_string_forget(&db
, MDL
);
905 oc
= lookup_option(&server_universe
, options
, SV_OMAPI_PORT
);
907 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
908 &global_scope
, oc
, MDL
)) {
910 omapi_port
= getUShort(db
.data
);
912 log_fatal("invalid omapi port data length");
913 data_string_forget(&db
, MDL
);
916 oc
= lookup_option(&server_universe
, options
, SV_OMAPI_KEY
);
918 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
919 &global_scope
, oc
, MDL
)) {
920 s
= dmalloc(db
.len
+ 1, MDL
);
922 log_fatal("no memory for OMAPI key filename.");
923 memcpy(s
, db
.data
, db
.len
);
925 data_string_forget(&db
, MDL
);
926 result
= omapi_auth_key_lookup_name(&omapi_key
, s
);
928 if (result
!= ISC_R_SUCCESS
)
929 log_fatal("OMAPI key %s: %s",
930 s
, isc_result_totext (result
));
933 oc
= lookup_option(&server_universe
, options
, SV_LOCAL_PORT
);
935 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
936 &global_scope
, oc
, MDL
)) {
938 local_port
= htons(getUShort (db
.data
));
940 log_fatal("invalid local port data length");
941 data_string_forget(&db
, MDL
);
944 oc
= lookup_option(&server_universe
, options
, SV_REMOTE_PORT
);
946 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
947 &global_scope
, oc
, MDL
)) {
949 remote_port
= htons(getUShort (db
.data
));
951 log_fatal("invalid remote port data length");
952 data_string_forget(&db
, MDL
);
955 oc
= lookup_option(&server_universe
, options
,
956 SV_LIMITED_BROADCAST_ADDRESS
);
958 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
959 &global_scope
, oc
, MDL
)) {
961 memcpy(&limited_broadcast
, db
.data
, 4);
963 log_fatal("invalid broadcast address data length");
964 data_string_forget(&db
, MDL
);
967 oc
= lookup_option(&server_universe
, options
, SV_LOCAL_ADDRESS
);
969 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
970 &global_scope
, oc
, MDL
)) {
972 memcpy(&local_address
, db
.data
, 4);
974 log_fatal("invalid local address data length");
975 data_string_forget(&db
, MDL
);
978 oc
= lookup_option(&server_universe
, options
, SV_DDNS_UPDATE_STYLE
);
980 if (evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
981 &global_scope
, oc
, MDL
)) {
983 ddns_update_style
= db
.data
[0];
985 log_fatal("invalid dns update type");
986 data_string_forget(&db
, MDL
);
989 ddns_update_style
= DDNS_UPDATE_STYLE_NONE
;
991 #if defined (NSUPDATE)
992 /* We no longer support ad_hoc, tell the user */
993 if (ddns_update_style
== DDNS_UPDATE_STYLE_AD_HOC
) {
994 log_fatal("ddns-update-style ad_hoc no longer supported");
997 oc
= lookup_option(&server_universe
, options
, SV_DDNS_LOCAL_ADDRESS4
);
999 if (evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
1000 &global_scope
, oc
, MDL
)) {
1002 memcpy(&local4
, db
.data
, 4);
1003 local4_ptr
= &local4
;
1005 data_string_forget(&db
, MDL
);
1009 oc
= lookup_option(&server_universe
, options
, SV_DDNS_LOCAL_ADDRESS6
);
1011 if (evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
1012 &global_scope
, oc
, MDL
)) {
1014 memcpy(&local6
, db
.data
, 16);
1015 local6_ptr
= &local6
;
1017 data_string_forget(&db
, MDL
);
1021 if (dhcp_context_create(DHCP_CONTEXT_POST_DB
, local4_ptr
, local6_ptr
)
1023 log_fatal("Unable to complete ddns initialization");
1026 /* If we don't have support for updates compiled in tell the user */
1027 if (ddns_update_style
!= DDNS_UPDATE_STYLE_NONE
) {
1028 log_fatal("Support for ddns-update-style not compiled in");
1033 log_info ("Config file: %s", path_dhcpd_conf
);
1034 log_info ("Database file: %s", path_dhcpd_db
);
1035 log_info ("PID file: %s", path_dhcpd_pid
);
1038 oc
= lookup_option(&server_universe
, options
, SV_LOG_FACILITY
);
1040 if (evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
1041 &global_scope
, oc
, MDL
)) {
1044 openlog("dhcpd", DHCP_LOG_OPTIONS
, db
.data
[0]);
1045 /* Log the startup banner into the new
1047 /* Don't log to stderr twice. */
1050 log_info("%s %s", message
, PACKAGE_VERSION
);
1051 log_info(copyright
);
1056 log_fatal("invalid log facility");
1057 data_string_forget(&db
, MDL
);
1061 oc
= lookup_option(&server_universe
, options
, SV_DELAYED_ACK
);
1063 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
1064 &global_scope
, oc
, MDL
)) {
1066 max_outstanding_acks
= htons(getUShort(db
.data
));
1068 log_fatal("invalid max delayed ACK count ");
1070 data_string_forget(&db
, MDL
);
1073 oc
= lookup_option(&server_universe
, options
, SV_MAX_ACK_DELAY
);
1075 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
1076 &global_scope
, oc
, MDL
)) {
1080 log_fatal("invalid max ack delay configuration");
1082 timeval
= getULong(db
.data
);
1083 max_ack_delay_secs
= timeval
/ 1000000;
1084 max_ack_delay_usecs
= timeval
% 1000000;
1086 data_string_forget(&db
, MDL
);
1089 oc
= lookup_option(&server_universe
, options
, SV_DONT_USE_FSYNC
);
1091 evaluate_boolean_option_cache(NULL
, NULL
, NULL
, NULL
, options
, NULL
,
1092 &global_scope
, oc
, MDL
)) {
1094 log_error("Not using fsync() to flush lease writes");
1097 oc
= lookup_option(&server_universe
, options
, SV_SERVER_ID_CHECK
);
1099 evaluate_boolean_option_cache(NULL
, NULL
, NULL
, NULL
, options
, NULL
,
1100 &global_scope
, oc
, MDL
)) {
1101 log_info("Setting server-id-check true");
1102 server_id_check
= 1;
1105 oc
= lookup_option(&server_universe
, options
, SV_PREFIX_LEN_MODE
);
1107 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
1108 &global_scope
, oc
, MDL
)) {
1110 prefix_length_mode
= db
.data
[0];
1112 log_fatal("invalid prefix-len-mode");
1115 data_string_forget(&db
, MDL
);
1118 /* Don't need the options anymore. */
1119 option_state_dereference(&options
, MDL
);
1122 void postdb_startup (void)
1124 /* Initialize the omapi listener state. */
1125 if (omapi_port
!= -1) {
1126 omapi_listener_start (0);
1129 #if defined (FAILOVER_PROTOCOL)
1130 /* Initialize the failover listener state. */
1131 dhcp_failover_startup ();
1135 * Begin our lease timeout background task.
1137 schedule_all_ipv6_lease_timeouts();
1140 /* Print usage message. */
1144 log_info("%s %s", message
, PACKAGE_VERSION
);
1145 log_info(copyright
);
1148 log_fatal("Usage: dhcpd [-p <UDP port #>] [-f] [-d] [-q] [-t|-T]\n"
1150 " [-4|-6] [-cf config-file] [-lf lease-file]\n"
1152 " [-cf config-file] [-lf lease-file]\n"
1154 #if defined (PARANOIA)
1155 /* meld into the following string */
1156 " [-user user] [-group group] [-chroot dir]\n"
1157 #endif /* PARANOIA */
1158 #if defined (TRACING)
1159 " [-tf trace-output-file]\n"
1160 " [-play trace-input-file]\n"
1161 #endif /* TRACING */
1162 " [-pf pid-file] [--no-pid] [-s server]\n"
1167 void lease_pinged (from
, packet
, length
)
1174 /* Don't try to look up a pinged lease if we aren't trying to
1175 ping one - otherwise somebody could easily make us churn by
1176 just forging repeated ICMP EchoReply packets for us to look
1178 if (!outstanding_pings
)
1181 lp
= (struct lease
*)0;
1182 if (!find_lease_by_ip_addr (&lp
, from
, MDL
)) {
1183 log_debug ("unexpected ICMP Echo Reply from %s",
1189 #if defined (FAILOVER_PROTOCOL)
1191 !lp
-> pool
-> failover_peer
)
1193 log_debug ("ICMP Echo Reply for %s late or spurious.",
1198 if (lp
-> ends
> cur_time
) {
1199 log_debug ("ICMP Echo reply while lease %s valid.",
1203 /* At this point it looks like we pinged a lease and got a
1204 response, which shouldn't have happened. */
1205 data_string_forget (&lp
-> state
-> parameter_request_list
, MDL
);
1206 free_lease_state (lp
-> state
, MDL
);
1207 lp
-> state
= (struct lease_state
*)0;
1209 abandon_lease (lp
, "pinged before offer");
1210 cancel_timeout (lease_ping_timeout
, lp
);
1211 --outstanding_pings
;
1213 lease_dereference (&lp
, MDL
);
1216 void lease_ping_timeout (vlp
)
1219 struct lease
*lp
= vlp
;
1221 #if defined (DEBUG_MEMORY_LEAKAGE)
1222 unsigned long previous_outstanding
= dmalloc_outstanding
;
1225 --outstanding_pings
;
1228 #if defined (DEBUG_MEMORY_LEAKAGE)
1229 log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term",
1231 dmalloc_outstanding
- previous_outstanding
,
1232 dmalloc_outstanding
, dmalloc_longterm
);
1234 #if defined (DEBUG_MEMORY_LEAKAGE)
1235 dmalloc_dump_outstanding ();
1239 int dhcpd_interface_setup_hook (struct interface_info
*ip
, struct iaddr
*ia
)
1241 struct subnet
*subnet
;
1242 struct shared_network
*share
;
1243 isc_result_t status
;
1245 /* Special case for fallback network - not sure why this is
1248 const char *fnn
= "fallback-net";
1249 status
= shared_network_allocate (&ip
-> shared_network
, MDL
);
1250 if (status
!= ISC_R_SUCCESS
)
1251 log_fatal ("No memory for shared subnet: %s",
1252 isc_result_totext (status
));
1253 ip
-> shared_network
-> name
= dmalloc (strlen (fnn
) + 1, MDL
);
1254 strcpy (ip
-> shared_network
-> name
, fnn
);
1258 /* If there's a registered subnet for this address,
1259 connect it together... */
1260 subnet
= (struct subnet
*)0;
1261 if (find_subnet (&subnet
, *ia
, MDL
)) {
1262 /* If this interface has multiple aliases on the same
1263 subnet, ignore all but the first we encounter. */
1264 if (!subnet
-> interface
) {
1265 interface_reference (&subnet
-> interface
, ip
, MDL
);
1266 subnet
-> interface_address
= *ia
;
1267 } else if (subnet
-> interface
!= ip
) {
1268 log_error ("Multiple interfaces match the %s: %s %s",
1270 subnet
-> interface
-> name
, ip
-> name
);
1272 share
= subnet
-> shared_network
;
1273 if (ip
-> shared_network
&&
1274 ip
-> shared_network
!= share
) {
1275 log_fatal ("Interface %s matches multiple shared %s",
1276 ip
-> name
, "networks");
1278 if (!ip
-> shared_network
)
1279 shared_network_reference
1280 (&ip
-> shared_network
, share
, MDL
);
1283 if (!share
-> interface
) {
1284 interface_reference (&share
-> interface
, ip
, MDL
);
1285 } else if (share
-> interface
!= ip
) {
1286 log_error ("Multiple interfaces match the %s: %s %s",
1287 "same shared network",
1288 share
-> interface
-> name
, ip
-> name
);
1290 subnet_dereference (&subnet
, MDL
);
1295 static TIME shutdown_time
;
1296 static int omapi_connection_count
;
1297 enum dhcp_shutdown_state shutdown_state
;
1299 isc_result_t
dhcp_io_shutdown (omapi_object_t
*obj
, void *foo
)
1301 /* Shut down all listeners. */
1302 if (shutdown_state
== shutdown_listeners
&&
1303 obj
-> type
== omapi_type_listener
&&
1305 obj
-> inner
-> type
== omapi_type_protocol_listener
) {
1306 omapi_listener_destroy (obj
, MDL
);
1307 return ISC_R_SUCCESS
;
1310 /* Shut down all existing omapi connections. */
1311 if (obj
-> type
== omapi_type_connection
&&
1313 obj
-> inner
-> type
== omapi_type_protocol
) {
1314 if (shutdown_state
== shutdown_drop_omapi_connections
) {
1315 omapi_disconnect (obj
, 1);
1317 omapi_connection_count
++;
1318 if (shutdown_state
== shutdown_omapi_connections
) {
1319 omapi_disconnect (obj
, 0);
1320 return ISC_R_SUCCESS
;
1324 /* Shutdown all DHCP interfaces. */
1325 if (obj
-> type
== dhcp_type_interface
&&
1326 shutdown_state
== shutdown_dhcp
) {
1327 dhcp_interface_remove (obj
, (omapi_object_t
*)0);
1328 return ISC_R_SUCCESS
;
1330 return ISC_R_SUCCESS
;
1333 static isc_result_t
dhcp_io_shutdown_countdown (void *vlp
)
1335 #if defined (FAILOVER_PROTOCOL)
1336 dhcp_failover_state_t
*state
;
1337 int failover_connection_count
= 0;
1342 if (shutdown_state
== shutdown_listeners
||
1343 shutdown_state
== shutdown_omapi_connections
||
1344 shutdown_state
== shutdown_drop_omapi_connections
||
1345 shutdown_state
== shutdown_dhcp
) {
1346 omapi_connection_count
= 0;
1347 omapi_io_state_foreach (dhcp_io_shutdown
, 0);
1350 if ((shutdown_state
== shutdown_listeners
||
1351 shutdown_state
== shutdown_omapi_connections
||
1352 shutdown_state
== shutdown_drop_omapi_connections
) &&
1353 omapi_connection_count
== 0) {
1354 shutdown_state
= shutdown_dhcp
;
1355 shutdown_time
= cur_time
;
1357 } else if (shutdown_state
== shutdown_listeners
&&
1358 cur_time
- shutdown_time
> 4) {
1359 shutdown_state
= shutdown_omapi_connections
;
1360 shutdown_time
= cur_time
;
1361 } else if (shutdown_state
== shutdown_omapi_connections
&&
1362 cur_time
- shutdown_time
> 4) {
1363 shutdown_state
= shutdown_drop_omapi_connections
;
1364 shutdown_time
= cur_time
;
1365 } else if (shutdown_state
== shutdown_drop_omapi_connections
&&
1366 cur_time
- shutdown_time
> 4) {
1367 shutdown_state
= shutdown_dhcp
;
1368 shutdown_time
= cur_time
;
1370 } else if (shutdown_state
== shutdown_dhcp
&&
1371 cur_time
- shutdown_time
> 4) {
1372 shutdown_state
= shutdown_done
;
1373 shutdown_time
= cur_time
;
1376 #if defined (FAILOVER_PROTOCOL)
1377 /* Set all failover peers into the shutdown state. */
1378 if (shutdown_state
== shutdown_dhcp
) {
1379 for (state
= failover_states
; state
; state
= state
-> next
) {
1380 if (state
-> me
.state
== normal
) {
1381 dhcp_failover_set_state (state
, shut_down
);
1382 failover_connection_count
++;
1384 if (state
-> me
.state
== shut_down
&&
1385 state
-> partner
.state
!= partner_down
)
1386 failover_connection_count
++;
1390 if (shutdown_state
== shutdown_done
) {
1391 for (state
= failover_states
; state
; state
= state
-> next
) {
1392 if (state
-> me
.state
== shut_down
) {
1393 if (state
-> link_to_peer
)
1394 dhcp_failover_link_dereference (&state
-> link_to_peer
,
1396 dhcp_failover_set_state (state
, recover
);
1399 #if defined (DEBUG_MEMORY_LEAKAGE) && \
1400 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1402 omapi_print_dmalloc_usage_by_caller ();
1404 if (no_pid_file
== ISC_FALSE
)
1405 (void) unlink(path_dhcpd_pid
);
1409 if (shutdown_state
== shutdown_done
) {
1410 #if defined (DEBUG_MEMORY_LEAKAGE) && \
1411 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1413 omapi_print_dmalloc_usage_by_caller ();
1415 if (no_pid_file
== ISC_FALSE
)
1416 (void) unlink(path_dhcpd_pid
);
1420 if (shutdown_state
== shutdown_dhcp
&&
1421 #if defined(FAILOVER_PROTOCOL)
1422 !failover_connection_count
&&
1425 shutdown_state
= shutdown_done
;
1426 shutdown_time
= cur_time
;
1429 tv
.tv_sec
= cur_tv
.tv_sec
+ 1;
1430 tv
.tv_usec
= cur_tv
.tv_usec
;
1432 (void (*)(void *))dhcp_io_shutdown_countdown
, 0, 0, 0);
1433 return ISC_R_SUCCESS
;
1436 isc_result_t
dhcp_set_control_state (control_object_state_t oldstate
,
1437 control_object_state_t newstate
)
1441 if (newstate
!= server_shutdown
)
1442 return DHCP_R_INVALIDARG
;
1444 if (shutdown_signal
== SIGUSR1
)
1445 return ISC_R_SUCCESS
;
1446 shutdown_time
= cur_time
;
1447 shutdown_state
= shutdown_listeners
;
1448 /* Called by user. */
1449 if (shutdown_signal
== 0) {
1450 shutdown_signal
= SIGUSR1
;
1451 dhcp_io_shutdown_countdown (0);
1452 return ISC_R_SUCCESS
;
1454 /* Called on signal. */
1455 log_info("Received signal %d, initiating shutdown.", shutdown_signal
);
1456 shutdown_signal
= SIGUSR1
;
1459 * Prompt the shutdown event onto the timer queue
1460 * and return to the dispatch loop.
1462 tv
.tv_sec
= cur_tv
.tv_sec
;
1463 tv
.tv_usec
= cur_tv
.tv_usec
+ 1;
1465 (void (*)(void *))dhcp_io_shutdown_countdown
, 0, 0, 0);
1466 return ISC_R_SUCCESS
;