diff --git a/nmap.cc b/nmap.cc index 4a74e45b9..7cc369ab3 100644 --- a/nmap.cc +++ b/nmap.cc @@ -2070,18 +2070,26 @@ int nmap_main(int argc, char *argv[]) { group. This happens when: 1. it uses a different interface, or 2. it uses a different source address, or - 3. it has the same IP address as another target already in the group. + 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) { +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 && @@ -2093,6 +2101,10 @@ static bool target_needs_new_hostgroup(std::vector &targets, 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 diff --git a/targets.cc b/targets.cc index 694b0ad6f..32be183a1 100644 --- a/targets.cc +++ b/targets.cc @@ -284,6 +284,7 @@ static bool target_needs_new_hostgroup(const HostGroupState *hs, const Target *t /* Different interface name? */ if (hs->hostbatch[0]->deviceName() != NULL && + target->deviceName() != NULL && strcmp(hs->hostbatch[0]->deviceName(), target->deviceName()) != 0) { return true; }