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 + -
显示快捷键?