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