1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-08 21:51:28 +00:00

Normalize whitespace in traceroute.cc.

This commit is contained in:
david
2009-08-19 20:14:54 +00:00
parent fec2cc40d0
commit 43acb0eab8

View File

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