traceroute.cc
来自「Ubuntu packages of security software。 相」· CC 代码 · 共 1,501 行 · 第 1/4 页
CC
1,501 行
log_write(LOG_XML, " host=\"%s\"", hostname_tmp); 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++) { tp = it->second; if(tp->probeType() == PROBE_TTL) break; if(tp->timing.getState() == P_TIMEDOUT) { continue; } timediff = TIMEVAL_SUBTRACT (tp->timing.recvTime, tp->timing.sendTime); log_write(LOG_XML, "<hop ttl=\"%d\" rtt=\"%.2f\" ipaddr=\"%s\"", tp->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())) log_write(LOG_XML, "<error errorstr=\"maximum TTL reached\"/>\n"); else if(!tg->gotReply || (tp && (tp->ipreplysrc.s_addr != tg->ipdst))) log_write(LOG_XML, "<error errorstr=\"destination not reached (%s)\"/>\n", inet_ntoa(tp->ipdst)); /* traceroute XML footer */ log_write(LOG_XML, "</trace>\n"); log_flush(LOG_XML);} TraceGroup::TraceGroup (u32 dip, u16 sport, u16 dport, u8 proto) { this->ipdst = dip; this->dport = dport; this->sport = sport; this->proto = proto; ttl = 0; state = G_OK; remaining = 0; hopDistance = 0; start_ttl = 0; TraceProbes.clear (); gotReply = false; noDistProbe = false; scanDelay = o.scan_delay ? o.scan_delay : 0; 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);}/* 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 */voidTraceGroup::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) continue; gettimeofday (&now, NULL); timediff = TIMEVAL_SUBTRACT (now, it->second->timing.sendTime); if (timediff < it->second->timing.probeTimeout ()) continue; if (it->second->timing.retranLimit () >= maxRetransmissions) { /* this probe has timedout */ 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) { hopDistance = 1; noDistProbe = true; if (o.verbose) log_write (LOG_STDOUT, "%s: no reply to our hop distance probe!\n", IPStr ()); } } else { droppedPackets++; 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); if (droppedPackets > 10 && (droppedPackets / ((double) droppedPackets + repliedPackets) > threshold)) { if (!scanDelay) scanDelay = (proto == IPPROTO_TCP) ? 5 : 50; else scanDelay = MIN (scanDelay * 2, MAX (scanDelay, 800)); droppedPackets = 0; repliedPackets = 0; } else { scanDelay = MAX (scanDelay - (scanDelay / 5), 5); } }}/* Remove uneeded probes and mark timed out probes for consolidation */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 = 1; ttl_count <= hopDistance; ttl_count++) { tp = TraceProbes[ttl_count]; if(!tp) { TraceProbes.erase (ttl_count); continue; } /* timeout consolidation flags, ignore if in debugging more */ 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; } /* we may have accidently shot past the intended destination */ while (ttl_count <= hopDistance) TraceProbes.erase (++ttl_count);}u8TraceGroup::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); return this->state;}u8TraceGroup::setHopDistance (u8 hop_distance, u8 ttl) { if (this->hopDistance) return 0; 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) this->hopDistance -= ttl; else if(!this->hopDistance && ttl) this->hopDistance = ttl; else this->hopDistance = hop_distance; /* 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;}TraceProbe::TraceProbe (u8 proto, u32 dip, u32 sip, u16 sport, u16 dport) { this->proto = proto; this->sport = sport; this->dport = dport; ipdst.s_addr = dip; ipsrc.s_addr = sip; ipreplysrc.s_addr = 0; hostnameip = NULL; hostname = NULL; probetype = PROBE_TRACE;}TraceProbe::~TraceProbe () { if (hostnameip) free (hostnameip);}const char *TraceProbe::nameIP(void) { 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;}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);}u8TimeInfo::setState (u8 state) { if (state <= P_OK) this->state = state; else if (o.debugging) log_write (LOG_STDOUT, ": invalid traceprobe state %d\n", state); return state;}intTimeInfo::retranLimit () { return ++this->retransmissions;}voidTimeInfo::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, to.timeout); } delta = TIMEVAL_SUBTRACT (*received, sendTime); /* Argh ... pcap receive time is sometimes a little off my getimeofday() results on various platforms :(. So a packet may appear to be received as much as a hundredth of a second before 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); delta = 10000; } 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.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); 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); return; } to.srtt += delta >> 3; 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"); 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); if (scan_delay) 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); }}/* 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 voidenforce_scan_delay (struct timeval *tv, int scan_delay) { static int init = -1; static struct timeval lastcall; struct timeval now; int time_diff; if (!scan_delay) { if (tv) gettimeofday (tv, NULL); return; } if (init == -1) { gettimeofday (&lastcall, NULL); init = 0; if (tv) memcpy (tv, &lastcall, sizeof (struct timeval)); return; } 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); } else memcpy (&lastcall, &now, sizeof (struct timeval)); if (tv) { memcpy (tv, &lastcall, sizeof (struct timeval)); } return;}static char *hostStr (u32 ip) { static char nameipbuf[MAXHOSTNAMELEN + INET6_ADDRSTRLEN] = { '0' }; const char *hname; struct in_addr addr; memset (nameipbuf, '\0', MAXHOSTNAMELEN + INET6_ADDRSTRLEN); addr.s_addr = ip; if((hname = lookup_cached_host(ip)) == "") Snprintf(nameipbuf, MAXHOSTNAMELEN+INET6_ADDRSTRLEN, "%s", inet_ntoa(addr)); else Snprintf (nameipbuf, MAXHOSTNAMELEN + INET6_ADDRSTRLEN, "%s (%s)", hname, inet_ntoa (addr)); return nameipbuf;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?