mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Merge from svn://svn.insecure.org/nmap-exp/david/nmap-traceroute. This
brings in a new, faster, parallel version of traceroute.
This commit is contained in:
@@ -116,6 +116,7 @@ void Target::Initialize() {
|
||||
FPR = NULL;
|
||||
osscan_flag = OS_NOTPERF;
|
||||
weird_responses = flags = 0;
|
||||
traceroute_probespec.type = PS_NONE;
|
||||
memset(&to, 0, sizeof(to));
|
||||
memset(&targetsock, 0, sizeof(targetsock));
|
||||
memset(&sourcesock, 0, sizeof(sourcesock));
|
||||
@@ -228,7 +229,7 @@ void Target::setTargetSockAddr(struct sockaddr_storage *ss, size_t ss_len) {
|
||||
}
|
||||
|
||||
// Returns IPv4 host address or {0} if unavailable.
|
||||
struct in_addr Target::v4host() {
|
||||
struct in_addr Target::v4host() const {
|
||||
const struct in_addr *addy = v4hostip();
|
||||
struct in_addr in;
|
||||
if (addy) return *addy;
|
||||
|
||||
25
Target.h
25
Target.h
@@ -106,6 +106,8 @@
|
||||
#include "tcpip.h"
|
||||
#include "scan_engine.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
#ifndef INET6_ADDRSTRLEN
|
||||
#define INET6_ADDRSTRLEN 46
|
||||
#endif
|
||||
@@ -131,6 +133,22 @@ struct host_timeout_nfo {
|
||||
time_t host_start, host_end; /* The absolute start and end for this host */
|
||||
};
|
||||
|
||||
struct TracerouteHop {
|
||||
struct sockaddr_storage tag;
|
||||
bool timedout;
|
||||
std::string name;
|
||||
struct sockaddr_storage addr;
|
||||
int ttl;
|
||||
float rtt; /* In milliseconds. */
|
||||
|
||||
int display_name(char *buf, size_t len) {
|
||||
if (name.empty())
|
||||
return Snprintf(buf, len, "%s", inet_ntop_ez(&addr, sizeof(addr)));
|
||||
else
|
||||
return Snprintf(buf, len, "%s (%s)", name.c_str(), inet_ntop_ez(&addr, sizeof(addr)));
|
||||
}
|
||||
};
|
||||
|
||||
class Target {
|
||||
public: /* For now ... a lot of the data members should be made private */
|
||||
Target();
|
||||
@@ -148,7 +166,7 @@ class Target {
|
||||
to sockaddr_storage */
|
||||
void setTargetSockAddr(struct sockaddr_storage *ss, size_t ss_len);
|
||||
// Returns IPv4 target host address or {0} if unavailable.
|
||||
struct in_addr v4host();
|
||||
struct in_addr v4host() const;
|
||||
const struct in_addr *v4hostip() const;
|
||||
/* The source address used to reach the target */
|
||||
int SourceSockAddr(struct sockaddr_storage *ss, size_t *ss_len);
|
||||
@@ -158,7 +176,7 @@ class Target {
|
||||
struct in_addr v4source() const;
|
||||
const struct in_addr *v4sourceip() const;
|
||||
/* The IPv4 or IPv6 literal string for the target host */
|
||||
const char *targetipstr() { return targetipstring; }
|
||||
const char *targetipstr() const { return targetipstring; }
|
||||
/* Give the name from the last setHostName() call, which should be
|
||||
the name obtained from reverse-resolution (PTR query) of the IP (v4
|
||||
or v6). If the name has not been set, or was set to NULL, an empty
|
||||
@@ -262,6 +280,9 @@ class Target {
|
||||
char *hostname; // Null if unable to resolve or unset
|
||||
char * targetname; // The name of the target host given on the commmand line if it is a named host
|
||||
|
||||
struct probespec traceroute_probespec;
|
||||
std::list <TracerouteHop> traceroute_hops;
|
||||
|
||||
#ifndef NOLUA
|
||||
ScriptResults scriptResults;
|
||||
#endif
|
||||
|
||||
@@ -236,6 +236,6 @@ struct scan_lists {
|
||||
int prot_count;
|
||||
};
|
||||
|
||||
typedef enum { STYPE_UNKNOWN, HOST_DISCOVERY, ACK_SCAN, SYN_SCAN, FIN_SCAN, XMAS_SCAN, UDP_SCAN, CONNECT_SCAN, NULL_SCAN, WINDOW_SCAN, SCTP_INIT_SCAN, SCTP_COOKIE_ECHO_SCAN, RPC_SCAN, MAIMON_SCAN, IPPROT_SCAN, PING_SCAN, PING_SCAN_ARP, IDLE_SCAN, BOUNCE_SCAN, SERVICE_SCAN, OS_SCAN, SCRIPT_SCAN, TRACEROUTE, REF_TRACEROUTE}stype;
|
||||
typedef enum { STYPE_UNKNOWN, HOST_DISCOVERY, ACK_SCAN, SYN_SCAN, FIN_SCAN, XMAS_SCAN, UDP_SCAN, CONNECT_SCAN, NULL_SCAN, WINDOW_SCAN, SCTP_INIT_SCAN, SCTP_COOKIE_ECHO_SCAN, RPC_SCAN, MAIMON_SCAN, IPPROT_SCAN, PING_SCAN, PING_SCAN_ARP, IDLE_SCAN, BOUNCE_SCAN, SERVICE_SCAN, OS_SCAN, SCRIPT_SCAN, TRACEROUTE}stype;
|
||||
|
||||
#endif /*GLOBAL_STRUCTURES_H */
|
||||
|
||||
25
nmap.cc
25
nmap.cc
@@ -569,7 +569,6 @@ int nmap_main(int argc, char *argv[]) {
|
||||
char *endptr = NULL;
|
||||
struct scan_lists ports = { 0 };
|
||||
TargetGroup *exclude_group = NULL;
|
||||
Traceroute *troute = NULL;
|
||||
char myname[MAXHOSTNAMELEN + 1];
|
||||
#if (defined(IN_ADDR_DEEPSTRUCT) || defined( SOLARIS))
|
||||
/* Note that struct in_addr in solaris is 3 levels deep just to store an
|
||||
@@ -1811,9 +1810,7 @@ int nmap_main(int argc, char *argv[]) {
|
||||
if(o.traceroute && o.noportscan) {
|
||||
/* Assume that all targets in a group use the same device */
|
||||
vector<Target *>::iterator it;
|
||||
troute = new Traceroute(Targets[0]->deviceName(), Targets[0]->ifType(), &ports);
|
||||
troute->trace(Targets);
|
||||
troute->resolveHops();
|
||||
traceroute(Targets);
|
||||
|
||||
/* print ping traceroutes, making sure the reference
|
||||
* trace is first */
|
||||
@@ -1823,7 +1820,7 @@ int nmap_main(int argc, char *argv[]) {
|
||||
log_write(LOG_XML, "<host>");
|
||||
write_host_status(currenths, o.resolve_all);
|
||||
printmacinfo(currenths);
|
||||
troute->outputTarget(currenths);
|
||||
printtraceroute(currenths);
|
||||
log_write(LOG_XML, "</host>\n");
|
||||
log_write(LOG_PLAIN,"\n");
|
||||
}
|
||||
@@ -1834,8 +1831,6 @@ int nmap_main(int argc, char *argv[]) {
|
||||
}
|
||||
o.numhosts_scanning = 0;
|
||||
log_flush_all();
|
||||
delete troute;
|
||||
troute = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1906,11 +1901,8 @@ int nmap_main(int argc, char *argv[]) {
|
||||
if (o.osscan == OS_SCAN_DEFAULT)
|
||||
os_scan2(Targets);
|
||||
|
||||
if(o.traceroute) {
|
||||
troute = new Traceroute(Targets[0]->deviceName(), Targets[0]->ifType(), &ports);
|
||||
troute->trace(Targets);
|
||||
troute->resolveHops();
|
||||
}
|
||||
if(o.traceroute)
|
||||
traceroute(Targets);
|
||||
|
||||
if (o.servicescan || o.rpcscan) {
|
||||
/* This scantype must be after any TCP or UDP scans since it
|
||||
@@ -1949,8 +1941,8 @@ int nmap_main(int argc, char *argv[]) {
|
||||
#endif
|
||||
}
|
||||
|
||||
if(troute)
|
||||
troute->outputTarget(currenths);
|
||||
if(o.traceroute)
|
||||
printtraceroute(currenths);
|
||||
|
||||
if (o.debugging)
|
||||
log_write(LOG_STDOUT, "Final times for host: srtt: %d rttvar: %d to: %d\n",
|
||||
@@ -1973,9 +1965,6 @@ int nmap_main(int argc, char *argv[]) {
|
||||
o.numhosts_scanning = 0;
|
||||
} while(!o.max_ips_to_scan || o.max_ips_to_scan > o.numhosts_scanned);
|
||||
|
||||
if(troute)
|
||||
delete troute;
|
||||
|
||||
delete hstate;
|
||||
if (exclude_group)
|
||||
delete[] exclude_group;
|
||||
@@ -2027,6 +2016,7 @@ void nmap_free_mem() {
|
||||
close_nse();
|
||||
free(o.scriptargs);
|
||||
#endif
|
||||
traceroute_hop_cache_clear();
|
||||
}
|
||||
|
||||
/* Reads in a (normal or machine format) Nmap log file and gathers enough
|
||||
@@ -2646,7 +2636,6 @@ const char *scantype2str(stype scantype) {
|
||||
case OS_SCAN: return "OS Scan"; break;
|
||||
case SCRIPT_SCAN: return "Script Scan"; break;
|
||||
case TRACEROUTE: return "Traceroute" ; break;
|
||||
case REF_TRACEROUTE: return "Reference Traceroute"; break;
|
||||
default: assert(0); break;
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +88,8 @@
|
||||
|
||||
class Target;
|
||||
|
||||
#include "nbase.h"
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
|
||||
156
output.cc
156
output.cc
@@ -1897,6 +1897,162 @@ void printhostscriptresults(Target *currenths) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Print a table with traceroute hops. */
|
||||
static void printtraceroute_normal(Target *currenths) {
|
||||
static const int HOP_COL = 0, RTT_COL = 1, HOST_COL = 2;
|
||||
NmapOutputTable Tbl(currenths->traceroute_hops.size() + 1, 3);
|
||||
struct probespec probe;
|
||||
list <TracerouteHop>::iterator it;
|
||||
int row;
|
||||
|
||||
/* No trace, must be localhost. */
|
||||
if (currenths->traceroute_hops.size() == 0)
|
||||
return;
|
||||
|
||||
/* Print header. */
|
||||
log_write(LOG_PLAIN, "\n");
|
||||
probe = currenths->traceroute_probespec;
|
||||
if (probe.type == PS_TCP) {
|
||||
log_write(LOG_PLAIN, "TRACEROUTE (using port %d/%s)\n",
|
||||
probe.pd.tcp.dport, proto2ascii(probe.proto));
|
||||
} else if (probe.type == PS_UDP) {
|
||||
log_write(LOG_PLAIN, "TRACEROUTE (using port %d/%s)\n",
|
||||
probe.pd.udp.dport, proto2ascii(probe.proto));
|
||||
} else if (probe.type == PS_SCTP) {
|
||||
log_write(LOG_PLAIN, "TRACEROUTE (using port %d/%s)\n",
|
||||
probe.pd.sctp.dport, proto2ascii(probe.proto));
|
||||
} else if (probe.type == PS_ICMP || probe.type == PS_PROTO) {
|
||||
struct protoent *proto = nmap_getprotbynum(htons(probe.proto));
|
||||
log_write(LOG_PLAIN, "TRACEROUTE (using proto %d/%s)\n",
|
||||
probe.proto, proto ? proto->p_name : "unknown");
|
||||
}
|
||||
|
||||
row = 0;
|
||||
Tbl.addItem(row, HOP_COL, false, "HOP");
|
||||
Tbl.addItem(row, RTT_COL, false, "RTT");
|
||||
Tbl.addItem(row, HOST_COL, false, "ADDRESS");
|
||||
row++;
|
||||
|
||||
it = currenths->traceroute_hops.begin();
|
||||
|
||||
if (!o.debugging) {
|
||||
/* Consolidate shared hops. */
|
||||
TracerouteHop *shared_hop = NULL;
|
||||
struct sockaddr_storage addr;
|
||||
size_t sslen;
|
||||
|
||||
sslen = sizeof(addr);
|
||||
currenths->TargetSockAddr(&addr, &sslen);
|
||||
while (it != currenths->traceroute_hops.end()
|
||||
&& sockaddr_storage_cmp(&it->tag, &addr) != 0) {
|
||||
shared_hop = &*it;
|
||||
it++;
|
||||
}
|
||||
|
||||
if (shared_hop != NULL) {
|
||||
Tbl.addItem(row, HOP_COL, false, "-");
|
||||
if (shared_hop->ttl == 1) {
|
||||
Tbl.addItemFormatted(row, RTT_COL, true, "Hop 1 is the same as for %s",
|
||||
inet_ntop_ez(&shared_hop->tag, sizeof(shared_hop->tag)));
|
||||
} else if (shared_hop->ttl > 1) {
|
||||
Tbl.addItemFormatted(row, RTT_COL, true,
|
||||
"Hops 1-%d are the same as for %s", shared_hop->ttl,
|
||||
inet_ntop_ez(&shared_hop->tag, sizeof(shared_hop->tag)));
|
||||
}
|
||||
row++;
|
||||
}
|
||||
}
|
||||
|
||||
while (it != currenths->traceroute_hops.end()) {
|
||||
Tbl.addItemFormatted(row, HOP_COL, false, "%d", it->ttl);
|
||||
if (it->timedout) {
|
||||
if (o.debugging) {
|
||||
Tbl.addItem(row, RTT_COL, false, "...");
|
||||
it++;
|
||||
} else {
|
||||
/* The beginning and end of timeout consolidation. */
|
||||
int begin_ttl, end_ttl;
|
||||
begin_ttl = end_ttl = it->ttl;
|
||||
for (; it != currenths->traceroute_hops.end() && it->timedout; it++)
|
||||
end_ttl = it->ttl;
|
||||
if (begin_ttl == end_ttl)
|
||||
Tbl.addItem(row, RTT_COL, false, "...");
|
||||
else
|
||||
Tbl.addItemFormatted(row, RTT_COL, false, "... %d", end_ttl);
|
||||
}
|
||||
row++;
|
||||
} else {
|
||||
char namebuf[256];
|
||||
/* Normal hop output. */
|
||||
|
||||
it->display_name(namebuf, sizeof(namebuf));
|
||||
Tbl.addItemFormatted(row, RTT_COL, false, "%.2f ms", it->rtt);
|
||||
Tbl.addItemFormatted(row, HOST_COL, false, "%s", namebuf);
|
||||
row++;
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
log_write(LOG_PLAIN, "%s", Tbl.printableTable(NULL));
|
||||
|
||||
log_flush(LOG_PLAIN);
|
||||
}
|
||||
|
||||
static void printtraceroute_xml(Target *currenths) {
|
||||
struct probespec probe;
|
||||
list <TracerouteHop>::iterator it;
|
||||
|
||||
/* No trace, must be localhost. */
|
||||
if (currenths->traceroute_hops.size() == 0)
|
||||
return;
|
||||
|
||||
/* XML traceroute header */
|
||||
log_write(LOG_XML, "<trace ");
|
||||
probe = currenths->traceroute_probespec;
|
||||
if (probe.type == PS_TCP) {
|
||||
log_write(LOG_XML, "port=\"%d\" ", probe.pd.tcp.dport);
|
||||
} else if (probe.type == PS_UDP) {
|
||||
log_write(LOG_XML, "port=\"%d\" ", probe.pd.udp.dport);
|
||||
} else if (probe.type == PS_SCTP) {
|
||||
log_write(LOG_XML, "port=\"%d\" ", probe.pd.sctp.dport);
|
||||
} else if (probe.type == PS_ICMP || probe.type == PS_PROTO) {
|
||||
struct protoent *proto = nmap_getprotbynum(htons(probe.proto));
|
||||
if (proto == NULL)
|
||||
log_write(LOG_XML, "proto=\"%d\"", probe.proto);
|
||||
else
|
||||
log_write(LOG_XML, "proto=\"%s\"", proto->p_name);
|
||||
}
|
||||
log_write(LOG_XML, ">\n");
|
||||
|
||||
for (it = currenths->traceroute_hops.begin();
|
||||
it != currenths->traceroute_hops.end();
|
||||
it++) {
|
||||
if (it->timedout)
|
||||
continue;
|
||||
log_write(LOG_XML, "<hop ttl=\"%d\" rtt=\"%.2f\" ipaddr=\"%s\"",
|
||||
it->ttl, it->rtt, inet_ntop_ez(&it->addr, sizeof(it->addr)));
|
||||
if (!it->name.empty())
|
||||
log_write(LOG_XML, " host=\"%s\"", it->name.c_str());
|
||||
log_write(LOG_XML, "/>\n");
|
||||
}
|
||||
|
||||
/*
|
||||
if (tg->getState() == G_DEAD_TTL)
|
||||
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);
|
||||
}
|
||||
|
||||
void printtraceroute(Target *currenths) {
|
||||
printtraceroute_normal(currenths);
|
||||
printtraceroute_xml(currenths);
|
||||
}
|
||||
|
||||
/* Prints a status message while the program is running */
|
||||
void printStatusMessage() {
|
||||
// Pre-computations
|
||||
|
||||
3
output.h
3
output.h
@@ -194,6 +194,9 @@ void printserviceinfooutput(Target *currenths);
|
||||
|
||||
void printhostscriptresults(Target *currenths);
|
||||
|
||||
/* Print a table with traceroute hops. */
|
||||
void printtraceroute(Target *currenths);
|
||||
|
||||
/* Print a detailed list of Nmap interfaces and routes to
|
||||
normal/skiddy/stdout output */
|
||||
int print_iflist(void);
|
||||
|
||||
10
tcpip.cc
10
tcpip.cc
@@ -1149,7 +1149,7 @@ void eth_close_cached() {
|
||||
|
||||
// fill ip header. no error check.
|
||||
// This function is also changing what's needed from host to network order.
|
||||
static inline int fill_ip_raw(struct ip *ip, int packetlen, u8 *ipopt,
|
||||
static inline int fill_ip_raw(struct ip *ip, int packetlen, const u8 *ipopt,
|
||||
int ipoptlen, int ip_tos, int ip_id,
|
||||
int ip_off, int ip_ttl, int ip_p,
|
||||
const struct in_addr *ip_src,
|
||||
@@ -1221,9 +1221,9 @@ int send_tcp_raw_decoys(int sd, struct eth_nfo *eth,
|
||||
packetlen, which must be a valid int pointer. */
|
||||
u8 *build_tcp_raw(const struct in_addr *source,
|
||||
const struct in_addr *victim, int ttl, u16 ipid, u8 tos,
|
||||
bool df, u8 *ipopt, int ipoptlen, u16 sport, u16 dport,
|
||||
bool df, const u8 *ipopt, int ipoptlen, u16 sport, u16 dport,
|
||||
u32 seq, u32 ack, u8 reserved, u8 flags, u16 window,
|
||||
u16 urp, u8 *tcpopt, int tcpoptlen, char *data,
|
||||
u16 urp, const u8 *tcpopt, int tcpoptlen, char *data,
|
||||
u16 datalen, u32 *outpacketlen) {
|
||||
int packetlen = sizeof(struct ip) + ipoptlen + sizeof(struct tcp_hdr) + tcpoptlen + datalen;
|
||||
u8 *packet = (u8 *) safe_malloc(packetlen);
|
||||
@@ -1792,11 +1792,11 @@ int send_udp_raw_decoys(int sd, struct eth_nfo *eth,
|
||||
actually sent by this function. Caller must delete the buffer when
|
||||
finished with the packet. The packet length is returned in
|
||||
packetlen, which must be a valid int pointer. */
|
||||
u8 *build_udp_raw(struct in_addr *source, const struct in_addr *victim,
|
||||
u8 *build_udp_raw(const struct in_addr *source, const struct in_addr *victim,
|
||||
int ttl, u16 ipid, u8 tos, bool df,
|
||||
u8 *ipopt, int ipoptlen,
|
||||
u16 sport, u16 dport,
|
||||
char *data, u16 datalen, u32 *outpacketlen) {
|
||||
const char *data, u16 datalen, u32 *outpacketlen) {
|
||||
int packetlen =
|
||||
sizeof(struct ip) + ipoptlen + sizeof(struct udp_hdr) + datalen;
|
||||
u8 *packet = (u8 *) safe_malloc(packetlen);
|
||||
|
||||
8
tcpip.h
8
tcpip.h
@@ -505,10 +505,10 @@ int send_ip_raw( int sd, struct eth_nfo *eth,
|
||||
packetlen, which must be a valid int pointer. */
|
||||
u8 *build_tcp_raw(const struct in_addr *source, const struct in_addr *victim,
|
||||
int ttl, u16 ipid, u8 tos, bool df,
|
||||
u8* ipopt, int ipoptlen,
|
||||
const u8* ipopt, int ipoptlen,
|
||||
u16 sport, u16 dport,
|
||||
u32 seq, u32 ack, u8 reserved, u8 flags, u16 window, u16 urp,
|
||||
u8 *options, int optlen,
|
||||
const u8 *options, int optlen,
|
||||
char *data, u16 datalen,
|
||||
u32 *packetlen);
|
||||
|
||||
@@ -518,11 +518,11 @@ u8 *build_tcp_raw(const struct in_addr *source, const struct in_addr *victim,
|
||||
actually sent by this function. Caller must delete the buffer when
|
||||
finished with the packet. The packet length is returned in
|
||||
packetlen, which must be a valid int pointer. */
|
||||
u8 *build_udp_raw(struct in_addr *source, const struct in_addr *victim,
|
||||
u8 *build_udp_raw(const struct in_addr *source, const struct in_addr *victim,
|
||||
int ttl, u16 ipid, u8 tos, bool df,
|
||||
u8* ipopt, int ipoptlen,
|
||||
u16 sport, u16 dport,
|
||||
char *data, u16 datalen,
|
||||
const char *data, u16 datalen,
|
||||
u32 *packetlen);
|
||||
|
||||
/* Builds an SCTP packet (including an IP header) by packing the fields
|
||||
|
||||
2498
traceroute.cc
2498
traceroute.cc
File diff suppressed because it is too large
Load Diff
219
traceroute.h
219
traceroute.h
@@ -93,221 +93,6 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
/* Probe types */
|
||||
#define PROBE_TRACE 0
|
||||
#define PROBE_TTL 1
|
||||
int traceroute(std::vector<Target *> &Targets);
|
||||
|
||||
/* Probe states */
|
||||
#define P_TIMEDOUT 0 /* probe has timedout */
|
||||
#define P_RETRANS 1 /* probe needs to be retransmitted */
|
||||
#define P_OK 2 /* waiting for response or received response */
|
||||
|
||||
/* Group states */
|
||||
#define G_OK P_OK
|
||||
#define G_DEAD_TTL 3 /* TTL has reached maximum value */
|
||||
#define G_FINISH 5 /* tracing has complete successfully */
|
||||
|
||||
#define MAX_TTL 50
|
||||
|
||||
#define HOP_COL 0
|
||||
#define RTT_COL 1
|
||||
#define HOST_COL 2
|
||||
|
||||
#define NAMEIPLEN MAXHOSTNAMELEN+INET6_ADDRSTRLEN
|
||||
|
||||
class NmapOutputTable;
|
||||
|
||||
/* Keeps track of each probes timing state */
|
||||
class TimeInfo {
|
||||
public:
|
||||
TimeInfo();
|
||||
int retranLimit();
|
||||
void adjustTimeouts(struct timeval *recv, u16 scan_delay);
|
||||
|
||||
unsigned long probeTimeout() {
|
||||
return MIN(10000000, to.timeout * 10);
|
||||
}
|
||||
/* true if this probe has been replied to */
|
||||
u8 gotReply() {
|
||||
return recvTime.tv_usec != 0 && recvTime.tv_sec != 0;
|
||||
}
|
||||
u8 getState() {
|
||||
return state;
|
||||
}
|
||||
u8 setState(u8 state);
|
||||
|
||||
struct timeout_info to;
|
||||
/* set to true if this probe is going to
|
||||
* consolidated because it has timed out */
|
||||
bool consolidated;
|
||||
|
||||
/* Rtt and timeout calculation */
|
||||
struct timeval recvTime;
|
||||
struct timeval sendTime;
|
||||
|
||||
private:
|
||||
u8 retransmissions;
|
||||
u8 state;
|
||||
};
|
||||
|
||||
/* traceprobes represent a single packet at a specific ttl. Traceprobes are
|
||||
* stored inside tracegroups. */
|
||||
class TraceProbe {
|
||||
public:
|
||||
TraceProbe(u32 dip, u32 sip, u16 sport, struct probespec& probe);
|
||||
~TraceProbe();
|
||||
|
||||
/* Return the ip address and resolved hostname in a string such as
|
||||
* "host.com (1.2.3.4)" or "6.6.6.6". */
|
||||
const char *nameIP();
|
||||
const char *HostName() {
|
||||
if (!hostname || !(*hostname))
|
||||
return NULL;
|
||||
else
|
||||
return *hostname;
|
||||
}
|
||||
/* probe type is either a standard probe (PROBE_TRACE) or a hop distance
|
||||
* probe (PROBE_TTL) */
|
||||
void setProbeType(u8 type) {
|
||||
this->probetype = type;
|
||||
}
|
||||
u8 probeType() {
|
||||
return probetype;
|
||||
}
|
||||
char *ipReplyStr() {
|
||||
return inet_ntoa (ipreplysrc);
|
||||
}
|
||||
|
||||
/* protocol information for this probe */
|
||||
TimeInfo timing;
|
||||
struct in_addr ipdst;
|
||||
struct in_addr ipsrc;
|
||||
struct in_addr ipreplysrc;
|
||||
struct probespec probe;
|
||||
u16 sport;
|
||||
u8 ttl;
|
||||
char **hostname;
|
||||
|
||||
private:
|
||||
u8 probetype;
|
||||
char *hostnameip;
|
||||
};
|
||||
|
||||
/* each trace group represents a target ip and contains a map of probes that
|
||||
* have been sent/recv'ed to/from the ip */
|
||||
class TraceGroup {
|
||||
public:
|
||||
TraceGroup(u32 dip, u16 sport, struct probespec& probe);
|
||||
~TraceGroup();
|
||||
/* map of all probes sent to this TraceGroups IP address. The map is keyed
|
||||
* by the source port number of the probe */
|
||||
std::map < u16, TraceProbe * >TraceProbes;
|
||||
std::map < u16, TraceProbe * >::size_type size() {
|
||||
return TraceProbes.size ();
|
||||
}
|
||||
/* checks for timedout probes and retransmits them Any probe that exceeds
|
||||
* the timing limits is considered non-responsive */
|
||||
void retransmissions(std::vector < TraceProbe * >&retrans);
|
||||
/* Returns a map from TTLs to probes, stripped of all unneeded probes and
|
||||
* with timed-out probes marked for consolidation. */
|
||||
std::map < u8, TraceProbe * > consolidateHops() const;
|
||||
/* the next ttl to send, if the destination has replied the ttl is
|
||||
* decremented, if it hasn't it is incremented */
|
||||
void nextTTL();
|
||||
/* number of probes currently waiting for replies */
|
||||
void incRemaining();
|
||||
void decRemaining();
|
||||
char *IPStr();
|
||||
u8 getRemaining() {
|
||||
return remaining;
|
||||
}
|
||||
u8 getState() {
|
||||
return state;
|
||||
}
|
||||
u8 setState(u8 state);
|
||||
u8 setHopDistance(u8 hop_distance, u8 ttl);
|
||||
|
||||
/* Get the number of hops to the target, or -1 if unknown. Use this instead
|
||||
* of reading hopDistance, which despite its name does not contain the final
|
||||
* hop count. */
|
||||
int getDistance();
|
||||
|
||||
bool gotReply;
|
||||
bool noDistProbe;
|
||||
|
||||
/* Group wide timing */
|
||||
int scanDelay;
|
||||
int maxRetransmissions;
|
||||
u16 droppedPackets;
|
||||
u16 repliedPackets;
|
||||
u8 consecTimeouts;
|
||||
/* protocol information */
|
||||
struct probespec probe;
|
||||
u16 sport;
|
||||
u32 ipdst;
|
||||
/* estimated ttl distance to target */
|
||||
u8 hopDistance;
|
||||
/* largest ttl send so far */
|
||||
u8 ttl;
|
||||
/* the initial ttl guess. This is needed because the ttl may have to be
|
||||
* incremented to reach the destination host. Once nmap has reached the
|
||||
* destination it needs to start decrementing the ttl from the original
|
||||
* value so no duplicate probes are sent.
|
||||
*
|
||||
* For example, if the guess is 20 but the target is at 23. We will start
|
||||
* tracing backwards at 19. */
|
||||
u8 start_ttl;
|
||||
u8 consolidation_start;
|
||||
const u8 *src_mac_addr;
|
||||
const u8 *nxt_mac_addr;
|
||||
|
||||
private:
|
||||
/* the number of probes sent but and not yet replied to */
|
||||
u8 remaining;
|
||||
/* default state is G_OK, set to G_FINISH when
|
||||
* complete or one of the G_* error codes if this
|
||||
* group fails */
|
||||
u8 state;
|
||||
};
|
||||
|
||||
/* Public interface to traceroute functionality */
|
||||
class Traceroute {
|
||||
public:
|
||||
Traceroute(const char *device_name, devtype type, const scan_lists * probe_ports);
|
||||
~Traceroute();
|
||||
|
||||
/* perform the traceroute on a list of targets */
|
||||
void trace(std::vector < Target * >&Targets);
|
||||
/* Use nmaps rDNS functions to mass resolve the hops ip addresses */
|
||||
void resolveHops();
|
||||
/* display plain and XML traceroutes for target t */
|
||||
void outputTarget(Target * t);
|
||||
|
||||
private:
|
||||
/* map of all TraceGroups, keyed by
|
||||
* the groups destination IP address */
|
||||
std::map < u32, TraceGroup * >TraceGroups;
|
||||
|
||||
const struct scan_lists * scanlists;
|
||||
Target **hops;
|
||||
pcap_t *pd;
|
||||
eth_t *ethsd;
|
||||
int fd, total_size, cp_flag;
|
||||
struct in_addr ref_ipaddr;
|
||||
|
||||
/* called by outputTarget to log XML data */
|
||||
void outputXMLTrace(TraceGroup * tg);
|
||||
/* find a responsive port for t based on scan results */
|
||||
const probespec getTraceProbe(Target * t);
|
||||
/* sendTTLProbes() guesses the hop distance to a target by actively probing
|
||||
* the host. */
|
||||
void sendTTLProbes(std::vector < Target * >&Targets, std::vector < Target * >&vaild_targets);
|
||||
int sendProbe(TraceProbe * tp);
|
||||
/* reads probe replies for all protocols. returns finished(), which returns
|
||||
* true when all groups have finished or failed */
|
||||
bool readTraceResponses();
|
||||
bool finished();
|
||||
/* add message to output table "hops 1 to X are the same as <reference ip>".
|
||||
* This message should always come before none-consolidated hop output */
|
||||
void addConsolidationMessage(NmapOutputTable *Tbl, unsigned short row_count, unsigned short ttl);
|
||||
};
|
||||
void traceroute_hop_cache_clear();
|
||||
|
||||
Reference in New Issue
Block a user