summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RELNOTES5
-rw-r--r--client/dhclient.c109
-rw-r--r--includes/site.h7
-rw-r--r--relay/dhcrelay.c81
-rw-r--r--server/dhcpd.c104
5 files changed, 192 insertions, 114 deletions
diff --git a/RELNOTES b/RELNOTES
index 0bb6db6b..958d5347 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -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;