1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-06 06:29:03 +00:00

Merging from nmap-exp/colin/nmap-addrset, nmap-exp/colin/nbase-addrset, and /nmap-exp/colin/ncat-addrset

Ported addrset from ncat to nbase. Made --exclude and --exclude-file options use addrset. As a side effect IPv6 Excludes work.
This commit is contained in:
colin
2011-06-20 20:46:41 +00:00
parent 6677593def
commit 6cd1cee328
3 changed files with 33 additions and 164 deletions

View File

@@ -101,7 +101,6 @@
#include "nmap_dns.h"
#include "nmap_tty.h"
#include "utils.h"
using namespace std;
extern NmapOps o;
@@ -156,133 +155,40 @@ void returnhost(HostGroupState *hs) {
/* Is the host passed as Target to be excluded? Much of this logic had
to be rewritten from wam's original code to allow for the objects */
static int hostInExclude(struct sockaddr *checksock, size_t checksocklen,
TargetGroup *exclude_group) {
unsigned long tmpTarget; /* ip we examine */
int i=0; /* a simple index */
char targets_type; /* what is the address type of the Target Group */
struct sockaddr_storage ss;
struct sockaddr_in *sin = (struct sockaddr_in *) &ss;
size_t slen; /* needed for funct but not used */
unsigned long mask = 0; /* our trusty netmask, which we convert to nbo */
struct sockaddr_in *checkhost_in;
if ((TargetGroup *)0 == exclude_group)
const addrset *exclude_group) {
if (exclude_group == NULL)
return 0;
checkhost_in = NULL;
if (checksock->sa_family == AF_INET) {
assert(checksocklen >= sizeof(struct sockaddr_in));
checkhost_in = (struct sockaddr_in *) checksock;
}
if (checksock == NULL)
return 0;
/* First find out what type of addresses are in the target group */
targets_type = exclude_group[i].get_targets_type();
/* Lets go through the targets until we reach our uninitialized placeholder */
while (exclude_group[i].get_targets_type() != TargetGroup::TYPE_NONE) {
/* while there are still hosts in the target group */
while (exclude_group[i].get_next_host(&ss, &slen) == 0) {
tmpTarget = sin->sin_addr.s_addr;
/* For Netmasks simply compare the network bits and move to the next
* group if it does not compare, we don't care about the individual addrs */
if (targets_type == TargetGroup::IPV4_NETMASK) {
if (checkhost_in == NULL)
break;
mask = htonl((unsigned long) (0-1) << (32-exclude_group[i].get_mask()));
if ((tmpTarget & mask) == (checkhost_in->sin_addr.s_addr & mask)) {
exclude_group[i].rewind();
return 1;
} else {
break;
}
}
/* For ranges we need to be a little more slick, if we don't find a match
* we should skip the rest of the addrs in the octet, thank wam for this
* optimization */
else if (targets_type == TargetGroup::IPV4_RANGES) {
if (checkhost_in == NULL)
break;
if (tmpTarget == checkhost_in->sin_addr.s_addr) {
exclude_group[i].rewind();
return 1;
} else {
/* note these are in network byte order */
if ((tmpTarget & 0x000000ff) != (checkhost_in->sin_addr.s_addr & 0x000000ff))
exclude_group[i].skip_range(TargetGroup::FIRST_OCTET);
else if ((tmpTarget & 0x0000ff00) != (checkhost_in->sin_addr.s_addr & 0x0000ff00))
exclude_group[i].skip_range(TargetGroup::SECOND_OCTET);
else if ((tmpTarget & 0x00ff0000) != (checkhost_in->sin_addr.s_addr & 0x00ff0000))
exclude_group[i].skip_range(TargetGroup::THIRD_OCTET);
continue;
}
}
#if HAVE_IPV6
else if (targets_type == TargetGroup::IPV6_ADDRESS) {
fatal("exclude file not supported for IPV6 -- If it is important to you, send a mail to fyodor@insecure.org so I can guage support\n");
}
#endif
}
exclude_group[i++].rewind();
}
/* we did not find the host */
if (addrset_contains(exclude_group,checksock))
return 1;
return 0;
}
/* Convert a vector of host specifications to an array (allocated with new[]) of
TargetGroups. The size of the returned array is one greater than the number
of host specs, to leave on uninitialized member at the end. */
static TargetGroup *specs_to_targetgroups(const std::vector<std::string> &specs) {
TargetGroup *excludelist;
unsigned int i;
excludelist = new TargetGroup[specs.size() + 1];
for (i = 0; i < specs.size(); i++) {
if (excludelist[i].parse_expr(specs[i].c_str(), o.af()) == 0) {
if (o.debugging > 1)
error("Loaded exclude target of: %s", specs[i].c_str());
}
}
return excludelist;
}
/* Load an exclude list from a file for --excludefile. */
TargetGroup* load_exclude_file(FILE *fp) {
std::vector<std::string> specs;
int load_exclude_file(addrset *excludelist, FILE *fp) {
addrset_init(excludelist);
char host_spec[1024];
size_t n;
while ((n = read_host_from_file(fp, host_spec, sizeof(host_spec))) > 0) {
if (n >= sizeof(host_spec))
fatal("One of your exclude file specifications was too long to read (>= %u chars)", (unsigned int) sizeof(host_spec));
specs.push_back(host_spec);
addrset_add_spec(excludelist, host_spec, o.af(), 1);
}
return specs_to_targetgroups(specs);
return 1;
}
/* Load a comma-separated exclude list from a string, the argument to
--exclude. */
TargetGroup* load_exclude_string(const char *s) {
std::vector<std::string> specs;
const char *begin, *p;
int load_exclude_string(addrset *excludelist, const char *s) {
addrset_init(excludelist);
addrset_add_spec(excludelist, s, o.af(), 1);
p = s;
while (*p != '\0') {
begin = p;
while (*p != '\0' && *p != ',')
p++;
specs.push_back(std::string(begin, p - begin));
if (*p == '\0')
break;
p++;
}
return specs_to_targetgroups(specs);
return 1;
}
@@ -292,43 +198,11 @@ TargetGroup* load_exclude_string(const char *s) {
the Target Group Object. Rather than writing a bunch of methods to return
private attributes, which would only be used for debugging, I went for the
method below. */
int dumpExclude(TargetGroup *exclude_group) {
int i=0, debug_save=0, type=TargetGroup::TYPE_NONE;
unsigned int mask = 0;
struct sockaddr_storage ss;
struct sockaddr_in *sin = (struct sockaddr_in *) &ss;
size_t slen;
/* shut off debugging for now, this is a debug routine in itself, we don't
want to see all the debug messages inside of the object */
debug_save = o.debugging;
o.debugging = 0;
while ((type = exclude_group[i].get_targets_type()) != TargetGroup::TYPE_NONE) {
switch (type) {
case TargetGroup::IPV4_NETMASK:
exclude_group[i].get_next_host(&ss, &slen);
mask = exclude_group[i].get_mask();
error("exclude host group %d is %s/%d", i, inet_ntoa(sin->sin_addr), mask);
break;
case TargetGroup::IPV4_RANGES:
while (exclude_group[i].get_next_host(&ss, &slen) == 0)
error("exclude host group %d is %s", i, inet_ntoa(sin->sin_addr));
break;
case TargetGroup::IPV6_ADDRESS:
fatal("IPV6 addresses are not supported in the exclude file\n");
break;
default:
fatal("Unknown target type in exclude file.\n");
}
exclude_group[i++].rewind();
}
/* return debugging to what it was */
o.debugging = debug_save;
int dumpExclude(addrset *exclude_group) {
/* When we updated the exclude code to use addrset from libnetutil (originally
from ncat) there was no simple available debugging function. Thus we are
zeroing this and if it is needed look in addrset.cc for the lower level
debug function -Colin */
return 1;
}
@@ -415,7 +289,7 @@ static bool target_needs_new_hostgroup(const HostGroupState *hs, const Target *t
return false;
}
Target *nexthost(HostGroupState *hs, TargetGroup *exclude_group,
Target *nexthost(HostGroupState *hs, const addrset *exclude_group,
struct scan_lists *ports, int pingtype) {
int i;
struct sockaddr_storage ss;