6 * Copyright (c) 2004-2014 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
67 char std_nsupdate
[] = " \n\
68 option server.ddns-hostname = \n\
69 pick (option fqdn.hostname, option host-name); \n\
70 option server.ddns-domainname = config-option domain-name; \n\
71 option server.ddns-rev-domainname = \"in-addr.arpa.\";";
74 int ddns_update_style
;
75 int dont_use_fsync
= 0; /* 0 = default, use fsync, 1 = don't use fsync */
77 const char *path_dhcpd_conf
= _PATH_DHCPD_CONF
;
78 const char *path_dhcpd_db
= _PATH_DHCPD_DB
;
79 const char *path_dhcpd_pid
= _PATH_DHCPD_PID
;
80 /* False (default) => we write and use a pid file */
81 isc_boolean_t no_pid_file
= ISC_FALSE
;
83 int dhcp_max_agent_option_packet_length
= DHCP_MTU_MAX
;
85 static omapi_auth_key_t
*omapi_key
= (omapi_auth_key_t
*)0;
89 trace_type_t
*trace_srandom
;
92 static isc_result_t
verify_addr (omapi_object_t
*l
, omapi_addr_t
*addr
) {
96 static isc_result_t
verify_auth (omapi_object_t
*p
, omapi_auth_key_t
*a
) {
98 return DHCP_R_INVALIDKEY
;
102 static void omapi_listener_start (void *foo
)
104 omapi_object_t
*listener
;
108 listener
= (omapi_object_t
*)0;
109 result
= omapi_generic_new (&listener
, MDL
);
110 if (result
!= ISC_R_SUCCESS
)
111 log_fatal ("Can't allocate new generic object: %s",
112 isc_result_totext (result
));
113 result
= omapi_protocol_listen (listener
,
114 (unsigned)omapi_port
, 1);
115 if (result
== ISC_R_SUCCESS
&& omapi_key
)
116 result
= omapi_protocol_configure_security
117 (listener
, verify_addr
, verify_auth
);
118 if (result
!= ISC_R_SUCCESS
) {
119 log_error ("Can't start OMAPI protocol: %s",
120 isc_result_totext (result
));
121 tv
.tv_sec
= cur_tv
.tv_sec
+ 5;
122 tv
.tv_usec
= cur_tv
.tv_usec
;
123 add_timeout (&tv
, omapi_listener_start
, 0, 0, 0);
125 omapi_object_dereference (&listener
, MDL
);
128 #if defined (PARANOIA)
129 /* to be used in one of two possible scenarios */
130 static void setup_chroot (char *chroot_dir
) {
132 log_fatal ("you must be root to use chroot");
134 if (chroot(chroot_dir
)) {
135 log_fatal ("chroot(\"%s\"): %m", chroot_dir
);
138 /* probably permission denied */
139 log_fatal ("chdir(\"/\"): %m");
142 #endif /* PARANOIA */
146 main(int argc
, char **argv
) {
159 char *server
= (char *)0;
162 struct interface_info
*ip
;
163 #if defined (NSUPDATE)
167 int no_dhcpd_conf
= 0;
169 int no_dhcpd_pid
= 0;
171 int local_family_set
= 0;
173 #if defined (TRACING)
174 char *traceinfile
= (char *)0;
175 char *traceoutfile
= (char *)0;
178 #if defined (PARANOIA)
181 char *set_chroot
= 0;
185 #endif /* PARANOIA */
187 /* Make sure that file descriptors 0 (stdin), 1, (stdout), and
188 2 (stderr) are open. To do this, we assume that when we
189 open a file the lowest available file descriptor is used. */
190 fd
= open("/dev/null", O_RDWR
);
192 fd
= open("/dev/null", O_RDWR
);
194 fd
= open("/dev/null", O_RDWR
);
196 log_perror
= 0; /* No sense logging to /dev/null. */
200 /* Set up the isc and dns library managers */
201 status
= dhcp_context_create(DHCP_CONTEXT_PRE_DB
,
203 if (status
!= ISC_R_SUCCESS
)
204 log_fatal("Can't initialize context: %s",
205 isc_result_totext(status
));
207 /* Set up the client classification system. */
208 classification_setup ();
210 /* Initialize the omapi system. */
211 result
= omapi_init ();
212 if (result
!= ISC_R_SUCCESS
)
213 log_fatal ("Can't initialize OMAPI: %s",
214 isc_result_totext (result
));
216 /* Set up the OMAPI wrappers for common objects. */
217 dhcp_db_objects_setup ();
218 /* Set up the OMAPI wrappers for various server database internal
220 dhcp_common_objects_setup ();
222 /* Initially, log errors to stderr as well as to syslogd. */
223 openlog ("dhcpd", LOG_NDELAY
, DHCPD_LOG_FACILITY
);
225 for (i
= 1; i
< argc
; i
++) {
226 if (!strcmp (argv
[i
], "-p")) {
229 local_port
= validate_port (argv
[i
]);
230 log_debug ("binding to user-specified port %d",
232 } else if (!strcmp (argv
[i
], "-f")) {
236 } else if (!strcmp (argv
[i
], "-d")) {
241 } else if (!strcmp (argv
[i
], "-s")) {
245 #if defined (PARANOIA)
246 } else if (!strcmp (argv
[i
], "-user")) {
250 } else if (!strcmp (argv
[i
], "-group")) {
253 set_group
= argv
[i
];
254 } else if (!strcmp (argv
[i
], "-chroot")) {
257 set_chroot
= argv
[i
];
258 #endif /* PARANOIA */
259 } else if (!strcmp (argv
[i
], "-cf")) {
262 path_dhcpd_conf
= argv
[i
];
264 } else if (!strcmp (argv
[i
], "-lf")) {
267 path_dhcpd_db
= argv
[i
];
269 } else if (!strcmp (argv
[i
], "-pf")) {
272 path_dhcpd_pid
= argv
[i
];
274 } else if (!strcmp(argv
[i
], "--no-pid")) {
275 no_pid_file
= ISC_TRUE
;
276 } else if (!strcmp (argv
[i
], "-t")) {
277 /* test configurations only */
283 } else if (!strcmp (argv
[i
], "-T")) {
284 /* test configurations and lease file only */
291 } else if (!strcmp (argv
[i
], "-q")) {
293 quiet_interface_discovery
= 1;
295 } else if (!strcmp(argv
[i
], "-4")) {
296 if (local_family_set
&& (local_family
!= AF_INET
)) {
297 log_fatal("Server cannot run in both IPv4 and "
298 "IPv6 mode at the same time.");
300 local_family
= AF_INET
;
301 local_family_set
= 1;
302 } else if (!strcmp(argv
[i
], "-6")) {
303 if (local_family_set
&& (local_family
!= AF_INET6
)) {
304 log_fatal("Server cannot run in both IPv4 and "
305 "IPv6 mode at the same time.");
307 local_family
= AF_INET6
;
308 local_family_set
= 1;
310 } else if (!strcmp (argv
[i
], "--version")) {
311 log_info("isc-dhcpd-%s", PACKAGE_VERSION
);
313 #if defined (TRACING)
314 } else if (!strcmp (argv
[i
], "-tf")) {
317 traceoutfile
= argv
[i
];
318 } else if (!strcmp (argv
[i
], "-play")) {
321 traceinfile
= argv
[i
];
322 trace_replay_init ();
324 } else if (argv
[i
][0] == '-') {
327 struct interface_info
*tmp
=
328 (struct interface_info
*)0;
329 if (strlen(argv
[i
]) >= sizeof(tmp
->name
))
330 log_fatal("%s: interface name too long "
332 argv
[i
], (long)strlen(argv
[i
]));
333 result
= interface_allocate (&tmp
, MDL
);
334 if (result
!= ISC_R_SUCCESS
)
335 log_fatal ("Insufficient memory to %s %s: %s",
336 "record interface", argv
[i
],
337 isc_result_totext (result
));
338 strcpy (tmp
-> name
, argv
[i
]);
340 interface_reference (&tmp
-> next
,
342 interface_dereference (&interfaces
, MDL
);
344 interface_reference (&interfaces
, tmp
, MDL
);
345 tmp
-> flags
= INTERFACE_REQUESTED
;
349 if (!no_dhcpd_conf
&& (s
= getenv ("PATH_DHCPD_CONF"))) {
354 if (local_family
== AF_INET6
) {
355 /* DHCPv6: override DHCPv4 lease and pid filenames */
357 if ((s
= getenv ("PATH_DHCPD6_DB")))
360 path_dhcpd_db
= _PATH_DHCPD6_DB
;
363 if ((s
= getenv ("PATH_DHCPD6_PID")))
366 path_dhcpd_pid
= _PATH_DHCPD6_PID
;
371 if (!no_dhcpd_db
&& (s
= getenv ("PATH_DHCPD_DB"))) {
374 if (!no_dhcpd_pid
&& (s
= getenv ("PATH_DHCPD_PID"))) {
381 * convert relative path names to absolute, for files that need
382 * to be reopened after chdir() has been called
384 if (path_dhcpd_db
[0] != '/') {
385 const char *path
= path_dhcpd_db
;
386 path_dhcpd_db
= realpath(path_dhcpd_db
, NULL
);
387 if (path_dhcpd_db
== NULL
)
388 log_fatal("Failed to get realpath for %s: %s", path
,
393 log_info("%s %s", message
, PACKAGE_VERSION
);
394 log_info (copyright
);
402 #if defined (TRACING)
403 trace_init (set_time
, MDL
);
405 result
= trace_begin (traceoutfile
, MDL
);
406 if (result
!= ISC_R_SUCCESS
)
407 log_fatal ("Unable to begin trace: %s",
408 isc_result_totext (result
));
410 interface_trace_setup ();
411 parse_trace_setup ();
412 trace_srandom
= trace_type_register ("random-seed", (void *)0,
414 trace_seed_stop
, MDL
);
415 #if defined (NSUPDATE)
417 #endif /* NSUPDATE */
420 #if defined (PARANOIA)
421 /* get user and group info if those options were given */
423 struct passwd
*tmp_pwd
;
426 log_fatal ("you must be root to set user");
428 if (!(tmp_pwd
= getpwnam(set_user
)))
429 log_fatal ("no such user: %s", set_user
);
431 set_uid
= tmp_pwd
->pw_uid
;
433 /* use the user's group as the default gid */
435 set_gid
= tmp_pwd
->pw_gid
;
439 /* get around the ISC declaration of group */
440 #define group real_group
441 struct group
*tmp_grp
;
444 log_fatal ("you must be root to set group");
446 if (!(tmp_grp
= getgrnam(set_group
)))
447 log_fatal ("no such group: %s", set_group
);
449 set_gid
= tmp_grp
->gr_gid
;
453 # if defined (EARLY_CHROOT)
454 if (set_chroot
) setup_chroot (set_chroot
);
455 # endif /* EARLY_CHROOT */
456 #endif /* PARANOIA */
458 /* Default to the DHCP/BOOTP port. */
461 if ((s
= getenv ("DHCPD_PORT"))) {
462 local_port
= validate_port (s
);
463 log_debug ("binding to environment-specified port %d",
466 if (local_family
== AF_INET
) {
467 ent
= getservbyname("dhcp", "udp");
469 local_port
= htons(67);
471 local_port
= ent
->s_port
;
474 /* INSIST(local_family == AF_INET6); */
475 ent
= getservbyname("dhcpv6-server", "udp");
477 local_port
= htons(547);
479 local_port
= ent
->s_port
;
482 #ifndef __CYGWIN32__ /* XXX */
488 if (local_family
== AF_INET
) {
489 remote_port
= htons(ntohs(local_port
) + 1);
491 /* INSIST(local_family == AF_INET6); */
492 ent
= getservbyname("dhcpv6-client", "udp");
494 remote_port
= htons(546);
496 remote_port
= ent
->s_port
;
501 if (local_family
!= AF_INET
) {
502 log_fatal("You can only specify address to send "
503 "replies to when running an IPv4 server.");
505 if (!inet_aton (server
, &limited_broadcast
)) {
507 he
= gethostbyname (server
);
509 memcpy (&limited_broadcast
,
510 he
-> h_addr_list
[0],
511 sizeof limited_broadcast
);
513 limited_broadcast
.s_addr
= INADDR_BROADCAST
;
516 limited_broadcast
.s_addr
= INADDR_BROADCAST
;
519 /* Get the current time... */
520 gettimeofday(&cur_tv
, NULL
);
522 /* Set up the initial dhcp option universe. */
523 initialize_common_option_spaces ();
524 initialize_server_option_spaces ();
526 /* Add the ddns update style enumeration prior to parsing. */
527 add_enumeration (&ddns_styles
);
528 add_enumeration (&syslog_enum
);
529 #if defined (LDAP_CONFIGURATION)
530 add_enumeration (&ldap_methods
);
531 #if defined (LDAP_USE_SSL)
532 add_enumeration (&ldap_ssl_usage_enum
);
533 add_enumeration (&ldap_tls_reqcert_enum
);
534 add_enumeration (&ldap_tls_crlcheck_enum
);
538 if (!group_allocate (&root_group
, MDL
))
539 log_fatal ("Can't allocate root group!");
540 root_group
-> authoritative
= 0;
542 /* Set up various hooks. */
543 dhcp_interface_setup_hook
= dhcpd_interface_setup_hook
;
544 bootp_packet_handler
= do_packet
;
546 dhcpv6_packet_handler
= do_packet6
;
549 #if defined (NSUPDATE)
550 /* Set up the standard name service updater routine. */
552 status
= new_parse(&parse
, -1, std_nsupdate
, sizeof(std_nsupdate
) - 1,
553 "standard name service update routine", 0);
554 if (status
!= ISC_R_SUCCESS
)
555 log_fatal ("can't begin parsing name service updater!");
559 if (!(parse_executable_statements(&root_group
->statements
,
560 parse
, &lose
, context_any
))) {
562 log_fatal("can't parse standard name service updater!");
568 /* Initialize icmp support... */
569 if (!cftest
&& !lftest
)
570 icmp_startup (1, lease_pinged
);
572 #if defined (TRACING)
575 log_error ("%s", "");
576 log_error ("** You must specify a lease file with -lf.");
577 log_error (" Dhcpd will not overwrite your default");
578 log_fatal (" lease file when playing back a trace. **");
580 trace_file_replay (traceinfile
);
582 #if defined (DEBUG_MEMORY_LEAKAGE) && \
583 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
585 omapi_print_dmalloc_usage_by_caller ();
593 /* set up DHCPv6 hashes */
594 if (!ia_new_hash(&ia_na_active
, DEFAULT_HASH_SIZE
, MDL
)) {
595 log_fatal("Out of memory creating hash for active IA_NA.");
597 if (!ia_new_hash(&ia_ta_active
, DEFAULT_HASH_SIZE
, MDL
)) {
598 log_fatal("Out of memory creating hash for active IA_TA.");
600 if (!ia_new_hash(&ia_pd_active
, DEFAULT_HASH_SIZE
, MDL
)) {
601 log_fatal("Out of memory creating hash for active IA_PD.");
605 /* Read the dhcpd.conf file... */
606 if (readconf () != ISC_R_SUCCESS
)
607 log_fatal ("Configuration file errors encountered -- exiting");
609 postconf_initialization (quiet
);
611 #if defined (PARANOIA) && !defined (EARLY_CHROOT)
612 if (set_chroot
) setup_chroot (set_chroot
);
613 #endif /* PARANOIA && !EARLY_CHROOT */
615 /* test option should cause an early exit */
616 if (cftest
&& !lftest
)
619 group_write_hook
= group_writer
;
621 /* Start up the database... */
627 /* Discover all the network interfaces and initialize them. */
628 discover_interfaces(DISCOVER_SERVER
);
632 * Remove addresses from our pools that we should not issue
635 * We currently have no support for this in IPv4. It is not
636 * as important in IPv4, as making pools with ranges that
637 * leave out interfaces and hosts is fairly straightforward
638 * using range notation, but not so handy with CIDR notation.
640 if (local_family
== AF_INET6
) {
641 mark_hosts_unavailable();
642 mark_phosts_unavailable();
643 mark_interfaces_unavailable();
648 /* Make up a seed for the random number generator from current
649 time plus the sum of the last four bytes of each
650 interface's hardware address interpreted as an integer.
651 Not much entropy, but we're booting, so we're not likely to
652 find anything better. */
654 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
657 &ip
-> hw_address
.hbuf
[ip
-> hw_address
.hlen
-
658 sizeof seed
], sizeof seed
);
661 srandom (seed
+ cur_time
);
662 #if defined (TRACING)
663 trace_seed_stash (trace_srandom
, seed
+ cur_time
);
669 * Set server DHCPv6 identifier.
670 * See dhcpv6.c for discussion of setting DUID.
672 if (set_server_duid_from_option() == ISC_R_SUCCESS
) {
675 if (!server_duid_isset()) {
676 if (generate_new_server_duid() != ISC_R_SUCCESS
) {
677 log_fatal("Unable to set server identifier.");
686 /* First part of becoming a daemon... */
687 if ((pid
= fork ()) < 0)
688 log_fatal ("Can't fork daemon: %m");
693 #if defined (PARANOIA)
694 /* change uid to the specified one */
697 if (setgroups (0, (void *)0))
698 log_fatal ("setgroups: %m");
699 if (setgid (set_gid
))
700 log_fatal ("setgid(%d): %m", (int) set_gid
);
704 if (setuid (set_uid
))
705 log_fatal ("setuid(%d): %m", (int) set_uid
);
707 #endif /* PARANOIA */
710 * Deal with pid files. If the user told us
711 * not to write a file we don't read one either
713 if (no_pid_file
== ISC_FALSE
) {
714 /*Read previous pid file. */
715 if ((i
= open (path_dhcpd_pid
, O_RDONLY
)) >= 0) {
716 status
= read(i
, pbuf
, (sizeof pbuf
) - 1);
723 * If there was a previous server process and
724 * it is still running, abort
727 (pid
!= getpid() && kill(pid
, 0) == 0))
728 log_fatal("There's already a "
729 "DHCP server running.");
733 /* Write new pid file. */
734 i
= open(path_dhcpd_pid
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0644);
736 sprintf(pbuf
, "%d\n", (int) getpid());
737 IGNORE_RET (write(i
, pbuf
, strlen(pbuf
)));
740 log_error("Can't create PID file %s: %m.",
745 /* If we were requested to log to stdout on the command line,
746 keep doing so; otherwise, stop. */
747 if (log_perror
== -1)
753 /* Become session leader and get pid... */
756 /* Close standard I/O descriptors. */
761 /* Reopen them on /dev/null. */
762 (void) open("/dev/null", O_RDWR
);
763 (void) open("/dev/null", O_RDWR
);
764 (void) open("/dev/null", O_RDWR
);
765 log_perror
= 0; /* No sense logging to /dev/null. */
767 IGNORE_RET (chdir("/"));
771 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
772 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
773 dmalloc_cutoff_generation
= dmalloc_generation
;
774 dmalloc_longterm
= dmalloc_outstanding
;
775 dmalloc_outstanding
= 0;
778 omapi_set_int_value ((omapi_object_t
*)dhcp_control_object
,
779 (omapi_object_t
*)0, "state", server_running
);
781 /* install signal handlers */
782 signal(SIGINT
, dhcp_signal_handler
); /* control-c */
783 signal(SIGTERM
, dhcp_signal_handler
); /* kill */
785 /* Log that we are about to start working */
786 log_info("Server starting service.");
789 * Receive packets and dispatch them...
790 * dispatch() will never return.
794 /* Let's return status code */
797 #endif /* !UNIT_TEST */
799 void postconf_initialization (int quiet
)
801 struct option_state
*options
= NULL
;
802 struct data_string db
;
803 struct option_cache
*oc
;
807 #if defined (NSUPDATE)
808 struct in_addr local4
, *local4_ptr
= NULL
;
809 struct in6_addr local6
, *local6_ptr
= NULL
;
812 /* Now try to get the lease file name. */
813 option_state_allocate(&options
, MDL
);
815 execute_statements_in_scope(NULL
, NULL
, NULL
, NULL
, NULL
,
816 options
, &global_scope
, root_group
,
818 memset(&db
, 0, sizeof db
);
819 oc
= lookup_option(&server_universe
, options
, SV_LEASE_FILE_NAME
);
821 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
822 &global_scope
, oc
, MDL
)) {
823 s
= dmalloc(db
.len
+ 1, MDL
);
825 log_fatal("no memory for lease db filename.");
826 memcpy(s
, db
.data
, db
.len
);
828 data_string_forget(&db
, MDL
);
832 oc
= lookup_option(&server_universe
, options
, SV_PID_FILE_NAME
);
834 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
835 &global_scope
, oc
, MDL
)) {
836 s
= dmalloc(db
.len
+ 1, MDL
);
838 log_fatal("no memory for pid filename.");
839 memcpy(s
, db
.data
, db
.len
);
841 data_string_forget(&db
, MDL
);
846 if (local_family
== AF_INET6
) {
848 * Override lease file name with dhcpv6 lease file name,
849 * if it was set; then, do the same with the pid file name
851 oc
= lookup_option(&server_universe
, options
,
852 SV_DHCPV6_LEASE_FILE_NAME
);
854 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
855 &global_scope
, oc
, MDL
)) {
856 s
= dmalloc(db
.len
+ 1, MDL
);
858 log_fatal("no memory for lease db filename.");
859 memcpy(s
, db
.data
, db
.len
);
861 data_string_forget(&db
, MDL
);
865 oc
= lookup_option(&server_universe
, options
,
866 SV_DHCPV6_PID_FILE_NAME
);
868 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
869 &global_scope
, oc
, MDL
)) {
870 s
= dmalloc(db
.len
+ 1, MDL
);
872 log_fatal("no memory for pid filename.");
873 memcpy(s
, db
.data
, db
.len
);
875 data_string_forget(&db
, MDL
);
882 oc
= lookup_option(&server_universe
, options
, SV_OMAPI_PORT
);
884 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
885 &global_scope
, oc
, MDL
)) {
887 omapi_port
= getUShort(db
.data
);
889 log_fatal("invalid omapi port data length");
890 data_string_forget(&db
, MDL
);
893 oc
= lookup_option(&server_universe
, options
, SV_OMAPI_KEY
);
895 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
896 &global_scope
, oc
, MDL
)) {
897 s
= dmalloc(db
.len
+ 1, MDL
);
899 log_fatal("no memory for OMAPI key filename.");
900 memcpy(s
, db
.data
, db
.len
);
902 data_string_forget(&db
, MDL
);
903 result
= omapi_auth_key_lookup_name(&omapi_key
, s
);
905 if (result
!= ISC_R_SUCCESS
)
906 log_fatal("OMAPI key %s: %s",
907 s
, isc_result_totext (result
));
910 oc
= lookup_option(&server_universe
, options
, SV_LOCAL_PORT
);
912 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
913 &global_scope
, oc
, MDL
)) {
915 local_port
= htons(getUShort (db
.data
));
917 log_fatal("invalid local port data length");
918 data_string_forget(&db
, MDL
);
921 oc
= lookup_option(&server_universe
, options
, SV_REMOTE_PORT
);
923 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
924 &global_scope
, oc
, MDL
)) {
926 remote_port
= htons(getUShort (db
.data
));
928 log_fatal("invalid remote port data length");
929 data_string_forget(&db
, MDL
);
932 oc
= lookup_option(&server_universe
, options
,
933 SV_LIMITED_BROADCAST_ADDRESS
);
935 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
936 &global_scope
, oc
, MDL
)) {
938 memcpy(&limited_broadcast
, db
.data
, 4);
940 log_fatal("invalid broadcast address data length");
941 data_string_forget(&db
, MDL
);
944 oc
= lookup_option(&server_universe
, options
, SV_LOCAL_ADDRESS
);
946 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
947 &global_scope
, oc
, MDL
)) {
949 memcpy(&local_address
, db
.data
, 4);
951 log_fatal("invalid local address data length");
952 data_string_forget(&db
, MDL
);
955 oc
= lookup_option(&server_universe
, options
, SV_DDNS_UPDATE_STYLE
);
957 if (evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
958 &global_scope
, oc
, MDL
)) {
960 ddns_update_style
= db
.data
[0];
962 log_fatal("invalid dns update type");
963 data_string_forget(&db
, MDL
);
966 ddns_update_style
= DDNS_UPDATE_STYLE_NONE
;
968 #if defined (NSUPDATE)
969 /* We no longer support ad_hoc, tell the user */
970 if (ddns_update_style
== DDNS_UPDATE_STYLE_AD_HOC
) {
971 log_fatal("ddns-update-style ad_hoc no longer supported");
974 oc
= lookup_option(&server_universe
, options
, SV_DDNS_LOCAL_ADDRESS4
);
976 if (evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
977 &global_scope
, oc
, MDL
)) {
979 memcpy(&local4
, db
.data
, 4);
980 local4_ptr
= &local4
;
982 data_string_forget(&db
, MDL
);
986 oc
= lookup_option(&server_universe
, options
, SV_DDNS_LOCAL_ADDRESS6
);
988 if (evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
989 &global_scope
, oc
, MDL
)) {
991 memcpy(&local6
, db
.data
, 16);
992 local6_ptr
= &local6
;
994 data_string_forget(&db
, MDL
);
998 if (dhcp_context_create(DHCP_CONTEXT_POST_DB
, local4_ptr
, local6_ptr
)
1000 log_fatal("Unable to complete ddns initialization");
1003 /* If we don't have support for updates compiled in tell the user */
1004 if (ddns_update_style
!= DDNS_UPDATE_STYLE_NONE
) {
1005 log_fatal("Support for ddns-update-style not compiled in");
1009 oc
= lookup_option(&server_universe
, options
, SV_LOG_FACILITY
);
1011 if (evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
1012 &global_scope
, oc
, MDL
)) {
1015 openlog("dhcpd", LOG_NDELAY
, db
.data
[0]);
1016 /* Log the startup banner into the new
1019 /* Don't log to stderr twice. */
1023 message
, PACKAGE_VERSION
);
1024 log_info(copyright
);
1030 log_fatal("invalid log facility");
1031 data_string_forget(&db
, MDL
);
1035 oc
= lookup_option(&server_universe
, options
, SV_DELAYED_ACK
);
1037 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
1038 &global_scope
, oc
, MDL
)) {
1040 max_outstanding_acks
= htons(getUShort(db
.data
));
1042 log_fatal("invalid max delayed ACK count ");
1044 data_string_forget(&db
, MDL
);
1047 oc
= lookup_option(&server_universe
, options
, SV_MAX_ACK_DELAY
);
1049 evaluate_option_cache(&db
, NULL
, NULL
, NULL
, options
, NULL
,
1050 &global_scope
, oc
, MDL
)) {
1054 log_fatal("invalid max ack delay configuration");
1056 timeval
= getULong(db
.data
);
1057 max_ack_delay_secs
= timeval
/ 1000000;
1058 max_ack_delay_usecs
= timeval
% 1000000;
1060 data_string_forget(&db
, MDL
);
1063 oc
= lookup_option(&server_universe
, options
, SV_DONT_USE_FSYNC
);
1065 evaluate_boolean_option_cache(NULL
, NULL
, NULL
, NULL
, options
, NULL
,
1066 &global_scope
, oc
, MDL
)) {
1068 log_error("Not using fsync() to flush lease writes");
1071 /* Don't need the options anymore. */
1072 option_state_dereference(&options
, MDL
);
1075 void postdb_startup (void)
1077 /* Initialize the omapi listener state. */
1078 if (omapi_port
!= -1) {
1079 omapi_listener_start (0);
1082 #if defined (FAILOVER_PROTOCOL)
1083 /* Initialize the failover listener state. */
1084 dhcp_failover_startup ();
1088 * Begin our lease timeout background task.
1090 schedule_all_ipv6_lease_timeouts();
1093 /* Print usage message. */
1097 log_info("%s %s", message
, PACKAGE_VERSION
);
1098 log_info(copyright
);
1101 log_fatal("Usage: dhcpd [-p <UDP port #>] [-f] [-d] [-q] [-t|-T]\n"
1103 " [-4|-6] [-cf config-file] [-lf lease-file]\n"
1105 " [-cf config-file] [-lf lease-file]\n"
1107 #if defined (PARANOIA)
1108 /* meld into the following string */
1109 " [-user user] [-group group] [-chroot dir]\n"
1110 #endif /* PARANOIA */
1111 #if defined (TRACING)
1112 " [-tf trace-output-file]\n"
1113 " [-play trace-input-file]\n"
1114 #endif /* TRACING */
1115 " [-pf pid-file] [--no-pid] [-s server]\n"
1120 void lease_pinged (from
, packet
, length
)
1127 /* Don't try to look up a pinged lease if we aren't trying to
1128 ping one - otherwise somebody could easily make us churn by
1129 just forging repeated ICMP EchoReply packets for us to look
1131 if (!outstanding_pings
)
1134 lp
= (struct lease
*)0;
1135 if (!find_lease_by_ip_addr (&lp
, from
, MDL
)) {
1136 log_debug ("unexpected ICMP Echo Reply from %s",
1142 #if defined (FAILOVER_PROTOCOL)
1144 !lp
-> pool
-> failover_peer
)
1146 log_debug ("ICMP Echo Reply for %s late or spurious.",
1151 if (lp
-> ends
> cur_time
) {
1152 log_debug ("ICMP Echo reply while lease %s valid.",
1156 /* At this point it looks like we pinged a lease and got a
1157 response, which shouldn't have happened. */
1158 data_string_forget (&lp
-> state
-> parameter_request_list
, MDL
);
1159 free_lease_state (lp
-> state
, MDL
);
1160 lp
-> state
= (struct lease_state
*)0;
1162 abandon_lease (lp
, "pinged before offer");
1163 cancel_timeout (lease_ping_timeout
, lp
);
1164 --outstanding_pings
;
1166 lease_dereference (&lp
, MDL
);
1169 void lease_ping_timeout (vlp
)
1172 struct lease
*lp
= vlp
;
1174 #if defined (DEBUG_MEMORY_LEAKAGE)
1175 unsigned long previous_outstanding
= dmalloc_outstanding
;
1178 --outstanding_pings
;
1181 #if defined (DEBUG_MEMORY_LEAKAGE)
1182 log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term",
1184 dmalloc_outstanding
- previous_outstanding
,
1185 dmalloc_outstanding
, dmalloc_longterm
);
1187 #if defined (DEBUG_MEMORY_LEAKAGE)
1188 dmalloc_dump_outstanding ();
1192 int dhcpd_interface_setup_hook (struct interface_info
*ip
, struct iaddr
*ia
)
1194 struct subnet
*subnet
;
1195 struct shared_network
*share
;
1196 isc_result_t status
;
1198 /* Special case for fallback network - not sure why this is
1201 const char *fnn
= "fallback-net";
1202 status
= shared_network_allocate (&ip
-> shared_network
, MDL
);
1203 if (status
!= ISC_R_SUCCESS
)
1204 log_fatal ("No memory for shared subnet: %s",
1205 isc_result_totext (status
));
1206 ip
-> shared_network
-> name
= dmalloc (strlen (fnn
) + 1, MDL
);
1207 strcpy (ip
-> shared_network
-> name
, fnn
);
1211 /* If there's a registered subnet for this address,
1212 connect it together... */
1213 subnet
= (struct subnet
*)0;
1214 if (find_subnet (&subnet
, *ia
, MDL
)) {
1215 /* If this interface has multiple aliases on the same
1216 subnet, ignore all but the first we encounter. */
1217 if (!subnet
-> interface
) {
1218 interface_reference (&subnet
-> interface
, ip
, MDL
);
1219 subnet
-> interface_address
= *ia
;
1220 } else if (subnet
-> interface
!= ip
) {
1221 log_error ("Multiple interfaces match the %s: %s %s",
1223 subnet
-> interface
-> name
, ip
-> name
);
1225 share
= subnet
-> shared_network
;
1226 if (ip
-> shared_network
&&
1227 ip
-> shared_network
!= share
) {
1228 log_fatal ("Interface %s matches multiple shared %s",
1229 ip
-> name
, "networks");
1231 if (!ip
-> shared_network
)
1232 shared_network_reference
1233 (&ip
-> shared_network
, share
, MDL
);
1236 if (!share
-> interface
) {
1237 interface_reference (&share
-> interface
, ip
, MDL
);
1238 } else if (share
-> interface
!= ip
) {
1239 log_error ("Multiple interfaces match the %s: %s %s",
1240 "same shared network",
1241 share
-> interface
-> name
, ip
-> name
);
1243 subnet_dereference (&subnet
, MDL
);
1248 static TIME shutdown_time
;
1249 static int omapi_connection_count
;
1250 enum dhcp_shutdown_state shutdown_state
;
1252 isc_result_t
dhcp_io_shutdown (omapi_object_t
*obj
, void *foo
)
1254 /* Shut down all listeners. */
1255 if (shutdown_state
== shutdown_listeners
&&
1256 obj
-> type
== omapi_type_listener
&&
1258 obj
-> inner
-> type
== omapi_type_protocol_listener
) {
1259 omapi_listener_destroy (obj
, MDL
);
1260 return ISC_R_SUCCESS
;
1263 /* Shut down all existing omapi connections. */
1264 if (obj
-> type
== omapi_type_connection
&&
1266 obj
-> inner
-> type
== omapi_type_protocol
) {
1267 if (shutdown_state
== shutdown_drop_omapi_connections
) {
1268 omapi_disconnect (obj
, 1);
1270 omapi_connection_count
++;
1271 if (shutdown_state
== shutdown_omapi_connections
) {
1272 omapi_disconnect (obj
, 0);
1273 return ISC_R_SUCCESS
;
1277 /* Shutdown all DHCP interfaces. */
1278 if (obj
-> type
== dhcp_type_interface
&&
1279 shutdown_state
== shutdown_dhcp
) {
1280 dhcp_interface_remove (obj
, (omapi_object_t
*)0);
1281 return ISC_R_SUCCESS
;
1283 return ISC_R_SUCCESS
;
1286 static isc_result_t
dhcp_io_shutdown_countdown (void *vlp
)
1288 #if defined (FAILOVER_PROTOCOL)
1289 dhcp_failover_state_t
*state
;
1290 int failover_connection_count
= 0;
1295 if (shutdown_state
== shutdown_listeners
||
1296 shutdown_state
== shutdown_omapi_connections
||
1297 shutdown_state
== shutdown_drop_omapi_connections
||
1298 shutdown_state
== shutdown_dhcp
) {
1299 omapi_connection_count
= 0;
1300 omapi_io_state_foreach (dhcp_io_shutdown
, 0);
1303 if ((shutdown_state
== shutdown_listeners
||
1304 shutdown_state
== shutdown_omapi_connections
||
1305 shutdown_state
== shutdown_drop_omapi_connections
) &&
1306 omapi_connection_count
== 0) {
1307 shutdown_state
= shutdown_dhcp
;
1308 shutdown_time
= cur_time
;
1310 } else if (shutdown_state
== shutdown_listeners
&&
1311 cur_time
- shutdown_time
> 4) {
1312 shutdown_state
= shutdown_omapi_connections
;
1313 shutdown_time
= cur_time
;
1314 } else if (shutdown_state
== shutdown_omapi_connections
&&
1315 cur_time
- shutdown_time
> 4) {
1316 shutdown_state
= shutdown_drop_omapi_connections
;
1317 shutdown_time
= cur_time
;
1318 } else if (shutdown_state
== shutdown_drop_omapi_connections
&&
1319 cur_time
- shutdown_time
> 4) {
1320 shutdown_state
= shutdown_dhcp
;
1321 shutdown_time
= cur_time
;
1323 } else if (shutdown_state
== shutdown_dhcp
&&
1324 cur_time
- shutdown_time
> 4) {
1325 shutdown_state
= shutdown_done
;
1326 shutdown_time
= cur_time
;
1329 #if defined (FAILOVER_PROTOCOL)
1330 /* Set all failover peers into the shutdown state. */
1331 if (shutdown_state
== shutdown_dhcp
) {
1332 for (state
= failover_states
; state
; state
= state
-> next
) {
1333 if (state
-> me
.state
== normal
) {
1334 dhcp_failover_set_state (state
, shut_down
);
1335 failover_connection_count
++;
1337 if (state
-> me
.state
== shut_down
&&
1338 state
-> partner
.state
!= partner_down
)
1339 failover_connection_count
++;
1343 if (shutdown_state
== shutdown_done
) {
1344 for (state
= failover_states
; state
; state
= state
-> next
) {
1345 if (state
-> me
.state
== shut_down
) {
1346 if (state
-> link_to_peer
)
1347 dhcp_failover_link_dereference (&state
-> link_to_peer
,
1349 dhcp_failover_set_state (state
, recover
);
1352 #if defined (DEBUG_MEMORY_LEAKAGE) && \
1353 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1355 omapi_print_dmalloc_usage_by_caller ();
1360 if (shutdown_state
== shutdown_done
) {
1361 #if defined (DEBUG_MEMORY_LEAKAGE) && \
1362 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1364 omapi_print_dmalloc_usage_by_caller ();
1369 if (shutdown_state
== shutdown_dhcp
&&
1370 #if defined(FAILOVER_PROTOCOL)
1371 !failover_connection_count
&&
1374 shutdown_state
= shutdown_done
;
1375 shutdown_time
= cur_time
;
1378 tv
.tv_sec
= cur_tv
.tv_sec
+ 1;
1379 tv
.tv_usec
= cur_tv
.tv_usec
;
1381 (void (*)(void *))dhcp_io_shutdown_countdown
, 0, 0, 0);
1382 return ISC_R_SUCCESS
;
1385 isc_result_t
dhcp_set_control_state (control_object_state_t oldstate
,
1386 control_object_state_t newstate
)
1390 if (newstate
!= server_shutdown
)
1391 return DHCP_R_INVALIDARG
;
1393 if (shutdown_signal
== SIGUSR1
)
1394 return ISC_R_SUCCESS
;
1395 shutdown_time
= cur_time
;
1396 shutdown_state
= shutdown_listeners
;
1397 /* Called by user. */
1398 if (shutdown_signal
== 0) {
1399 shutdown_signal
= SIGUSR1
;
1400 dhcp_io_shutdown_countdown (0);
1401 return ISC_R_SUCCESS
;
1403 /* Called on signal. */
1404 log_info("Received signal %d, initiating shutdown.", shutdown_signal
);
1405 shutdown_signal
= SIGUSR1
;
1408 * Prompt the shutdown event onto the timer queue
1409 * and return to the dispatch loop.
1411 tv
.tv_sec
= cur_tv
.tv_sec
;
1412 tv
.tv_usec
= cur_tv
.tv_usec
+ 1;
1414 (void (*)(void *))dhcp_io_shutdown_countdown
, 0, 0, 0);
1415 return ISC_R_SUCCESS
;