diff --git a/CHANGELOG b/CHANGELOG index b3c553872..21276d8b2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -17,6 +17,10 @@ o Fixed a Traceroute bug relating to scanning through the localhost interface on Windows (which previously caused a crash). Thanks to Alan Jones for the report and Eddie Bell for the fix. +o Fixed a traceroute bug related to tracing between interfaces of a + multi-homed host. Thanks to David Fifield for reporting the problem + and Eddie Bell for the fix. + o Updated IANA assignment IP list for random IP (-iR) generation. [Kris] 4.21ALPHA4 diff --git a/traceroute.cc b/traceroute.cc index a84dcf9b0..8f346b29c 100644 --- a/traceroute.cc +++ b/traceroute.cc @@ -535,7 +535,7 @@ Traceroute::readTraceResponses () { /* The probe was the reply from a ttl guess */ if (tp->probeType () == PROBE_TTL) { tg->setHopDistance (get_initial_ttl_guess (ip->ip_ttl), ip->ip_ttl); - tg->start_ttl = tg->ttl = --tg->hopDistance; + tg->start_ttl = tg->ttl = tg->hopDistance; } else { tg->gotReply = true; if (tg->start_ttl < tg->ttl) @@ -574,7 +574,7 @@ Traceroute::readTraceResponses () { if (tp->probeType () == PROBE_TTL) { tg->setHopDistance (get_initial_ttl_guess (ip->ip_ttl), ip->ip_ttl); tg->setState (G_OK); - tg->start_ttl = tg->ttl = --tg->hopDistance; + tg->start_ttl = tg->ttl = tg->hopDistance; } else { tg->gotReply = true; if (tg->start_ttl < tg->ttl) @@ -714,6 +714,11 @@ Traceroute::sendProbe (TraceProbe * tp) { if (tg->TraceProbes.find (tp->sport) == tg->TraceProbes.end ()) { tg->nextTTL (); + + if (tg->ttl > MAX_TTL) { + tg->setState (G_ALIVE_TTL); + return -1; + } if (!tg->ttl || tg->gotReply && tg->noDistProbe) { tg->setState (G_FINISH); return 0; @@ -727,8 +732,6 @@ Traceroute::sendProbe (TraceProbe * tp) { tp->timing.setState (P_OK); } - if (tg->TraceProbes.size () >= MAX_TTL) - tg->setState (G_TTL); tg->TraceProbes[tp->sport] = tp; for (decoy = 0; decoy < o.numdecoys; decoy++) { @@ -1021,6 +1024,8 @@ Traceroute::outputTarget (Target * t) { last_consolidation = true; Tbl->addItemFormatted(row_count, HOP_COL, false, "%d", tp->ttl); } + else if(tg->getState() == G_DEAD_TTL && ttl_count == tg->hopDistance) + Tbl->addItem (row_count, RTT_COL, false, "... 50"); row_count--; } else if(!tp->timing.consolidated && last_consolidation) { if(consol_count>1) @@ -1042,12 +1047,10 @@ Traceroute::outputTarget (Target * t) { Tbl->addItem (row_count, HOST_COL, true, tp->nameIP ()); } else Tbl->addItemFormatted (row_count, RTT_COL, false, "..."); - } } - if(tg->getState() == G_TTL) - Tbl->addItem (row_count, RTT_COL, false, "... 50"); + } /* Traceroute header and footer */ proto = nmap_getprotbynum(htons(tg->proto)); @@ -1057,7 +1060,7 @@ Traceroute::outputTarget (Target * t) { log_write(LOG_PLAIN, "\nTRACEROUTE (using port %d/%s)\n", tg->dport, proto2ascii(tg->proto)); log_write (LOG_PLAIN, "%s", Tbl->printableTable(NULL)); - if(tg->getState() == G_TTL) + if(G_TTL(tg->getState())) log_write(LOG_PLAIN, "! maximum TTL reached (50)\n"); else if(!tg->gotReply || (tp && (tp->ipreplysrc.s_addr != tg->ipdst))) log_write(LOG_PLAIN, "! destination not reached (%s)\n", inet_ntoa(tp->ipdst)); @@ -1120,7 +1123,7 @@ Traceroute::outputXMLTrace(TraceGroup * tg) { log_write(LOG_XML, "/>\n"); } - if(tg->getState() == G_TTL) + if(G_TTL(tg->getState())) log_write(LOG_XML, "\n"); else if(!tg->gotReply || (tp && (tp->ipreplysrc.s_addr != tg->ipdst))) log_write(LOG_XML, "\n", inet_ntoa(tp->ipdst)); @@ -1183,6 +1186,9 @@ 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) { @@ -1236,6 +1242,10 @@ u8 TraceGroup::tableSize () { last_probe = it->second; } + /* reached max ttl */ + if(G_TTL(getState())) + return size; + /* no consolidation in debug mode */ if(o.debugging) return size + pathCount; @@ -1299,22 +1309,23 @@ TraceGroup::setHopDistance (u8 hop_distance, u8 ttl) { this->hopDistance = hop_distance; - if (hopDistance && ttl) { - this->hopDistance -= ttl; - /* Hop distance seems too small */ - if (this->hopDistance <= 2) - this->hopDistance = hop_distance; - } + if(o.debugging) + log_write(LOG_STDOUT, "%s: hop distance parameters -> hg:%d ttl:%d\n", IPStr(), hop_distance, ttl); - if (!this->hopDistance && ttl) + if (this->hopDistance && ttl) + this->hopDistance -= ttl; + else this->hopDistance = ttl; - if (this->hopDistance >= MAX_TTL - 1) - this->hopDistance = MAX_TTL - 1; + /* guess is too big */ + if (this->hopDistance >= MAX_TTL) + this->hopDistance = MAX_TTL- 2; + /* guess is too small */ + else if(this->hopDistance == 0) + this->hopDistance = 1; if (o.verbose) log_write (LOG_STDOUT, "%s: guessing hop distance at %d\n", IPStr (), this->hopDistance); - return this->hopDistance; } diff --git a/traceroute.h b/traceroute.h index 59d4b8849..df8d0170f 100644 --- a/traceroute.h +++ b/traceroute.h @@ -112,8 +112,11 @@ /* Group states */ #define G_OK P_OK -#define G_TTL 3 /* TTL has reached MAX_TTL */ -#define G_FINISH 4 /* tracing has complete successfully */ +#define G_DEAD_TTL 3 /* TTL has reached maximum value */ +#define G_ALIVE_TTL 4 /* TTL has reached maximum value */ +#define G_FINISH 5 /* tracing has complete successfully */ + +#define G_TTL(x) (x == G_ALIVE_TTL || x == G_DEAD_TTL) #define MAX_TTL 50