diff options
author | tb <tb@cvs.openbsd.org> | 2015-12-07 02:38:55 +0000 |
---|---|---|
committer | tb <tb@cvs.openbsd.org> | 2015-12-07 02:38:55 +0000 |
commit | a89dfcc63c1861093d1deb834aabd4dc4cb5df3a (patch) | |
tree | 9faa04913ae380bc91659a90314fbcf07b16b328 | |
parent | 10621099f65cef40eada031871a9fb8877af1332 (diff) |
Get rid of modulo bias and replace the naive shuffle by the
Knuth-Fisher-Yates shuffle to make the random sequence of ports
less biased. Based on the implementation in sys/netinet/ip_id.c.
With helpful input from daniel@ and beck@
ok beck@ despite eye twitching
-rw-r--r-- | usr.bin/nc/netcat.c | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/usr.bin/nc/netcat.c b/usr.bin/nc/netcat.c index 4c3ed4e97f0..cfc5a2363b8 100644 --- a/usr.bin/nc/netcat.c +++ b/usr.bin/nc/netcat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: netcat.c,v 1.144 2015/11/23 01:23:56 bcook Exp $ */ +/* $OpenBSD: netcat.c,v 1.145 2015/12/07 02:38:54 tb Exp $ */ /* * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> * Copyright (c) 2015 Bob Beck. All rights reserved. @@ -58,7 +58,6 @@ #include "atomicio.h" #define PORT_MAX 65535 -#define PORT_MAX_LEN 6 #define UNIX_DG_TMP_SOCKET_SIZE 19 #define POLL_STDIN 0 @@ -1289,25 +1288,22 @@ build_ports(char *p) lo = cp; } - /* Load ports sequentially. */ - for (cp = lo; cp <= hi; cp++) { - portlist[x] = calloc(1, PORT_MAX_LEN); - if (portlist[x] == NULL) - err(1, NULL); - snprintf(portlist[x], PORT_MAX_LEN, "%d", cp); - x++; - } - - /* Randomly swap ports. */ + /* + * Initialize portlist with a random permutation. Based on + * Knuth, as in ip_randomid() in sys/netinet/ip_id.c. + */ if (rflag) { - int y; - char *c; - - for (x = 0; x <= (hi - lo); x++) { - y = (arc4random() & 0xFFFF) % (hi - lo); - c = portlist[x]; - portlist[x] = portlist[y]; - portlist[y] = c; + for (x = 0; x <= hi - lo; x++) { + cp = arc4random_uniform(x + 1); + portlist[x] = portlist[cp]; + if (asprintf(&portlist[cp], "%d", x + lo) < 0) + err(1, "asprintf"); + } + } else { /* Load ports sequentially. */ + for (cp = lo; cp <= hi; cp++) { + if (asprintf(&portlist[x], "%d", cp) < 0) + err(1, "asprintf"); + x++; } } } else { |