1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-31 20:09:02 +00:00

Remove the allow_ipid_match checking from scan_engine.cc. This was a

test that was applied to packets returned in ICMP error messages.
Because some operating systems modify the IP ID outside of Nmap's
control, the apply_ipid_match function had a built-in heuristic whereby
it would deactivate itself (always return true) if this seemed to be
happening. What this meant in practice was that every time a successful
match was made, a counter was incremented, and if the ratio of
successful matches to successful matches was over 80%, IP ID matching
was enforced.

The matching and heuristic could cause relevant probes to be dropped in
some cases. See http://seclists.org/nmap-dev/2009/q2/665 for an example
of this and discussion. The IP ID match was always done in combination
with other tests; so even without it we are still dealing with a
relevant probe. The IP ID distinction could at best distinguish between
retransmissions of the same probe, and it was not necessary for that in
every case, such as with most TCP probes where we can use the SEQ field.
I thought this small benefit was not worth the risk of potentially
losing replies that we care about.
This commit is contained in:
david
2009-11-05 02:19:19 +00:00
parent 2db9068013
commit b0976983bc

View File

@@ -3896,41 +3896,6 @@ static bool do_one_select_round(UltraScanInfo *USI, struct timeval *stime) {
return numGoodSD;
}
/* ICMP error messages generally return the IP header they were sent
with. That provides the opportunity to look at the IPID to
determine which probe the packet matches up with. Unfortunately,
this doesn't always work. Some systems screw up the IPID in the
process of sending, and remote systems can screw it up as well.
This function is a "soft" match, that returns true if hey really do
match, or if matching seems to be broken for one reason or
another. You can send in HBO or NBO, just as
long as the two values are in the same byte order. */
static bool allow_ipid_match(u16 ipid_sent, u16 ipid_rcvd) {
static int numvalid = 0;
static int numbogus = 0;
/* TODO: I should check if this applies to more recent Solaris releases */
/* These systems seem to hose sent IPID */
#if defined(SOLARIS) || defined(SUNOS) || defined(IRIX) || defined(HPUX)
return true;
#endif
if (ipid_sent == ipid_rcvd) {
numvalid++;
return true;
} else numbogus++;
if (numbogus >= 2 && numvalid == 0)
return true; /* Test does not seem to be working */
/* This test is because sometimes a valid will come by luck */
if (numbogus / (numbogus + numvalid) > .8)
return true;
return false;
}
/* Tries to get one *good* (finishes a probe) ARP response with pcap
by the (absolute) time given in stime. Even if stime is now, try
an ultra-quick pcap read just in case. Returns true if a "good"
@@ -4278,10 +4243,6 @@ static bool get_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
assert(0);
}
/* Checking IPID is a little more complex because you can't always count on it */
if (!allow_ipid_match(probe->ipid(), ntohs(ip2->ip_id)))
continue;
if (icmp->icmp_type == 3) {
switch(icmp->icmp_code) {
case 0: /* Network unreachable */
@@ -4625,9 +4586,6 @@ static int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
assert(0);
}
if (!allow_ipid_match(probe->ipid(), ntohs(ip2->ip_id)))
continue;
/* If we made it this far, we found it. We don't yet know if it's
going to change a host state (goodone) or not. */
break;