summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Habets <thomas@habets.se>2022-10-26 21:09:16 +0100
committerThomas Habets <thomas@habets.se>2022-10-26 21:09:16 +0100
commitc32c317f7ecfe5af5da64be4c8cac8d87db04654 (patch)
tree64b500e0c662492d7085f8a9f08066663db0afec
parentdaa6052f16336b55bfddda6b5f0a4f19da3b0477 (diff)
downloadarping-c32c317f7ecfe5af5da64be4c8cac8d87db04654.tar.gz
Parse -wW strictly as float
-rw-r--r--src/arping.c49
-rw-r--r--src/arping_test.c67
2 files changed, 113 insertions, 3 deletions
diff --git a/src/arping.c b/src/arping.c
index a2717cd..d09b9ec 100644
--- a/src/arping.c
+++ b/src/arping.c
@@ -238,6 +238,32 @@ int verbose = 0; /* Increase with -v */
/* Doesn't really need to be volatile, but doesn't hurt. */
static volatile sig_atomic_t time_to_die = 0;
+static float
+must_parse_float(const char* in, const char* what)
+{
+ if (!*in) {
+ fprintf(stderr, "arping: %s: value was empty\n", what);
+ exit(1);
+ }
+ char *endp = NULL;
+ errno = 0;
+ // Maybe need to use strtod() instead? It's in C89, whereas
+ // looks like strtof() is in POSIX.1-2001, POSIX.1-2008, C99.
+ const float ret = strtof(in, &endp);
+ if (errno) {
+ fprintf(stderr, "arping: %s: parsing <%s> as float: %s\n",
+ what, in, strerror(errno));
+ exit(1);
+ }
+ if (*endp) {
+ fprintf(stderr,
+ "arping: %s: failed parsing <%s> as float\n",
+ what, in);
+ exit(1);
+ }
+ return ret;
+}
+
static int
must_parse_int(const char* in, const char* what)
{
@@ -2111,11 +2137,28 @@ arping_main(int argc, char **argv)
}
break;
case 'w':
- deadline = atof(optarg);
+ deadline = must_parse_float(optarg, "deadline (-w)");
+ if (deadline < 0) {
+ fprintf(stderr,
+ "arping: deadline (-w) must be >=0. Is %f\n",
+ deadline);
+ exit(1);
+ }
break;
- case 'W':
- packetwait = (unsigned)(1000000.0 * atof(optarg));
+ case 'W': {
+ const float val = must_parse_float(optarg,
+ "packetwait (-W)");
+ // TODO: range check into unsigned.
+ // Also turns out zero doesn't work.
+ packetwait = (unsigned)(1000000.0 * val);
+ if (val < 0) {
+ fprintf(stderr,
+ "arping: packetwait (-W) must be >=0. Is %f\n",
+ val);
+ exit(1);
+ }
break;
+ }
case 'z':
use_seccomp = 1;
break;
diff --git a/src/arping_test.c b/src/arping_test.c
index 9166c54..9db2d60 100644
--- a/src/arping_test.c
+++ b/src/arping_test.c
@@ -497,6 +497,7 @@ START_TEST(badarg_maxcount_neg)
char* args[] = {
"arping",
"-c", "-1",
+ "-h", // To exit cleanly.
"dummy",
NULL
};
@@ -508,6 +509,19 @@ START_TEST(badarg_maxcount_nan)
char* args[] = {
"arping",
"-c", "number",
+ "-h", // To exit cleanly.
+ "dummy",
+ NULL
+ };
+ arping_main(sizeof(args)/sizeof(char*)-1, args);
+}
+
+START_TEST(badarg_maxcount_range)
+{
+ char* args[] = {
+ "arping",
+ "-c", "100000000000000000000000000000",
+ "-h", // To exit cleanly.
"dummy",
NULL
};
@@ -538,6 +552,54 @@ START_TEST(arg_maxcount_hex)
arping_main(sizeof(args)/sizeof(char*)-1, args);
}
+START_TEST(badarg_packetwait_neg)
+{
+ char* args[] = {
+ "arping",
+ "-W", "-1",
+ "-h", // To exit cleanly.
+ "dummy",
+ NULL
+ };
+ arping_main(sizeof(args)/sizeof(char*)-1, args);
+}
+
+START_TEST(badarg_packetwait_nan)
+{
+ char* args[] = {
+ "arping",
+ "-W", "huteosu",
+ "-h", // To exit cleanly.
+ "dummy",
+ NULL
+ };
+ arping_main(sizeof(args)/sizeof(char*)-1, args);
+}
+
+START_TEST(badarg_packetwait_range)
+{
+ char* args[] = {
+ "arping",
+ "-W", "10000000000000000000000000000000000000000",
+ "-h", // To exit cleanly.
+ "dummy",
+ NULL
+ };
+ arping_main(sizeof(args)/sizeof(char*)-1, args);
+}
+
+START_TEST(arg_packetwait_good)
+{
+ char* args[] = {
+ "arping",
+ "-W", "1.2",
+ "-h", // To exit cleanly.
+ "dummy",
+ NULL
+ };
+ arping_main(sizeof(args)/sizeof(char*)-1, args);
+}
+
START_TEST(libnet_init_bad_nolo)
{
// It'll only try lo if named interface fails.
@@ -595,6 +657,7 @@ arping_suite(void)
SIGH_LIBCHECK(libnet_init_good);
SIGH_LIBCHECK(arg_maxcount_good);
SIGH_LIBCHECK(arg_maxcount_hex);
+ SIGH_LIBCHECK(arg_packetwait_good);
#define SIGH_LIBCHECK_EXIT(tn) \
tc_core = tcase_create(#tn); \
@@ -603,6 +666,10 @@ arping_suite(void)
SIGH_LIBCHECK_EXIT(badarg_maxcount_neg);
SIGH_LIBCHECK_EXIT(badarg_maxcount_nan);
+ SIGH_LIBCHECK_EXIT(badarg_maxcount_range);
+ SIGH_LIBCHECK_EXIT(badarg_packetwait_neg);
+ SIGH_LIBCHECK_EXIT(badarg_packetwait_nan);
+ SIGH_LIBCHECK_EXIT(badarg_packetwait_range);
SIGH_LIBCHECK_EXIT(libnet_init_bad_nolo);
SIGH_LIBCHECK_EXIT(libnet_init_null_nolo_nonull);