mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Use the cached timing ping probe as the traceroute probe in all situations.
This commit is contained in:
@@ -6,6 +6,13 @@ o zenmap scan inventory place holder.
|
|||||||
|
|
||||||
o zenmap radialnet integration place holder.
|
o zenmap radialnet integration place holder.
|
||||||
|
|
||||||
|
o --traceroute now uses the timing ping probe saved from host
|
||||||
|
discovery and port scanning instead of finding its own probe. The
|
||||||
|
timing ping probe is always the best probe for eliciting a response
|
||||||
|
Nmap knows of. This will have the most effect on traceroute after a
|
||||||
|
ping scan, where traceroute would sometimes pick the wrong probe and
|
||||||
|
traceroute would fail even though the target was up.
|
||||||
|
|
||||||
o Expanded nmap-services to include information on how frequently each
|
o Expanded nmap-services to include information on how frequently each
|
||||||
port number is found open. The results were generated by scanning
|
port number is found open. The results were generated by scanning
|
||||||
tens of millions of IPs on the Internet. [Fyodor]
|
tens of millions of IPs on the Internet. [Fyodor]
|
||||||
|
|||||||
302
traceroute.cc
302
traceroute.cc
@@ -227,85 +227,6 @@ Traceroute::Traceroute (const char *device_name, devtype type, const scan_lists
|
|||||||
/* rely on each group using the same device */
|
/* rely on each group using the same device */
|
||||||
pd = my_pcap_open_live (device_name, 100, o.spoofsource ? 1 : 0, 2);
|
pd = my_pcap_open_live (device_name, 100, o.spoofsource ? 1 : 0, 2);
|
||||||
|
|
||||||
scaninfo.initial_proto = IPPROTO_IP;
|
|
||||||
scaninfo.open_response = 0;
|
|
||||||
scaninfo.open_state = PORT_OPEN;
|
|
||||||
scaninfo.closed_state = PORT_CLOSED;
|
|
||||||
scaninfo.ipproto = false;
|
|
||||||
|
|
||||||
/* Set up which protocols, tcp flags and responsive
|
|
||||||
* states to use with the current scan type.
|
|
||||||
*
|
|
||||||
* Horribly messy but it is better then peppering
|
|
||||||
* the nmap source code with references to traceroute */
|
|
||||||
if (o.synscan) {
|
|
||||||
scaninfo.scan_flags = TH_SYN;
|
|
||||||
scaninfo.open_response = TH_SYN | TH_ACK;
|
|
||||||
scaninfo.closed_response = TH_RST;
|
|
||||||
} else if (o.ackscan) {
|
|
||||||
scaninfo.scan_flags = TH_ACK;
|
|
||||||
scaninfo.open_response = TH_RST;
|
|
||||||
scaninfo.closed_response = TH_RST;
|
|
||||||
scaninfo.open_state = PORT_UNFILTERED;
|
|
||||||
scaninfo.closed_state = PORT_UNFILTERED;
|
|
||||||
} else if (o.finscan) {
|
|
||||||
scaninfo.scan_flags = TH_FIN;
|
|
||||||
scaninfo.closed_response = TH_RST;
|
|
||||||
} else if (o.xmasscan) {
|
|
||||||
scaninfo.scan_flags = TH_FIN | TH_URG | TH_PUSH;
|
|
||||||
scaninfo.closed_response = TH_RST;
|
|
||||||
} else if (o.nullscan) {
|
|
||||||
scaninfo.scan_flags = 0;
|
|
||||||
scaninfo.closed_response = TH_RST;
|
|
||||||
} else if (o.windowscan) {
|
|
||||||
scaninfo.scan_flags = TH_ACK;
|
|
||||||
scaninfo.open_response = TH_RST;
|
|
||||||
scaninfo.closed_response = TH_RST;
|
|
||||||
} else if (o.maimonscan) {
|
|
||||||
scaninfo.scan_flags = TH_FIN | TH_ACK;
|
|
||||||
scaninfo.open_response = TH_RST;
|
|
||||||
scaninfo.closed_response = TH_RST;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o.udpscan)
|
|
||||||
scaninfo.initial_proto = IPPROTO_UDP;
|
|
||||||
if (o.synscan || o.finscan || o.xmasscan || o.nullscan ||
|
|
||||||
o.ackscan || o.windowscan || o.maimonscan)
|
|
||||||
scaninfo.initial_proto = IPPROTO_TCP;
|
|
||||||
|
|
||||||
if (o.ipprotscan)
|
|
||||||
scaninfo.ipproto = true;
|
|
||||||
|
|
||||||
if(o.pingscan) {
|
|
||||||
scaninfo.open_state = HOST_UP;
|
|
||||||
if (o.pingtype & PINGTYPE_TCP_USE_SYN) {
|
|
||||||
scaninfo.scan_flags = TH_SYN;
|
|
||||||
scaninfo.open_response = TH_SYN | TH_ACK;
|
|
||||||
scaninfo.closed_response = TH_RST;
|
|
||||||
scaninfo.initial_proto = IPPROTO_TCP;
|
|
||||||
} else if (o.pingtype & PINGTYPE_TCP_USE_ACK) {
|
|
||||||
scaninfo.scan_flags = TH_ACK;
|
|
||||||
scaninfo.open_response = TH_RST;
|
|
||||||
scaninfo.closed_response = TH_RST;
|
|
||||||
scaninfo.initial_proto = IPPROTO_TCP;
|
|
||||||
} else if (o.pingtype & PINGTYPE_UDP) {
|
|
||||||
scaninfo.initial_proto = IPPROTO_UDP;
|
|
||||||
} else if (o.pingtype & PINGTYPE_ICMP_PING) {
|
|
||||||
scaninfo.initial_proto = IPPROTO_ICMP;
|
|
||||||
scaninfo.icmp_type = ICMP_ECHO;
|
|
||||||
} else if (o.pingtype & PINGTYPE_ICMP_TS) {
|
|
||||||
scaninfo.initial_proto = IPPROTO_ICMP;
|
|
||||||
scaninfo.icmp_type = ICMP_TIMESTAMP;
|
|
||||||
} else if(o.pingtype & PINGTYPE_ICMP_MASK) {
|
|
||||||
scaninfo.initial_proto = IPPROTO_ICMP;
|
|
||||||
scaninfo.icmp_type = ICMP_ADDRESS;
|
|
||||||
} else if (o.pingtype & PINGTYPE_PROTO) {
|
|
||||||
scaninfo.ipproto = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o.scanflags != -1)
|
|
||||||
scaninfo.scan_flags = o.scanflags;
|
|
||||||
memset (commonPath, 0, sizeof (commonPath));
|
memset (commonPath, 0, sizeof (commonPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,86 +248,26 @@ Traceroute::~Traceroute () {
|
|||||||
|
|
||||||
/* get an open or closed port from the portlist. Traceroute requires a positive response,
|
/* get an open or closed port from the portlist. Traceroute requires a positive response,
|
||||||
* positive responses are generated by different port states depending on the type of scan */
|
* positive responses are generated by different port states depending on the type of scan */
|
||||||
inline int
|
inline const probespec
|
||||||
Traceroute::getTracePort (u8 proto, Target * t) {
|
Traceroute::getTraceProbe (Target * t) {
|
||||||
u16 open_port = 1;
|
struct probespec probe;
|
||||||
u16 closed_port = 1;
|
|
||||||
u16 filtered_port = 1;
|
|
||||||
u16 port = 0;
|
|
||||||
int state = -1;
|
|
||||||
Port *np;
|
|
||||||
|
|
||||||
/* Use the first specified port for ping traceroutes */
|
probe = t->pingprobe;
|
||||||
if (o.pingscan) {
|
/* If this is an IP protocol probe, fill in some fields for some common
|
||||||
if (o.pingtype & PINGTYPE_TCP_USE_SYN)
|
protocols. We cheat and store them in the TCP-, UDP-, and ICMP-specific
|
||||||
return scanlists->syn_ping_ports[0];
|
fields. Traceroute::sendProbe checks for them there. */
|
||||||
else if (o.pingtype & PINGTYPE_TCP_USE_ACK)
|
if (probe.type == PS_PROTO) {
|
||||||
return scanlists->ack_ping_ports[0];
|
if (probe.proto == IPPROTO_TCP) {
|
||||||
else if (o.pingtype & PINGTYPE_UDP)
|
probe.pd.tcp.flags = TH_ACK;
|
||||||
return scanlists->udp_ping_ports[0];
|
probe.pd.tcp.dport = get_random_u16();
|
||||||
else if (o.pingtype & PINGTYPE_PROTO) {
|
} else if (probe.proto == IPPROTO_UDP) {
|
||||||
// Initialize protocol header information
|
probe.pd.udp.dport = get_random_u16();
|
||||||
port = scanlists->proto_ping_ports[0];
|
} else if (probe.proto == IPPROTO_ICMP) {
|
||||||
goto ipproto;
|
probe.pd.icmp.type = ICMP_ECHO;
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (proto == IPPROTO_TCP) {
|
|
||||||
/* can't use filtered ports for tcp */
|
|
||||||
filtered_port = 0;
|
|
||||||
open_port = (!scaninfo.open_response) ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For UDP we try for a closed port, then an open one. For everything else
|
|
||||||
* we try the opposite. When all else fails, we try for filtered */
|
|
||||||
if (proto == IPPROTO_UDP) {
|
|
||||||
if (closed_port && t->ports.getStateCounts (proto, scaninfo.closed_state))
|
|
||||||
state = scaninfo.closed_state;
|
|
||||||
else if (open_port && t->ports.getStateCounts (proto, scaninfo.open_state))
|
|
||||||
state = scaninfo.open_state;
|
|
||||||
} else {
|
|
||||||
if (open_port && t->ports.getStateCounts (proto, scaninfo.open_state))
|
|
||||||
state = scaninfo.open_state;
|
|
||||||
else if (closed_port && t->ports.getStateCounts (proto, scaninfo.closed_state))
|
|
||||||
state = scaninfo.closed_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == -1 && filtered_port &&
|
|
||||||
t->ports.getStateCounts (proto, PORT_FILTERED)) {
|
|
||||||
state = PORT_FILTERED;
|
|
||||||
if (o.verbose)
|
|
||||||
log_write (LOG_PLAIN, "%s: only filtered %s available, results may be incorrect\n",
|
|
||||||
t->targetipstr (), scaninfo.ipproto ? "protocols" : "ports");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
np = t->ports.nextPort (NULL, proto, state);
|
|
||||||
if (!np)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
port = np->portno;
|
|
||||||
|
|
||||||
ipproto:
|
|
||||||
/* If this is a protocol scan/ping traceroute and we are using
|
|
||||||
* one of the major protocols, set up the required information
|
|
||||||
* so we include the correct protocol headers */
|
|
||||||
if (proto == IPPROTO_IP) {
|
|
||||||
if (port == IPPROTO_TCP) {
|
|
||||||
scaninfo.initial_proto = IPPROTO_TCP;
|
|
||||||
scaninfo.scan_flags = TH_ACK;
|
|
||||||
scaninfo.open_response = TH_RST;
|
|
||||||
scaninfo.closed_response = TH_RST;
|
|
||||||
} else if (port == IPPROTO_UDP) {
|
|
||||||
scaninfo.initial_proto = IPPROTO_UDP;
|
|
||||||
} else if (port == IPPROTO_ICMP) {
|
|
||||||
scaninfo.initial_proto = IPPROTO_ICMP;
|
|
||||||
scaninfo.icmp_type = ICMP_ECHO;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return port;
|
|
||||||
|
return probe;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* finite state machine that reads all incoming packets
|
/* finite state machine that reads all incoming packets
|
||||||
@@ -480,7 +341,7 @@ Traceroute::readTraceResponses () {
|
|||||||
if (tp->ipreplysrc.s_addr)
|
if (tp->ipreplysrc.s_addr)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((tg->proto == IPPROTO_UDP && (ip2 && ip2->ip_p == IPPROTO_UDP)) ||
|
if ((tg->probe.proto == IPPROTO_UDP && (ip2 && ip2->ip_p == IPPROTO_UDP)) ||
|
||||||
(icmp->icmp_type == ICMP_DEST_UNREACH)) {
|
(icmp->icmp_type == ICMP_DEST_UNREACH)) {
|
||||||
switch (icmp->icmp_code) {
|
switch (icmp->icmp_code) {
|
||||||
/* reply from a closed port */
|
/* reply from a closed port */
|
||||||
@@ -502,7 +363,7 @@ Traceroute::readTraceResponses () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* icmp ping scan replies */
|
/* icmp ping scan replies */
|
||||||
else if (tg->proto == IPPROTO_ICMP && (icmp->icmp_type == ICMP_ECHOREPLY ||
|
else if (tg->probe.proto == IPPROTO_ICMP && (icmp->icmp_type == ICMP_ECHOREPLY ||
|
||||||
icmp->icmp_type == ICMP_ADDRESSREPLY || icmp->icmp_type == ICMP_TIMESTAMPREPLY)) {
|
icmp->icmp_type == ICMP_ADDRESSREPLY || icmp->icmp_type == ICMP_TIMESTAMPREPLY)) {
|
||||||
if (tp->probeType () == PROBE_TTL) {
|
if (tp->probeType () == PROBE_TTL) {
|
||||||
tg->setHopDistance (get_initial_ttl_guess (ip->ip_ttl), ip->ip_ttl);
|
tg->setHopDistance (get_initial_ttl_guess (ip->ip_ttl), ip->ip_ttl);
|
||||||
@@ -562,8 +423,8 @@ Traceroute::readTraceResponses () {
|
|||||||
|
|
||||||
/* We have reached the destination host and the
|
/* We have reached the destination host and the
|
||||||
* trace can stop for this target */
|
* trace can stop for this target */
|
||||||
if (tcp->th_flags & scaninfo.open_response || tcp->th_flags & scaninfo.closed_response) {
|
if ((tcp->th_flags & TH_RST) == TH_RST
|
||||||
|
|| (tcp->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) {
|
||||||
/* We might have got a late reply */
|
/* We might have got a late reply */
|
||||||
if (tp->timing.getState () == P_TIMEDOUT)
|
if (tp->timing.getState () == P_TIMEDOUT)
|
||||||
tp->timing.setState (P_OK);
|
tp->timing.setState (P_OK);
|
||||||
@@ -643,16 +504,14 @@ Traceroute::readTraceResponses () {
|
|||||||
inline void
|
inline void
|
||||||
Traceroute::sendTTLProbes (vector < Target * >&Targets, vector < Target * >&valid_targets) {
|
Traceroute::sendTTLProbes (vector < Target * >&Targets, vector < Target * >&valid_targets) {
|
||||||
Target *t = NULL;
|
Target *t = NULL;
|
||||||
long dport = 0;
|
struct probespec probe;
|
||||||
u16 sport = 0;
|
u16 sport = 0;
|
||||||
u8 proto;
|
|
||||||
TraceProbe *tp;
|
TraceProbe *tp;
|
||||||
TraceGroup *tg = NULL;
|
TraceGroup *tg = NULL;
|
||||||
vector < Target * >::iterator it = Targets.begin ();
|
vector < Target * >::iterator it = Targets.begin ();
|
||||||
|
|
||||||
for (; it != Targets.end (); ++it) {
|
for (; it != Targets.end (); ++it) {
|
||||||
t = *it;
|
t = *it;
|
||||||
proto = scaninfo.initial_proto;
|
|
||||||
|
|
||||||
/* No point in tracing directly connected nodes */
|
/* No point in tracing directly connected nodes */
|
||||||
if (t->directlyConnected ())
|
if (t->directlyConnected ())
|
||||||
@@ -665,36 +524,19 @@ Traceroute::sendTTLProbes (vector < Target * >&Targets, vector < Target * >&vali
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Determine active port to probe */
|
/* Determine active port to probe */
|
||||||
if ((dport = getTracePort (proto, t)) == -1) {
|
probe = getTraceProbe (t);
|
||||||
/* If we could not find a responsive tcp port then try
|
if (probe.type == PS_NONE) {
|
||||||
* to find a responsive udp port */
|
|
||||||
if (o.udpscan && proto != IPPROTO_UDP) {
|
|
||||||
proto = IPPROTO_UDP;
|
|
||||||
dport = getTracePort (proto, t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dport == -1) {
|
|
||||||
if (o.verbose > 1)
|
if (o.verbose > 1)
|
||||||
log_write (LOG_STDOUT, "%s: no responsive %s\n",
|
log_write (LOG_STDOUT, "%s: no responsive %s\n",
|
||||||
t->targetipstr (), scaninfo.ipproto ? "protocols" : "ports");
|
t->targetipstr (), "probes");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is a protocol scan/ping, getTracePort() returns
|
|
||||||
* a protocol number so we need a random destination
|
|
||||||
* port */
|
|
||||||
if (scaninfo.ipproto) {
|
|
||||||
proto = dport;
|
|
||||||
dport = get_random_u16 ();
|
|
||||||
scaninfo.initial_proto = IPPROTO_IP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* start off with a random source port and increment
|
/* start off with a random source port and increment
|
||||||
* it for each probes sent. The source port is the
|
* it for each probes sent. The source port is the
|
||||||
* distinguishing value used to identify each probe */
|
* distinguishing value used to identify each probe */
|
||||||
sport = get_random_u16 ();
|
sport = get_random_u16 ();
|
||||||
tg = new TraceGroup (t->v4hostip ()->s_addr, sport, dport, proto);
|
tg = new TraceGroup (t->v4hostip ()->s_addr, sport, probe);
|
||||||
tg->src_mac_addr = t->SrcMACAddress ();
|
tg->src_mac_addr = t->SrcMACAddress ();
|
||||||
tg->nxt_mac_addr = t->NextHopMACAddress ();
|
tg->nxt_mac_addr = t->NextHopMACAddress ();
|
||||||
tg->sport++;
|
tg->sport++;
|
||||||
@@ -705,8 +547,8 @@ Traceroute::sendTTLProbes (vector < Target * >&Targets, vector < Target * >&vali
|
|||||||
if (t->distance != -1) {
|
if (t->distance != -1) {
|
||||||
tg->setHopDistance (0, t->distance);
|
tg->setHopDistance (0, t->distance);
|
||||||
} else {
|
} else {
|
||||||
tp = new TraceProbe (proto, t->v4hostip ()->s_addr,
|
tp = new TraceProbe (t->v4hostip ()->s_addr,
|
||||||
t->v4sourceip ()->s_addr, sport, dport);
|
t->v4sourceip ()->s_addr, sport, probe);
|
||||||
tp->setProbeType (PROBE_TTL);
|
tp->setProbeType (PROBE_TTL);
|
||||||
tp->ttl = o.ttl;
|
tp->ttl = o.ttl;
|
||||||
tg->TraceProbes[sport] = tp;
|
tg->TraceProbes[sport] = tp;
|
||||||
@@ -731,9 +573,9 @@ Traceroute::sendProbe (TraceProbe * tp) {
|
|||||||
struct eth_nfo eth;
|
struct eth_nfo eth;
|
||||||
struct eth_nfo *ethptr = NULL;
|
struct eth_nfo *ethptr = NULL;
|
||||||
|
|
||||||
if (scaninfo.scan_flags & TH_ACK)
|
if (tp->probe.type == PS_TCP && (tp->probe.pd.tcp.flags & TH_ACK) == TH_ACK)
|
||||||
ack = rand ();
|
ack = rand ();
|
||||||
if (scaninfo.scan_flags & TH_SYN) {
|
if (tp->probe.type == PS_TCP && (tp->probe.pd.tcp.flags & TH_SYN) == TH_SYN) {
|
||||||
tcpopts = (u8 *) "\x02\x04\x05\xb4";
|
tcpopts = (u8 *) "\x02\x04\x05\xb4";
|
||||||
tcpoptslen = 4;
|
tcpoptslen = 4;
|
||||||
}
|
}
|
||||||
@@ -764,7 +606,6 @@ Traceroute::sendProbe (TraceProbe * tp) {
|
|||||||
}
|
}
|
||||||
tg->sport++;
|
tg->sport++;
|
||||||
tp->ttl = tg->ttl;
|
tp->ttl = tg->ttl;
|
||||||
tp->dport = tg->dport;
|
|
||||||
tg->incRemaining ();
|
tg->incRemaining ();
|
||||||
} else {
|
} else {
|
||||||
/* this probe is a retransmission */
|
/* this probe is a retransmission */
|
||||||
@@ -781,29 +622,34 @@ Traceroute::sendProbe (TraceProbe * tp) {
|
|||||||
else
|
else
|
||||||
source = o.decoys[decoy];
|
source = o.decoys[decoy];
|
||||||
|
|
||||||
switch (tp->proto) {
|
/* For TCP, UDP, and ICMP, also check if the probe is an IP proto probe
|
||||||
case IPPROTO_TCP:
|
whose protocol happens to be one of those protocols. The
|
||||||
|
protocol-specific fields will have been filled in by
|
||||||
|
Traceroute::getTraceProbe. */
|
||||||
|
if (tp->probe.type == PS_TCP
|
||||||
|
|| (tp->probe.type == PS_PROTO && tp->probe.proto == IPPROTO_TCP)) {
|
||||||
packet = build_tcp_raw (&source, &tp->ipdst, tp->ttl, get_random_u16 (),
|
packet = build_tcp_raw (&source, &tp->ipdst, tp->ttl, get_random_u16 (),
|
||||||
get_random_u8 (), 0, NULL, 0, tp->sport, tp->dport,
|
get_random_u8 (), false, NULL, 0, tp->sport, tp->probe.pd.tcp.dport,
|
||||||
get_random_u32 (), ack, 0, scaninfo.scan_flags,
|
get_random_u32 (), ack, 0, tp->probe.pd.tcp.flags,
|
||||||
get_random_u16 (), 0, tcpopts, tcpoptslen,
|
get_random_u16 (), 0, tcpopts, tcpoptslen,
|
||||||
o.extra_payload, o.extra_payload_length, &packetlen);
|
o.extra_payload, o.extra_payload_length, &packetlen);
|
||||||
break;
|
} else if (tp->probe.type == PS_UDP
|
||||||
case IPPROTO_UDP:
|
|| (tp->probe.type == PS_PROTO && tp->probe.proto == IPPROTO_UDP)) {
|
||||||
packet = build_udp_raw (&source, &tp->ipdst, tp->ttl, get_random_u16 (),
|
packet = build_udp_raw (&source, &tp->ipdst, tp->ttl, get_random_u16 (),
|
||||||
get_random_u8 (), false,
|
get_random_u8 (), false,
|
||||||
NULL, 0, tp->sport,
|
NULL, 0, tp->sport,
|
||||||
tp->dport, o.extra_payload, o.extra_payload_length, &packetlen);
|
tp->probe.pd.udp.dport, o.extra_payload, o.extra_payload_length, &packetlen);
|
||||||
break;
|
} else if (tp->probe.type == PS_ICMP
|
||||||
case IPPROTO_ICMP:
|
|| (tp->probe.type == PS_PROTO && tp->probe.proto == IPPROTO_ICMP)) {
|
||||||
packet = build_icmp_raw (&source, &tp->ipdst, tp->ttl, 0, 0, false,
|
packet = build_icmp_raw (&source, &tp->ipdst, tp->ttl, 0, 0, false,
|
||||||
NULL, 0, get_random_u16 (), tp->sport, scaninfo.icmp_type, 0,
|
NULL, 0, get_random_u16 (), tp->sport, tp->probe.pd.icmp.type, 0,
|
||||||
o.extra_payload, o.extra_payload_length, &packetlen);
|
o.extra_payload, o.extra_payload_length, &packetlen);
|
||||||
break;
|
} else if (tp->probe.type == PS_PROTO) {
|
||||||
default:
|
packet = build_ip_raw(&source, &tp->ipdst, tp->probe.proto, tp->ttl,
|
||||||
packet = build_ip_raw (&source, &tp->ipdst, tp->proto, tp->ttl, tp->sport,
|
tp->sport, get_random_u8 (), false, NULL, 0,
|
||||||
get_random_u8 (), false, NULL, 0, o.extra_payload,
|
o.extra_payload, o.extra_payload_length, &packetlen);
|
||||||
o.extra_payload_length, &packetlen);
|
} else {
|
||||||
|
fatal("Unknown probespec type %d in %s\n", tp->probe.type, __func__);
|
||||||
}
|
}
|
||||||
send_ip_packet (fd, ethptr, packet, packetlen);
|
send_ip_packet (fd, ethptr, packet, packetlen);
|
||||||
free (packet);
|
free (packet);
|
||||||
@@ -891,8 +737,8 @@ Traceroute::trace (vector < Target * >&Targets) {
|
|||||||
if (tg->getState () != G_OK || !tg->hopDistance)
|
if (tg->getState () != G_OK || !tg->hopDistance)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
tp = new TraceProbe (tg->proto, t->v4hostip ()->s_addr,
|
tp = new TraceProbe (t->v4hostip ()->s_addr,
|
||||||
t->v4sourceip ()->s_addr, tg->sport, 0);
|
t->v4sourceip ()->s_addr, tg->sport, tg->probe);
|
||||||
sendProbe (tp);
|
sendProbe (tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -993,7 +839,6 @@ Traceroute::outputTarget (Target * t) {
|
|||||||
TraceGroup *tg = NULL;
|
TraceGroup *tg = NULL;
|
||||||
NmapOutputTable *Tbl = NULL;
|
NmapOutputTable *Tbl = NULL;
|
||||||
|
|
||||||
struct protoent *proto;
|
|
||||||
bool last_consolidation = false;
|
bool last_consolidation = false;
|
||||||
bool common_consolidation = false;
|
bool common_consolidation = false;
|
||||||
char row_count = 0;
|
char row_count = 0;
|
||||||
@@ -1108,11 +953,14 @@ Traceroute::outputTarget (Target * t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Traceroute header and footer */
|
/* Traceroute header and footer */
|
||||||
proto = nmap_getprotbynum(htons(tg->proto));
|
if (tg->probe.type == PS_TCP) {
|
||||||
if(o.ipprotscan || (o.pingscan && !(o.pingtype & PINGTYPE_TCP || o.pingtype & PINGTYPE_UDP)))
|
log_write(LOG_PLAIN, "\nTRACEROUTE (using port %d/%s)\n", tg->probe.pd.tcp.dport, proto2ascii(tg->probe.proto));
|
||||||
log_write(LOG_PLAIN, "\nTRACEROUTE (using proto %d/%s)\n", tg->proto, proto?proto->p_name:"unknown");
|
} else if (tg->probe.type == PS_UDP) {
|
||||||
else
|
log_write(LOG_PLAIN, "\nTRACEROUTE (using port %d/%s)\n", tg->probe.pd.udp.dport, proto2ascii(tg->probe.proto));
|
||||||
log_write(LOG_PLAIN, "\nTRACEROUTE (using port %d/%s)\n", tg->dport, proto2ascii(tg->proto));
|
} else if (tg->probe.type == PS_ICMP || tg->probe.type == PS_PROTO) {
|
||||||
|
struct protoent *proto = nmap_getprotbynum(htons(tg->probe.proto));
|
||||||
|
log_write(LOG_PLAIN, "\nTRACEROUTE (using proto %d/%s)\n", tg->probe.proto, proto?proto->p_name:"unknown");
|
||||||
|
}
|
||||||
log_write (LOG_PLAIN, "%s", Tbl->printableTable(NULL));
|
log_write (LOG_PLAIN, "%s", Tbl->printableTable(NULL));
|
||||||
|
|
||||||
if(G_TTL(tg->getState()))
|
if(G_TTL(tg->getState()))
|
||||||
@@ -1130,19 +978,23 @@ Traceroute::outputXMLTrace(TraceGroup * tg) {
|
|||||||
map < u16, TraceProbe * >::const_iterator it;
|
map < u16, TraceProbe * >::const_iterator it;
|
||||||
TraceProbe *tp = NULL;
|
TraceProbe *tp = NULL;
|
||||||
const char *hostname_tmp = NULL;
|
const char *hostname_tmp = NULL;
|
||||||
struct protoent *proto;
|
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
long timediff;
|
long timediff;
|
||||||
short ttl_count;
|
short ttl_count;
|
||||||
|
|
||||||
/* XML traceroute header */
|
/* XML traceroute header */
|
||||||
log_write(LOG_XML, "<trace ");
|
log_write(LOG_XML, "<trace ");
|
||||||
if ((o.pingscan && (o.pingtype & PINGTYPE_TCP || o.pingtype & PINGTYPE_UDP)) || (!o.ipprotscan && !o.pingscan))
|
if (tg->probe.type == PS_TCP) {
|
||||||
log_write(LOG_XML, "port=\"%d\" ", tg->dport);
|
log_write(LOG_XML, "port=\"%d\" ", tg->probe.pd.tcp.dport);
|
||||||
if((proto = nmap_getprotbynum(htons(tg->proto))))
|
} else if (tg->probe.type == PS_UDP) {
|
||||||
log_write(LOG_XML, "proto=\"%s\"", proto->p_name);
|
log_write(LOG_XML, "port=\"%d\" ", tg->probe.pd.udp.dport);
|
||||||
else
|
} else if (tg->probe.type == PS_ICMP || tg->probe.type == PS_PROTO) {
|
||||||
log_write(LOG_XML, "proto=\"%d\"", tg->proto);
|
struct protoent *proto = nmap_getprotbynum(htons(tg->probe.proto));
|
||||||
|
if (proto == NULL)
|
||||||
|
log_write(LOG_XML, "proto=\"%d\"", tg->probe.proto);
|
||||||
|
else
|
||||||
|
log_write(LOG_XML, "proto=\"%s\"", proto->p_name);
|
||||||
|
}
|
||||||
log_write(LOG_XML, ">\n");
|
log_write(LOG_XML, ">\n");
|
||||||
|
|
||||||
/* add missing hosts host from the common path */
|
/* add missing hosts host from the common path */
|
||||||
@@ -1185,11 +1037,10 @@ Traceroute::outputXMLTrace(TraceGroup * tg) {
|
|||||||
log_flush(LOG_XML);
|
log_flush(LOG_XML);
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceGroup::TraceGroup (u32 dip, u16 sport, u16 dport, u8 proto) {
|
TraceGroup::TraceGroup (u32 dip, u16 sport, struct probespec& probe) {
|
||||||
this->ipdst = dip;
|
this->ipdst = dip;
|
||||||
this->dport = dport;
|
|
||||||
this->sport = sport;
|
this->sport = sport;
|
||||||
this->proto = proto;
|
this->probe = probe;
|
||||||
ttl = 0;
|
ttl = 0;
|
||||||
state = G_OK;
|
state = G_OK;
|
||||||
remaining = 0;
|
remaining = 0;
|
||||||
@@ -1263,7 +1114,7 @@ TraceGroup::retransmissions (vector < TraceProbe * >&retrans) {
|
|||||||
if (droppedPackets > 10 && (droppedPackets /
|
if (droppedPackets > 10 && (droppedPackets /
|
||||||
((double) droppedPackets + repliedPackets) > threshold)) {
|
((double) droppedPackets + repliedPackets) > threshold)) {
|
||||||
if (!scanDelay)
|
if (!scanDelay)
|
||||||
scanDelay = (proto == IPPROTO_TCP) ? 5 : 50;
|
scanDelay = (probe.type == PS_TCP) ? 5 : 50;
|
||||||
else
|
else
|
||||||
scanDelay = MIN (scanDelay * 2, MAX (scanDelay, 800));
|
scanDelay = MIN (scanDelay * 2, MAX (scanDelay, 800));
|
||||||
droppedPackets = 0;
|
droppedPackets = 0;
|
||||||
@@ -1349,10 +1200,9 @@ TraceGroup::setHopDistance (u8 hop_distance, u8 ttl) {
|
|||||||
return this->hopDistance;
|
return this->hopDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceProbe::TraceProbe (u8 proto, u32 dip, u32 sip, u16 sport, u16 dport) {
|
TraceProbe::TraceProbe (u32 dip, u32 sip, u16 sport, struct probespec& probe) {
|
||||||
this->proto = proto;
|
|
||||||
this->sport = sport;
|
this->sport = sport;
|
||||||
this->dport = dport;
|
this->probe = probe;
|
||||||
ipdst.s_addr = dip;
|
ipdst.s_addr = dip;
|
||||||
ipsrc.s_addr = sip;
|
ipsrc.s_addr = sip;
|
||||||
ipreplysrc.s_addr = 0;
|
ipreplysrc.s_addr = 0;
|
||||||
|
|||||||
27
traceroute.h
27
traceroute.h
@@ -172,20 +172,6 @@
|
|||||||
|
|
||||||
class NmapOutputTable;
|
class NmapOutputTable;
|
||||||
|
|
||||||
/* various pieces of scan data used by
|
|
||||||
* traceroute to find responsive ports
|
|
||||||
* and match probes */
|
|
||||||
struct scan_info {
|
|
||||||
u8 initial_proto;
|
|
||||||
u8 icmp_type;
|
|
||||||
u8 scan_flags;
|
|
||||||
u8 open_response;
|
|
||||||
u8 open_state;
|
|
||||||
u8 closed_response;
|
|
||||||
u8 closed_state;
|
|
||||||
bool ipproto;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Keeps track of each probes timing state */
|
/* Keeps track of each probes timing state */
|
||||||
class TimeInfo {
|
class TimeInfo {
|
||||||
public:
|
public:
|
||||||
@@ -217,7 +203,7 @@ class TimeInfo {
|
|||||||
* ttl. Traceprobes are stored inside tracegroups. */
|
* ttl. Traceprobes are stored inside tracegroups. */
|
||||||
class TraceProbe {
|
class TraceProbe {
|
||||||
public:
|
public:
|
||||||
TraceProbe (u8 proto, u32 dip, u32 sip, u16 sport, u16 dport);
|
TraceProbe (u32 dip, u32 sip, u16 sport, struct probespec& probe);
|
||||||
~TraceProbe ();
|
~TraceProbe ();
|
||||||
|
|
||||||
/* Return the ip address and resolved hostname in a string
|
/* Return the ip address and resolved hostname in a string
|
||||||
@@ -244,9 +230,8 @@ class TraceProbe {
|
|||||||
struct in_addr ipdst;
|
struct in_addr ipdst;
|
||||||
struct in_addr ipsrc;
|
struct in_addr ipsrc;
|
||||||
struct in_addr ipreplysrc;
|
struct in_addr ipreplysrc;
|
||||||
|
struct probespec probe;
|
||||||
u16 sport;
|
u16 sport;
|
||||||
u16 dport;
|
|
||||||
u8 proto;
|
|
||||||
u8 ttl;
|
u8 ttl;
|
||||||
char **hostname;
|
char **hostname;
|
||||||
|
|
||||||
@@ -260,7 +245,7 @@ class TraceProbe {
|
|||||||
* the ip */
|
* the ip */
|
||||||
class TraceGroup {
|
class TraceGroup {
|
||||||
public:
|
public:
|
||||||
TraceGroup (u32 dip, u16 dport, u16 sport, u8 proto);
|
TraceGroup (u32 dip, u16 sport, struct probespec& probe);
|
||||||
~TraceGroup ();
|
~TraceGroup ();
|
||||||
/* map of all probes sent to this TraceGroups IP address. The map
|
/* map of all probes sent to this TraceGroups IP address. The map
|
||||||
* is keyed by the source port of the probe */
|
* is keyed by the source port of the probe */
|
||||||
@@ -295,9 +280,8 @@ class TraceGroup {
|
|||||||
u16 repliedPackets;
|
u16 repliedPackets;
|
||||||
u8 consecTimeouts;
|
u8 consecTimeouts;
|
||||||
/* protocol information */
|
/* protocol information */
|
||||||
u8 proto;
|
struct probespec probe;
|
||||||
u16 sport;
|
u16 sport;
|
||||||
u16 dport;
|
|
||||||
u32 ipdst;
|
u32 ipdst;
|
||||||
/* estimated ttl distance to target */
|
/* estimated ttl distance to target */
|
||||||
u8 hopDistance;
|
u8 hopDistance;
|
||||||
@@ -344,7 +328,6 @@ class Traceroute {
|
|||||||
* the groups destination IP address */
|
* the groups destination IP address */
|
||||||
std::map < u32, TraceGroup * >TraceGroups;
|
std::map < u32, TraceGroup * >TraceGroups;
|
||||||
|
|
||||||
struct scan_info scaninfo;
|
|
||||||
const struct scan_lists * scanlists;
|
const struct scan_lists * scanlists;
|
||||||
Target **hops;
|
Target **hops;
|
||||||
pcap_t *pd;
|
pcap_t *pd;
|
||||||
@@ -355,7 +338,7 @@ class Traceroute {
|
|||||||
/* called by outputTarget to log XML data */
|
/* called by outputTarget to log XML data */
|
||||||
void outputXMLTrace (TraceGroup * tg);
|
void outputXMLTrace (TraceGroup * tg);
|
||||||
/* find a responsive port for t based on scan results */
|
/* find a responsive port for t based on scan results */
|
||||||
int getTracePort (u8 proto, Target * t);
|
const probespec getTraceProbe (Target * t);
|
||||||
/* sendTTLProbes() guesses the hop distance to a
|
/* sendTTLProbes() guesses the hop distance to a
|
||||||
* target by actively probing the host. */
|
* target by actively probing the host. */
|
||||||
void sendTTLProbes (std::vector < Target * >&Targets, std::vector < Target * >&vaild_targets);
|
void sendTTLProbes (std::vector < Target * >&Targets, std::vector < Target * >&vaild_targets);
|
||||||
|
|||||||
Reference in New Issue
Block a user