1
0
mirror of https://github.com/cmand/yarrp.git synced 2024-05-11 05:55:06 +00:00

Remove separate code-path for internet-wide (-Q) probing

This commit is contained in:
rbeverly
2019-11-15 13:13:48 -08:00
parent eb52311f87
commit 69fad9b762
6 changed files with 55 additions and 137 deletions

View File

@ -3,7 +3,6 @@ SUBDIRS = utils
bin_PROGRAMS = yarrp
yarrp_SOURCES = \
entire.cpp \
icmp.cpp \
iplist.cpp \
listener.cpp \

View File

@ -1,116 +1,8 @@
/****************************************************************************
* Description: Special code for fast, entire Internet-wide IPv4 probing
*
* Description: Special code for fast, entire Internet-wide IPv6 probing
****************************************************************************/
#include "yarrp.h"
void internet(YarrpConfig *config, Traceroute *trace, Patricia *tree, Stats *stats) {
uint8_t ttl;
uint32_t val = 0;
struct in_addr target;
TTLHisto *ttlhisto = NULL;
Status *status = NULL;
uint32_t host = 1 << 24;
char *p = NULL;
int i;
double prob, flip;
uint32_t octets_to_skip[13] = {0, /* reserved */
6, /* Army */
10, /* 1918 */
11, /* DoD */
22, /* DISA */
25, /* UK Defence */
26, /* DISA */
29, /* DISA */
30, /* DISA */
55, /* DoD */
127, /* loopback */
214, /* DoD */
215, /* DoD */
};
cout << ">> Randomizing permutation." << endl;
uint8_t key[KEYLEN] = { 0 };
if (config->seed)
permseed(key, config->seed);
else
permseed(key);
struct cperm_t* perm = cperm_create(UINT32_MAX, PERM_MODE_CYCLE,
PERM_CIPHER_RC5, key, KEYLEN);
p = (char *) &val;
while (PERM_END != cperm_next(perm, &val)) {
target.s_addr = val & 0x00FFFFFF; // pick out 24 bits of network
ttl = val >> 24; // use remaining 8 bits of perm as ttl
/* Probe a host in each /24 that's a function of the /24
(so it appears somewhat random), but is deterministic,
and fast to compute */
host = (p[0] + p[1] + p[2]) & 0xFF;
target.s_addr += (host << 24);
if ( (ttl & 0xE0) != 0x0) { // fast check: ttls in [0,31]
stats->ttl_outside++;
continue;
}
if (ttl >= config->maxttl)
continue;
#if 1
/* Only send probe if destination is in BGP table */
status = (Status *) tree->get(target.s_addr);
if (not status) {
stats->bgp_outside++;
continue;
}
#else
if ( (val & 0xE0) == 0xE0) { // multicast, class E
stats->adr_outside++;
continue;
}
for (i=0;i<13;i++) {
if ( (val & 0xFF) == octets_to_skip[i])
stats->adr_outside++;
continue;
}
#endif
ttl++; // probe ttls from 1 to 32
#if 1
if (ttl < config->ttl_neighborhood) {
ttlhisto = trace->ttlhisto[ttl];
if (ttlhisto->shouldProbe() == false) {
stats->nbr_skipped++;
continue;
}
ttlhisto->probed(trace->elapsed());
}
#endif
/* Running w/ a biased TTL probability distribution */
if (config->poisson) {
prob = poisson_pmf(ttl, config->poisson); /* poisson(k, lambda) */
flip = zrand(); /* uniform [0.0, 1.0) */
if (flip > prob)
continue;
}
/* Passed all checks, continue and send probe */
if (not config->testing)
trace->probe(target.s_addr, ttl);
else
trace->probePrint(&target, ttl);
stats->count++;
if (stats->count == config->count)
break;
/* Every 4096, do this */
if ( (stats->count & 0xFFF) == 0xFFF ) {
if (not config->testing)
stats->dump(stderr);
if (config->rate) {
/* Calculate sleep time based on scan rate */
usleep( (1000000 / config->rate) * 4096 );
}
}
}
}
/* SPECK 48/96 implementation */
#define MASK24 0xFFFFFF
#define SPECK_ROUNDS 23

View File

