mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-30 13:57:50 +00:00
- Cut some things out into subroutines to support tracing.
- Do all the relevant tracing setup. - Clarify ddns-update-style startup error message. - Print version information and exit if --version is given.
This commit is contained in:
387
server/dhcpd.c
387
server/dhcpd.c
@@ -43,7 +43,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char ocopyright[] =
|
||||
"$Id: dhcpd.c,v 1.109 2001/01/25 08:32:57 mellon Exp $ Copyright 1995-2001 Internet Software Consortium.";
|
||||
"$Id: dhcpd.c,v 1.110 2001/02/12 21:04:06 mellon Exp $ Copyright 1995-2001 Internet Software Consortium.";
|
||||
#endif
|
||||
|
||||
static char copyright[] =
|
||||
@@ -165,6 +165,11 @@ const char *path_dhcpd_pid = _PATH_DHCPD_PID;
|
||||
int dhcp_max_agent_option_packet_length = DHCP_MTU_MAX;
|
||||
|
||||
static omapi_auth_key_t *omapi_key = (omapi_auth_key_t *)0;
|
||||
int omapi_port;
|
||||
|
||||
#if defined (TRACING)
|
||||
trace_type_t *trace_srandom;
|
||||
#endif
|
||||
|
||||
static isc_result_t verify_addr (omapi_object_t *l, omapi_addr_t *addr) {
|
||||
return ISC_R_SUCCESS;
|
||||
@@ -197,18 +202,16 @@ int main (argc, argv, envp)
|
||||
omapi_object_t *listener;
|
||||
unsigned seed;
|
||||
struct interface_info *ip;
|
||||
struct data_string db;
|
||||
struct option_cache *oc;
|
||||
struct option_state *options = (struct option_state *)0;
|
||||
struct parse *parse;
|
||||
int lose;
|
||||
int omapi_port;
|
||||
omapi_object_t *auth;
|
||||
struct tsig_key *key;
|
||||
omapi_typed_data_t *td;
|
||||
int no_dhcpd_conf = 0;
|
||||
int no_dhcpd_db = 0;
|
||||
int no_dhcpd_pid = 0;
|
||||
char *traceinfile = (char *)0;
|
||||
char *traceoutfile = (char *)0;
|
||||
|
||||
/* Set up the client classification system. */
|
||||
classification_setup ();
|
||||
@@ -294,6 +297,18 @@ int main (argc, argv, envp)
|
||||
} else if (!strcmp (argv [i], "-q")) {
|
||||
quiet = 1;
|
||||
quiet_interface_discovery = 1;
|
||||
} else if (!strcmp (argv [i], "--version")) {
|
||||
log_info ("isc-dhcpd-%s", DHCP_VERSION);
|
||||
exit (0);
|
||||
} else if (!strcmp (argv [i], "-tf")) {
|
||||
if (++i == argc)
|
||||
usage ();
|
||||
traceoutfile = argv [i];
|
||||
} else if (!strcmp (argv [i], "-play")) {
|
||||
if (++i == argc)
|
||||
usage ();
|
||||
traceinfile = argv [i];
|
||||
trace_replay_init ();
|
||||
} else if (argv [i][0] == '-') {
|
||||
usage ();
|
||||
} else {
|
||||
@@ -335,17 +350,34 @@ int main (argc, argv, envp)
|
||||
log_perror = 0;
|
||||
}
|
||||
|
||||
#if defined (TRACING)
|
||||
trace_init (set_time, MDL);
|
||||
if (traceoutfile)
|
||||
trace_begin (traceoutfile, MDL);
|
||||
interface_trace_setup ();
|
||||
parse_trace_setup ();
|
||||
trace_srandom = trace_type_register ("random-seed", (void *)0,
|
||||
trace_seed_input,
|
||||
trace_seed_stop, MDL);
|
||||
#endif
|
||||
|
||||
/* Default to the DHCP/BOOTP port. */
|
||||
if (!local_port)
|
||||
{
|
||||
ent = getservbyname ("dhcp", "udp");
|
||||
if (!ent)
|
||||
local_port = htons (67);
|
||||
else
|
||||
local_port = ent -> s_port;
|
||||
if ((s = getenv ("DHCPD_PORT"))) {
|
||||
local_port = htons (atoi (s));
|
||||
log_debug ("binding to environment-specified port %d",
|
||||
ntohs (local_port));
|
||||
} else {
|
||||
ent = getservbyname ("dhcp", "udp");
|
||||
if (!ent)
|
||||
local_port = htons (67);
|
||||
else
|
||||
local_port = ent -> s_port;
|
||||
#ifndef __CYGWIN32__ /* XXX */
|
||||
endservent ();
|
||||
endservent ();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
remote_port = htons (ntohs (local_port) + 1);
|
||||
@@ -380,6 +412,10 @@ int main (argc, argv, envp)
|
||||
log_fatal ("Can't allocate root group!");
|
||||
root_group -> authoritative = 0;
|
||||
|
||||
/* Set up various hooks. */
|
||||
dhcp_interface_setup_hook = dhcpd_interface_setup_hook;
|
||||
bootp_packet_handler = do_packet;
|
||||
|
||||
#if defined (NSUPDATE)
|
||||
/* Set up the standard name service updater routine. */
|
||||
parse = (struct parse *)0;
|
||||
@@ -398,6 +434,22 @@ int main (argc, argv, envp)
|
||||
end_parse (&parse);
|
||||
#endif
|
||||
|
||||
/* Initialize icmp support... */
|
||||
icmp_startup (1, lease_pinged);
|
||||
|
||||
#if defined (TRACING)
|
||||
if (traceinfile) {
|
||||
if (!no_dhcpd_db) {
|
||||
log_error ("%s", "");
|
||||
log_error ("** You must specify a lease file with -lf.");
|
||||
log_error (" Dhcpd will not overwrite your default");
|
||||
log_fatal (" lease file when playing back a trace. **");
|
||||
}
|
||||
trace_file_replay (traceinfile);
|
||||
exit (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Read the dhcpd.conf file... */
|
||||
if (readconf () != ISC_R_SUCCESS)
|
||||
log_fatal ("Configuration file errors encountered -- exiting");
|
||||
@@ -406,6 +458,148 @@ int main (argc, argv, envp)
|
||||
if (cftest && !lftest)
|
||||
exit(0);
|
||||
|
||||
postconf_initialization (quiet);
|
||||
|
||||
group_write_hook = group_writer;
|
||||
|
||||
/* Start up the database... */
|
||||
db_startup (lftest);
|
||||
|
||||
if (lftest)
|
||||
exit (0);
|
||||
|
||||
/* Discover all the network interfaces and initialize them. */
|
||||
discover_interfaces (DISCOVER_SERVER);
|
||||
|
||||
/* Make up a seed for the random number generator from current
|
||||
time plus the sum of the last four bytes of each
|
||||
interface's hardware address interpreted as an integer.
|
||||
Not much entropy, but we're booting, so we're not likely to
|
||||
find anything better. */
|
||||
seed = 0;
|
||||
for (ip = interfaces; ip; ip = ip -> next) {
|
||||
int junk;
|
||||
memcpy (&junk,
|
||||
&ip -> hw_address.hbuf [ip -> hw_address.hlen -
|
||||
sizeof seed], sizeof seed);
|
||||
seed += junk;
|
||||
}
|
||||
srandom (seed + cur_time);
|
||||
#if defined (TRACING)
|
||||
trace_seed_stash (trace_srandom, seed + cur_time);
|
||||
#endif
|
||||
|
||||
/* Start up a listener for the object management API protocol. */
|
||||
if (omapi_port != -1) {
|
||||
listener = (omapi_object_t *)0;
|
||||
result = omapi_generic_new (&listener, MDL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
log_fatal ("Can't allocate new generic object: %s",
|
||||
isc_result_totext (result));
|
||||
result = omapi_protocol_listen (listener,
|
||||
(unsigned)omapi_port, 1);
|
||||
if (result == ISC_R_SUCCESS && omapi_key)
|
||||
result = omapi_protocol_configure_security
|
||||
(listener, verify_addr, verify_auth);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
log_fatal ("Can't start OMAPI protocol: %s",
|
||||
isc_result_totext (result));
|
||||
}
|
||||
|
||||
#if defined (FAILOVER_PROTOCOL)
|
||||
/* Start the failover protocol. */
|
||||
dhcp_failover_startup ();
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG
|
||||
if (daemon) {
|
||||
/* First part of becoming a daemon... */
|
||||
if ((pid = fork ()) < 0)
|
||||
log_fatal ("Can't fork daemon: %m");
|
||||
else if (pid)
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/* Read previous pid file. */
|
||||
if ((i = open (path_dhcpd_pid, O_RDONLY)) >= 0) {
|
||||
status = read (i, pbuf, (sizeof pbuf) - 1);
|
||||
close (i);
|
||||
pbuf [status] = 0;
|
||||
pid = atoi (pbuf);
|
||||
|
||||
/* If the previous server process is not still running,
|
||||
write a new pid file immediately. */
|
||||
if (pid && (pid == getpid() || kill (pid, 0) < 0)) {
|
||||
unlink (path_dhcpd_pid);
|
||||
if ((i = open (path_dhcpd_pid,
|
||||
O_WRONLY | O_CREAT, 0640)) >= 0) {
|
||||
sprintf (pbuf, "%d\n", (int)getpid ());
|
||||
write (i, pbuf, strlen (pbuf));
|
||||
close (i);
|
||||
pidfilewritten = 1;
|
||||
}
|
||||
} else
|
||||
log_fatal ("There's already a DHCP server running.");
|
||||
}
|
||||
|
||||
/* If we were requested to log to stdout on the command line,
|
||||
keep doing so; otherwise, stop. */
|
||||
if (log_perror == -1)
|
||||
log_perror = 1;
|
||||
else
|
||||
log_perror = 0;
|
||||
|
||||
if (daemon) {
|
||||
/* Become session leader and get pid... */
|
||||
close (0);
|
||||
close (1);
|
||||
close (2);
|
||||
pid = setsid ();
|
||||
}
|
||||
|
||||
/* If we didn't write the pid file earlier because we found a
|
||||
process running the logged pid, but we made it to here,
|
||||
meaning nothing is listening on the bootp port, then write
|
||||
the pid file out - what's in it now is bogus anyway. */
|
||||
if (!pidfilewritten) {
|
||||
unlink (path_dhcpd_pid);
|
||||
if ((i = open (path_dhcpd_pid,
|
||||
O_WRONLY | O_CREAT, 0640)) >= 0) {
|
||||
sprintf (pbuf, "%d\n", (int)getpid ());
|
||||
write (i, pbuf, strlen (pbuf));
|
||||
close (i);
|
||||
pidfilewritten = 1;
|
||||
}
|
||||
}
|
||||
#endif /* !DEBUG */
|
||||
|
||||
#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
|
||||
dmalloc_cutoff_generation = dmalloc_generation;
|
||||
dmalloc_longterm = dmalloc_outstanding;
|
||||
dmalloc_outstanding = 0;
|
||||
#endif
|
||||
|
||||
#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
|
||||
dump_rc_history ();
|
||||
#endif
|
||||
|
||||
/* Receive packets and dispatch them... */
|
||||
dispatch ();
|
||||
|
||||
/* Not reached */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void postconf_initialization (int quiet)
|
||||
{
|
||||
struct option_state *options = (struct option_state *)0;
|
||||
struct data_string db;
|
||||
struct option_cache *oc;
|
||||
char *s;
|
||||
isc_result_t result;
|
||||
struct parse *parse;
|
||||
int tmp;
|
||||
|
||||
/* Now try to get the lease file name. */
|
||||
option_state_allocate (&options, MDL);
|
||||
|
||||
@@ -552,13 +746,14 @@ int main (argc, argv, envp)
|
||||
}
|
||||
} else {
|
||||
log_info ("%s", "");
|
||||
log_error ("** You must set ddns-update-style before %s",
|
||||
"dhcpd will run. **");
|
||||
log_error ("** To get the same behaviour as in 3.0b2pl11 %s",
|
||||
log_error ("** You must add a ddns-update-style %s%s.",
|
||||
"statement to ", path_dhcpd_conf);
|
||||
log_error (" To get the same behaviour as in 3.0b2pl11 %s",
|
||||
"and previous");
|
||||
log_error (" versions, use \"ddns-update-style ad-hoc;\" **");
|
||||
log_fatal ("ddns-update-style is documented in the %s",
|
||||
"dhcpd.conf manual page.");
|
||||
log_error (" versions, add a line that says \"%s\"",
|
||||
"ddns-update-style ad-hoc;");
|
||||
log_fatal (" Please read the dhcpd.conf manual page %s",
|
||||
"for more information. **");
|
||||
}
|
||||
|
||||
oc = lookup_option (&server_universe, options, SV_LOG_FACILITY);
|
||||
@@ -578,12 +773,18 @@ int main (argc, argv, envp)
|
||||
openlog ("dhcpd",
|
||||
LOG_NDELAY, db.data [0]);
|
||||
#endif
|
||||
/* Log the startup banner into the new
|
||||
log file. */
|
||||
if (!quiet) {
|
||||
/* Don't log to stderr twice. */
|
||||
tmp = log_perror;
|
||||
log_perror = 0;
|
||||
log_info ("%s %s",
|
||||
message, DHCP_VERSION);
|
||||
log_info (copyright);
|
||||
log_info (arr);
|
||||
log_info (url);
|
||||
log_perror = tmp;
|
||||
}
|
||||
} else
|
||||
log_fatal ("invalid log facility");
|
||||
@@ -619,167 +820,35 @@ int main (argc, argv, envp)
|
||||
|
||||
/* Set up the standard name service updater routine. */
|
||||
parse = (struct parse *)0;
|
||||
status = new_parse (&parse, -1,
|
||||
old_nsupdate, (sizeof old_nsupdate) - 1,
|
||||
"old name service update routine");
|
||||
if (status != ISC_R_SUCCESS)
|
||||
result = new_parse (&parse, -1,
|
||||
old_nsupdate, (sizeof old_nsupdate) - 1,
|
||||
"old name service update routine");
|
||||
if (result != ISC_R_SUCCESS)
|
||||
log_fatal ("can't begin parsing old ddns updater!");
|
||||
|
||||
lose = 0;
|
||||
tmp = 0;
|
||||
if (!(parse_executable_statements (e, parse,
|
||||
&lose, context_any))) {
|
||||
&tmp, context_any))) {
|
||||
end_parse (&parse);
|
||||
log_fatal ("can't parse standard ddns updater!");
|
||||
}
|
||||
end_parse (&parse);
|
||||
}
|
||||
#endif
|
||||
|
||||
group_write_hook = group_writer;
|
||||
|
||||
/* Start up the database... */
|
||||
db_startup (lftest);
|
||||
|
||||
if (lftest)
|
||||
exit (0);
|
||||
|
||||
dhcp_interface_setup_hook = dhcpd_interface_setup_hook;
|
||||
|
||||
/* Discover all the network interfaces and initialize them. */
|
||||
discover_interfaces (DISCOVER_SERVER);
|
||||
|
||||
/* Make up a seed for the random number generator from current
|
||||
time plus the sum of the last four bytes of each
|
||||
interface's hardware address interpreted as an integer.
|
||||
Not much entropy, but we're booting, so we're not likely to
|
||||
find anything better. */
|
||||
seed = 0;
|
||||
for (ip = interfaces; ip; ip = ip -> next) {
|
||||
int junk;
|
||||
memcpy (&junk,
|
||||
&ip -> hw_address.hbuf [ip -> hw_address.hlen -
|
||||
sizeof seed], sizeof seed);
|
||||
seed += junk;
|
||||
}
|
||||
srandom (seed + cur_time);
|
||||
|
||||
/* Initialize icmp support... */
|
||||
icmp_startup (1, lease_pinged);
|
||||
|
||||
/* Start up a listener for the object management API protocol. */
|
||||
if (omapi_port != -1) {
|
||||
listener = (omapi_object_t *)0;
|
||||
result = omapi_generic_new (&listener, MDL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
log_fatal ("Can't allocate new generic object: %s",
|
||||
isc_result_totext (result));
|
||||
result = omapi_protocol_listen (listener,
|
||||
(unsigned)omapi_port, 1);
|
||||
if (result == ISC_R_SUCCESS && omapi_key)
|
||||
result = omapi_protocol_configure_security
|
||||
(listener, verify_addr, verify_auth);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
log_fatal ("Can't start OMAPI protocol: %s",
|
||||
isc_result_totext (result));
|
||||
}
|
||||
|
||||
#if defined (FAILOVER_PROTOCOL)
|
||||
/* Start the failover protocol. */
|
||||
dhcp_failover_startup ();
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG
|
||||
if (daemon) {
|
||||
/* First part of becoming a daemon... */
|
||||
if ((pid = fork ()) < 0)
|
||||
log_fatal ("Can't fork daemon: %m");
|
||||
else if (pid)
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/* Read previous pid file. */
|
||||
if ((i = open (path_dhcpd_pid, O_RDONLY)) >= 0) {
|
||||
status = read (i, pbuf, (sizeof pbuf) - 1);
|
||||
close (i);
|
||||
pbuf [status] = 0;
|
||||
pid = atoi (pbuf);
|
||||
|
||||
/* If the previous server process is not still running,
|
||||
write a new pid file immediately. */
|
||||
if (pid && (pid == getpid() || kill (pid, 0) < 0)) {
|
||||
unlink (path_dhcpd_pid);
|
||||
if ((i = open (path_dhcpd_pid,
|
||||
O_WRONLY | O_CREAT, 0640)) >= 0) {
|
||||
sprintf (pbuf, "%d\n", (int)getpid ());
|
||||
write (i, pbuf, strlen (pbuf));
|
||||
close (i);
|
||||
pidfilewritten = 1;
|
||||
}
|
||||
} else
|
||||
log_fatal ("There's already a DHCP server running.");
|
||||
}
|
||||
|
||||
/* If we were requested to log to stdout on the command line,
|
||||
keep doing so; otherwise, stop. */
|
||||
if (log_perror == -1)
|
||||
log_perror = 1;
|
||||
else
|
||||
log_perror = 0;
|
||||
|
||||
if (daemon) {
|
||||
/* Become session leader and get pid... */
|
||||
close (0);
|
||||
close (1);
|
||||
close (2);
|
||||
pid = setsid ();
|
||||
}
|
||||
|
||||
/* If we didn't write the pid file earlier because we found a
|
||||
process running the logged pid, but we made it to here,
|
||||
meaning nothing is listening on the bootp port, then write
|
||||
the pid file out - what's in it now is bogus anyway. */
|
||||
if (!pidfilewritten) {
|
||||
unlink (path_dhcpd_pid);
|
||||
if ((i = open (path_dhcpd_pid,
|
||||
O_WRONLY | O_CREAT, 0640)) >= 0) {
|
||||
sprintf (pbuf, "%d\n", (int)getpid ());
|
||||
write (i, pbuf, strlen (pbuf));
|
||||
close (i);
|
||||
pidfilewritten = 1;
|
||||
}
|
||||
}
|
||||
#endif /* !DEBUG */
|
||||
|
||||
/* Set up the bootp packet handler... */
|
||||
bootp_packet_handler = do_packet;
|
||||
|
||||
#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
|
||||
dmalloc_cutoff_generation = dmalloc_generation;
|
||||
dmalloc_longterm = dmalloc_outstanding;
|
||||
dmalloc_outstanding = 0;
|
||||
#endif
|
||||
|
||||
#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
|
||||
dump_rc_history ();
|
||||
#endif
|
||||
|
||||
/* Receive packets and dispatch them... */
|
||||
dispatch ();
|
||||
|
||||
/* Not reached */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Print usage message. */
|
||||
|
||||
static void usage ()
|
||||
{
|
||||
log_info (message);
|
||||
log_info ("%s %s", message, DHCP_VERSION);
|
||||
log_info (copyright);
|
||||
log_info (arr);
|
||||
|
||||
log_fatal ("Usage: dhcpd [-p <UDP port #>] [-d] [-f]%s%s",
|
||||
log_fatal ("Usage: dhcpd [-p <UDP port #>] [-d] [-f]%s%s%s%s",
|
||||
"\n [-cf config-file] [-lf lease-file]",
|
||||
"\n [-tf trace-output-file]",
|
||||
"\n [-play trace-input-file]",
|
||||
"\n [-t] [-T] [-s server] [if0 [...ifN]]");
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user