Nmap Development mailing list archives
Proposed patch for more efficient random host generation
From: Chad Loder <cloder () acm org>
Date: Sun, 29 Jul 2001 08:41:40 -0700
Hello. I've been using nmap lately to perform large statistical "walks" of random IP address on the internet (similar to Bernstein's old "get random hosts with port 25/tcp open, and then run another script to determine what MTA they're running" approach). The random host address generation works pretty well, in that it uses 4 totally random bytes and then sanity checks some obviously non-routable or non-desirable ranges (including 6.* which is some army base -- fyodor, you have a story to tell here?). However, there are plenty more ranges which are either non-routable, reserved, or black-holed by IANA, and I've modified the code to filter all (or most) of these yucky addresses out of the generator, and I'm quite happy with the results (a higher "hit rate" on random hosts). I'm decent at IP address/mask arithmetic, but I wrote the code at around 5am so I apologize if there are any mistakes. It seems to work well for me (any mistakes on these ranges would merely cause the randomization not to pick them, which not that big of a deal). The list of ranges was compiled from several sources, including IANA's database of black holed address ranges, some of fyodor's existing code, and obviously any private/reserved ranges from RFC1819. I can send you some URLs if you're interested in how I did my research... Here's the patch: [thales ~/nmap-2.54BETA28] # diff nmap.c nmap.patched 1589a1590,1682 > /** > * Returns 1 if this is a reserved IP address, where "reserved" means > * either a private address, non-routable address, or even a non-reserved > * but unassigned address which has an extremely high probability of being > * black-holed. > * > * We try to optimize speed when ordering the tests. This optimization > * assumes that all byte values are equally likely in the input. > * > * TODO: optimize some of the inequality tests with bit arithmetic, nest > * some of the if statements > */ > int is_reserved(unsigned char* ipc) > { > unsigned char i1 = ipc[0], i2 = ipc[1], i3 = ipc[2], i4 = ipc[3]; >> /* 224.0.0.0/3 (224.0.0.0 through 255.255.255.255) is all multicast stuff */
> if (i1 >= 224) > return 1; >> /* 96.0.0.0/3 (96.0.0.0 through 127.255.255.255) is a huge unassigned range */
> if (i1 >= 96 && i1 <= 127) > return 1; > > /* 72.0.0.0/5 (72.0.0.0 through 79.255.255.255) is empty */> /* 80.0.0.0/4 (80.0.0.0 through 95.255.255.255) is another big empty block */
> if (i1 >= 72 && i1 <= 95) > return 1; > > /* do all the /7's and /8's with a big switch statement, hopefully the> * compiler will be able to optimize this a little better using a jump table
> * or what have you > */ > switch (i1) > { > case 0: /* 0.0.0.0/8, 1.0.0.0/8, 2.0.0.0/8 */ > case 1: > case 2: > case 5: /* 5.0.0.0/8, 6.0.0.0/8, and 7.0.0.0/8 */ > case 6: > case 7: > case 10: /* the infamous 10.0.0.0/8 */ > case 23: > case 27: > case 31: > case 36: /* 36.0.0.0/7 */ > case 37: > case 58: /* 58.0.0.0/7 */ > case 59: > case 60: > case 69: > case 70: /* 70.0.0.0/7 */ > case 71: > case 82: /* 82.0.0.0/7 */ > case 83: > /* case 127: already accounted for in 96.0.0.0/3 above */ > case 197: > case 201: > case 219: > case 220: > return 1; > default: > break; > } > > /* 172.16.0.0/12 is reserved for private nets by RFC1819 */ > if (i1 == 172 && i2 >= 16 && i2 <= 31) > return 1; > > /* 192.168.0.0/16 is reserved for private nets by RFC1819 */ > /* 192.0.2.0/24 is reserved for documentation and examples */ > if (i1 == 192) { > if (i2 == 168) > return 1; > else if (i2 == 0 && i3 == 2) > return 1; > } >> /* reserved for DHCP clients seeking addresses, not routable outside LAN */
> if (i1 == 169 && i2 == 254) > return 1; > > /* believe it or not, 204.152.64.0/23 is some bizarre Sun proprietary > * clustering thing */ > if (i1 == 204 && i2 == 152 && (i3 == 64 || i3 == 65)) > return 1; > > /* 255.255.255.255, note we already tested for i1 in this range */ > if (i2 == 255 && i3 == 255 && i4 == 255) > return 1; > > return 0; > } 1603,1608c1696,1697 < } while(ipc[0] == 10 || ipc[0] > 224 || ipc[0] == 127 || !ipc[0] || < ipc[0] == 6 || ( ipc[0] == 192 && ipc[1] == 168) || < (ipc[0] == 172 && ipc[1] >= 16 && ipc[1] <= 31)); < /* Skip the above private, multicast, reserved, and localhost < addresses -- I also skip 6.*.*.* because that is the < U.S. Army Yuma Proving Ground and it is kindof wacky */ --- > } while (is_reserved(ipc)); > ---------------------------------------------------------------------For help using this (nmap-dev) mailing list, send a blank email to nmap-dev-help () insecure org . List run by ezmlm-idx (www.ezmlm.org).
Current thread:
- Proposed patch for more efficient random host generation Chad Loder (Jul 29)
- Re: Proposed patch for more efficient random host generation H D Moore (Jul 29)
- Re: Proposed patch for more efficient random host generation Fyodor (Jul 29)
- Re: Proposed patch for more efficient random host generation Jay Freeman (saurik) (Jul 30)
- Re: Proposed patch for more efficient random host generation Fyodor (Jul 30)
- Re: Proposed patch for more efficient random host generation Jay Freeman (saurik) (Jul 30)