summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Habets <thomas@habets.se>2022-10-30 16:33:38 +0000
committerThomas Habets <thomas@habets.se>2022-10-30 16:34:08 +0000
commitf7e17aaca0ffbd2ca6921a91eba22237a2d38d23 (patch)
treeb0625e65bf8155dd666826db168b25c19d1ce21e
parent61105e441ec7f9ace2e723153611a8b80e5b63a0 (diff)
downloadarping-f7e17aaca0ffbd2ca6921a91eba22237a2d38d23.tar.gz
Fix conversion warnings for -C
Warnings 28 -> 27
-rw-r--r--configure.ac2
-rw-r--r--src/arping.c52
2 files changed, 45 insertions, 9 deletions
diff --git a/configure.ac b/configure.ac
index a44f42d..3e78b9c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -90,7 +90,7 @@ AC_FUNC_SETVBUF_REVERSED
AC_TYPE_SIGNAL
AC_CHECK_FUNCS([gettimeofday memset select strchr strdup strerror strstr \
getifaddrs cap_init pcap_create pcap_list_tstamp_types pcap_set_immediate_mode \
-pledge unveil pcap_findalldevs getrandom])
+pledge unveil pcap_findalldevs getrandom strtoll])
if test x$ac_cv_func_getifaddrs = xyes; then
AC_LIBOBJ([findif_getifaddrs])
diff --git a/src/arping.c b/src/arping.c
index 9f98396..9109413 100644
--- a/src/arping.c
+++ b/src/arping.c
@@ -292,6 +292,48 @@ must_parse_int(const char* in, const char* what)
return ret; // TODO: range check.
}
+/*
+ * It's not actually possible to parse unsigned numbers in C.
+ * The best this function can do is parse as a long, then reject
+ * negative numbers. If sizeof(int) == sizeof(long) then that cuts
+ * off half of all possible values.
+ *
+ * More ranting here:
+ * https://blog.habets.se/2022/10/No-way-to-parse-integers-in-C.html
+ */
+static unsigned int
+must_parse_uint(const char* in, const char* what)
+{
+ if (!*in) {
+ fprintf(stderr, "arping: %s: value was empty\n", what);
+ exit(1);
+ }
+ char *endp = NULL;
+ errno = 0;
+#if HAVE_STRTOLL
+ const long long ret = strtoll(in, &endp, 0);
+#else
+ const long ret = strtol(in, &endp, 0);
+#endif
+ if (errno) {
+ fprintf(stderr, "arping: %s: parsing <%s> as integer: %s\n",
+ what, in, strerror(errno));
+ exit(1);
+ }
+ if (*endp) {
+ fprintf(stderr,
+ "arping: %s: failed parsing <%s> as integer\n",
+ what, in);
+ exit(1);
+ }
+ if (ret < 0) {
+ fprintf(stderr,
+ "arping: %s: <%s> is negative\n", what, in);
+ exit(1);
+ }
+ return ret; // TODO: range check.
+}
+
static ssize_t
xgetrandom(void *buf, const size_t buflen, const unsigned int flags)
{
@@ -2034,14 +2076,8 @@ arping_main(int argc, char **argv)
}
break;
case 'C':
- max_replies = must_parse_int(optarg,
- "max replies (-C)");
- if (max_replies < 0) {
- fprintf(stderr,
- "arping: max replies (-C) must be >0. Got %d\n",
- max_replies);
- exit(1);
- }
+ max_replies = must_parse_uint(optarg,
+ "max replies (-C)");
break;
case 'd':
finddup = 1;