diff --git a/config.h b/config.h index 3991bad..100bef4 100644 --- a/config.h +++ b/config.h @@ -18,6 +18,10 @@ struct config { double rate; double scaling; char *dev; + enum { + FORMAT_TC, + FORMAT_VILLAS + } format; }; /* Declared in main.c */ diff --git a/dist-maketable.c b/dist-maketable.c index b1ec143..a5fc611 100644 --- a/dist-maketable.c +++ b/dist-maketable.c @@ -176,8 +176,6 @@ void printtable(const short *table, int limit) { int i; - printf("# This is the distribution table for the experimental distribution.\n"); - for (i=0 ; i < limit; ++i) { printf("%d%c", table[i], (i % 8) == 7 ? '\n' : ' '); diff --git a/dist.c b/dist.c index ccda90e..33c2a3d 100644 --- a/dist.c +++ b/dist.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include @@ -88,6 +90,7 @@ static int dist_generate(int argc, char *argv[]) { FILE *fp; double mu, sigma, rho; + int cnt; if (argc == 1) { if (!(fp = fopen(argv[0], "r"))) @@ -96,11 +99,42 @@ static int dist_generate(int argc, char *argv[]) else fp = stdin; - short *inverse = dist_make(fp, &mu, &sigma, &rho); + short *inverse = dist_make(fp, &mu, &sigma, &rho, &cnt); if (!inverse) error(-1, 0, "Failed to generate distribution"); - printtable(inverse, TABLESIZE); + char date[100], user[100], host[100]; + time_t now = time (0); + strftime(date, sizeof(date), "%Y-%m-%d %H:%M", localtime(&now)); + gethostname(host, sizeof(host)); + getlogin_r(user, sizeof(user)); + + printf("# This is the distribution table for the experimental distribution.\n"); + printf("# Read %d values, mu %.6f, sigma %.6f, rho %.6f\n", cnt, mu, sigma, rho); + printf("# Generated %s, by %s on %s\n", date, user, host); + printf("#\n"); + + switch (cfg.format) { + case FORMAT_TC: + printtable(inverse, TABLESIZE); + break; + + case FORMAT_VILLAS: + printf("netem = {\n"); + printf(" delay = %f\n", mu * 1e6); + printf(" jitter = %f\n", sigma * 1e6); + printf(" distribution = [ %d", inverse[0]); + + for (int i = 1; i < TABLESIZE; i++) + printf(", %d", inverse[i]); + + printf(" ]\n"); + printf(" loss = 0,\n"); + printf(" duplicate = 0,\n"); + printf(" corrupt = 0\n"); + printf(" }\n"); + break; + } return 0; } @@ -109,6 +143,7 @@ static int dist_load(int argc, char *argv[]) { FILE *fp; double mu, sigma, rho; + int cnt; if (argc == 1) { if (!(fp = fopen(argv[0], "r"))) @@ -117,7 +152,7 @@ static int dist_load(int argc, char *argv[]) else fp = stdin; - short *inverse = dist_make(fp, &mu, &sigma, &rho); + short *inverse = dist_make(fp, &mu, &sigma, &rho, &cnt); if (!inverse) error(-1, 0, "Failed to generate distribution"); diff --git a/main.c b/main.c index 1d479d4..e234508 100644 --- a/main.c +++ b/main.c @@ -30,7 +30,8 @@ struct config cfg = { .scaling = 1, .mark = 0xCD, .mask = 0xFFFFFFFF, - .dev = "eth0" + .dev = "eth0", + .format = FORMAT_TC }; int probe(int argc, char *argv[]); @@ -66,6 +67,7 @@ int main(int argc, char *argv[]) " -l --limit how many probes should we sent\n" " -d --dev network interface\n" " -s FACTOR a scaling factor for the dist subcommands\n" + " -f FMT the output format of the distribution tables\n" "\n" "netem util %s (built on %s %s)\n" " Copyright 2015, Steffen Vogel \n", argv[0], VERSION, __DATE__, __TIME__); @@ -88,7 +90,7 @@ int main(int argc, char *argv[]) /* Parse Arguments */ char c, *endptr; - while ((c = getopt(argc, argv, "h:m:M:i:l:d:r:s:")) != -1) { + while ((c = getopt(argc, argv, "h:m:M:i:l:d:r:s:f:")) != -1) { switch (c) { case 'm': cfg.mark = strtoul(optarg, &endptr, 0); @@ -111,6 +113,16 @@ int main(int argc, char *argv[]) case 'd': cfg.dev = strdup(optarg); break; + case 'f': + if (strcmp(optarg, "villas") == 0) + cfg.format = FORMAT_VILLAS; + else if (strcmp(optarg, "tc") == 0) + cfg.format = FORMAT_TC; + else { + error(-1, 0, "Unknown format: %s.", optarg); + exit(EXIT_FAILURE); + } + break; case '?': if (optopt == 'c') error(-1, 0, "Option -%c requires an argument.", optopt);