From 3ba4a87c75b3322b7251d395ff7ca70d95534147 Mon Sep 17 00:00:00 2001 From: tudor Date: Tue, 9 Aug 2016 06:12:17 +0000 Subject: [PATCH] o.ping_group_sz can be increased above 4096 with a higher --min-hostgroup value, calls to target_needs_new_hostgroup limited as much as possible --- nmap.cc | 71 +++++++++++++----------------------------------------- targets.cc | 22 ++++++++--------- targets.h | 3 +++ 3 files changed, 31 insertions(+), 65 deletions(-) diff --git a/nmap.cc b/nmap.cc index 99cf6c264..7fa66f3ea 100644 --- a/nmap.cc +++ b/nmap.cc @@ -189,8 +189,6 @@ extern char *optarg; extern int optind; extern NmapOps o; /* option structure */ -static bool target_needs_new_hostgroup(std::vector &targets, - const Target *target); static void display_nmap_version(); /* A mechanism to save argv[0] for code that requires that. */ @@ -1752,6 +1750,8 @@ int nmap_main(int argc, char *argv[]) { char hostname[FQDN_LEN + 1] = ""; struct sockaddr_storage ss; size_t sslen; + int processed_hosts; + bool check_target; now = time(NULL); local_time = localtime(&now); @@ -1975,16 +1975,30 @@ int nmap_main(int argc, char *argv[]) { } #endif + if (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); + processed_hosts = 0; do { ideal_scan_group_sz = determineScanGroupSize(o.numhosts_scanned, &ports); + + check_target = false; + if (processed_hosts == hstate.current_batch_sz) + processed_hosts = 0; + while (Targets.size() < ideal_scan_group_sz) { o.current_scantype = HOST_DISCOVERY; currenths = nexthost(&hstate, &exclude_group, &ports, o.pingtype); if (!currenths) break; + if (processed_hosts == hstate.current_batch_sz) { + check_target = true; + processed_hosts = 0; + } + processed_hosts++; + if (currenths->flags & HOST_UP && !o.listscan) o.numhosts_up++; @@ -2055,7 +2069,7 @@ int nmap_main(int argc, char *argv[]) { /* Hosts in a group need to be somewhat homogeneous. Put this host in the next group if necessary. See target_needs_new_hostgroup for the details of when we need to split. */ - if (target_needs_new_hostgroup(Targets, currenths)) { + if (check_target && target_needs_new_hostgroup(&Targets[0], Targets.size(), currenths)) { returnhost(&hstate); o.numhosts_up--; break; @@ -2241,57 +2255,6 @@ int nmap_main(int argc, char *argv[]) { return 0; } -/* Returns true iff this target is incompatible with the other hosts in the host - group. This happens when: - 1. it uses a different interface, or - 2. it uses a different source address, or - 3. it is directly connected when the other hosts are not, or vice versa, or - 4. it has the same IP address as another target already in the group. - These restrictions only apply for raw scans. This function is similar to one - of the same name in targets.cc. That one is for ping scanning, this one is - for port scanning. */ -static bool target_needs_new_hostgroup(std::vector &targets, const Target *target) { - std::vector::iterator it; - - /* We've just started a new hostgroup, so any target is acceptable. */ - if (targets.empty()) - return false; - - /* There are no restrictions on non-root scans. */ - if (!(o.isr00t && target->deviceName() != NULL)) - return false; - - /* Different address family? */ - if (targets[0]->af() != target->af()) - return true; - - /* Different interface name? */ - if (targets[0]->deviceName() != NULL && - target->deviceName() != NULL && - strcmp(targets[0]->deviceName(), target->deviceName()) != 0) { - return true; - } - - /* Different source address? */ - if (sockaddr_storage_cmp(targets[0]->SourceSockAddr(), target->SourceSockAddr()) != 0) - return true; - - /* Different direct connectedness? */ - if (targets[0]->directlyConnected() != target->directlyConnected()) - return true; - - /* Is there already a target with this same IP address? ultra_scan doesn't - cope with that, because it uses IP addresses to look up targets from - replies. What happens is one target gets the replies for all probes - referring to the same IP address. */ - for (it = targets.begin(); it != targets.end(); it++) { - if (sockaddr_storage_cmp((*it)->TargetSockAddr(), target->TargetSockAddr()) == 0) - return true; - } - - return false; -} - // Free some global memory allocations. // This is used for detecting memory leaks. void nmap_free_mem() { diff --git a/targets.cc b/targets.cc index 667269e49..4c877e765 100644 --- a/targets.cc +++ b/targets.cc @@ -302,11 +302,11 @@ static void massping(Target *hostbatch[], int num_hosts, struct scan_lists *port These restrictions only apply for raw scans. This function is similar to one of the same name in nmap.cc. That one is for port scanning, this one is for ping scanning. */ -static bool target_needs_new_hostgroup(const HostGroupState *hs, const Target *target) { - int i; +bool target_needs_new_hostgroup(Target **targets, int targets_sz, const Target *target) { + int i = 0; /* We've just started a new hostgroup, so any target is acceptable. */ - if (hs->current_batch_sz == 0) + if (targets_sz == 0) return false; /* There are no restrictions on non-root scans. */ @@ -314,30 +314,30 @@ static bool target_needs_new_hostgroup(const HostGroupState *hs, const Target *t return false; /* Different address family? */ - if (hs->hostbatch[0]->af() != target->af()) + if (targets[0]->af() != target->af()) return true; /* Different interface name? */ - if (hs->hostbatch[0]->deviceName() != NULL && + if (targets[0]->deviceName() != NULL && target->deviceName() != NULL && - strcmp(hs->hostbatch[0]->deviceName(), target->deviceName()) != 0) { + strcmp(targets[0]->deviceName(), target->deviceName()) != 0) { return true; } /* Different source address? */ - if (sockaddr_storage_cmp(hs->hostbatch[0]->SourceSockAddr(), target->SourceSockAddr()) != 0) + if (sockaddr_storage_cmp(targets[0]->SourceSockAddr(), target->SourceSockAddr()) != 0) return true; /* Different direct connectedness? */ - if (hs->hostbatch[0]->directlyConnected() != target->directlyConnected()) + if (targets[0]->directlyConnected() != target->directlyConnected()) return true; /* Is there already a target with this same IP address? ultra_scan doesn't cope with that, because it uses IP addresses to look up targets from replies. What happens is one target gets the replies for all probes referring to the same IP address. */ - for (i = 0; i < hs->current_batch_sz; i++) { - if (sockaddr_storage_cmp(hs->hostbatch[i]->TargetSockAddr(), target->TargetSockAddr()) == 0) + for (i = 0; i < targets_sz; i++) { + if (sockaddr_storage_cmp(targets[i]->TargetSockAddr(), target->TargetSockAddr()) == 0) return true; } @@ -653,7 +653,7 @@ static void refresh_hostbatch(HostGroupState *hs, const addrset *exclude_group, break; /* Does this target need to go in a separate host group? */ - if (target_needs_new_hostgroup(hs, t)) { + if (target_needs_new_hostgroup(hs->hostbatch, hs->current_batch_sz, t)) { if (hs->defer(t)) continue; else diff --git a/targets.h b/targets.h index 9df644396..fe1cc4c77 100644 --- a/targets.h +++ b/targets.h @@ -209,5 +209,8 @@ int dumpExclude(addrset *exclude_group); time you call nexthost(). */ void returnhost(HostGroupState *hs); + +bool target_needs_new_hostgroup(Target **targets, int targets_sz, const Target *target); + #endif /* TARGETS_H */