@ -1,13 +1,14 @@
#include "yarrp.h"
#include "random_list.h"
IPList::IPList(uint8_t _maxttl, bool _rand) {
IPList::IPList(uint8_t _maxttl, bool _rand, bool _entire) {
perm = NULL;
permsize = 0;
maxttl = _maxttl;
ttlbits = intlog(maxttl);
ttlmask = 0xffffffff >> (32 - ttlbits);
rand = _rand;
entire = _entire;
memset(key, 0, KEYLEN);
//std::cout << ">> MAXTTL: " << int(maxttl) << " TTLBits: " << int(ttlbits) << std::endl;
//printf("ttlmask: %02x\n", ttlmask);
@ -31,10 +32,14 @@ IPList6::~IPList6() {
/* seed */
void IPList4::seed() {
PermMode mode = PERM_MODE_CYCLE;
assert(targets.size() > 0);
permsize = targets.size() * maxttl;
if (permsize < 1000000)
mode = PERM_MODE_PREFIX;
if (not entire) {
assert(targets.size() > 0);
permsize = targets.size() * maxttl;
if (permsize < 1000000)
mode = PERM_MODE_PREFIX;
} else {
permsize = UINT32_MAX;
}
perm = cperm_create(permsize, mode, PERM_CIPHER_RC5, key, 16);
assert(perm);
}
@ -97,7 +102,9 @@ void IPList6::read(std::istream& inlist) {
}
uint32_t IPList4::next_address(struct in_addr *in, uint8_t * ttl) {
if (rand)
if (entire)
return next_address_entire(in, ttl);
else if (rand)
return next_address_rand(in, ttl);
else
return next_address_seq(in, ttl);
@ -140,6 +147,29 @@ uint32_t IPList4::next_address_rand(struct in_addr *in, uint8_t * ttl) {
return 1;
}
/* Internet-wide scanning mode */
uint32_t IPList4::next_address_entire(struct in_addr *in, uint8_t * ttl) {
static uint32_t next = 0;
static uint32_t host;
static char *p;
if (permsize == 0)
seed();
p = (char *) &next;
while (PERM_END != cperm_next(perm, &next)) {
*ttl = next >> 24; // use remaining 8 bits of perm as ttl
if ( (*ttl & 0xE0) != 0x0) { // fast check: ttls in [0,31]
continue;
}
in->s_addr = next & 0x00FFFFFF; // pick out 24 bits of network
host = (p[0] + p[1] + p[2]) & 0xFF;
in->s_addr += (host << 24);
return 1;
}
return 0;
}
uint32_t IPList6::next_address(struct in6_addr *in, uint8_t * ttl) {
if (rand)
return next_address_rand(in, ttl);

View File

@ -37,7 +37,7 @@ class RandomSubnetList : public SubnetList {
class IPList {
public:
IPList(uint8_t _maxttl, bool _rand);
IPList(uint8_t _maxttl, bool _rand, bool _entire);
virtual ~IPList() {};
virtual uint32_t next_address(struct in_addr *in, uint8_t * ttl) = 0;
virtual uint32_t next_address(struct in6_addr *in, uint8_t * ttl) = 0;
@ -56,15 +56,17 @@ class IPList {
uint8_t ttlbits;
uint32_t ttlmask;
bool rand;
bool entire;
};
class IPList4 : public IPList {
public:
IPList4(uint8_t _maxttl, bool _rand) : IPList(_maxttl, _rand) {};
IPList4(uint8_t _maxttl, bool _rand, bool _entire) : IPList(_maxttl, _rand, _entire) {};
virtual ~IPList4();
uint32_t next_address(struct in_addr *in, uint8_t * ttl);
uint32_t next_address_seq(struct in_addr *in, uint8_t * ttl);
uint32_t next_address_rand(struct in_addr *in, uint8_t * ttl);
uint32_t next_address_entire(struct in_addr *in, uint8_t * ttl);
uint32_t next_address(struct in6_addr *in, uint8_t * ttl) { return 0; };
void read(std::istream& in);
void seed();
@ -75,7 +77,7 @@ class IPList4 : public IPList {
class IPList6 : public IPList {
public:
IPList6(uint8_t _maxttl, bool _rand) : IPList(_maxttl, _rand) {};
IPList6(uint8_t _maxttl, bool _rand, bool _entire) : IPList(_maxttl, _rand, _entire) {};
virtual ~IPList6();
uint32_t next_address(struct in6_addr *in, uint8_t * ttl);
uint32_t next_address_seq(struct in6_addr *in, uint8_t * ttl);

View File

@ -211,6 +211,8 @@ sane(YarrpConfig *config) {
}
if (config->entire and not config->bgpfile)
fatal("Entire Internet mode requires BGP table");
if (config->inlist and config->entire)
fatal("Cannot run in entire Internet mode with input targets");
return true;
}
@ -242,16 +244,15 @@ main(int argc, char **argv) {
/* Init target list (individual IPs, *NOT* subnets) from input file */
IPList *iplist = NULL;
if (config.inlist) {
if (config.entire)
config.usage(argv[0]);
if (config.inlist or config.entire) {
if (config.ipv6)
iplist = new IPList6(config.maxttl, config.random_scan);
iplist = new IPList6(config.maxttl, config.random_scan, config.entire);
else
iplist = new IPList4(config.maxttl, config.random_scan);
iplist = new IPList4(config.maxttl, config.random_scan, config.entire);
/* randomize permutation key */
iplist->setkey(config.seed);
iplist->read(config.inlist);
if (config.inlist)
iplist->read(config.inlist);
}
/* Initialize subnet list and add subnets from args */
@ -318,20 +319,12 @@ main(int argc, char **argv) {
if (config.probe) {
debug(LOW, ">> Probing begins.");
if (config.inlist) {
/* Normal mode of operation, using individual IPs from input file */
if (config.entire or config.inlist) {
/* individual IPs from input file or entire mode*/
loop(&config, iplist, trace, tree, stats);
} else if (not config.entire) {
/* Normal mode of operation, using subnets from args */
loop(&config, subnetlist, trace, tree, stats);
} else {
/* you better really, really, know what you're doing */
debug(LOW, "** Entire Internet mode starting in 10s...");
sleep(10);
if (config.ipv6)
internet6(&config, trace, tree, stats);
else
internet(&config, trace, tree, stats);
/* using subnets from args */
loop(&config, subnetlist, trace, tree, stats);
}
}

View File

@ -108,6 +108,8 @@ YarrpConfig::parse_opts(int argc, char **argv) {
break;
case 'Q':
entire = true;
minttl = 1;
maxttl = 31;
break;
case 'n':
ttl_neighborhood = strtol(optarg, &endptr, 10);