DEV: udp: switch parser to getopt() instead of positional arguments
In order to ease addition of new types of perturbations to udp-perturb,
let's first switch to getopt() and get rid of the positional arguments.
The random seed was already a conditional option of the rate which was
a conditional option as well. We add -r and -s for the rate and the
seed, and new options will follow.
diff --git a/dev/udp/udp-perturb.c b/dev/udp/udp-perturb.c
index 824628d..3df0f79 100644
--- a/dev/udp/udp-perturb.c
+++ b/dev/udp/udp-perturb.c
@@ -36,6 +36,7 @@
#include <netdb.h>
#include <fcntl.h>
#include <errno.h>
+#include <getopt.h>
#include <signal.h>
#include <stdarg.h>
#include <sys/stat.h>
@@ -409,31 +410,53 @@
return ret;
}
+/* print the usage message for program named <name> and exit with status <status> */
+void usage(int status, const char *name)
+{
+ if (strchr(name, '/'))
+ name = strrchr(name, '/') + 1;
+ die(status,
+ "Usage: %s [-h] [options] [<laddr>:]<lport> [<saddr>:]<sport>\n"
+ "Options:\n"
+ " -h display this help\n"
+ " -r rate reorder/duplicate/lose around <rate>%% of packets\n"
+ " -s seed force initial random seed (currently %#x)\n"
+ "", name, prng_state);
+}
+
int main(int argc, char **argv)
{
struct errmsg err;
struct pollfd *pfd;
+ int opt;
int i;
err.len = 0;
err.size = 100;
err.msg = malloc(err.size);
+ while ((opt = getopt(argc, argv, "hr:s:")) != -1) {
+ switch (opt) {
+ case 'r': // rand_rate%
+ rand_rate = atoi(optarg);
+ break;
+ case 's': // seed
+ prng_state = atol(optarg);
+ break;
+ default: // help, anything else
+ usage(0, argv[0]);
+ }
+ }
+
- if (argc < 3)
- die(1, "Usage: %s [<laddr>:]<lport> [<saddr>:]<sport> [rand_rate%% [seed]]\n", argv[0]);
+ if (argc - optind < 2)
+ usage(1, argv[0]);
- if (addr_to_ss(argv[1], &frt_addr, &err) < 0)
+ if (addr_to_ss(argv[optind], &frt_addr, &err) < 0)
die(1, "parsing listen address: %s\n", err.msg);
- if (addr_to_ss(argv[2], &srv_addr, &err) < 0)
+ if (addr_to_ss(argv[optind+1], &srv_addr, &err) < 0)
die(1, "parsing server address: %s\n", err.msg);
- if (argc > 3)
- rand_rate = atoi(argv[3]);
-
- if (argc > 4)
- prng_state = atol(argv[4]);
-
pfd = calloc(sizeof(struct pollfd), MAXCONN + 1);
if (!pfd)
die(1, "out of memory\n");