traceroute.cc

来自「Ubuntu packages of security software。 相」· CC 代码 · 共 1,501 行 · 第 1/4 页

CC
1,501
字号
        if (decoy == o.decoyturn)            source = tp->ipsrc;        else            source = o.decoys[decoy];        switch (tp->proto) {        case IPPROTO_TCP:            packet = build_tcp_raw (&source, &tp->ipdst, tp->ttl, get_random_u16 (),                                    get_random_u8 (), 0, NULL, 0, tp->sport, tp->dport,                                    get_random_u32 (), ack, 0, scaninfo.scan_flags,                                    get_random_u16 (), 0, tcpopts, tcpoptslen,                                    o.extra_payload, o.extra_payload_length, &packetlen);            break;        case IPPROTO_UDP:            packet = build_udp_raw (&source, &tp->ipdst, tp->ttl, get_random_u16 (),                                    get_random_u8 (), false,                                    NULL, 0, tp->sport,                                    tp->dport, o.extra_payload, o.extra_payload_length, &packetlen);            break;        case IPPROTO_ICMP:            packet = build_icmp_raw (&source, &tp->ipdst, tp->ttl, 0, 0, false,                                     NULL, 0, get_random_u16 (), tp->sport, scaninfo.icmp_type, 0,                                     o.extra_payload, o.extra_payload_length, &packetlen);            break;        default:            packet = build_ip_raw (&source, &tp->ipdst, tp->proto, tp->ttl, tp->sport,                                   get_random_u8 (), false, NULL, 0, o.extra_payload,                                   o.extra_payload_length, &packetlen);        }        send_ip_packet (fd, ethptr, packet, packetlen);        free (packet);    }    return 0;}/* true if all groups have finished or failed */boolTraceroute::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;}/* Main parallel send and recv loop */voidTraceroute::trace (vector < Target * >&Targets) {    map < u32, TraceGroup * >::iterator it;    vector < Target * >::iterator targ;    vector < Target * >valid_targets;    vector < Target * >reference;    vector < TraceProbe * >retrans_probes;    vector < TraceGroup * >::size_type pcount;    TraceProbe *tp = NULL;    TraceGroup *tg = NULL;    Target *t = NULL;    ScanProgressMeter *SPM;    u16 total_size, total_complete;    if (o.af () == AF_INET6) {        error ("Traceroute does not support ipv6\n");        return;    }    /* perform the reference trace first */    if (Targets.size () > 1) {        o.current_scantype = TRACEROUTE;        for (targ = Targets.begin (); targ != Targets.end (); ++targ) {            reference.push_back (*targ);            sendTTLProbes (reference, valid_targets);            if (valid_targets.size ()) {                o.current_scantype = REF_TRACEROUTE;                this->trace (valid_targets);                o.current_scantype = TRACEROUTE;                break;            }        }    }    /* 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");    while (!readTraceResponses ()) {        for (targ = valid_targets.begin (); targ != valid_targets.end (); ++targ) {            t = *targ;            tg = TraceGroups[t->v4host ().s_addr];            /* Check for any timedout probes and              * retransmit them. If too many probes             * are outstanding we wait for replies or             * timeouts before sending any more */            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                  * it is equal to 1 */                if (tg->getRemaining () >=                    (tg->gotReply ? (!o.timing_level ? 1 : o.timing_level) : 2))                    continue;            }            if (tg->getState () != G_OK || !tg->hopDistance)                continue;            tp = new TraceProbe (tg->proto, t->v4hostip ()->s_addr,                                 t->v4sourceip ()->s_addr, tg->sport, 0);            sendProbe (tp);        }        if (!keyWasPressed ())            continue;        total_size = total_complete = 0;        for (it = TraceGroups.begin (); it != TraceGroups.end (); ++it) {            total_complete += it->second->size ();            total_size += it->second->hopDistance;        }        if (!total_size)            continue;        if (total_size < total_complete)            swap (total_complete, total_size);        SPM->printStats (MIN ((double) total_complete / total_size, 0.99), NULL);    }    SPM->endTask(NULL, NULL);    delete (SPM);  }/* Resolves traceroute hops through nmaps * parallel caching rdns infrastructure. * The <hops> class variable should be NULL and needs * freeing after the hostnames are finished  * with  * * N.B TraceProbes contain pointers into the Target * structure, if it is free'ed prematurely something * nasty will happen */void Traceroute::resolveHops () {    map<u32, TraceGroup *>::iterator tg_iter;    map<u16, TraceProbe *>::iterator tp_iter;    int count = 0;    struct sockaddr_storage ss;    struct sockaddr_in *sin = (struct sockaddr_in *) &ss;      if(o.noresolve)        return;    assert(hops == NULL);    memset(&ss, '\0', sizeof(ss));    sin->sin_family = o.af();    for(tg_iter = TraceGroups.begin(); tg_iter != TraceGroups.end(); ++tg_iter)         total_size += tg_iter->second->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) {        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) {                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;                 count++;            }        }    }    /* resolve all hops in this group at onces */    nmap_mass_rdns(hops, count);}voidTraceroute::addConsolidationMessage(NmapOutputTable *Tbl, unsigned short row_count, unsigned short ttl) {	char mbuf[64];	int len;	assert(ref_ipaddr.s_addr);	char *ip = inet_ntoa(ref_ipaddr);	if(ttl == 1)		len = Snprintf(mbuf, 64, "Hop 1 is the same as for %s", ip);	else		len = Snprintf(mbuf, 64, "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);}/* print a trace in plain text format */voidTraceroute::outputTarget (Target * t) {    map < u16, TraceProbe * >::const_iterator it;    map < u16, TraceProbe * >::size_type ttl_count;    map < u16, TraceProbe * >sortedProbes;    TraceProbe *tp = NULL;    TraceGroup *tg = NULL;    NmapOutputTable *Tbl = NULL;    struct protoent *proto;    bool last_consolidation = false;    bool common_consolidation = false;    char row_count = 0;    char timebuf[16];    u8 consol_count = 0;    if ((TraceGroups.find (t->v4host ().s_addr)) == TraceGroups.end ())        return;    tg = TraceGroups[t->v4host ().s_addr];    /* sort into ttl order */    for (it = tg->TraceProbes.begin (); it != tg->TraceProbes.end (); ++it)        sortedProbes[it->second->ttl] = it->second;    sortedProbes.swap (tg->TraceProbes);    /* clean up and consolidate traces */    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);    for (ttl_count = 1; ttl_count <= tg->hopDistance; ttl_count++) {		assert(row_count <= tg->hopDistance);        /* consolidate hops based on the reference trace (commonPath)  */        if(commonPath[ttl_count] && ttl_count <= tg->consolidation_start) {             /* do not consolidate in debug mode */            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) {                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 consolidate the probe that first matched the common path */        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) {                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);	    }            common_consolidation = false;        }        row_count++;        /* timeout consolidation */        if(tp->timing.consolidated) {            consol_count++;            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");            row_count--;        } 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, "...");            row_count++;            last_consolidation = false;            consol_count = 0;        }        /* normal hop output (rtt, ip and hostname) */        if (!tp->timing.consolidated && !last_consolidation) {            Snprintf(timebuf, 16, "%.2f", (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 */    proto = nmap_getprotbynum(htons(tg->proto));    if(o.ipprotscan || (o.pingscan && !(o.pingtype & PINGTYPE_TCP || o.pingtype & PINGTYPE_UDP)))         log_write(LOG_PLAIN, "\nTRACEROUTE (using proto %d/%s)\n", tg->proto, proto?proto->p_name:"unknown");    else         log_write(LOG_PLAIN, "\nTRACEROUTE (using port %d/%s)\n", tg->dport, proto2ascii(tg->proto));    log_write (LOG_PLAIN, "%s", Tbl->printableTable(NULL));    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)))        log_write(LOG_PLAIN, "! destination not reached (%s)\n", inet_ntoa(tp->ipdst));    log_flush (LOG_PLAIN);    delete Tbl;}/* print a trace in xml */voidTraceroute::outputXMLTrace(TraceGroup * tg) {    map < u16, TraceProbe * >::const_iterator it;    TraceProbe *tp = NULL;    const char *hostname_tmp = NULL;    struct protoent *proto;    struct in_addr addr;    long timediff;    short ttl_count;    /* XML traceroute header */    log_write(LOG_XML, "<trace ");    if ((o.pingscan && (o.pingtype & PINGTYPE_TCP || o.pingtype & PINGTYPE_UDP)) || (!o.ipprotscan && !o.pingscan))	log_write(LOG_XML, "port=\"%d\" ", tg->dport);    if((proto = nmap_getprotbynum(htons(tg->proto))))        log_write(LOG_XML, "proto=\"%s\"", proto->p_name);    else        log_write(LOG_XML, "proto=\"%d\"", tg->proto);    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++) {        addr.s_addr = commonPath[ttl_count];        log_write(LOG_XML, "<hop ttl=\"%d\" rtt=\"--\" ", ttl_count);        log_write(LOG_XML, "ipaddr=\"%s\"", inet_ntoa(addr));        if((hostname_tmp = lookup_cached_host(commonPath[ttl_count])) != "")

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?