diff --git a/CHANGELOG b/CHANGELOG index 3d07a21b7..137ae8e3f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ #Nmap Changelog ($Id$); -*-text-*- +o New Nmap option --unique will prevent Nmap from scanning the same IP address + twice, which can happen when different names resolve to the same address. [Daniel Miller] + o [NSE][GH#2175] Fixed NSE so it will not consolidate all port script output for targets which share an IP (e.g. HTTP vhosts) under one target. [Daniel Miller] diff --git a/NmapOps.cc b/NmapOps.cc index fab4ac3b8..bc2bab7d5 100644 --- a/NmapOps.cc +++ b/NmapOps.cc @@ -298,6 +298,7 @@ void NmapOps::Initialize() { deprecated_xml_osclass = false; always_resolve = false; resolve_all = false; + unique = false; dns_servers = NULL; implicitARPPing = true; numhosts_scanned = 0; diff --git a/NmapOps.h b/NmapOps.h index e3b9f2ba8..29ee2cbaa 100644 --- a/NmapOps.h +++ b/NmapOps.h @@ -304,6 +304,7 @@ class NmapOps { bool mass_dns; bool always_resolve; bool resolve_all; + bool unique; char *dns_servers; /* Do IPv4 ARP or IPv6 ND scan of directly connected Ethernet hosts, even if diff --git a/nmap.cc b/nmap.cc index d844e7886..18604259a 100644 --- a/nmap.cc +++ b/nmap.cc @@ -593,6 +593,7 @@ void parse_options(int argc, char **argv) { {"version-all", no_argument, 0, 0}, {"system-dns", no_argument, 0, 0}, {"resolve-all", no_argument, 0, 0}, + {"unique", no_argument, 0, 0}, {"log-errors", no_argument, 0, 0}, {"deprecated-xml-osclass", no_argument, 0, 0}, {(char*)k, no_argument, 0, 0}, @@ -844,6 +845,8 @@ void parse_options(int argc, char **argv) { o.dns_servers = strdup(optarg); } else if (strcmp(long_options[option_index].name, "resolve-all") == 0) { o.resolve_all = true; + } else if (strcmp(long_options[option_index].name, "unique") == 0) { + o.unique = true; } else if (strcmp(long_options[option_index].name, "log-errors") == 0) { /*Nmap Log errors is deprecated and is now always enabled by default. This option is left in so as to not break anybody's scanning scripts. diff --git a/targets.cc b/targets.cc index 444e07bc8..7592e22d1 100644 --- a/targets.cc +++ b/targets.cc @@ -423,7 +423,7 @@ bail: return NULL; } -static Target *next_target(HostGroupState *hs, const struct addrset *exclude_group, +static Target *next_target(HostGroupState *hs, struct addrset *exclude_group, struct scan_lists *ports, int pingtype) { struct sockaddr_storage ss; size_t sslen; @@ -473,10 +473,14 @@ tryagain: if (t == NULL) goto tryagain; + if (o.unique) { + // Use the exclude list to avoid scanning this IP again if the user requested it. + addrset_add_spec(exclude_group, t->targetipstr(), o.af(), 0); + } return t; } -static void refresh_hostbatch(HostGroupState *hs, const struct addrset *exclude_group, +static void refresh_hostbatch(HostGroupState *hs, struct addrset *exclude_group, struct scan_lists *ports, int pingtype) { int i; bool arpping_done = false; @@ -570,7 +574,7 @@ static void refresh_hostbatch(HostGroupState *hs, const struct addrset *exclude_ nmap_mass_rdns(hs->hostbatch, hs->current_batch_sz); } -Target *nexthost(HostGroupState *hs, const struct addrset *exclude_group, +Target *nexthost(HostGroupState *hs, struct addrset *exclude_group, struct scan_lists *ports, int pingtype) { if (hs->next_batch_no >= hs->current_batch_sz) refresh_hostbatch(hs, exclude_group, ports, pingtype); diff --git a/targets.h b/targets.h index 65bfd0b8b..fedb00806 100644 --- a/targets.h +++ b/targets.h @@ -106,7 +106,7 @@ public: }; /* ports is used to pass information about what ports to use for host discovery */ -Target *nexthost(HostGroupState *hs,const struct addrset *exclude_group, +Target *nexthost(HostGroupState *hs, struct addrset *exclude_group, struct scan_lists *ports, int pingtype); int load_exclude_file(struct addrset *exclude_group, FILE *fp); int load_exclude_string(struct addrset *exclude_group, const char *s);