[PATCH 01/28] batctl: fix parsing of parameters with arguments
Sven Eckelmann <[email protected]> Sun, 21 Jun 2026 16:23:51 +0200
| Newsgroups | org.open-mesh.lists.batman |
|---|---|
| Message-ID | <[email protected]> |
If using a getopt argument with an argument, it can be supplied via:
* -m asd
* -m=asd
* -masd
Only the first version is correctly handled by the found_args
implementation (without causing undefined behavior). But it can be instead
simplified and fixed at the same time by directly using the optind variable
from getopt.
Fixes: 87ade2869cf3 ("add interval and loop count options")
Fixes: 3bdfc388e74b ("implement simple tcpdump, first only batman packets")
Fixes: ece05e1c4c1f ("[batctl] bisect (a tool to analyze logfiles) added")
Fixes: f3c9cf9e730e ("source out calculation of round trip time to functions.c add abbreviation for modules, example ping = p add traceroute module, not complete")
Fixes: f109b3473f86 ("batctl: introduce throughput meter support")
Signed-off-by: Sven Eckelmann <[email protected]>
---
bisect_iv.c | 15 ++++-----------
main.c | 2 +-
ping.c | 10 ++--------
tcpdump.c | 13 ++++---------
throughputmeter.c | 7 ++-----
traceroute.c | 7 ++-----
6 files changed, 15 insertions(+), 39 deletions(-)
diff --git a/bisect_iv.c b/bisect_iv.c
index d4d507a..5da5bf1 100644
--- a/bisect_iv.c
+++ b/bisect_iv.c
@@ -1495,7 +1495,6 @@ static int bisect_iv(struct state *state __maybe_unused, int argc, char **argv)
int num_parsed_files;
long long tmp_seqno;
char orig[NAME_LEN];
- int found_args = 1;
char *dash_ptr;
int optchar;
int res;
@@ -1510,19 +1509,15 @@ static int bisect_iv(struct state *state __maybe_unused, int argc, char **argv)
return EXIT_SUCCESS;
case 'l':
loop_orig_ptr = optarg;
- found_args += ((*((char *)(optarg - 1)) == optchar) ? 1 : 2);
break;
case 'n':
read_opt &= ~USE_BAT_HOSTS;
- found_args += 1;
break;
case 'o':
filter_orig_ptr = optarg;
- found_args += ((*((char *)(optarg - 1)) == optchar) ? 1 : 2);
break;
case 'r':
rt_orig_ptr = optarg;
- found_args += ((*((char *)(optarg - 1)) == optchar) ? 1 : 2);
break;
case 's':
dash_ptr = strchr(optarg, '-');
@@ -1549,11 +1544,9 @@ static int bisect_iv(struct state *state __maybe_unused, int argc, char **argv)
*dash_ptr = '-';
}
- found_args += ((*((char *)(optarg - 1)) == optchar) ? 1 : 2);
break;
case 't':
trace_orig_ptr = optarg;
- found_args += ((*((char *)(optarg - 1)) == optchar) ? 1 : 2);
break;
default:
bisect_iv_usage();
@@ -1561,7 +1554,7 @@ static int bisect_iv(struct state *state __maybe_unused, int argc, char **argv)
}
}
- if (argc <= found_args + 1) {
+ if (argc <= optind + 1) {
fprintf(stderr, "Error - need at least 2 log files to compare\n");
bisect_iv_usage();
goto err;
@@ -1624,13 +1617,13 @@ static int bisect_iv(struct state *state __maybe_unused, int argc, char **argv)
goto err;
}
- while (argc > found_args) {
- res = parse_log_file(argv[found_args]);
+ while (argc > optind) {
+ res = parse_log_file(argv[optind]);
if (res > 0)
num_parsed_files++;
- found_args++;
+ optind++;
}
if (num_parsed_files < 2) {
diff --git a/main.c b/main.c
index da4cbb6..79ed4ef 100644
--- a/main.c
+++ b/main.c
@@ -357,7 +357,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Warning - option -m was deprecated and will be removed in the future\n");
- state.arg_iface = argv[2];
+ state.arg_iface = optarg;
break;
case 'v':
version();
diff --git a/ping.c b/ping.c
index b61bca4..4dbbada 100644
--- a/ping.c
+++ b/ping.c
@@ -75,7 +75,6 @@ static int ping(struct state *state, int argc, char **argv)
uint8_t last_rr_cur = 0;
int ret = EXIT_FAILURE;
int loop_count = -1;
- int found_args = 1;
size_t packet_len;
struct timeval tv;
double time_delta;
@@ -100,7 +99,6 @@ static int ping(struct state *state, int argc, char **argv)
loop_count = strtol(optarg, NULL, 10);
if (loop_count < 1)
loop_count = -1;
- found_args += ((*((char *)(optarg - 1)) == optchar) ? 1 : 2);
break;
case 'h':
ping_usage();
@@ -117,21 +115,17 @@ static int ping(struct state *state, int argc, char **argv)
fractional_part = modf(ping_interval, &integral_part);
loop_interval.tv_sec = (time_t)integral_part;
loop_interval.tv_nsec = (long)(fractional_part * 1000000000l);
- found_args += ((*((char *)(optarg - 1)) == optchar) ? 1 : 2);
break;
case 't':
timeout = strtol(optarg, NULL, 10);
if (timeout < 1)
timeout = 1;
- found_args += ((*((char *)(optarg - 1)) == optchar) ? 1 : 2);
break;
case 'R':
rr = 1;
- found_args++;
break;
case 'T':
disable_translate_mac = 1;
- found_args += 1;
break;
default:
ping_usage();
@@ -139,13 +133,13 @@ static int ping(struct state *state, int argc, char **argv)
}
}
- if (argc <= found_args) {
+ if (optind >= argc) {
fprintf(stderr, "Error - target mac address or bat-host name not specified\n");
ping_usage();
return EXIT_FAILURE;
}
- dst_string = argv[found_args];
+ dst_string = argv[optind];
bat_hosts_init(0);
bat_host = bat_hosts_find_by_name(dst_string);
diff --git a/tcpdump.c b/tcpdump.c
index eb7524e..3409e59 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -1493,7 +1493,6 @@ static int tcpdump(struct state *state __maybe_unused, int argc, char **argv)
fd_set tmp_wait_sockets;
int ret = EXIT_FAILURE;
fd_set wait_sockets;
- int found_args = 1;
struct timeval tv;
int max_sock = 0;
ssize_t read_len;
@@ -1507,26 +1506,22 @@ static int tcpdump(struct state *state __maybe_unused, int argc, char **argv)
switch (optchar) {
case 'c':
read_opt |= COMPAT_FILTER;
- found_args += 1;
break;
case 'h':
tcpdump_usage();
return EXIT_SUCCESS;
case 'n':
read_opt &= ~USE_BAT_HOSTS;
- found_args += 1;
break;
case 'p':
tmp = strtol(optarg, NULL, 10);
if (tmp > 0 && tmp <= dump_level_all)
dump_level = tmp;
- found_args += ((*((char *)(optarg - 1)) == optchar) ? 1 : 2);
break;
case 'x':
tmp = strtol(optarg, NULL, 10);
if (tmp > 0 && tmp <= dump_level_all)
dump_level &= ~tmp;
- found_args += ((*((char *)(optarg - 1)) == optchar) ? 1 : 2);
break;
default:
tcpdump_usage();
@@ -1534,7 +1529,7 @@ static int tcpdump(struct state *state __maybe_unused, int argc, char **argv)
}
}
- if (argc <= found_args) {
+ if (optind >= argc) {
fprintf(stderr, "Error - target interface not specified\n");
tcpdump_usage();
return EXIT_FAILURE;
@@ -1549,8 +1544,8 @@ static int tcpdump(struct state *state __maybe_unused, int argc, char **argv)
INIT_LIST_HEAD(&dump_if_list);
FD_ZERO(&wait_sockets);
- while (argc > found_args) {
- dump_if = create_dump_interface(argv[found_args]);
+ while (optind < argc) {
+ dump_if = create_dump_interface(argv[optind]);
if (!dump_if)
goto out;
@@ -1559,7 +1554,7 @@ static int tcpdump(struct state *state __maybe_unused, int argc, char **argv)
FD_SET(dump_if->raw_sock, &wait_sockets);
list_add_tail(&dump_if->list, &dump_if_list);
- found_args++;
+ optind++;
}
while (!is_aborted) {
diff --git a/throughputmeter.c b/throughputmeter.c
index bfd59a5..d670c51 100644
--- a/throughputmeter.c
+++ b/throughputmeter.c
@@ -326,7 +326,6 @@ static int throughputmeter(struct state *state, int argc, char **argv)
struct bat_host *bat_host;
int ret = EXIT_FAILURE;
uint64_t throughput;
- int found_args = 1;
uint32_t time = 0;
char *dst_string;
int optchar;
@@ -334,12 +333,10 @@ static int throughputmeter(struct state *state, int argc, char **argv)
while ((optchar = getopt(argc, argv, "t:n")) != -1) {
switch (optchar) {
case 't':
- found_args += 2;
time = strtoul(optarg, NULL, 10);
break;
case 'n':
read_opt &= ~USE_BAT_HOSTS;
- found_args += 1;
break;
default:
tp_meter_usage();
@@ -347,12 +344,12 @@ static int throughputmeter(struct state *state, int argc, char **argv)
}
}
- if (argc <= found_args) {
+ if (optind >= argc) {
tp_meter_usage();
return EXIT_FAILURE;
}
- dst_string = argv[found_args];
+ dst_string = argv[optind];
bat_hosts_init(read_opt);
bat_host = bat_hosts_find_by_name(dst_string);
diff --git a/traceroute.c b/traceroute.c
index a0fb925..8f23128 100644
--- a/traceroute.c
+++ b/traceroute.c
@@ -48,7 +48,6 @@ static int traceroute(struct state *state, int argc, char **argv)
int ret = EXIT_FAILURE;
char dst_reached = 0;
int seq_counter = 0;
- int found_args = 1;
struct timeval tv;
ssize_t read_len;
char *dst_string;
@@ -65,11 +64,9 @@ static int traceroute(struct state *state, int argc, char **argv)
return EXIT_SUCCESS;
case 'n':
read_opt &= ~USE_BAT_HOSTS;
- found_args += 1;
break;
case 'T':
disable_translate_mac = 1;
- found_args += 1;
break;
default:
traceroute_usage();
@@ -77,13 +74,13 @@ static int traceroute(struct state *state, int argc, char **argv)
}
}
- if (argc <= found_args) {
+ if (optind >= argc) {
fprintf(stderr, "Error - target mac address or bat-host name not specified\n");
traceroute_usage();
return EXIT_FAILURE;
}
- dst_string = argv[found_args];
+ dst_string = argv[optind];
bat_hosts_init(read_opt);
bat_host = bat_hosts_find_by_name(dst_string);
--
2.47.3