1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-21 06:59:01 +00:00

Run probe send events through a HostScanStats::probeSent before passing them to

GroupScanStats::probeSent. This will allow updating timing variables for a
per-host rate limiter.

This fixes a bug, which was that decoy probes were not recorded by the scan
rate meter. Decoy scans would show a lower scan rate than the actual: with four
decoys the rate printed would be 1/5 of actual. This only affects printed
output, not the actual scan rate.
This commit is contained in:
david
2008-12-04 00:12:25 +00:00
parent 55482759d3
commit 88143d667b

View File

@@ -318,7 +318,7 @@ public:
struct sockaddr_storage latestip; struct sockaddr_storage latestip;
GroupScanStats(UltraScanInfo *UltraSI); GroupScanStats(UltraScanInfo *UltraSI);
~GroupScanStats(); ~GroupScanStats();
void probeSent(); void probeSent(unsigned int nbytes);
/* Returns true if the GLOBAL system says that sending is OK. */ /* Returns true if the GLOBAL system says that sending is OK. */
bool sendOK(struct timeval *when); bool sendOK(struct timeval *when);
/* Total # of probes outstanding (active) for all Hosts */ /* Total # of probes outstanding (active) for all Hosts */
@@ -414,6 +414,8 @@ public:
/* Whether we have sent an ICMP timestamp request. */ /* Whether we have sent an ICMP timestamp request. */
bool sent_icmp_ts; bool sent_icmp_ts;
void probeSent(unsigned int nbytes);
/* How long I am currently willing to wait for a probe response /* How long I am currently willing to wait for a probe response
before considering it timed out. Uses the host values from before considering it timed out. Uses the host values from
target if they are available, otherwise from gstats. Results target if they are available, otherwise from gstats. Results
@@ -890,7 +892,11 @@ GroupScanStats::~GroupScanStats() {
delete CSI; delete CSI;
} }
void GroupScanStats::probeSent() { /* Called whenever a probe is sent to any host. Should only be called by
HostScanStats::probeSent. */
void GroupScanStats::probeSent(unsigned int nbytes) {
USI->send_rate_meter.update(nbytes, &USI->now);
/* Find a new scheduling interval for minimum- and maximum-rate sending. /* Find a new scheduling interval for minimum- and maximum-rate sending.
Recall that these have effect only when --min-rate or --max-rate is Recall that these have effect only when --min-rate or --max-rate is
given. */ given. */
@@ -1116,6 +1122,15 @@ HostScanStats::~HostScanStats() {
} }
} }
/* Called whenever a probe is sent to this host. Takes care of updating scan
delay and rate limiting variables. */
void HostScanStats::probeSent(unsigned int nbytes) {
lastprobe_sent = USI->now;
/* Update group variables. */
USI->gstats->probeSent(nbytes);
}
/* How long I am currently willing to wait for a probe response before /* How long I am currently willing to wait for a probe response before
considering it timed out. Uses the host values from target if they considering it timed out. Uses the host values from target if they
are available, otherwise from gstats. Results returned in are available, otherwise from gstats. Results returned in
@@ -2717,15 +2732,14 @@ static UltraProbe *sendConnectScanProbe(UltraScanInfo *USI, HostScanStats *hss,
#if HAVE_IPV6 #if HAVE_IPV6
else sin6->sin6_port = htons(probe->pspec()->pd.tcp.dport); else sin6->sin6_port = htons(probe->pspec()->pd.tcp.dport);
#endif #endif
hss->lastprobe_sent = probe->sent = USI->now; probe->sent = USI->now;
USI->gstats->probeSent(); /* We don't record a byte count for connect probes. */
hss->probeSent(0);
rc = connect(CP->sd, (struct sockaddr *)&sock, socklen); rc = connect(CP->sd, (struct sockaddr *)&sock, socklen);
gettimeofday(&USI->now, NULL); gettimeofday(&USI->now, NULL);
if (rc == -1) connect_errno = socket_errno(); if (rc == -1) connect_errno = socket_errno();
PacketTrace::traceConnect(IPPROTO_TCP, (sockaddr *) &sock, socklen, rc, PacketTrace::traceConnect(IPPROTO_TCP, (sockaddr *) &sock, socklen, rc,
connect_errno, &USI->now); connect_errno, &USI->now);
/* We don't record a byte count for connect probes. */
USI->send_rate_meter.update(0, &USI->now);
/* This counts as probe being sent, so update structures */ /* This counts as probe being sent, so update structures */
hss->probes_outstanding.push_back(probe); hss->probes_outstanding.push_back(probe);
probeI = hss->probes_outstanding.end(); probeI = hss->probes_outstanding.end();
@@ -2816,14 +2830,13 @@ static UltraProbe *sendArpScanProbe(UltraScanInfo *USI, HostScanStats *hss,
*hss->target->SrcMACAddress(), *hss->target->v4sourceip(), *hss->target->SrcMACAddress(), *hss->target->v4sourceip(),
ETH_ADDR_BROADCAST, *hss->target->v4hostip()); ETH_ADDR_BROADCAST, *hss->target->v4hostip());
gettimeofday(&USI->now, NULL); gettimeofday(&USI->now, NULL);
hss->lastprobe_sent = probe->sent = USI->now; probe->sent = USI->now;
USI->gstats->probeSent(); hss->probeSent(sizeof(frame));
if ((rc = eth_send(USI->ethsd, frame, sizeof(frame))) != sizeof(frame)) { if ((rc = eth_send(USI->ethsd, frame, sizeof(frame))) != sizeof(frame)) {
int err = socket_errno(); int err = socket_errno();
error("WARNING: eth_send of ARP packet returned %i rather than expected %d (errno=%i: %s)", rc, (int) sizeof(frame), err, strerror(err)); error("WARNING: eth_send of ARP packet returned %i rather than expected %d (errno=%i: %s)", rc, (int) sizeof(frame), err, strerror(err));
} }
PacketTrace::traceArp(PacketTrace::SENT, (u8 *) frame, sizeof(frame), &USI->now); PacketTrace::traceArp(PacketTrace::SENT, (u8 *) frame, sizeof(frame), &USI->now);
USI->send_rate_meter.update(sizeof(frame), &USI->now);
probe->tryno = tryno; probe->tryno = tryno;
probe->pingseq = pingseq; probe->pingseq = pingseq;
/* First build the probe */ /* First build the probe */
@@ -2899,9 +2912,9 @@ static UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
&packetlen); &packetlen);
if (decoy == o.decoyturn) { if (decoy == o.decoyturn) {
probe->setIP(packet, packetlen, pspec); probe->setIP(packet, packetlen, pspec);
hss->lastprobe_sent = probe->sent = USI->now; probe->sent = USI->now;
} }
USI->gstats->probeSent(); hss->probeSent(packetlen);
send_ip_packet(USI->rawsd, ethptr, packet, packetlen); send_ip_packet(USI->rawsd, ethptr, packet, packetlen);
free(packet); free(packet);
} }
@@ -2915,9 +2928,9 @@ static UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
&packetlen); &packetlen);
if (decoy == o.decoyturn) { if (decoy == o.decoyturn) {
probe->setIP(packet, packetlen, pspec); probe->setIP(packet, packetlen, pspec);
hss->lastprobe_sent = probe->sent = USI->now; probe->sent = USI->now;
} }
USI->gstats->probeSent(); hss->probeSent(packetlen);
send_ip_packet(USI->rawsd, ethptr, packet, packetlen); send_ip_packet(USI->rawsd, ethptr, packet, packetlen);
free(packet); free(packet);
} }
@@ -2971,9 +2984,9 @@ static UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
} }
if (decoy == o.decoyturn) { if (decoy == o.decoyturn) {
probe->setIP(packet, packetlen, pspec); probe->setIP(packet, packetlen, pspec);
hss->lastprobe_sent = probe->sent = USI->now; probe->sent = USI->now;
} }
USI->gstats->probeSent(); hss->probeSent(packetlen);
send_ip_packet(USI->rawsd, ethptr, packet, packetlen); send_ip_packet(USI->rawsd, ethptr, packet, packetlen);
free(packet); free(packet);
} }
@@ -2994,14 +3007,13 @@ static UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
&packetlen); &packetlen);
if (decoy == o.decoyturn) { if (decoy == o.decoyturn) {
probe->setIP(packet, packetlen, pspec); probe->setIP(packet, packetlen, pspec);
hss->lastprobe_sent = probe->sent = USI->now; probe->sent = USI->now;
} }
USI->gstats->probeSent(); hss->probeSent(packetlen);
send_ip_packet(USI->rawsd, ethptr, packet, packetlen); send_ip_packet(USI->rawsd, ethptr, packet, packetlen);
free(packet); free(packet);
} }
} else assert(0); /* TODO: Maybe RPC scan and the like */ } else assert(0); /* TODO: Maybe RPC scan and the like */
USI->send_rate_meter.update(packetlen, &USI->now);
/* Now that the probe has been sent, add it to the Queue for this host */ /* Now that the probe has been sent, add it to the Queue for this host */
hss->probes_outstanding.push_back(probe); hss->probes_outstanding.push_back(probe);
USI->gstats->num_probes_active++; USI->gstats->num_probes_active++;