]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
- Cut some things out into subroutines to support tracing.
authorTed Lemon <source@isc.org>
Mon, 12 Feb 2001 21:04:06 +0000 (21:04 +0000)
committerTed Lemon <source@isc.org>
Mon, 12 Feb 2001 21:04:06 +0000 (21:04 +0000)
- Do all the relevant tracing setup.
- Clarify ddns-update-style startup error message.
- Print version information and exit if --version is given.

server/dhcpd.c

index b83b38068ed6828afbac48c29dd952f56258ef1a..f671c06bbd655900974ca386dd03013c4710e8a1 100644 (file)
@@ -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]]");
 }