Like ultra_scan, OS scan has global and host-based congestion control
mechanisms like those in TCP. Part of global congestion control is
keeping track of how many probes are outstanding in the network; OS scan
keeps the number in a member variable called num_probes_active.
num_probes_active is meant to be the sum of the sizes of each host's
list of outstanding probes. It was correctly being decremented whenever
a probe was removed from an active list, but it was never incremented.
num_probes_active was always zero or negative, and therefore never
exceeded the global congestion window. This almost completely disabled
global congestion control.
With this fix OS scan will send a maximum of ten probes immediately at
the beginning of the scan. Previously it was limited only by the number
of hosts being scanned (20 or 30).
This brings in four discrete changes:
1. The widening of ranges for T test expressions in nmap-os-db. Any expressions
that were not already ranges were expanded to cover plus and minus five of
their original values.
2. The normalization of TG expressions in nmap-os-db. Nmap is only capable of
outputting 0x20, 0x40, 0x80, and 0xFF for a TG value, but many fingerprints
had values other than these. They have all been rounded to their nearest
likely value.
3. The elimination of the U1.TOS and IE.TOSI tests (both having to do with type
of service). This was effected by setting their MatchPoints to 0.
4. A cleanup and refactoring of OS fingerprint output code. This should not
have any impact on output, except in one case: when debugging is non-zero or
verbosity is greater than one, and at least one perfect match was found,
Nmap used to print "OS Fingerprint:" before the fingerprint. Now it prints
"TCP/IP fingerprint:" in this case like in all the others.
packet is OK from the get-go rather than running basic checks of it's own.
In a nutshell this patch checks to make sure:
1) there is enough room for an IP header in the amount of bytes read
2) the IP version number is correct
3) the IP length fields are at least as big as the standard header
4) the IP packet received isn't a fragment, or is the initial fragment
5) that next level headers seem reasonable
For TCP, this checks that there is enough room for the header in the number
of bytes read, and that any option lengths are correct. The options checked
are MSS, WScale, SackOK, Sack, and Timestamp.
This also fixes a bug I discovered while testing. Since the Ethernet CRC
(and other datalink-layer data) could be read and counted, it was being
returned that there was more IP packet than there really was. This didn't
cause an overrun of the buffer or anything, just that garbage data could have
easily been read instead of real packet data. Now, if validity is checked for
and the number of total bytes read is larger than the IP's length, the length
is set to the IP header's total length field.
This seems to work great after doing what testing I could. It's been out on
nmap-dev for a couple of weeks without any bad reports (none at all for that
matter). I reviewed this patch again before committing and it looks good as
well.