mirror of
https://github.com/nmap/nmap.git
synced 2025-12-08 13:41:29 +00:00
Normalize whitespace in traceroute.cc.
This commit is contained in:
182
traceroute.cc
182
traceroute.cc
@@ -98,18 +98,18 @@
|
||||
* responsive port to trace to based on the scan results, scan protocol and
|
||||
* various pieces of protocol data.
|
||||
*
|
||||
* Nmap first sends a probe to the target port, from the reply traceroute is able
|
||||
* to infer how many hops away the target is. Nmap starts the trace by sending
|
||||
* a packet with a TTL equal to that of the hop distance guess. If it gets an
|
||||
* ICMP_TTL_EXCEEDED message back it know the hop distance guess was under so
|
||||
* nmap will continue sending probes with incremental TTLs until it receives a
|
||||
* reply from the target host.
|
||||
* Nmap first sends a probe to the target port, from the reply traceroute is
|
||||
* able to infer how many hops away the target is. Nmap starts the trace by
|
||||
* sending a packet with a TTL equal to that of the hop distance guess. If it
|
||||
* gets an ICMP_TTL_EXCEEDED message back it know the hop distance guess was
|
||||
* under so nmap will continue sending probes with incremental TTLs until it
|
||||
* receives a reply from the target host.
|
||||
*
|
||||
* Once a reply from the host is received nmap sets the TTL to one below the
|
||||
* hop guess and continues to send probes with decremental TTLs until it reaches
|
||||
* TTL 0. Then we have a complete trace to the target. If nmap does not get a
|
||||
* hop distance probe reply, the trace TTL starts at one and is incremented
|
||||
* until it hits the target host.
|
||||
* Once a reply from the host is received nmap sets the TTL to one below the hop
|
||||
* guess and continues to send probes with decremental TTLs until it reaches TTL
|
||||
* 0. Then we have a complete trace to the target. If nmap does not get a hop
|
||||
* distance probe reply, the trace TTL starts at one and is incremented until it
|
||||
* hits the target host.
|
||||
*
|
||||
* Forwards/Backwards tracing example
|
||||
* hop guess:20
|
||||
@@ -122,27 +122,27 @@
|
||||
*
|
||||
* The forward/backwards tracing method seems a little convoluted at first but
|
||||
* there is a reason for it. The first host traced in a Target group is
|
||||
* designated as the reference trace. All other traces
|
||||
* (once they have reached their destination host) are compared against the
|
||||
* reference trace. If a match is found the trace is ended prematurely and the
|
||||
* remaining hops are assumed to be the same as the reference trace. This
|
||||
* normally only happens in the lower TTls, which rarely change. On average nmap
|
||||
* sends 5 less packets per host. If nmap is tracing related hosts
|
||||
* (EG. 1.2.3.0/24) it will send a lot less packets. Depending on the network
|
||||
* topology it may only have to send a single packet to each host.
|
||||
* designated as the reference trace. All other traces (once they have reached
|
||||
* their destination host) are compared against the reference trace. If a match
|
||||
* is found the trace is ended prematurely and the remaining hops are assumed to
|
||||
* be the same as the reference trace. This normally only happens in the lower
|
||||
* TTls, which rarely change. On average nmap sends 5 less packets per host. If
|
||||
* nmap is tracing related hosts (EG. 1.2.3.0/24) it will send a lot less
|
||||
* packets. Depending on the network topology it may only have to send a single
|
||||
* packet to each host.
|
||||
*
|
||||
* Nmap's traceroute employs a dynamic timing model similar to nmap's scanning engine
|
||||
* but a little more light weight. It keeps track of sent, received and dropped
|
||||
* packet, then adjusts timing parameters accordingly. The parameters are; number of
|
||||
* retransmissions, delay between each sent packet and the amount of time to wait
|
||||
* for a reply. They are initially based on the timing level (-T0 to -T5).
|
||||
* Traceroute also has to watch out for rate-limiting of ICMP TTL EXCEEDED
|
||||
* messages, sometimes there is nothing we can do and just have to settle with a
|
||||
* timedout hop.
|
||||
* Nmap's traceroute employs a dynamic timing model similar to nmap's scanning
|
||||
* engine but a little more light weight. It keeps track of sent, received and
|
||||
* dropped packet, then adjusts timing parameters accordingly. The parameters
|
||||
* are; number of retransmissions, delay between each sent packet and the amount
|
||||
* of time to wait for a reply. They are initially based on the timing level
|
||||
* (-T0 to -T5). Traceroute also has to watch out for rate-limiting of ICMP TTL
|
||||
* EXCEEDED messages, sometimes there is nothing we can do and just have to
|
||||
* settle with a timedout hop.
|
||||
*
|
||||
* The output from each trace is consolidated to save space, XML logging and debug
|
||||
* mode ignore consolidation. There are two type of consolidation time-out and
|
||||
* reference trace.
|
||||
* The output from each trace is consolidated to save space, XML logging and
|
||||
* debug mode ignore consolidation. There are two type of consolidation time-out
|
||||
* and reference trace.
|
||||
*
|
||||
* Timed out
|
||||
* 23 ... 24 no response
|
||||
@@ -179,11 +179,9 @@ extern NmapOps o;
|
||||
static void enforce_scan_delay (struct timeval *, int);
|
||||
static char *hostStr(u32 ip);
|
||||
|
||||
/* Each target group has a single reference trace. All
|
||||
* other traces are compared to it and if a match is
|
||||
* found the trace is ended prematurely and the
|
||||
* remaining hops are assumed to match the reference
|
||||
* trace */
|
||||
/* Each target group has a single reference trace. All other traces are compared
|
||||
* to it and if a match is found the trace is ended prematurely and the
|
||||
* remaining hops are assumed to match the reference trace */
|
||||
unsigned long commonPath[MAX_TTL + 1];
|
||||
|
||||
Traceroute::Traceroute(const char *device_name, devtype type, const scan_lists * ports) {
|
||||
@@ -199,8 +197,7 @@ Traceroute::Traceroute (const char *device_name, devtype type, const scan_lists
|
||||
if (type == devt_loopback)
|
||||
return;
|
||||
|
||||
/* open various socks to send and read from on windows and
|
||||
* unix */
|
||||
/* open various socks to send and read from on windows and unix */
|
||||
if ((o.sendpref & PACKET_SEND_ETH) && type == devt_ethernet) {
|
||||
/* We'll send ethernet packets with dnet */
|
||||
ethsd = eth_open_cached(device_name);
|
||||
@@ -231,7 +228,7 @@ Traceroute::~Traceroute () {
|
||||
if (hops)
|
||||
free(hops);
|
||||
for (; it != TraceGroups.end(); ++it)
|
||||
delete (it->second);
|
||||
delete it->second;
|
||||
if (ethsd)
|
||||
ethsd = NULL;
|
||||
if (fd != -1)
|
||||
@@ -240,8 +237,9 @@ Traceroute::~Traceroute () {
|
||||
pcap_close(pd);
|
||||
}
|
||||
|
||||
/* get an open or closed port from the portlist. Traceroute requires a positive response,
|
||||
* positive responses are generated by different port states depending on the type of scan */
|
||||
/* get an open or closed port from the portlist. Traceroute requires a positive
|
||||
* response, positive responses are generated by different port states depending
|
||||
* on the type of scan */
|
||||
inline const probespec
|
||||
Traceroute::getTraceProbe(Target *t) {
|
||||
struct probespec probe;
|
||||
@@ -273,8 +271,8 @@ Traceroute::getTraceProbe (Target * t) {
|
||||
return probe;
|
||||
}
|
||||
|
||||
/* finite state machine that reads all incoming packets
|
||||
* and attempts to match them with sent probes */
|
||||
/* finite state machine that reads all incoming packets and attempts to match
|
||||
* them with sent probes */
|
||||
inline bool
|
||||
Traceroute::readTraceResponses() {
|
||||
struct ip *ip = NULL;
|
||||
@@ -394,9 +392,9 @@ Traceroute::readTraceResponses () {
|
||||
tp->timing.adjustTimeouts(&rcvdtime, tg->scanDelay);
|
||||
tp->ipreplysrc.s_addr = ip->ip_src.s_addr;
|
||||
|
||||
/* check to see if this hop is in the referece trace. If
|
||||
* it is then we stop tracing this target and assume
|
||||
* all subsequent hops match the common path */
|
||||
/* check to see if this hop is in the referece trace. If it is then we
|
||||
* stop tracing this target and assume all subsequent hops match the
|
||||
* common path */
|
||||
if (commonPath[tp->ttl] == tp->ipreplysrc.s_addr &&
|
||||
tp->ttl > 1 && tg->gotReply && tg->getState() != G_FINISH) {
|
||||
tg->setState(G_FINISH);
|
||||
@@ -425,16 +423,16 @@ Traceroute::readTraceResponses () {
|
||||
else
|
||||
break;
|
||||
|
||||
/* already got the tcp packet for this group,
|
||||
* could be a left over rst or syn-ack */
|
||||
/* already got the tcp packet for this group, could be a left over rst
|
||||
* or syn-ack */
|
||||
if (tp->ipreplysrc.s_addr)
|
||||
break;
|
||||
|
||||
/* We have reached the destination host and the
|
||||
* trace can stop for this target */
|
||||
/* We have reached the destination host and the trace can stop for this
|
||||
* target */
|
||||
if ((tcp->th_flags & TH_RST) == TH_RST
|
||||
|| (tcp->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) {
|
||||
/* We might have got a late reply */
|
||||
/* We might have gotten a late reply */
|
||||
if (tp->timing.getState() == P_TIMEDOUT)
|
||||
tp->timing.setState(P_OK);
|
||||
else
|
||||
@@ -470,7 +468,7 @@ Traceroute::readTraceResponses () {
|
||||
if (tp->ipreplysrc.s_addr)
|
||||
break;
|
||||
|
||||
/* We might have got a late reply */
|
||||
/* We might have gotten a late reply */
|
||||
if (tp->timing.getState() == P_TIMEDOUT)
|
||||
tp->timing.setState(P_OK);
|
||||
else
|
||||
@@ -503,12 +501,12 @@ Traceroute::readTraceResponses () {
|
||||
else
|
||||
break;
|
||||
|
||||
/* already got the sctp packet for this group,
|
||||
* could be a left over abort or init-ack */
|
||||
/* already got the sctp packet for this group, could be a left over
|
||||
* abort or init-ack */
|
||||
if (tp->ipreplysrc.s_addr)
|
||||
break;
|
||||
|
||||
/* We might have got a late reply */
|
||||
/* We might have gotten a late reply */
|
||||
if (tp->timing.getState() == P_TIMEDOUT)
|
||||
tp->timing.setState(P_OK);
|
||||
else
|
||||
@@ -542,9 +540,9 @@ Traceroute::sendTTLProbes (vector < Target * >&Targets, vector < Target * >&vali
|
||||
u16 sport = 0;
|
||||
TraceProbe *tp;
|
||||
TraceGroup *tg = NULL;
|
||||
vector < Target * >::iterator it = Targets.begin ();
|
||||
vector < Target * >::iterator it;
|
||||
|
||||
for (; it != Targets.end (); ++it) {
|
||||
for (Targets.begin(); it != Targets.end(); ++it) {
|
||||
t = *it;
|
||||
|
||||
/* No point in tracing directly connected nodes */
|
||||
@@ -561,9 +559,9 @@ Traceroute::sendTTLProbes (vector < Target * >&Targets, vector < Target * >&vali
|
||||
probe = getTraceProbe(t);
|
||||
assert(probe.type != PS_NONE);
|
||||
|
||||
/* start off with a random source port and increment
|
||||
* it for each probes sent. The source port is the
|
||||
* distinguishing value used to identify each probe */
|
||||
/* start off with a random source port and increment it for each probes
|
||||
* sent. The source port is the distinguishing value used to identify
|
||||
* each probe */
|
||||
sport = get_random_u16();
|
||||
tg = new TraceGroup(t->v4hostip()->s_addr, sport, probe);
|
||||
tg->src_mac_addr = t->SrcMACAddress();
|
||||
@@ -750,9 +748,8 @@ Traceroute::trace (vector < Target * >&Targets) {
|
||||
o.current_scantype = TRACEROUTE;
|
||||
}
|
||||
|
||||
/* guess hop distance to targets. valid_targets
|
||||
* is populated with all Target object that are
|
||||
* legitimate to trace to */
|
||||
/* guess hop distance to targets. valid_targets is populated with all Target
|
||||
* object that are legitimate to trace to */
|
||||
sendTTLProbes(Targets, valid_targets);
|
||||
|
||||
if (!valid_targets.size())
|
||||
@@ -765,10 +762,9 @@ Traceroute::trace (vector < Target * >&Targets) {
|
||||
t = *targ;
|
||||
tg = TraceGroups[t->v4host().s_addr];
|
||||
|
||||
/* Check for any timedout probes and
|
||||
* retransmit them. If too many probes
|
||||
* are outstanding we wait for replies or
|
||||
* timeouts before sending any more */
|
||||
/* Check for any timedout probes and retransmit them. If too many
|
||||
* probes are outstanding we wait for replies or timeouts before
|
||||
* sending any more */
|
||||
if (tg->getRemaining()) {
|
||||
tg->retransmissions(retrans_probes);
|
||||
for (pcount = 0; pcount < retrans_probes.size(); pcount++)
|
||||
@@ -806,18 +802,15 @@ Traceroute::trace (vector < Target * >&Targets) {
|
||||
SPM->printStats(MIN((double) total_complete / total_size, 0.99), NULL);
|
||||
}
|
||||
SPM->endTask(NULL, NULL);
|
||||
delete (SPM);
|
||||
delete SPM;
|
||||
}
|
||||
|
||||
/* Resolves traceroute hops through nmaps
|
||||
* parallel caching rdns infrastructure.
|
||||
* The <hops> class variable should be NULL and needs
|
||||
* freeing after the hostnames are finished
|
||||
* with
|
||||
/* Resolves traceroute hops through Nmap's parallel caching rdns infrastructure.
|
||||
* The <hops> class variable should be NULL and needs freeing after the
|
||||
* hostnames are finished with.
|
||||
*
|
||||
* N.B TraceProbes contain pointers into the Target
|
||||
* structure, if it is free'ed prematurely something
|
||||
* nasty will happen */
|
||||
* N.B TraceProbes contain pointers into the Target structure, if it is free'ed
|
||||
* prematurely something nasty will happen. */
|
||||
void Traceroute::resolveHops() {
|
||||
map<u32, TraceGroup *>::iterator tg_iter;
|
||||
map<u16, TraceProbe *>::iterator tp_iter;
|
||||
@@ -969,9 +962,9 @@ Traceroute::outputTarget (Target * t) {
|
||||
if (!last_consolidation) {
|
||||
last_consolidation = true;
|
||||
Tbl->addItemFormatted(row_count, HOP_COL, false, "%d", tp->ttl);
|
||||
}
|
||||
else if(tg->getState() == G_DEAD_TTL && ttl_count == tg->hopDistance)
|
||||
} 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) {
|
||||
Tbl->addItem(row_count, HOST_COL, false, "no response", 11);
|
||||
@@ -987,16 +980,16 @@ Traceroute::outputTarget (Target * t) {
|
||||
|
||||
/* normal hop output (rtt, ip and hostname) */
|
||||
if (!tp->timing.consolidated && !last_consolidation) {
|
||||
Snprintf(timebuf, sizeof(timebuf), "%.2f ms", (float)
|
||||
TIMEVAL_SUBTRACT(tp->timing.recvTime, tp->timing.sendTime) / 1000);
|
||||
Snprintf(timebuf, sizeof(timebuf), "%.2f ms",
|
||||
(float) TIMEVAL_SUBTRACT(tp->timing.recvTime, tp->timing.sendTime) / 1000);
|
||||
Tbl->addItemFormatted(row_count, HOP_COL, false, "%d", tp->ttl);
|
||||
if (tp->timing.getState() != P_TIMEDOUT) {
|
||||
Tbl->addItem(row_count, RTT_COL, true, timebuf);
|
||||
Tbl->addItem(row_count, HOST_COL, true, tp->nameIP());
|
||||
} else
|
||||
} else {
|
||||
Tbl->addItemFormatted(row_count, RTT_COL, false, "...");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Traceroute header and footer */
|
||||
@@ -1058,17 +1051,16 @@ Traceroute::outputXMLTrace(TraceGroup * tg) {
|
||||
log_write(LOG_XML, "/>\n");
|
||||
}
|
||||
|
||||
/* display normal traceroute nodes. Consolidation based on the
|
||||
* common path is not performed */
|
||||
/* display normal traceroute nodes. Consolidation based on the common path
|
||||
* is not performed */
|
||||
for (it = tg->TraceProbes.begin() ;it != tg->TraceProbes.end(); it++) {
|
||||
tp = it->second;
|
||||
|
||||
if (tp->probeType() == PROBE_TTL)
|
||||
break;
|
||||
|
||||
if(tp->timing.getState() == P_TIMEDOUT) {
|
||||
if (tp->timing.getState() == P_TIMEDOUT)
|
||||
continue;
|
||||
}
|
||||
|
||||
timediff = TIMEVAL_SUBTRACT(tp->timing.recvTime, tp->timing.sendTime);
|
||||
|
||||
@@ -1109,9 +1101,9 @@ TraceGroup::TraceGroup (u32 dip, u16 sport, struct probespec& probe) {
|
||||
}
|
||||
|
||||
TraceGroup::~TraceGroup() {
|
||||
map < u16, TraceProbe * >::const_iterator it = TraceProbes.begin ();
|
||||
for (; it != TraceProbes.end (); ++it)
|
||||
delete (it->second);
|
||||
map < u16, TraceProbe * >::const_iterator it;
|
||||
for (it = TraceProbes.begin(); it != TraceProbes.end(); ++it)
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
/* go through all probes in a group and check if any have timedout.
|
||||
@@ -1322,8 +1314,8 @@ TimeInfo::adjustTimeouts (struct timeval *received, u16 scan_delay) {
|
||||
it was sent. So I will allow small negative RTT numbers */
|
||||
if (delta < 0 && delta > -50000) {
|
||||
if (o.debugging > 2)
|
||||
log_write (LOG_STDOUT, "Small negative delta - adjusting from %lius to %dus\n", delta,
|
||||
10000);
|
||||
log_write(LOG_STDOUT, "Small negative delta - adjusting from %lius to %dus\n",
|
||||
delta, 10000);
|
||||
delta = 10000;
|
||||
}
|
||||
|
||||
@@ -1336,9 +1328,7 @@ TimeInfo::adjustTimeouts (struct timeval *received, u16 scan_delay) {
|
||||
} else {
|
||||
if (delta >= 8000000 || delta < 0) {
|
||||
if (o.verbose)
|
||||
error
|
||||
("adjust_timeout: packet supposedly had rtt of %lu microseconds. Ignoring time.",
|
||||
delta);
|
||||
error("adjust_timeout: packet supposedly had rtt of %lu microseconds. Ignoring time.", delta);
|
||||
return;
|
||||
}
|
||||
delta -= to.srtt;
|
||||
@@ -1372,9 +1362,9 @@ TimeInfo::adjustTimeouts (struct timeval *received, u16 scan_delay) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Sleeps if necessary to ensure that it isn't called twice within less
|
||||
* time than send_delay. If it is passed a non-null tv, the POST-SLEEP
|
||||
* time is recorded in it */
|
||||
/* Sleeps if necessary to ensure that it isn't called twice within less time
|
||||
* than send_delay. If it is passed a non-null tv, the POST-SLEEP time is
|
||||
* recorded in it */
|
||||
static void
|
||||
enforce_scan_delay(struct timeval *tv, int scan_delay) {
|
||||
static int init = -1;
|
||||
|
||||
Reference in New Issue
Block a user