mirror of
https://github.com/nmap/nmap.git
synced 2025-12-07 13:11:28 +00:00
Move random address generation to TargetGroup/NetBlock
This commit is contained in:
@@ -116,6 +116,18 @@ public:
|
|||||||
virtual std::string str() const = 0;
|
virtual std::string str() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NetBlockRandomIPv4 : public NetBlock {
|
||||||
|
public:
|
||||||
|
NetBlockRandomIPv4();
|
||||||
|
|
||||||
|
bool next(struct sockaddr_storage *ss, size_t *sslen);
|
||||||
|
void apply_netmask(int bits) {}
|
||||||
|
std::string str() const {return "Random IPv4 addresses";}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct sockaddr_in base;
|
||||||
|
};
|
||||||
|
|
||||||
class NetBlockIPv4Ranges : public NetBlock {
|
class NetBlockIPv4Ranges : public NetBlock {
|
||||||
public:
|
public:
|
||||||
octet_bitvector octets[4];
|
octet_bitvector octets[4];
|
||||||
@@ -325,6 +337,20 @@ bool NetBlock::is_resolved_address(const struct sockaddr_storage *ss) const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetBlockRandomIPv4::NetBlockRandomIPv4() {
|
||||||
|
memset(&base, 0, sizeof(base));
|
||||||
|
base.sin_family = AF_INET;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetBlockRandomIPv4::next(struct sockaddr_storage *ss, size_t *sslen) {
|
||||||
|
do {
|
||||||
|
base.sin_addr.s_addr = get_random_unique_u32();
|
||||||
|
} while (ip_is_reserved(&base.sin_addr));
|
||||||
|
memcpy(ss, &base, sizeof(base));
|
||||||
|
*sslen = sizeof(base);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
NetBlockIPv4Ranges::NetBlockIPv4Ranges() {
|
NetBlockIPv4Ranges::NetBlockIPv4Ranges() {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
@@ -777,6 +803,11 @@ int TargetGroup::parse_expr(const char *target_expr, int af) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TargetGroup::generate_random_ips() {
|
||||||
|
assert(this->netblock == NULL);
|
||||||
|
this->netblock = new NetBlockRandomIPv4();
|
||||||
|
}
|
||||||
|
|
||||||
/* Grab the next host from this expression (if any) and updates its internal
|
/* Grab the next host from this expression (if any) and updates its internal
|
||||||
state to reflect that the IP was given out. Returns 0 and
|
state to reflect that the IP was given out. Returns 0 and
|
||||||
fills in ss if successful. ss must point to a pre-allocated
|
fills in ss if successful. ss must point to a pre-allocated
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ public:
|
|||||||
const std::list<struct sockaddr_storage> &get_unscanned_addrs(void) const;
|
const std::list<struct sockaddr_storage> &get_unscanned_addrs(void) const;
|
||||||
/* is the current expression a named host */
|
/* is the current expression a named host */
|
||||||
int get_namedhost() const;
|
int get_namedhost() const;
|
||||||
|
void generate_random_ips();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* TARGETGROUP_H */
|
#endif /* TARGETGROUP_H */
|
||||||
|
|||||||
@@ -4673,19 +4673,12 @@ size_t read_host_from_file(FILE *fp, char *buf, size_t n)
|
|||||||
|
|
||||||
|
|
||||||
/* Return next target host specification from the supplied stream.
|
/* Return next target host specification from the supplied stream.
|
||||||
* if parameter "random" is set to true, then the function will
|
*/
|
||||||
* return a random, non-reserved, IP address in decimal-dot notation */
|
const char *grab_next_host_spec(FILE *inputfd, int argc, const char **argv) {
|
||||||
const char *grab_next_host_spec(FILE *inputfd, bool random, int argc, const char **argv) {
|
|
||||||
static char host_spec[1024];
|
static char host_spec[1024];
|
||||||
struct in_addr ip;
|
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
if (random) {
|
if (!inputfd) {
|
||||||
do {
|
|
||||||
ip.s_addr = get_random_unique_u32();
|
|
||||||
} while (ip_is_reserved(&ip));
|
|
||||||
Strncpy(host_spec, inet_ntoa(ip), sizeof(host_spec));
|
|
||||||
} else if (!inputfd) {
|
|
||||||
return( (optind < argc)? argv[optind++] : NULL);
|
return( (optind < argc)? argv[optind++] : NULL);
|
||||||
} else {
|
} else {
|
||||||
n = read_host_from_file(inputfd, host_spec, sizeof(host_spec));
|
n = read_host_from_file(inputfd, host_spec, sizeof(host_spec));
|
||||||
|
|||||||
@@ -533,9 +533,8 @@ int read_reply_pcap(pcap_t *pd, long to_usec,
|
|||||||
size_t read_host_from_file(FILE *fp, char *buf, size_t n);
|
size_t read_host_from_file(FILE *fp, char *buf, size_t n);
|
||||||
|
|
||||||
/* Return next target host specification from the supplied stream.
|
/* Return next target host specification from the supplied stream.
|
||||||
* if parameter "random" is set to true, then the function will
|
*/
|
||||||
* return a random, non-reserved, IP address in decimal-dot notation */
|
const char *grab_next_host_spec(FILE *inputfd, int argc, const char **fakeargv);
|
||||||
const char *grab_next_host_spec(FILE *inputfd, bool random, int argc, const char **fakeargv);
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
/* Convert a dnet interface name into the long pcap style. This also caches the
|
/* Convert a dnet interface name into the long pcap style. This also caches the
|
||||||
|
|||||||
3
nmap.cc
3
nmap.cc
@@ -2078,7 +2078,8 @@ int nmap_main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
if (o.ping_group_sz < o.minHostGroupSz())
|
if (o.ping_group_sz < o.minHostGroupSz())
|
||||||
o.ping_group_sz = o.minHostGroupSz();
|
o.ping_group_sz = o.minHostGroupSz();
|
||||||
HostGroupState hstate(o.ping_group_sz, o.randomize_hosts, argc, (const char **) argv);
|
HostGroupState hstate(o.ping_group_sz, o.randomize_hosts,
|
||||||
|
o.generate_random_ips ? o.max_ips_to_scan : 0, argc, (const char **) argv);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ideal_scan_group_sz = determineScanGroupSize(o.numhosts_scanned, &ports);
|
ideal_scan_group_sz = determineScanGroupSize(o.numhosts_scanned, &ports);
|
||||||
|
|||||||
@@ -1119,7 +1119,7 @@ int ArgParser::parseArguments(int argc, char *argv[]) {
|
|||||||
* through calls to getNextTarget();
|
* through calls to getNextTarget();
|
||||||
* */
|
* */
|
||||||
const char *next_spec=NULL;
|
const char *next_spec=NULL;
|
||||||
while ( (next_spec= grab_next_host_spec(NULL, false, argc, (const char **) argv)) != NULL )
|
while ( (next_spec= grab_next_host_spec(NULL, argc, (const char **) argv)) != NULL )
|
||||||
o.targets.addSpec( (char *) next_spec );
|
o.targets.addSpec( (char *) next_spec );
|
||||||
|
|
||||||
return OP_SUCCESS;
|
return OP_SUCCESS;
|
||||||
|
|||||||
12
targets.cc
12
targets.cc
@@ -285,7 +285,7 @@ bool target_needs_new_hostgroup(Target **targets, int targets_sz, const Target *
|
|||||||
The target_expressions array MUST REMAIN VALID IN MEMORY as long as
|
The target_expressions array MUST REMAIN VALID IN MEMORY as long as
|
||||||
this class instance is used -- the array is NOT copied.
|
this class instance is used -- the array is NOT copied.
|
||||||
*/
|
*/
|
||||||
HostGroupState::HostGroupState(int lookahead, int rnd, int argc, const char **argv) {
|
HostGroupState::HostGroupState(int lookahead, int rnd, int num_random, int argc, const char **argv) {
|
||||||
assert(lookahead > 0);
|
assert(lookahead > 0);
|
||||||
this->argc = argc;
|
this->argc = argc;
|
||||||
this->argv = argv;
|
this->argv = argv;
|
||||||
@@ -296,6 +296,10 @@ HostGroupState::HostGroupState(int lookahead, int rnd, int argc, const char **ar
|
|||||||
current_batch_sz = 0;
|
current_batch_sz = 0;
|
||||||
next_batch_no = 0;
|
next_batch_no = 0;
|
||||||
randomize = rnd;
|
randomize = rnd;
|
||||||
|
this->num_random = num_random;
|
||||||
|
if (num_random > 0) {
|
||||||
|
current_group.generate_random_ips();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HostGroupState::~HostGroupState() {
|
HostGroupState::~HostGroupState() {
|
||||||
@@ -315,7 +319,7 @@ void HostGroupState::undefer() {
|
|||||||
const char *HostGroupState::next_expression() {
|
const char *HostGroupState::next_expression() {
|
||||||
if (o.max_ips_to_scan == 0 || o.numhosts_scanned + this->current_batch_sz < o.max_ips_to_scan) {
|
if (o.max_ips_to_scan == 0 || o.numhosts_scanned + this->current_batch_sz < o.max_ips_to_scan) {
|
||||||
const char *expr;
|
const char *expr;
|
||||||
expr = grab_next_host_spec(o.inputfd, o.generate_random_ips, this->argc, this->argv);
|
expr = grab_next_host_spec(o.inputfd, this->argc, this->argv);
|
||||||
if (expr != NULL)
|
if (expr != NULL)
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
@@ -427,6 +431,7 @@ static Target *next_target(HostGroupState *hs, struct addrset *exclude_group,
|
|||||||
struct sockaddr_storage ss;
|
struct sockaddr_storage ss;
|
||||||
size_t sslen;
|
size_t sslen;
|
||||||
Target *t;
|
Target *t;
|
||||||
|
int num_queued = o.numhosts_scanned + hs->current_batch_sz;
|
||||||
|
|
||||||
/* First handle targets deferred in the last batch. */
|
/* First handle targets deferred in the last batch. */
|
||||||
if (!hs->undeferred.empty()) {
|
if (!hs->undeferred.empty()) {
|
||||||
@@ -435,6 +440,9 @@ static Target *next_target(HostGroupState *hs, struct addrset *exclude_group,
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (o.max_ips_to_scan > 0 && num_queued >= (int)o.max_ips_to_scan) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
tryagain:
|
tryagain:
|
||||||
|
|
||||||
if (hs->current_group.get_next_host(&ss, &sslen) != 0) {
|
if (hs->current_group.get_next_host(&ss, &sslen) != 0) {
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public:
|
|||||||
/* The maximum number of entries we want to allow storing in defer_buffer. */
|
/* The maximum number of entries we want to allow storing in defer_buffer. */
|
||||||
static const unsigned int DEFER_LIMIT = 64;
|
static const unsigned int DEFER_LIMIT = 64;
|
||||||
|
|
||||||
HostGroupState(int lookahead, int randomize, int argc, const char *argv[]);
|
HostGroupState(int lookahead, int randomize, int num_random, int argc, const char *argv[]);
|
||||||
~HostGroupState();
|
~HostGroupState();
|
||||||
Target **hostbatch;
|
Target **hostbatch;
|
||||||
|
|
||||||
@@ -102,6 +102,8 @@ public:
|
|||||||
void undefer();
|
void undefer();
|
||||||
const char *next_expression();
|
const char *next_expression();
|
||||||
Target *next_target();
|
Target *next_target();
|
||||||
|
private:
|
||||||
|
int num_random;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ports is used to pass information about what ports to use for host discovery */
|
/* ports is used to pass information about what ports to use for host discovery */
|
||||||
|
|||||||
Reference in New Issue
Block a user