diff options
-rw-r--r-- | RELNOTES | 5 | ||||
-rw-r--r-- | client/dhclient.c | 109 | ||||
-rw-r--r-- | includes/site.h | 7 | ||||
-rw-r--r-- | relay/dhcrelay.c | 81 | ||||
-rw-r--r-- | server/dhcpd.c | 104 |
5 files changed, 192 insertions, 114 deletions
@@ -120,6 +120,11 @@ by Eric Young (eay@cryptsoft.com). patch. [ISC-Bugs #41267] +- When handling an incorrect command line for dhcpd, dhclient or dhcrelay + print out a specific error message about the first error in addition + to the usage string. This may be disabled by editing includes/site.h. + [ISC-Bugs #40321] + Changes since 4.1-ESV-R12b1 - None diff --git a/client/dhclient.c b/client/dhclient.c index 1912e2d9..75fd94d5 100644 --- a/client/dhclient.c +++ b/client/dhclient.c @@ -3,7 +3,7 @@ DHCP Client. */ /* - * Copyright (c) 2004-2015 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2016 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -93,8 +93,6 @@ char *progname = NULL; void run_stateless(int exit_mode); -static void usage(void); - static isc_result_t write_duid(struct data_string *duid); static void add_reject(struct packet *packet); @@ -103,6 +101,52 @@ static int check_domain_name_list(const char *ptr, size_t len, int dots); static int check_option_values(struct universe *universe, unsigned int opt, const char *ptr, size_t len); +/*! + * + * \brief Print the generic usage message + * + * If the user has provided an incorrect command line print out + * the description of the command line. The arguments provide + * a way for the caller to request more specific information about + * the error be printed as well. Mostly this will be that some + * comamnd doesn't include its argument. + * + * \param sfmt - The basic string and format for the specific error + * \param sarg - Generally the offending argument from the comamnd line. + * + * \return Nothing + */ + +static const char use_noarg[] = "No argument for command: %s"; +static const char use_v6command[] = "Command not used for DHCPv4: %s"; + +static void +usage(const char *sfmt, const char *sarg) +{ + log_info("%s %s", message, PACKAGE_VERSION); + log_info(copyright); + log_info(arr); + log_info(url); + + /* If desired print out the specific error message */ +#ifdef PRINT_SPECIFIC_CL_ERRORS + if (sfmt != NULL) + log_error(sfmt, sarg); +#endif + + log_fatal("Usage: %s " +#ifdef DHCPv6 + "[-4|-6] [-SNTPR1dvrx] [-nw] [-p <port>]\n" +#else /* DHCPv6 */ + "[-1dvrx] [-nw] [-p <port>]\n" +#endif /* DHCPv6 */ + " [-s server-addr] [-cf config-file] " + "[-lf lease-file]\n" + " [-pf pid-file] [--no-pid] [-e VAR=val]\n" + " [-sf script-file] [interface]", + isc_file_basename(progname)); +} + int main(int argc, char **argv) { int fd; @@ -201,7 +245,7 @@ main(int argc, char **argv) { exit_mode = 1; } else if (!strcmp(argv[i], "-p")) { if (++i == argc) - usage(); + usage(use_noarg, argv[i-1]); local_port = validate_port(argv[i]); log_debug("binding to user-specified port %d", ntohs(local_port)); @@ -210,24 +254,24 @@ main(int argc, char **argv) { quiet = 0; } else if (!strcmp(argv[i], "-pf")) { if (++i == argc) - usage(); + usage(use_noarg, argv[i-1]); path_dhclient_pid = argv[i]; no_dhclient_pid = 1; } else if (!strcmp(argv[i], "--no-pid")) { no_pid_file = ISC_TRUE; } else if (!strcmp(argv[i], "-cf")) { if (++i == argc) - usage(); + usage(use_noarg, argv[i-1]); path_dhclient_conf = argv[i]; no_dhclient_conf = 1; } else if (!strcmp(argv[i], "-lf")) { if (++i == argc) - usage(); + usage(use_noarg, argv[i-1]); path_dhclient_db = argv[i]; no_dhclient_db = 1; } else if (!strcmp(argv[i], "-sf")) { if (++i == argc) - usage(); + usage(use_noarg, argv[i-1]); path_dhclient_script = argv[i]; no_dhclient_script = 1; } else if (!strcmp(argv[i], "-1")) { @@ -236,11 +280,11 @@ main(int argc, char **argv) { quiet = 1; } else if (!strcmp(argv[i], "-s")) { if (++i == argc) - usage(); + usage(use_noarg, argv[i-1]); server = argv[i]; } else if (!strcmp(argv[i], "-g")) { if (++i == argc) - usage(); + usage(use_noarg, argv[i-1]); mockup_relay = argv[i]; } else if (!strcmp(argv[i], "-nw")) { nowait = 1; @@ -253,7 +297,7 @@ main(int argc, char **argv) { } else if (!strcmp(argv[i], "-e")) { struct string_list *tmp; if (++i == argc) - usage(); + usage(use_noarg, argv[i-1]); tmp = dmalloc(strlen(argv[i]) + sizeof *tmp, MDL); if (!tmp) log_fatal("No memory for %s", argv[i]); @@ -264,7 +308,7 @@ main(int argc, char **argv) { #ifdef DHCPv6 } else if (!strcmp(argv[i], "-S")) { if (local_family_set && (local_family == AF_INET)) { - usage(); + usage(use_v6command, argv[i]); } local_family_set = 1; local_family = AF_INET6; @@ -272,7 +316,7 @@ main(int argc, char **argv) { stateless = 1; } else if (!strcmp(argv[i], "-N")) { if (local_family_set && (local_family == AF_INET)) { - usage(); + usage(use_v6command, argv[i]); } local_family_set = 1; local_family = AF_INET6; @@ -282,7 +326,7 @@ main(int argc, char **argv) { wanted_ia_na++; } else if (!strcmp(argv[i], "-T")) { if (local_family_set && (local_family == AF_INET)) { - usage(); + usage(use_v6command, argv[i]); } local_family_set = 1; local_family = AF_INET6; @@ -292,7 +336,7 @@ main(int argc, char **argv) { wanted_ia_ta++; } else if (!strcmp(argv[i], "-P")) { if (local_family_set && (local_family == AF_INET)) { - usage(); + usage(use_v6command, argv[i]); } local_family_set = 1; local_family = AF_INET6; @@ -302,7 +346,7 @@ main(int argc, char **argv) { wanted_ia_pd++; } else if (!strcmp(argv[i], "-R")) { if (local_family_set && (local_family == AF_INET)) { - usage(); + usage(use_v6command, argv[i]); } local_family_set = 1; local_family = AF_INET6; @@ -320,9 +364,10 @@ main(int argc, char **argv) { IGNORE_RET(write(STDERR_FILENO, "\n", 1)); exit(0); } else if (argv[i][0] == '-') { - usage(); + usage("Unknown command: %s", argv[i]); } else if (interfaces_requested < 0) { - usage(); + usage("No interfaces comamnd -n and " + " requested interface %s", argv[i]); } else { struct interface_info *tmp = NULL; @@ -351,7 +396,7 @@ main(int argc, char **argv) { /* Support only one (requested) interface for Prefix Delegation. */ if (wanted_ia_pd && (interfaces_requested != 1)) { - usage(); + usage("PD %s only supports one requested interface", "-P"); } if (!no_dhclient_conf && (s = getenv("PATH_DHCLIENT_CONF"))) { @@ -488,7 +533,8 @@ main(int argc, char **argv) { if (release_mode || (wanted_ia_na > 0) || wanted_ia_ta || wanted_ia_pd || (interfaces_requested != 1)) { - usage(); + usage("Stateless commnad: %s incompatibile with " + "other commands", "-S"); } run_stateless(exit_mode); return 0; @@ -714,27 +760,6 @@ main(int argc, char **argv) { return 0; } -static void usage() -{ - log_info("%s %s", message, PACKAGE_VERSION); - log_info(copyright); - log_info(arr); - log_info(url); - - - log_fatal("Usage: %s " -#ifdef DHCPv6 - "[-4|-6] [-SNTPR1dvrx] [-nw] [-p <port>]\n" -#else /* DHCPv6 */ - "[-1dvrx] [-nw] [-p <port>]\n" -#endif /* DHCPv6 */ - " [-s server-addr] [-cf config-file] " - "[-lf lease-file]\n" - " [-pf pid-file] [--no-pid] [-e VAR=val]\n" - " [-sf script-file] [interface]", - isc_file_basename(progname)); -} - void run_stateless(int exit_mode) { #ifdef DHCPv6 @@ -746,7 +771,7 @@ void run_stateless(int exit_mode) discover_interfaces(DISCOVER_REQUESTED); if (!interfaces) - usage(); + usage("No interfaces available for stateless command: %s", "-S"); /* Parse the dhclient.conf file. */ read_client_conf(); diff --git a/includes/site.h b/includes/site.h index 829657c9..009c7bad 100644 --- a/includes/site.h +++ b/includes/site.h @@ -294,4 +294,9 @@ from a single server and there won't be a difference. */ /* #define USE_ORIGINAL_CLIENT_LEASE_WEIGHTS */ - +/* Print out specific error messages for dhclient, dhcpd + or dhcrelay when processing an incorrect command line. This + is included for those that might require the exact error + messages, as we don't expect that is necessary it is on by + default. */ +#define PRINT_SPECIFIC_CL_ERRORS diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c index 8ab1d087..d894045f 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -3,7 +3,7 @@ DHCP/BOOTP Relay Agent. */ /* - * Copyright(c) 2004-2015 by Internet Systems Consortium, Inc.("ISC") + * Copyright(c) 2004-2016 by Internet Systems Consortium, Inc.("ISC") * Copyright(c) 1997-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -157,7 +157,35 @@ char *progname; " server0 [ ... serverN]\n\n" #endif -static void usage() { +/*! + * + * \brief Print the generic usage message + * + * If the user has provided an incorrect command line print out + * the description of the command line. The arguments provide + * a way for the caller to request more specific information about + * the error be printed as well. Mostly this will be that some + * comamnd doesn't include its argument. + * + * \param sfmt - The basic string and format for the specific error + * \param sarg - Generally the offending argument from the comamnd line. + * + * \return Nothing + */ +static const char use_noarg[] = "No argument for command: %s"; +static const char use_badproto[] = "Protocol already set, %s inappropriate"; +static const char use_v4command[] = "Command not used for DHCPv6: %s"; +static const char use_v6command[] = "Command not used for DHCPv4: %s"; + +static void +usage(const char *sfmt, const char *sarg) { + + /* If desired print out the specific error message */ +#ifdef PRINT_SPECIFIC_CL_ERRORS + if (sfmt != NULL) + log_error(sfmt, sarg); +#endif + log_fatal(DHCRELAY_USAGE, #ifdef DHCPv6 isc_file_basename(progname), @@ -227,13 +255,13 @@ main(int argc, char **argv) { if (!strcmp(argv[i], "-4")) { #ifdef DHCPv6 if (local_family_set && (local_family == AF_INET6)) { - usage(); + usage(use_badproto, "-4"); } local_family_set = 1; local_family = AF_INET; } else if (!strcmp(argv[i], "-6")) { if (local_family_set && (local_family == AF_INET)) { - usage(); + usage(use_badproto, "-6"); } local_family_set = 1; local_family = AF_INET6; @@ -245,29 +273,29 @@ main(int argc, char **argv) { quiet_interface_discovery = 1; } else if (!strcmp(argv[i], "-p")) { if (++i == argc) - usage(); + usage(use_noarg, argv[i-1]); local_port = validate_port(argv[i]); log_debug("binding to user-specified port %d", ntohs(local_port)); } else if (!strcmp(argv[i], "-c")) { int hcount; if (++i == argc) - usage(); + usage(use_noarg, argv[i-1]); hcount = atoi(argv[i]); if (hcount <= 255) max_hop_count= hcount; else - usage(); + usage("Bad hop count to -c: %s", argv[i]); } else if (!strcmp(argv[i], "-i")) { #ifdef DHCPv6 if (local_family_set && (local_family == AF_INET6)) { - usage(); + usage(use_v4command, argv[i]); } local_family_set = 1; local_family = AF_INET; #endif if (++i == argc) { - usage(); + usage(use_noarg, argv[i-1]); } if (strlen(argv[i]) >= sizeof(tmp->name)) { log_fatal("%s: interface name too long " @@ -286,7 +314,7 @@ main(int argc, char **argv) { } else if (!strcmp(argv[i], "-a")) { #ifdef DHCPv6 if (local_family_set && (local_family == AF_INET6)) { - usage(); + usage(use_v4command, argv[i]); } local_family_set = 1; local_family = AF_INET; @@ -295,13 +323,13 @@ main(int argc, char **argv) { } else if (!strcmp(argv[i], "-A")) { #ifdef DHCPv6 if (local_family_set && (local_family == AF_INET6)) { - usage(); + usage(use_v4command, argv[i]); } local_family_set = 1; local_family = AF_INET; #endif if (++i == argc) - usage(); + usage(use_noarg, argv[i-1]); dhcp_max_agent_option_packet_length = atoi(argv[i]); @@ -312,13 +340,13 @@ main(int argc, char **argv) { } else if (!strcmp(argv[i], "-m")) { #ifdef DHCPv6 if (local_family_set && (local_family == AF_INET6)) { - usage(); + usage(use_v4command, argv[i]); } local_family_set = 1; local_family = AF_INET; #endif if (++i == argc) - usage(); + usage(use_noarg, argv[i-1]); if (!strcasecmp(argv[i], "append")) { agent_relay_mode = forward_and_append; } else if (!strcasecmp(argv[i], "replace")) { @@ -328,11 +356,11 @@ main(int argc, char **argv) { } else if (!strcasecmp(argv[i], "discard")) { agent_relay_mode = discard; } else - usage(); + usage("Unknown argument to -m: %s", argv[i]); } else if (!strcmp(argv[i], "-D")) { #ifdef DHCPv6 if (local_family_set && (local_family == AF_INET6)) { - usage(); + usage(use_v4command, argv[i]); } local_family_set = 1; local_family = AF_INET; @@ -341,39 +369,39 @@ main(int argc, char **argv) { #ifdef DHCPv6 } else if (!strcmp(argv[i], "-I")) { if (local_family_set && (local_family == AF_INET)) { - usage(); + usage(use_v6command, argv[i]); } local_family_set = 1; local_family = AF_INET6; use_if_id = ISC_TRUE; } else if (!strcmp(argv[i], "-l")) { if (local_family_set && (local_family == AF_INET)) { - usage(); + usage(use_v6command, argv[i]); } local_family_set = 1; local_family = AF_INET6; if (downstreams != NULL) use_if_id = ISC_TRUE; if (++i == argc) - usage(); + usage(use_noarg, argv[i-1]); sl = parse_downstream(argv[i]); sl->next = downstreams; downstreams = sl; } else if (!strcmp(argv[i], "-u")) { if (local_family_set && (local_family == AF_INET)) { - usage(); + usage(use_v6command, argv[i]); } local_family_set = 1; local_family = AF_INET6; if (++i == argc) - usage(); + usage(use_noarg, argv[i-1]); sl = parse_upstream(argv[i]); sl->next = upstreams; upstreams = sl; #endif } else if (!strcmp(argv[i], "-pf")) { if (++i == argc) - usage(); + usage(use_noarg, argv[i-1]); path_dhcrelay_pid = argv[i]; no_dhcrelay_pid = ISC_TRUE; } else if (!strcmp(argv[i], "--no-pid")) { @@ -390,14 +418,14 @@ main(int argc, char **argv) { isc_file_basename(progname)); exit(0); } else if (argv[i][0] == '-') { - usage(); + usage("Unknown command: %s", argv[i]); } else { struct hostent *he; struct in_addr ia, *iap = NULL; #ifdef DHCPv6 if (local_family_set && (local_family == AF_INET6)) { - usage(); + usage(use_v4command, argv[i]); } local_family_set = 1; local_family = AF_INET; @@ -509,7 +537,7 @@ main(int argc, char **argv) { if (upstreams == NULL || downstreams == NULL) { log_info("Must specify at least one lower " "and one upper interface.\n"); - usage(); + usage(NULL, NULL); } /* Set up the initial dhcp option universe. */ @@ -1170,8 +1198,7 @@ parse_downstream(char *arg) { *iid++ = '\0'; } if (strlen(ifname) >= sizeof(ifp->name)) { - log_error("Interface name '%s' too long", ifname); - usage(); + usage("Interface name '%s' too long", ifname); } /* Don't declare twice. */ diff --git a/server/dhcpd.c b/server/dhcpd.c index 51f4ae52..934057cf 100644 --- a/server/dhcpd.c +++ b/server/dhcpd.c @@ -3,7 +3,7 @@ DHCP Server Daemon. */ /* - * Copyright (c) 2004-2015 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2016 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -56,10 +56,6 @@ uid_t set_uid = 0; gid_t set_gid = 0; #endif /* PARANOIA */ -#ifndef UNIT_TEST -static void usage(void); -#endif - struct iaddr server_identifier; int server_identifier_matched; @@ -214,6 +210,54 @@ static void omapi_listener_start (void *foo) #ifndef UNIT_TEST +/*! + * + * \brief Print the generic usage message + * + * If the user has provided an incorrect command line print out + * the description of the command line. The arguments provide + * a way for the caller to request more specific information about + * the error be printed as well. Mostly this will be that some + * comamnd doesn't include its argument. + * + * \param sfmt - The basic string and format for the specific error + * \param sarg - Generally the offending argument from the comamnd line. + * + * \return Nothing + */ +static char use_noarg[] = "No argument for command: %s "; + +static void +usage(const char *sfmt, const char *sarg) { + log_info("%s %s", message, PACKAGE_VERSION); + log_info(copyright); + log_info(arr); + + /* If desired print out the specific error message */ +#ifdef PRINT_SPECIFIC_CL_ERRORS + if (sfmt != NULL) + log_error(sfmt, sarg); +#endif + + log_fatal("Usage: %s [-p <UDP port #>] [-f] [-d] [-q] [-t|-T]\n" +#ifdef DHCPv6 + " [-4|-6] [-cf config-file] [-lf lease-file]\n" +#else /* !DHCPv6 */ + " [-cf config-file] [-lf lease-file]\n" +#endif /* DHCPv6 */ +#if defined (PARANOIA) + /* meld into the following string */ + " [-user user] [-group group] [-chroot dir]\n" +#endif /* PARANOIA */ +#if defined (TRACING) + " [-tf trace-output-file]\n" + " [-play trace-input-file]\n" +#endif /* TRACING */ + " [-pf pid-file] [--no-pid] [-s server]\n" + " [if0 [...ifN]]", + isc_file_basename(progname)); +} + /* Note: If we add unit tests to test setup_chroot it will * need to be moved to be outside the ifndef UNIT_TEST block. */ @@ -320,7 +364,7 @@ main(int argc, char **argv) { for (i = 1; i < argc; i++) { if (!strcmp (argv [i], "-p")) { if (++i == argc) - usage (); + usage(use_noarg, argv[i-1]); local_port = validate_port (argv [i]); log_debug ("binding to user-specified port %d", ntohs (local_port)); @@ -335,35 +379,35 @@ main(int argc, char **argv) { log_perror = -1; } else if (!strcmp (argv [i], "-s")) { if (++i == argc) - usage (); + usage(use_noarg, argv[i-1]); server = argv [i]; #if defined (PARANOIA) } else if (!strcmp (argv [i], "-user")) { if (++i == argc) - usage (); + usage(use_noarg, argv[i-1]); set_user = argv [i]; } else if (!strcmp (argv [i], "-group")) { if (++i == argc) - usage (); + usage(use_noarg, argv[i-1]); set_group = argv [i]; } else if (!strcmp (argv [i], "-chroot")) { if (++i == argc) - usage (); + usage(use_noarg, argv[i-1]); set_chroot = argv [i]; #endif /* PARANOIA */ } else if (!strcmp (argv [i], "-cf")) { if (++i == argc) - usage (); + usage(use_noarg, argv[i-1]); path_dhcpd_conf = argv [i]; no_dhcpd_conf = 1; } else if (!strcmp (argv [i], "-lf")) { if (++i == argc) - usage (); + usage(use_noarg, argv[i-1]); path_dhcpd_db = argv [i]; no_dhcpd_db = 1; } else if (!strcmp (argv [i], "-pf")) { if (++i == argc) - usage (); + usage(use_noarg, argv[i-1]); path_dhcpd_pid = argv [i]; no_dhcpd_pid = 1; } else if (!strcmp(argv[i], "--no-pid")) { @@ -408,16 +452,16 @@ main(int argc, char **argv) { #if defined (TRACING) } else if (!strcmp (argv [i], "-tf")) { if (++i == argc) - usage (); + usage(use_noarg, argv[i-1]); traceoutfile = argv [i]; } else if (!strcmp (argv [i], "-play")) { if (++i == argc) - usage (); + usage(use_noarg, argv[i-1]); traceinfile = argv [i]; trace_replay_init (); #endif /* TRACING */ } else if (argv [i][0] == '-') { - usage (); + usage("Unknown command %s", argv[i]); } else { struct interface_info *tmp = (struct interface_info *)0; @@ -1208,34 +1252,6 @@ void postdb_startup (void) schedule_all_ipv6_lease_timeouts(); } -/* Print usage message. */ -#ifndef UNIT_TEST -static void -usage(void) { - log_info("%s %s", message, PACKAGE_VERSION); - log_info(copyright); - log_info(arr); - - log_fatal("Usage: %s [-p <UDP port #>] [-f] [-d] [-q] [-t|-T]\n" -#ifdef DHCPv6 - " [-4|-6] [-cf config-file] [-lf lease-file]\n" -#else /* !DHCPv6 */ - " [-cf config-file] [-lf lease-file]\n" -#endif /* DHCPv6 */ -#if defined (PARANOIA) - /* meld into the following string */ - " [-user user] [-group group] [-chroot dir]\n" -#endif /* PARANOIA */ -#if defined (TRACING) - " [-tf trace-output-file]\n" - " [-play trace-input-file]\n" -#endif /* TRACING */ - " [-pf pid-file] [--no-pid] [-s server]\n" - " [if0 [...ifN]]", - isc_file_basename(progname)); -} -#endif - void lease_pinged (from, packet, length) struct iaddr from; u_int8_t *packet; |