diff --git a/dev/udp/udp-perturb.c b/dev/udp/udp-perturb.c index 3df0f797f..098e61c2c 100644 --- a/dev/udp/udp-perturb.c +++ b/dev/udp/udp-perturb.c @@ -77,6 +77,9 @@ struct { } history[MAXREORDER]; int history_idx = 0; unsigned int rand_rate = 0; +unsigned int corr_rate = 0; +unsigned int corr_span = 1; +unsigned int corr_base = 0; struct conn conns[MAXCONN]; // sole connection for now int fd_frt; @@ -319,6 +322,14 @@ int handle_frt(int fd, struct pollfd *pfd, struct conn *conns, int nbconn) if (ret < 0) return errno == EAGAIN ? 0 : -1; + if (corr_rate > 0 && prng(100) < corr_rate) { + unsigned int rnd = prng(corr_span * 256); // pos and value + unsigned int pos = corr_base + (rnd >> 8); + + if (pos < ret) + pktbuf[pos] ^= rnd; + } + conn = NULL; for (i = 0; i < nbconn; i++) { if (addr.ss_family != conns[i].cli_addr.ss_family) @@ -421,6 +432,9 @@ void usage(int status, const char *name) " -h display this help\n" " -r rate reorder/duplicate/lose around %% of packets\n" " -s seed force initial random seed (currently %#x)\n" + " -c rate corrupt around %% of packets\n" + " -o ofs start offset of corrupted area (def: 0)\n" + " -w width width of the corrupted area (def: 1)\n" "", name, prng_state); } @@ -435,7 +449,7 @@ int main(int argc, char **argv) err.size = 100; err.msg = malloc(err.size); - while ((opt = getopt(argc, argv, "hr:s:")) != -1) { + while ((opt = getopt(argc, argv, "hr:s:c:o:w:")) != -1) { switch (opt) { case 'r': // rand_rate% rand_rate = atoi(optarg); @@ -443,6 +457,15 @@ int main(int argc, char **argv) case 's': // seed prng_state = atol(optarg); break; + case 'c': // corruption rate + corr_rate = atol(optarg); + break; + case 'o': // corruption offset + corr_base = atol(optarg); + break; + case 'w': // corruption width + corr_span = atol(optarg); + break; default: // help, anything else usage(0, argv[0]); }