mirror of
https://github.com/nmap/nmap.git
synced 2025-12-22 07:29:01 +00:00
Be more parallel with ARP discovery
Two essential changes: 1. (ab)Use the ratelimit detection feature to hold off sending retransmissions, preferring to send new ARP probes. Late responses will still be recorded, but no longer counted as drops. This also gives each target the longest amount of time to respond. 2. Send timing pings much more frequently. Since we're not sending any retransmissions until timeout + ratelimit, we wouldn't otherwise have any data on drops in order to speed up or slow down. Results are faster ARP scans with fewer missed targets. See #92.
This commit is contained in:
@@ -166,6 +166,8 @@ extern NmapOps o;
|
|||||||
extern "C" int g_has_npcap_loopback;
|
extern "C" int g_has_npcap_loopback;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* How long extra to wait before retransmitting for rate-limit detection */
|
||||||
|
#define RLD_TIME_MS 1000
|
||||||
|
|
||||||
int HssPredicate::operator() (const HostScanStats *lhs, const HostScanStats *rhs) const {
|
int HssPredicate::operator() (const HostScanStats *lhs, const HostScanStats *rhs) const {
|
||||||
const struct sockaddr_storage *lss, *rss;
|
const struct sockaddr_storage *lss, *rss;
|
||||||
@@ -916,6 +918,7 @@ void UltraScanInfo::Init(std::vector<Target *> &Targets, struct scan_lists *pts,
|
|||||||
tcp_scan = udp_scan = sctp_scan = prot_scan = false;
|
tcp_scan = udp_scan = sctp_scan = prot_scan = false;
|
||||||
ping_scan = noresp_open_scan = ping_scan_arp = ping_scan_nd = false;
|
ping_scan = noresp_open_scan = ping_scan_arp = ping_scan_nd = false;
|
||||||
memset((char *) &ptech, 0, sizeof(ptech));
|
memset((char *) &ptech, 0, sizeof(ptech));
|
||||||
|
perf.init();
|
||||||
switch (scantype) {
|
switch (scantype) {
|
||||||
case FIN_SCAN:
|
case FIN_SCAN:
|
||||||
case XMAS_SCAN:
|
case XMAS_SCAN:
|
||||||
@@ -963,10 +966,14 @@ void UltraScanInfo::Init(std::vector<Target *> &Targets, struct scan_lists *pts,
|
|||||||
case PING_SCAN_ARP:
|
case PING_SCAN_ARP:
|
||||||
ping_scan = true;
|
ping_scan = true;
|
||||||
ping_scan_arp = true;
|
ping_scan_arp = true;
|
||||||
|
/* For ARP and ND scan, we send pings more frequently. Otherwise we can't
|
||||||
|
* notice drops until we start sending retransmits after RLD_TIME_MS. */
|
||||||
|
perf.pingtime = RLD_TIME_MS * 1000 / 4;
|
||||||
break;
|
break;
|
||||||
case PING_SCAN_ND:
|
case PING_SCAN_ND:
|
||||||
ping_scan = true;
|
ping_scan = true;
|
||||||
ping_scan_nd = true;
|
ping_scan_nd = true;
|
||||||
|
perf.pingtime = RLD_TIME_MS * 1000 / 4;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -974,8 +981,6 @@ void UltraScanInfo::Init(std::vector<Target *> &Targets, struct scan_lists *pts,
|
|||||||
|
|
||||||
set_default_port_state(Targets, scantype);
|
set_default_port_state(Targets, scantype);
|
||||||
|
|
||||||
perf.init();
|
|
||||||
|
|
||||||
/* Keep a completed host around for a standard TCP MSL (2 min) */
|
/* Keep a completed host around for a standard TCP MSL (2 min) */
|
||||||
completedHostLifetime = 120000;
|
completedHostLifetime = 120000;
|
||||||
memset(&lastCompletedHostRemoval, 0, sizeof(lastCompletedHostRemoval));
|
memset(&lastCompletedHostRemoval, 0, sizeof(lastCompletedHostRemoval));
|
||||||
@@ -2476,10 +2481,10 @@ static void doAnyOutstandingRetransmits(UltraScanInfo *USI) {
|
|||||||
/* For rate limit detection, we delay the first time a new tryno
|
/* For rate limit detection, we delay the first time a new tryno
|
||||||
is seen, as long as we are scanning at least 2 ports */
|
is seen, as long as we are scanning at least 2 ports */
|
||||||
if (probe->tryno + 1 > (int) host->rld.max_tryno_sent &&
|
if (probe->tryno + 1 > (int) host->rld.max_tryno_sent &&
|
||||||
USI->gstats->numprobes > 1) {
|
(USI->gstats->numprobes > 1 || USI->ping_scan_arp || USI->ping_scan_nd)) {
|
||||||
host->rld.max_tryno_sent = probe->tryno + 1;
|
host->rld.max_tryno_sent = probe->tryno + 1;
|
||||||
host->rld.rld_waiting = true;
|
host->rld.rld_waiting = true;
|
||||||
TIMEVAL_MSEC_ADD(host->rld.rld_waittime, USI->now, 1000);
|
TIMEVAL_MSEC_ADD(host->rld.rld_waittime, USI->now, RLD_TIME_MS);
|
||||||
} else {
|
} else {
|
||||||
host->rld.rld_waiting = false;
|
host->rld.rld_waiting = false;
|
||||||
retransmitProbe(USI, host, probe);
|
retransmitProbe(USI, host, probe);
|
||||||
|
|||||||
Reference in New Issue
Block a user