diff --git a/traceroute.cc b/traceroute.cc index 0e7b05aa4..91f4501af 100644 --- a/traceroute.cc +++ b/traceroute.cc @@ -25,7 +25,7 @@ * nmap-os-db or nmap-service-probes. * * o Executes Nmap and parses the results (as opposed to typical shell or * * execution-menu apps, which simply display raw Nmap output and so are * - * not derivative works.) * + * not derivative works.) * * o Integrates/includes/aggregates Nmap into a proprietary executable * * installer, such as those produced by InstallShield. * * o Links to a library or executes a program that does any of the above * @@ -95,21 +95,21 @@ * http://en.wikipedia.org/wiki/Traceroute * * Traceroute takes in a list of scanned targets and determines a valid - * 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. * - * 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 @@ -120,29 +120,29 @@ * .... * send:1 --> ICMP_TTL_EXCEEDED * - * 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 - * 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. + * 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. * - * 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. + * 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. * * Timed out * 23 ... 24 no response @@ -151,7 +151,7 @@ * Hops 1-10 are the same as for X.X.X.X * * Traceroute does not work with connect scans or idle scans and has trouble - * with ICMP_TIMESTAMP and ICMP_ADDRESSMASK scans because so many host filter + * with ICMP_TIMESTAMP and ICMP_ADDRESSMASK scans because so many host filter * them out. The quickest seems to be SYN scan. * * Bugs @@ -177,16 +177,14 @@ using namespace std; extern NmapOps o; 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 - * 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) { +Traceroute::Traceroute(const char *device_name, devtype type, const scan_lists * ports) { fd = -1; scanlists = ports; ethsd = NULL; @@ -196,54 +194,54 @@ Traceroute::Traceroute (const char *device_name, devtype type, const scan_lists memset(&ref_ipaddr, '\0', sizeof(struct in_addr)); cp_flag = 0; - if(type == devt_loopback) + 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); + ethsd = eth_open_cached(device_name); if (ethsd == NULL) - fatal ("dnet: Failed to open device %s", device_name); + fatal("dnet: Failed to open device %s", device_name); } else { #ifdef WIN32 win32_warn_raw_sockets(device_name); #endif - if ((fd = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) - pfatal ("Traceroute: socket troubles"); - broadcast_socket (fd); + if ((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) + pfatal("Traceroute: socket troubles"); + broadcast_socket(fd); #ifndef WIN32 - sethdrinclude (fd); + sethdrinclude(fd); #endif } /* rely on each group using the same device */ - pd = my_pcap_open_live (device_name, 100, o.spoofsource ? 1 : 0, 2); + pd = my_pcap_open_live(device_name, 100, o.spoofsource ? 1 : 0, 2); - memset (commonPath, 0, sizeof (commonPath)); + memset(commonPath, 0, sizeof(commonPath)); } -Traceroute::~Traceroute () { - map < u32, TraceGroup * >::iterator it = TraceGroups.begin (); - while ((--total_size) >= 0) +Traceroute::~Traceroute() { + map < u32, TraceGroup * >::iterator it = TraceGroups.begin(); + while ((--total_size) >= 0) delete(hops[total_size]); - if(hops) + if (hops) free(hops); - for (; it != TraceGroups.end (); ++it) - delete (it->second); + for (; it != TraceGroups.end(); ++it) + delete it->second; if (ethsd) ethsd = NULL; if (fd != -1) - close (fd); - if(pd) - pcap_close (pd); + close(fd); + if (pd) + 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) { +Traceroute::getTraceProbe(Target *t) { struct probespec probe; probe = t->pingprobe; @@ -273,10 +271,10 @@ 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 () { +Traceroute::readTraceResponses() { struct ip *ip = NULL; struct ip *ip2 = NULL; struct icmp *icmp = NULL; @@ -293,10 +291,10 @@ Traceroute::readTraceResponses () { u32 ipaddr; /* Got to look into readip_pcap's timeout value, perhaps make it dynamic */ - ip = (struct ip *) readip_pcap (pd, &bytes, 10000, &rcvdtime, &linkhdr, true); + ip = (struct ip *) readip_pcap(pd, &bytes, 10000, &rcvdtime, &linkhdr, true); if (ip == NULL) - return finished (); + return finished(); switch (ip->ip_p) { case IPPROTO_ICMP: @@ -315,12 +313,12 @@ Traceroute::readTraceResponses () { tcp = (struct tcp_hdr *) ((u8 *) ip2 + ip2->ip_hl * 4); if (ntohs(ip2->ip_len) - (ip2->ip_hl * 4) < 2) break; - sport = ntohs (tcp->th_sport); + sport = ntohs(tcp->th_sport); } else if (ip2->ip_p == IPPROTO_UDP) { udp = (struct udp_hdr *) ((u8 *) ip2 + ip2->ip_hl * 4); if (ntohs(ip2->ip_len) - (ip2->ip_hl * 4) < 2) break; - sport = ntohs (udp->uh_sport); + sport = ntohs(udp->uh_sport); } else if (ip2->ip_p == IPPROTO_SCTP) { sctp = (struct sctp_hdr *) ((u8 *) ip2 + ip2->ip_hl * 4); if (ntohs(ip2->ip_len) - (ip2->ip_hl * 4) < 2) @@ -337,12 +335,12 @@ Traceroute::readTraceResponses () { ipaddr = ip2->ip_dst.s_addr; } - if (TraceGroups.find (ipaddr) != TraceGroups.end ()) + if (TraceGroups.find(ipaddr) != TraceGroups.end()) tg = TraceGroups[ipaddr]; else break; - if (tg->TraceProbes.find (sport) != tg->TraceProbes.end ()) + if (tg->TraceProbes.find(sport) != tg->TraceProbes.end()) tp = tg->TraceProbes[sport]; else break; @@ -361,8 +359,8 @@ Traceroute::readTraceResponses () { case ICMP_NET_ANO: case ICMP_HOST_ANO: case ICMP_PKT_FILTERED: - if (tp->probeType () == PROBE_TTL) { - tg->setHopDistance (o.ttl - ip2->ip_ttl, 0); + if (tp->probeType() == PROBE_TTL) { + tg->setHopDistance(o.ttl - ip2->ip_ttl, 0); tg->start_ttl = tg->ttl = tg->hopDistance; } else { tg->gotReply = true; @@ -374,8 +372,8 @@ Traceroute::readTraceResponses () { /* icmp ping scan replies */ else if (tg->probe.proto == IPPROTO_ICMP && (icmp->icmp_type == ICMP_ECHOREPLY || icmp->icmp_type == ICMP_ADDRESSREPLY || icmp->icmp_type == ICMP_TIMESTAMPREPLY)) { - if (tp->probeType () == PROBE_TTL) { - tg->setHopDistance (get_initial_ttl_guess (ip->ip_ttl), ip->ip_ttl); + if (tp->probeType() == PROBE_TTL) { + tg->setHopDistance(get_initial_ttl_guess(ip->ip_ttl), ip->ip_ttl); tg->start_ttl = tg->ttl = tg->hopDistance; } else { tg->gotReply = true; @@ -384,68 +382,68 @@ Traceroute::readTraceResponses () { } } - if (tp->timing.getState () == P_TIMEDOUT) - tp->timing.setState (P_OK); + if (tp->timing.getState() == P_TIMEDOUT) + tp->timing.setState(P_OK); else - tg->decRemaining (); + tg->decRemaining(); tg->repliedPackets++; tg->consecTimeouts = 0; - tp->timing.adjustTimeouts (&rcvdtime, tg->scanDelay); + 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); + tp->ttl > 1 && tg->gotReply && tg->getState() != G_FINISH) { + tg->setState(G_FINISH); tg->consolidation_start = tp->ttl+1; - cp_flag = 1; + cp_flag = 1; break; } else if (commonPath[tp->ttl] == 0) { commonPath[tp->ttl] = tp->ipreplysrc.s_addr; - /* remember which host is the reference trace */ - if(!cp_flag) { + /* remember which host is the reference trace */ + if (!cp_flag) { ref_ipaddr.s_addr = tg->ipdst; cp_flag = 1; - } - } + } + } break; case IPPROTO_TCP: tcp = (struct tcp_hdr *) ((char *) ip + 4 * ip->ip_hl); - if (TraceGroups.find (ip->ip_src.s_addr) != TraceGroups.end ()) + if (TraceGroups.find(ip->ip_src.s_addr) != TraceGroups.end()) tg = TraceGroups[ip->ip_src.s_addr]; else break; - if (tg->TraceProbes.find (ntohs (tcp->th_dport)) != tg->TraceProbes.end ()) - tp = tg->TraceProbes[ntohs (tcp->th_dport)]; + if (tg->TraceProbes.find(ntohs(tcp->th_dport)) != tg->TraceProbes.end()) + tp = tg->TraceProbes[ntohs(tcp->th_dport)]; 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 */ - if (tp->timing.getState () == P_TIMEDOUT) - tp->timing.setState (P_OK); + /* We might have gotten a late reply */ + if (tp->timing.getState() == P_TIMEDOUT) + tp->timing.setState(P_OK); else - tg->decRemaining (); + tg->decRemaining(); tp->timing.recvTime = rcvdtime; tp->ipreplysrc = ip->ip_src; tg->repliedPackets++; /* 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); + if (tp->probeType() == PROBE_TTL) { + tg->setHopDistance(get_initial_ttl_guess(ip->ip_ttl), ip->ip_ttl); tg->start_ttl = tg->ttl = tg->hopDistance; } else { tg->gotReply = true; @@ -457,32 +455,32 @@ Traceroute::readTraceResponses () { case IPPROTO_UDP: udp = (udp_hdr *) ((u8 *) ip + ip->ip_hl * 4); - if (TraceGroups.find (ip->ip_src.s_addr) != TraceGroups.end ()) + if (TraceGroups.find(ip->ip_src.s_addr) != TraceGroups.end()) tg = TraceGroups[ip->ip_src.s_addr]; else break; - if (tg->TraceProbes.find (ntohs (udp->uh_dport)) != tg->TraceProbes.end ()) - tp = tg->TraceProbes[ntohs (udp->uh_dport)]; + if (tg->TraceProbes.find(ntohs(udp->uh_dport)) != tg->TraceProbes.end()) + tp = tg->TraceProbes[ntohs(udp->uh_dport)]; else break; if (tp->ipreplysrc.s_addr) break; - /* We might have got a late reply */ - if (tp->timing.getState () == P_TIMEDOUT) - tp->timing.setState (P_OK); + /* We might have gotten a late reply */ + if (tp->timing.getState() == P_TIMEDOUT) + tp->timing.setState(P_OK); else - tg->decRemaining (); + tg->decRemaining(); tp->timing.recvTime = rcvdtime; tp->ipreplysrc.s_addr = ip->ip_src.s_addr; tg->repliedPackets++; - if (tp->probeType () == PROBE_TTL) { - tg->setHopDistance (get_initial_ttl_guess (ip->ip_ttl), ip->ip_ttl); - tg->setState (G_OK); + 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; } else { tg->gotReply = true; @@ -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 @@ -530,67 +528,67 @@ Traceroute::readTraceResponses () { default: ; } - return finished (); + return finished(); } /* Estimate how many hops away a host is by actively probing it. The hop * distance is set by setHopDistance from readTraceResponses. */ inline void -Traceroute::sendTTLProbes (vector < Target * >&Targets, vector < Target * >&valid_targets) { +Traceroute::sendTTLProbes(vector < Target * >&Targets, vector < Target * >&valid_targets) { Target *t = NULL; struct probespec probe; 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 */ - if (t->directlyConnected ()) + if (t->directlyConnected()) continue; /* This node has already been sent a hop distance probe */ - if (TraceGroups.find (t->v4hostip ()->s_addr) != TraceGroups.end ()) { - valid_targets.push_back (t); + if (TraceGroups.find(t->v4hostip()->s_addr) != TraceGroups.end()) { + valid_targets.push_back(t); continue; } /* Determine active port to probe */ - probe = getTraceProbe (t); + 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 */ - sport = get_random_u16 (); - tg = new TraceGroup (t->v4hostip ()->s_addr, sport, probe); - tg->src_mac_addr = t->SrcMACAddress (); - tg->nxt_mac_addr = t->NextHopMACAddress (); + /* 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(); + tg->nxt_mac_addr = t->NextHopMACAddress(); tg->sport++; TraceGroups[tg->ipdst] = tg; /* OS fingerprint engine may already have the distance so * we don't need to calculate it */ if (t->distance != -1) { - tg->setHopDistance (0, t->distance); + tg->setHopDistance(0, t->distance); } else { - tp = new TraceProbe (t->v4hostip ()->s_addr, - t->v4sourceip ()->s_addr, sport, probe); - tp->setProbeType (PROBE_TTL); + tp = new TraceProbe(t->v4hostip()->s_addr, + t->v4sourceip()->s_addr, sport, probe); + tp->setProbeType(PROBE_TTL); tp->ttl = o.ttl; tg->TraceProbes[sport] = tp; - tg->incRemaining (); - sendProbe (tp); + tg->incRemaining(); + sendProbe(tp); } - valid_targets.push_back (t); + valid_targets.push_back(t); } } /* Send a single traceprobe object */ int -Traceroute::sendProbe (TraceProbe * tp) { +Traceroute::sendProbe(TraceProbe * tp) { u8 *tcpopts = NULL; int tcpoptslen = 0; u32 ack = 0; @@ -603,48 +601,48 @@ Traceroute::sendProbe (TraceProbe * tp) { struct eth_nfo *ethptr = NULL; if (tp->probe.type == PS_TCP && (tp->probe.pd.tcp.flags & TH_ACK) == TH_ACK) - ack = rand (); + ack = rand(); if (tp->probe.type == PS_TCP && (tp->probe.pd.tcp.flags & TH_SYN) == TH_SYN) { tcpopts = (u8 *) "\x02\x04\x05\xb4"; tcpoptslen = 4; } - if (TraceGroups.find (tp->ipdst.s_addr) == TraceGroups.end ()) + if (TraceGroups.find(tp->ipdst.s_addr) == TraceGroups.end()) return -1; tg = TraceGroups[tp->ipdst.s_addr]; /* required to send raw packets in windows */ if (ethsd) { - memcpy (eth.srcmac, tg->src_mac_addr, 6); - memcpy (eth.dstmac, tg->nxt_mac_addr, 6); + memcpy(eth.srcmac, tg->src_mac_addr, 6); + memcpy(eth.dstmac, tg->nxt_mac_addr, 6); eth.ethsd = ethsd; eth.devname[0] = '\0'; ethptr = ð } - if (tg->TraceProbes.find (tp->sport) == tg->TraceProbes.end ()) { - tg->nextTTL (); + if (tg->TraceProbes.find(tp->sport) == tg->TraceProbes.end()) { + tg->nextTTL(); if (tg->ttl > MAX_TTL) { - tg->setState (G_ALIVE_TTL); + tg->setState(G_ALIVE_TTL); return -1; } if (!tg->ttl || (tg->gotReply && tg->noDistProbe) ) { - tg->setState (G_FINISH); + tg->setState(G_FINISH); return 0; } tg->sport++; tp->ttl = tg->ttl; - tg->incRemaining (); + tg->incRemaining(); } else { /* this probe is a retransmission */ - tp->timing.setState (P_OK); + tp->timing.setState(P_OK); } tg->TraceProbes[tp->sport] = tp; for (decoy = 0; decoy < o.numdecoys; decoy++) { - enforce_scan_delay (&tp->timing.sendTime, tg->scanDelay); + enforce_scan_delay(&tp->timing.sendTime, tg->scanDelay); if (decoy == o.decoyturn) source = tp->ipsrc; @@ -657,15 +655,15 @@ Traceroute::sendProbe (TraceProbe * tp) { Traceroute::getTraceProbe. */ if (tp->probe.type == PS_TCP || (tp->probe.type == PS_PROTO && tp->probe.proto == IPPROTO_TCP)) { - packet = build_tcp_raw (&source, &tp->ipdst, tp->ttl, get_random_u16 (), - get_random_u8 (), false, NULL, 0, tp->sport, tp->probe.pd.tcp.dport, - get_random_u32 (), ack, 0, tp->probe.pd.tcp.flags, - get_random_u16 (), 0, tcpopts, tcpoptslen, + packet = build_tcp_raw(&source, &tp->ipdst, tp->ttl, get_random_u16(), + get_random_u8(), false, NULL, 0, tp->sport, tp->probe.pd.tcp.dport, + get_random_u32(), ack, 0, tp->probe.pd.tcp.flags, + get_random_u16(), 0, tcpopts, tcpoptslen, o.extra_payload, o.extra_payload_length, &packetlen); } else if (tp->probe.type == PS_UDP || (tp->probe.type == PS_PROTO && tp->probe.proto == IPPROTO_UDP)) { - packet = build_udp_raw (&source, &tp->ipdst, tp->ttl, get_random_u16 (), - get_random_u8 (), false, + packet = build_udp_raw(&source, &tp->ipdst, tp->ttl, get_random_u16(), + get_random_u8(), false, NULL, 0, tp->sport, tp->probe.pd.udp.dport, o.extra_payload, o.extra_payload_length, &packetlen); } else if (tp->probe.type == PS_SCTP @@ -680,34 +678,34 @@ Traceroute::sendProbe (TraceProbe * tp) { get_random_u16(), get_random_u8(), false, NULL, 0, tp->sport, tp->probe.pd.sctp.dport, - 0UL, (char*)&chunk, + 0UL, (char*) &chunk, sizeof(struct sctp_chunkhdr_init), o.extra_payload, o.extra_payload_length, &packetlen); } else if (tp->probe.type == PS_ICMP || (tp->probe.type == PS_PROTO && tp->probe.proto == IPPROTO_ICMP)) { - packet = build_icmp_raw (&source, &tp->ipdst, tp->ttl, 0, 0, false, - NULL, 0, get_random_u16 (), tp->sport, tp->probe.pd.icmp.type, 0, + packet = build_icmp_raw(&source, &tp->ipdst, tp->ttl, 0, 0, false, + NULL, 0, get_random_u16(), tp->sport, tp->probe.pd.icmp.type, 0, o.extra_payload, o.extra_payload_length, &packetlen); } else if (tp->probe.type == PS_PROTO) { packet = build_ip_raw(&source, &tp->ipdst, tp->probe.proto, tp->ttl, - tp->sport, get_random_u8 (), false, NULL, 0, + tp->sport, get_random_u8(), false, NULL, 0, o.extra_payload, o.extra_payload_length, &packetlen); } else { fatal("Unknown probespec type %d in %s\n", tp->probe.type, __func__); } - send_ip_packet (fd, ethptr, packet, packetlen); - free (packet); + send_ip_packet(fd, ethptr, packet, packetlen); + free(packet); } return 0; } /* true if all groups have finished or failed */ bool -Traceroute::finished () { - map < u32, TraceGroup * >::iterator it = TraceGroups.begin (); - for (; it != TraceGroups.end (); ++it) { - if (it->second->getState () == G_OK || it->second->getRemaining ()) +Traceroute::finished() { + map < u32, TraceGroup * >::iterator it = TraceGroups.begin(); + for (; it != TraceGroups.end(); ++it) { + if (it->second->getState() == G_OK || it->second->getRemaining()) return false; } return true; @@ -715,7 +713,7 @@ Traceroute::finished () { /* Main parallel send and recv loop */ void -Traceroute::trace (vector < Target * >&Targets) { +Traceroute::trace(vector < Target * >&Targets) { map < u32, TraceGroup * >::iterator it; vector < Target * >::iterator targ; vector < Target * >valid_targets; @@ -728,7 +726,7 @@ Traceroute::trace (vector < Target * >&Targets) { ScanProgressMeter *SPM; u16 total_size, total_complete; - if (o.af () == AF_INET6) { + if (o.af() == AF_INET6) { error("Traceroute does not support ipv6"); return; } @@ -737,64 +735,62 @@ Traceroute::trace (vector < Target * >&Targets) { o.current_scantype = TRACEROUTE; /* perform the reference trace first */ - if (Targets.size () > 1) { + if (Targets.size() > 1) { o.current_scantype = REF_TRACEROUTE; - for (targ = Targets.begin (); targ != Targets.end (); ++targ) { - reference.push_back (*targ); - sendTTLProbes (reference, valid_targets); - if (valid_targets.size ()) { - this->trace (valid_targets); + for (targ = Targets.begin(); targ != Targets.end(); ++targ) { + reference.push_back(*targ); + sendTTLProbes(reference, valid_targets); + if (valid_targets.size()) { + this->trace(valid_targets); break; } } o.current_scantype = TRACEROUTE; } - /* guess hop distance to targets. valid_targets - * is populated with all Target object that are - * legitimate to trace to */ - sendTTLProbes (Targets, valid_targets); + /* 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()) return; - SPM = new ScanProgressMeter ("Traceroute"); + SPM = new ScanProgressMeter("Traceroute"); - while (!readTraceResponses ()) { - for (targ = valid_targets.begin (); targ != valid_targets.end (); ++targ) { + while (!readTraceResponses()) { + for (targ = valid_targets.begin(); targ != valid_targets.end(); ++targ) { t = *targ; - tg = TraceGroups[t->v4host ().s_addr]; + 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 */ - if (tg->getRemaining ()) { - tg->retransmissions (retrans_probes); - for (pcount = 0; pcount < retrans_probes.size (); pcount++) - sendProbe (retrans_probes[pcount]); - retrans_probes.clear (); + /* 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++) + sendProbe(retrans_probes[pcount]); + retrans_probes.clear(); /* Max number of packets outstanding is 2 if we don't have a reply yet - * otherwise it is equal to o.timing_level. If the timing level it 0 + * otherwise it is equal to o.timing_level. If the timing level it 0 * it is equal to 1 */ - if (tg->getRemaining () >= + if (tg->getRemaining() >= (tg->gotReply ? (!o.timing_level ? 1 : o.timing_level) : 2)) continue; } - if (tg->getState () != G_OK || !tg->hopDistance) + if (tg->getState() != G_OK || !tg->hopDistance) continue; - tp = new TraceProbe (t->v4hostip ()->s_addr, - t->v4sourceip ()->s_addr, tg->sport, tg->probe); - sendProbe (tp); + tp = new TraceProbe(t->v4hostip()->s_addr, + t->v4sourceip()->s_addr, tg->sport, tg->probe); + sendProbe(tp); } - if (!keyWasPressed ()) + if (!keyWasPressed()) continue; total_size = total_complete = 0; - for (it = TraceGroups.begin (); it != TraceGroups.end (); ++it) { - total_complete += it->second->size (); + for (it = TraceGroups.begin(); it != TraceGroups.end(); ++it) { + total_complete += it->second->size(); total_size += it->second->hopDistance; } @@ -802,30 +798,27 @@ Traceroute::trace (vector < Target * >&Targets) { continue; if (total_size < total_complete) - swap (total_complete, total_size); - SPM->printStats (MIN ((double) total_complete / total_size, 0.99), NULL); + swap(total_complete, total_size); + 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 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 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 */ -void Traceroute::resolveHops () { + * N.B TraceProbes contain pointers into the Target structure, if it is free'ed + * prematurely something nasty will happen. */ +void Traceroute::resolveHops() { map::iterator tg_iter; map::iterator tp_iter; int count = 0; struct sockaddr_storage ss; struct sockaddr_in *sin = (struct sockaddr_in *) &ss; - - if(o.noresolve) + + if (o.noresolve) return; assert(hops == NULL); @@ -833,23 +826,23 @@ void Traceroute::resolveHops () { memset(&ss, '\0', sizeof(ss)); sin->sin_family = o.af(); - for(tg_iter = TraceGroups.begin(); tg_iter != TraceGroups.end(); ++tg_iter) + for (tg_iter = TraceGroups.begin(); tg_iter != TraceGroups.end(); ++tg_iter) total_size += tg_iter->second->size(); - if(!total_size) + if (!total_size) return; hops = (Target **) safe_zalloc(sizeof(Target *) * total_size); /* Move hop IP address to Target structures and point TraceProbes to * Targets hostname */ - for(tg_iter = TraceGroups.begin(); tg_iter != TraceGroups.end(); ++tg_iter) { + for (tg_iter = TraceGroups.begin(); tg_iter != TraceGroups.end(); ++tg_iter) { tp_iter = tg_iter->second->TraceProbes.begin(); - for(; tp_iter != tg_iter->second->TraceProbes.end(); ++tp_iter) { - if(tp_iter->second->ipreplysrc.s_addr && tp_iter->second->probeType() != PROBE_TTL) { + for (; tp_iter != tg_iter->second->TraceProbes.end(); ++tp_iter) { + if (tp_iter->second->ipreplysrc.s_addr && tp_iter->second->probeType() != PROBE_TTL) { sin->sin_addr = tp_iter->second->ipreplysrc; hops[count] = new Target(); hops[count]->setTargetSockAddr(&ss, sizeof(ss)); hops[count]->flags = HOST_UP; - tp_iter->second->hostname = &hops[count]->hostname; + tp_iter->second->hostname = &hops[count]->hostname; count++; } } @@ -860,25 +853,25 @@ void Traceroute::resolveHops () { void Traceroute::addConsolidationMessage(NmapOutputTable *Tbl, unsigned short row_count, unsigned short ttl) { - char mbuf[64]; - int len; + char mbuf[64]; + int len; - assert(ref_ipaddr.s_addr); - char *ip = inet_ntoa(ref_ipaddr); + assert(ref_ipaddr.s_addr); + char *ip = inet_ntoa(ref_ipaddr); - if(ttl == 1) - len = Snprintf(mbuf, sizeof(mbuf), "Hop 1 is the same as for %s", ip); - else - len = Snprintf(mbuf, sizeof(mbuf), "Hops 1-%d are the same as for %s", ttl, ip); + if (ttl == 1) + len = Snprintf(mbuf, sizeof(mbuf), "Hop 1 is the same as for %s", ip); + else + len = Snprintf(mbuf, sizeof(mbuf), "Hops 1-%d are the same as for %s", ttl, ip); - assert(len); - Tbl->addItem(row_count, HOP_COL, true, "-", 1); - Tbl->addItem(row_count, RTT_COL, true, true, mbuf, len); + assert(len); + Tbl->addItem(row_count, HOP_COL, true, "-", 1); + Tbl->addItem(row_count, RTT_COL, true, true, mbuf, len); } /* print a trace in plain text format */ void -Traceroute::outputTarget (Target * t) { +Traceroute::outputTarget(Target * t) { map < u16, TraceProbe * >::const_iterator it; map < u16, TraceProbe * >::size_type ttl_count; map < u16, TraceProbe * >sortedProbes; @@ -892,90 +885,90 @@ Traceroute::outputTarget (Target * t) { char timebuf[16]; u8 consol_count = 0; - if ((TraceGroups.find (t->v4host ().s_addr)) == TraceGroups.end ()) + if ((TraceGroups.find(t->v4host().s_addr)) == TraceGroups.end()) return; - tg = TraceGroups[t->v4host ().s_addr]; + tg = TraceGroups[t->v4host().s_addr]; /* sort into ttl order */ - for (it = tg->TraceProbes.begin (); it != tg->TraceProbes.end (); ++it) + for (it = tg->TraceProbes.begin(); it != tg->TraceProbes.end(); ++it) sortedProbes[it->second->ttl] = it->second; - sortedProbes.swap (tg->TraceProbes); + sortedProbes.swap(tg->TraceProbes); /* clean up and consolidate traces */ - tg->consolidateHops (); + tg->consolidateHops(); this->outputXMLTrace(tg); /* table headers */ - Tbl = new NmapOutputTable (tg->hopDistance+1, 3); - Tbl->addItem (row_count, HOP_COL, false, "HOP", 3); - Tbl->addItem (row_count, RTT_COL, false, "RTT", 3); - Tbl->addItem (row_count, HOST_COL, false, "ADDRESS", 7); + Tbl = new NmapOutputTable(tg->hopDistance+1, 3); + Tbl->addItem(row_count, HOP_COL, false, "HOP", 3); + Tbl->addItem(row_count, RTT_COL, false, "RTT", 3); + Tbl->addItem(row_count, HOST_COL, false, "ADDRESS", 7); for (ttl_count = 1; ttl_count <= tg->hopDistance; ttl_count++) { - - assert(row_count <= tg->hopDistance); + + assert(row_count <= tg->hopDistance); /* consolidate hops based on the reference trace (commonPath) */ - if(commonPath[ttl_count] && ttl_count <= tg->consolidation_start) { + if (commonPath[ttl_count] && ttl_count <= tg->consolidation_start) { /* do not consolidate in debug mode */ - if(o.debugging) { + if (o.debugging) { row_count++; Tbl->addItemFormatted(row_count, HOP_COL, false, "%d", ttl_count); Tbl->addItemFormatted(row_count, RTT_COL, false, "--"); Tbl->addItemFormatted(row_count, HOST_COL, false, "%s", hostStr(commonPath[ttl_count])); - } else if(!common_consolidation) { + } else if (!common_consolidation) { row_count++; common_consolidation = true; } } - /* here we print the final hop for a trace that is fully consolidated */ - if ((it = tg->TraceProbes.find (ttl_count)) == tg->TraceProbes.end ()) { - if (common_consolidation && ttl_count == tg->hopDistance) { - if(ttl_count-2 == 1) { - Tbl->addItemFormatted(row_count, RTT_COL, false, "--"); - Tbl->addItemFormatted(row_count, HOST_COL,false, "%s", hostStr(commonPath[ttl_count-2])); - } else { - addConsolidationMessage(Tbl, row_count, ttl_count-2); - } - common_consolidation = false; - break; - } - continue; - } + /* here we print the final hop for a trace that is fully consolidated */ + if ((it = tg->TraceProbes.find(ttl_count)) == tg->TraceProbes.end()) { + if (common_consolidation && ttl_count == tg->hopDistance) { + if (ttl_count-2 == 1) { + Tbl->addItemFormatted(row_count, RTT_COL, false, "--"); + Tbl->addItemFormatted(row_count, HOST_COL,false, "%s", hostStr(commonPath[ttl_count-2])); + } else { + addConsolidationMessage(Tbl, row_count, ttl_count-2); + } + common_consolidation = false; + break; + } + continue; + } /* Here we consolidate the probe that first matched the common path */ - if (ttl_count < tg->consolidation_start) + if (ttl_count < tg->consolidation_start) continue; tp = tg->TraceProbes[ttl_count]; /* end of reference trace consolidation */ - if(common_consolidation) { - if(ttl_count-1 == 1) { + if (common_consolidation) { + if (ttl_count-1 == 1) { Tbl->addItemFormatted(row_count, RTT_COL, false, "--", ttl_count-1); Tbl->addItemFormatted(row_count, HOST_COL,false, "%s", hostStr(commonPath[ttl_count-1])); } else { - addConsolidationMessage(Tbl, row_count, ttl_count-1); - } + addConsolidationMessage(Tbl, row_count, ttl_count-1); + } common_consolidation = false; } row_count++; /* timeout consolidation */ - if(tp->timing.consolidated) { + if (tp->timing.consolidated) { consol_count++; - if(!last_consolidation) { + 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) { + Tbl->addItem(row_count, RTT_COL, false, "... 50"); } - 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); - if(consol_count>1) + } else if (!tp->timing.consolidated && last_consolidation) { + Tbl->addItem(row_count, HOST_COL, false, "no response", 11); + if (consol_count>1) Tbl->addItemFormatted(row_count, RTT_COL, false, "... %d", tp->ttl-1); else Tbl->addItemFormatted(row_count, RTT_COL, false, "..."); @@ -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); - 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 - Tbl->addItemFormatted (row_count, RTT_COL, false, "..."); - } - + 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 { + Tbl->addItemFormatted(row_count, RTT_COL, false, "..."); + } + } } /* Traceroute header and footer */ @@ -1010,14 +1003,14 @@ Traceroute::outputTarget (Target * t) { struct protoent *proto = nmap_getprotbynum(htons(tg->probe.proto)); log_write(LOG_PLAIN, "\nTRACEROUTE (using proto %d/%s)\n", tg->probe.proto, proto?proto->p_name:"unknown"); } - log_write (LOG_PLAIN, "%s", Tbl->printableTable(NULL)); + log_write(LOG_PLAIN, "%s", Tbl->printableTable(NULL)); - if(G_TTL(tg->getState())) + 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))) + else if (!tg->gotReply || (tp && (tp->ipreplysrc.s_addr != tg->ipdst))) log_write(LOG_PLAIN, "! destination not reached (%s)\n", inet_ntoa(tp->ipdst)); - log_flush (LOG_PLAIN); + log_flush(LOG_PLAIN); delete Tbl; } @@ -1034,9 +1027,9 @@ Traceroute::outputXMLTrace(TraceGroup * tg) { /* XML traceroute header */ log_write(LOG_XML, "probe.type == PS_TCP) { - log_write(LOG_XML, "port=\"%d\" ", tg->probe.pd.tcp.dport); + log_write(LOG_XML, "port=\"%d\" ", tg->probe.pd.tcp.dport); } else if (tg->probe.type == PS_UDP) { - log_write(LOG_XML, "port=\"%d\" ", tg->probe.pd.udp.dport); + log_write(LOG_XML, "port=\"%d\" ", tg->probe.pd.udp.dport); } else if (tg->probe.type == PS_SCTP) { log_write(LOG_XML, "port=\"%d\" ", tg->probe.pd.sctp.dport); } else if (tg->probe.type == PS_ICMP || tg->probe.type == PS_PROTO) { @@ -1049,46 +1042,45 @@ Traceroute::outputXMLTrace(TraceGroup * tg) { log_write(LOG_XML, ">\n"); /* add missing hosts host from the common path */ - for(ttl_count = 1 ; ttl_count < tg->TraceProbes.begin()->second->ttl; ttl_count++) { + for (ttl_count = 1 ; ttl_count < tg->TraceProbes.begin()->second->ttl; ttl_count++) { addr.s_addr = commonPath[ttl_count]; log_write(LOG_XML, "\n"); } - /* display normal traceroute nodes. Consolidation based on the - * common path is not performed */ - for(it = tg->TraceProbes.begin() ;it != tg->TraceProbes.end(); it++) { + /* 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) + 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); + timediff = TIMEVAL_SUBTRACT(tp->timing.recvTime, tp->timing.sendTime); - log_write(LOG_XML, "ttl, (float)timediff/1000, tp->ipReplyStr()); - if(tp->HostName() != NULL) + log_write(LOG_XML, "ttl, (float) timediff/1000, tp->ipReplyStr()); + if (tp->HostName() != NULL) log_write(LOG_XML, " host=\"%s\"", tp->HostName()); log_write(LOG_XML, "/>\n"); } - if(G_TTL(tg->getState())) + if (G_TTL(tg->getState())) log_write(LOG_XML, "\n"); - else if(!tg->gotReply || (tp && (tp->ipreplysrc.s_addr != tg->ipdst))) + else if (!tg->gotReply || (tp && (tp->ipreplysrc.s_addr != tg->ipdst))) log_write(LOG_XML, "\n", inet_ntoa(tp->ipdst)); /* traceroute XML footer */ log_write(LOG_XML, "\n"); log_flush(LOG_XML); -} +} -TraceGroup::TraceGroup (u32 dip, u16 sport, struct probespec& probe) { +TraceGroup::TraceGroup(u32 dip, u16 sport, struct probespec& probe) { this->ipdst = dip; this->sport = sport; this->probe = probe; @@ -1097,114 +1089,114 @@ TraceGroup::TraceGroup (u32 dip, u16 sport, struct probespec& probe) { remaining = 0; hopDistance = 0; start_ttl = 0; - TraceProbes.clear (); + TraceProbes.clear(); gotReply = false; noDistProbe = false; scanDelay = o.scan_delay ? o.scan_delay : 0; - maxRetransmissions = (o.getMaxRetransmissions () < 2) ? 2 : o.getMaxRetransmissions () / 2; + maxRetransmissions = (o.getMaxRetransmissions() < 2) ? 2 : o.getMaxRetransmissions() / 2; droppedPackets = 0; repliedPackets = 0; consecTimeouts = 0; consolidation_start = 0; } -TraceGroup::~TraceGroup () { - map < u16, TraceProbe * >::const_iterator it = TraceProbes.begin (); - for (; it != TraceProbes.end (); ++it) - delete (it->second); +TraceGroup::~TraceGroup() { + 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. +/* go through all probes in a group and check if any have timedout. * If too many packets have been dropped then the groups scan delay * is increased */ void -TraceGroup::retransmissions (vector < TraceProbe * >&retrans) { +TraceGroup::retransmissions(vector < TraceProbe * >&retrans) { map < u16, TraceProbe * >::iterator it; u32 timediff; struct timeval now; double threshold = (o.timing_level >= 4) ? 0.40 : 0.30; - for (it = TraceProbes.begin (); it != TraceProbes.end (); ++it) { - if (it->second->timing.gotReply () || it->second->timing.getState () == P_TIMEDOUT) + for (it = TraceProbes.begin(); it != TraceProbes.end(); ++it) { + if (it->second->timing.gotReply() || it->second->timing.getState() == P_TIMEDOUT) continue; - gettimeofday (&now, NULL); - timediff = TIMEVAL_SUBTRACT (now, it->second->timing.sendTime); + gettimeofday(&now, NULL); + timediff = TIMEVAL_SUBTRACT(now, it->second->timing.sendTime); - if (timediff < it->second->timing.probeTimeout ()) + if (timediff < it->second->timing.probeTimeout()) continue; - if (it->second->timing.retranLimit () >= maxRetransmissions) { + if (it->second->timing.retranLimit() >= maxRetransmissions) { /* this probe has timedout */ - it->second->timing.setState (P_TIMEDOUT); - decRemaining (); + it->second->timing.setState(P_TIMEDOUT); + decRemaining(); if ((++consecTimeouts) > 5 && maxRetransmissions > 2) maxRetransmissions = 2; - if (it->second->probeType () == PROBE_TTL) { + if (it->second->probeType() == PROBE_TTL) { hopDistance = 1; noDistProbe = true; /* Give up on this host. We should be able to do a trace against an unresponsive target but for now it's too slow. */ setState(G_DEAD_TTL); if (o.verbose) - log_write (LOG_STDOUT, "%s: no reply to our hop distance probe!\n", IPStr ()); + 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++; - it->second->timing.setState (P_RETRANS); - retrans.push_back (it->second); + it->second->timing.setState(P_RETRANS); + retrans.push_back(it->second); } /* Calculate dynamic timing adjustments */ if (repliedPackets > droppedPackets / 5) maxRetransmissions = (maxRetransmissions == 2) ? 2 : maxRetransmissions - 1; else - maxRetransmissions = MIN (o.getMaxRetransmissions (), maxRetransmissions + 1); + maxRetransmissions = MIN(o.getMaxRetransmissions(), maxRetransmissions + 1); if (droppedPackets > 10 && (droppedPackets / ((double) droppedPackets + repliedPackets) > threshold)) { if (!scanDelay) scanDelay = (probe.type == PS_TCP || probe.type == PS_SCTP) ? 5 : 50; else - scanDelay = MIN (scanDelay * 2, MAX (scanDelay, 800)); + scanDelay = MIN(scanDelay * 2, MAX(scanDelay, 800)); droppedPackets = 0; repliedPackets = 0; } else { - scanDelay = MAX (scanDelay - (scanDelay / 5), 5); + scanDelay = MAX(scanDelay - (scanDelay / 5), 5); } } } /* Remove uneeded probes and mark timed out probes for consolidation */ -void TraceGroup::consolidateHops () { +void TraceGroup::consolidateHops() { map < u16, TraceProbe * >::size_type ttl_count; map < u16, u32 >::iterator com_iter; TraceProbe *tp; int timeout_count = 0; /* remove any superfluous probes */ - for (ttl_count = hopDistance + 1; ttl_count <= TraceProbes.size () + 1; ttl_count++) - TraceProbes.erase (ttl_count); + for (ttl_count = hopDistance + 1; ttl_count <= TraceProbes.size() + 1; ttl_count++) + TraceProbes.erase(ttl_count); for (ttl_count = 1; ttl_count <= hopDistance; ttl_count++) { tp = TraceProbes[ttl_count]; - if(!tp) { - TraceProbes.erase (ttl_count); + if (!tp) { + TraceProbes.erase(ttl_count); continue; } /* timeout consolidation flags, ignore if in debugging more */ - if (tp->timing.getState () != P_TIMEDOUT) { + if (tp->timing.getState() != P_TIMEDOUT) { timeout_count = 0; } else { if (++timeout_count > 1 && !o.debugging) { TraceProbes[(ttl_count == 1) ? 1 : ttl_count - 1]->timing.consolidated = true; TraceProbes[(ttl_count == 1) ? 1 : ttl_count]->timing.consolidated = true; } - } + } if (tp->ipreplysrc.s_addr == ipdst) break; @@ -1212,31 +1204,31 @@ void TraceGroup::consolidateHops () { /* we may have accidently shot past the intended destination */ while (ttl_count <= hopDistance) - TraceProbes.erase (++ttl_count); + TraceProbes.erase(++ttl_count); } u8 -TraceGroup::setState (u8 state) { +TraceGroup::setState(u8 state) { if (state <= G_FINISH && state >= G_OK) this->state = state; else if (o.debugging) - log_write (LOG_STDOUT, "%s: invalid tracegroup state %d\n", IPStr (), state); + log_write(LOG_STDOUT, "%s: invalid tracegroup state %d\n", IPStr(), state); return this->state; } u8 -TraceGroup::setHopDistance (u8 hop_distance, u8 ttl) { +TraceGroup::setHopDistance(u8 hop_distance, u8 ttl) { if (this->hopDistance) return 0; this->hopDistance = hop_distance; - if(o.debugging) + 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 if(!this->hopDistance && ttl) + else if (!this->hopDistance && ttl) this->hopDistance = ttl; else this->hopDistance = hop_distance; @@ -1245,15 +1237,15 @@ TraceGroup::setHopDistance (u8 hop_distance, u8 ttl) { if (this->hopDistance >= MAX_TTL) this->hopDistance = MAX_TTL- 2; /* guess is too small */ - else if(this->hopDistance == 0) + 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); + log_write(LOG_STDOUT, "%s: guessing hop distance at %d\n", IPStr(), this->hopDistance); return this->hopDistance; } -TraceProbe::TraceProbe (u32 dip, u32 sip, u16 sport, struct probespec& probe) { +TraceProbe::TraceProbe(u32 dip, u32 sip, u16 sport, struct probespec& probe) { this->sport = sport; this->probe = probe; ipdst.s_addr = dip; @@ -1264,57 +1256,57 @@ TraceProbe::TraceProbe (u32 dip, u32 sip, u16 sport, struct probespec& probe) { probetype = PROBE_TRACE; } -TraceProbe::~TraceProbe () { +TraceProbe::~TraceProbe() { if (hostnameip) - free (hostnameip); + free(hostnameip); } const char *TraceProbe::nameIP(void) { - hostnameip = (char *) safe_zalloc(NAMEIPLEN); + hostnameip = (char *) safe_zalloc(NAMEIPLEN); - if(hostname == NULL || *hostname == NULL) - Snprintf(hostnameip, NAMEIPLEN, "%s", inet_ntoa(ipreplysrc)); - else - Snprintf(hostnameip, NAMEIPLEN, "%s (%s)",*hostname, inet_ntoa(ipreplysrc)); - - return hostnameip; + if (hostname == NULL || *hostname == NULL) + Snprintf(hostnameip, NAMEIPLEN, "%s", inet_ntoa(ipreplysrc)); + else + Snprintf(hostnameip, NAMEIPLEN, "%s (%s)",*hostname, inet_ntoa(ipreplysrc)); + + return hostnameip; } -TimeInfo::TimeInfo () { - memset (&sendTime, 0, sizeof (struct timeval)); - memset (&recvTime, 0, sizeof (struct timeval)); +TimeInfo::TimeInfo() { + memset(&sendTime, 0, sizeof(struct timeval)); + memset(&recvTime, 0, sizeof(struct timeval)); retransmissions = 0; state = P_OK; consolidated = false; - initialize_timeout_info (&to); + initialize_timeout_info(&to); } u8 -TimeInfo::setState (u8 state) { +TimeInfo::setState(u8 state) { if (state <= P_OK) this->state = state; else if (o.debugging) - log_write (LOG_STDOUT, ": invalid traceprobe state %d\n", state); + log_write(LOG_STDOUT, ": invalid traceprobe state %d\n", state); return state; } int -TimeInfo::retranLimit () { +TimeInfo::retranLimit() { return ++this->retransmissions; } void -TimeInfo::adjustTimeouts (struct timeval *received, u16 scan_delay) { +TimeInfo::adjustTimeouts(struct timeval *received, u16 scan_delay) { long delta = 0; recvTime = *received; if (o.debugging > 3) { - log_write (LOG_STDOUT, "Timeout vals: srtt: %d rttvar: %d to: %d ", to.srtt, to.rttvar, + log_write(LOG_STDOUT, "Timeout vals: srtt: %d rttvar: %d to: %d ", to.srtt, to.rttvar, to.timeout); } - delta = TIMEVAL_SUBTRACT (*received, sendTime); + delta = TIMEVAL_SUBTRACT(*received, sendTime); /* Argh ... pcap receive time is sometimes a little off my getimeofday() results on various platforms :(. So a packet may @@ -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; } @@ -1331,52 +1323,50 @@ TimeInfo::adjustTimeouts (struct timeval *received, u16 scan_delay) { if (to.srtt == -1 && to.rttvar == -1) { /* We need to initialize the sucker ... */ to.srtt = delta; - to.rttvar = MAX (5000, MIN (to.srtt, 2000000)); + to.rttvar = MAX(5000, MIN(to.srtt, 2000000)); to.timeout = to.srtt + (to.rttvar << 2); } 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; /* sanity check 2 */ if (delta > 1500000 && delta > 3 * to.srtt + 2 * to.rttvar) { if (o.debugging) - log_write (LOG_STDOUT, "Bogus delta: %ld (srtt %d) ... ignoring\n", delta, to.srtt); + log_write(LOG_STDOUT, "Bogus delta: %ld (srtt %d) ... ignoring\n", delta, to.srtt); return; } to.srtt += delta >> 3; - to.rttvar += (ABS (delta) - to.rttvar) >> 2; + to.rttvar += (ABS(delta) - to.rttvar) >> 2; to.timeout = to.srtt + (to.rttvar << 2); } if (to.rttvar > 2300000) { - log_write (LOG_STDOUT, "RTTVAR has grown to over 2.3 seconds, decreasing to 2.0\n"); + log_write(LOG_STDOUT, "RTTVAR has grown to over 2.3 seconds, decreasing to 2.0\n"); to.rttvar = 2000000; } /* It hurts to do this ... it really does ... but otherwise we are being too risky */ - to.timeout = box (o.minRttTimeout () * 1000, o.maxRttTimeout () * 1000, to.timeout); + to.timeout = box(o.minRttTimeout() * 1000, o.maxRttTimeout() * 1000, to.timeout); if (scan_delay) - to.timeout = MAX (to.timeout, scan_delay * 1000); + to.timeout = MAX(to.timeout, scan_delay * 1000); if (o.debugging > 3) { - log_write (LOG_STDOUT, "delta %ld ==> srtt: %d rttvar: %d to: %d\n", - delta, to.srtt, to.rttvar, to.timeout); + log_write(LOG_STDOUT, "delta %ld ==> srtt: %d rttvar: %d to: %d\n", + delta, to.srtt, to.rttvar, to.timeout); } } -/* 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) { +enforce_scan_delay(struct timeval *tv, int scan_delay) { static int init = -1; static struct timeval lastcall; struct timeval now; @@ -1384,30 +1374,30 @@ enforce_scan_delay (struct timeval *tv, int scan_delay) { if (!scan_delay) { if (tv) - gettimeofday (tv, NULL); + gettimeofday(tv, NULL); return; } if (init == -1) { - gettimeofday (&lastcall, NULL); + gettimeofday(&lastcall, NULL); init = 0; if (tv) - memcpy (tv, &lastcall, sizeof (struct timeval)); + memcpy(tv, &lastcall, sizeof(struct timeval)); return; } - gettimeofday (&now, NULL); - time_diff = TIMEVAL_MSEC_SUBTRACT (now, lastcall); + gettimeofday(&now, NULL); + time_diff = TIMEVAL_MSEC_SUBTRACT(now, lastcall); if (time_diff < (int) scan_delay) { if (o.debugging > 2) log_write (LOG_STDOUT, "Sleeping for %d milliseconds in %s()\n", scan_delay - time_diff, __func__); - usleep ((scan_delay - time_diff) * 1000); - gettimeofday (&lastcall, NULL); + usleep((scan_delay - time_diff) * 1000); + gettimeofday(&lastcall, NULL); } else - memcpy (&lastcall, &now, sizeof (struct timeval)); + memcpy(&lastcall, &now, sizeof(struct timeval)); if (tv) { - memcpy (tv, &lastcall, sizeof (struct timeval)); + memcpy(tv, &lastcall, sizeof(struct timeval)); } return; } @@ -1418,11 +1408,11 @@ hostStr (u32 ip) { const char *hname; struct in_addr addr; - memset (nameipbuf, '\0', MAXHOSTNAMELEN + INET6_ADDRSTRLEN); + memset(nameipbuf, '\0', MAXHOSTNAMELEN + INET6_ADDRSTRLEN); addr.s_addr = ip; - if((hname = lookup_cached_host(ip)) == NULL) + if ((hname = lookup_cached_host(ip)) == NULL) Snprintf(nameipbuf, sizeof(nameipbuf), "%s", inet_ntoa(addr)); else - Snprintf(nameipbuf, sizeof(nameipbuf), "%s (%s)", hname, inet_ntoa (addr)); + Snprintf(nameipbuf, sizeof(nameipbuf), "%s (%s)", hname, inet_ntoa(addr)); return nameipbuf; }