diff options
author | Ted Lemon <source@isc.org> | 2001-02-12 21:04:06 +0000 |
---|---|---|
committer | Ted Lemon <source@isc.org> | 2001-02-12 21:04:06 +0000 |
commit | a920d3daf8e11a806f3c67c6b3661aa3e2ce88d4 (patch) | |
tree | 2c6fa4b9d81ee3d1417c28c9d974a389aeaa4aaa /server | |
parent | 0e74ff1fe82fb953e214f0f60dc0a01e914feaae (diff) | |
download | isc-dhcp-a920d3daf8e11a806f3c67c6b3661aa3e2ce88d4.tar.gz |
- 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.
Diffstat (limited to 'server')
-rw-r--r-- | server/dhcpd.c | 387 |
1 files changed, 228 insertions, 159 deletions
diff --git a/server/dhcpd.c b/server/dhcpd.c index b83b3806..f671c06b 100644 --- a/server/dhcpd.c +++ b/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]]"); } |