1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-27 08:39:02 +00:00

Use ICMP echo for traceroute if no other responsive probe is known. This

can happen with -PN against a filtered host or with -PN -sP against any
host.

This works as expected when the remote host actually responds to the
ping probes, but takes a long time when the remote host ignores it. Take
this for example:

nmap -PN -sP --traceroute www.microsoft.com -n
TRACEROUTE (using proto 1/icmp)
HOP RTT   ADDRESS
1   0.77  192.168.0.1
2   38.76 206.81.73.81
3   38.65 206.81.73.82
4   39.28 66.54.149.185
5   39.73 63.211.250.17
6   39.15 4.68.107.190
7   40.05 4.69.132.37
8   59.33 4.69.132.106
9   54.55 4.69.145.208
10  ...
11  ...
    [Lots more lines]
49  ...
50  ...
! maximum TTL reached (50)
Nmap done: 1 IP address (1 host up) scanned in 2201.79 seconds

The traceroute can't stop, as it normally does, when it gets a response
from the target because no such response is forthcoming. So it keeps
going until it hits its own limit. The same trace against www.google.com
takes only about 30 seconds.
This commit is contained in:
david
2009-07-29 16:06:03 +00:00
parent 7a8942eff2
commit 47bbcc165f

View File

@@ -247,10 +247,17 @@ Traceroute::getTraceProbe (Target * t) {
struct probespec probe;
probe = t->pingprobe;
/* If this is an IP protocol probe, fill in some fields for some common
protocols. We cheat and store them in the TCP-, UDP-, SCTP- and
ICMP-specific fields. Traceroute::sendProbe checks for them there. */
if (probe.type == PS_PROTO) {
if (probe.type == PS_NONE) {
/* No responsive probe known? The user probably skipped both ping and
port scan. Guess ICMP echo as the most likely to get a response. */
probe.type = PS_ICMP;
probe.proto = IPPROTO_ICMP;
probe.pd.icmp.type = ICMP_ECHO;
probe.pd.icmp.code = 0;
} else if (probe.type == PS_PROTO) {
/* If this is an IP protocol probe, fill in some fields for some common
protocols. We cheat and store them in the TCP-, UDP-, SCTP- and
ICMP-specific fields. Traceroute::sendProbe checks for them there. */
if (probe.proto == IPPROTO_TCP) {
probe.pd.tcp.flags = TH_ACK;
probe.pd.tcp.dport = get_random_u16();
@@ -552,12 +559,7 @@ Traceroute::sendTTLProbes (vector < Target * >&Targets, vector < Target * >&vali
/* Determine active port to probe */
probe = getTraceProbe (t);
if (probe.type == PS_NONE) {
if (o.verbose > 1)
log_write (LOG_STDOUT, "%s: no responsive probes\n",
t->targetipstr ());
continue;
}
assert(probe.type != PS_NONE);
/* start off with a random source port and increment
* it for each probes sent. The source port is the
@@ -1135,9 +1137,6 @@ TraceGroup::retransmissions (vector < TraceProbe * >&retrans) {
it->second->timing.setState (P_TIMEDOUT);
decRemaining ();
if(it->second->ttl > MAX_TTL)
setState(G_DEAD_TTL);
if ((++consecTimeouts) > 5 && maxRetransmissions > 2)
maxRetransmissions = 2;
if (it->second->probeType () == PROBE_TTL) {
@@ -1145,6 +1144,8 @@ TraceGroup::retransmissions (vector < TraceProbe * >&retrans) {
noDistProbe = true;
if (o.verbose)
log_write (LOG_STDOUT, "%s: no reply to our hop distance probe!\n", IPStr ());
} else if (it->second->ttl > MAX_TTL) {
setState(G_DEAD_TTL);
}
} else {
droppedPackets++;