mirror of
https://github.com/nmap/nmap.git
synced 2025-12-09 22:21:29 +00:00
Better handling for ICMP Host Unreachable
This commit is contained in:
@@ -1,5 +1,10 @@
|
|||||||
#Nmap Changelog ($Id$); -*-text-*-
|
#Nmap Changelog ($Id$); -*-text-*-
|
||||||
|
|
||||||
|
o Nmap no longer considers an ICMP Host Unreachable as confirmation that a
|
||||||
|
target is down, in accordance with RFC 1122 which says these errors may be
|
||||||
|
transient. Instead, the probe will be destroyed and other probes used to
|
||||||
|
determine aliveness. [Daniel Miller]
|
||||||
|
|
||||||
o [NSE][GH#711] New script openflow-info gathers preferred and supported
|
o [NSE][GH#711] New script openflow-info gathers preferred and supported
|
||||||
protocol versions from OpenFlow devices [Jay Smith, Mak Kolybabi]
|
protocol versions from OpenFlow devices [Jay Smith, Mak Kolybabi]
|
||||||
|
|
||||||
|
|||||||
@@ -2014,8 +2014,8 @@ static bool ultrascan_host_pspec_update(UltraScanInfo *USI, HostScanStats *hss,
|
|||||||
int oldstate = hss->target->flags;
|
int oldstate = hss->target->flags;
|
||||||
/* If the host is already up, ignore any further updates. */
|
/* If the host is already up, ignore any further updates. */
|
||||||
if (hss->target->flags != HOST_UP) {
|
if (hss->target->flags != HOST_UP) {
|
||||||
assert(newstate == HOST_UP || newstate == HOST_DOWN);
|
// don't allow HOST_UNKNOWN to override a known state.
|
||||||
hss->target->flags = newstate;
|
hss->target->flags = (newstate == HOST_UNKNOWN ? oldstate : newstate);
|
||||||
/* For port scans (not -sn) where output may be delayed until more scan
|
/* For port scans (not -sn) where output may be delayed until more scan
|
||||||
* phases are done, emit a hosthint element during host discovery when a
|
* phases are done, emit a hosthint element during host discovery when a
|
||||||
* target is found to be up. */
|
* target is found to be up. */
|
||||||
@@ -2066,12 +2066,12 @@ void ultrascan_host_probe_update(UltraScanInfo *USI, HostScanStats *hss,
|
|||||||
bool adjust_timing = adjust_timing_hint;
|
bool adjust_timing = adjust_timing_hint;
|
||||||
bool adjust_ping = adjust_timing_hint;
|
bool adjust_ping = adjust_timing_hint;
|
||||||
|
|
||||||
/* If we got a response that meant "down", then it was an ICMP error. These
|
/* If we got a response that meant "down" or "unknown", then it was an ICMP error. These
|
||||||
are often rate-limited (RFC 1812) or generated by a different host. We only
|
are often rate-limited (RFC 1812) or generated by a different host. We only
|
||||||
allow such responses to increase, not decrease, scanning speed by
|
allow such responses to increase, not decrease, scanning speed by
|
||||||
disallowing drops (probe->tryno > 0), and we don't allow changing the ping
|
disallowing drops (probe->tryno > 0), and we don't allow changing the ping
|
||||||
probe to something that's likely to get dropped. */
|
probe to something that's likely to get dropped. */
|
||||||
if (rcvdtime != NULL && newstate == HOST_DOWN) {
|
if (rcvdtime != NULL && newstate != HOST_UP) {
|
||||||
if (probe->tryno > 0) {
|
if (probe->tryno > 0) {
|
||||||
if (adjust_timing && o.debugging > 1)
|
if (adjust_timing && o.debugging > 1)
|
||||||
log_write(LOG_PLAIN, "Response for %s means new state is down; not adjusting timing.\n", hss->target->targetipstr());
|
log_write(LOG_PLAIN, "Response for %s means new state is down; not adjusting timing.\n", hss->target->targetipstr());
|
||||||
|
|||||||
@@ -666,24 +666,35 @@ int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
|
|||||||
if (probenum >= listsz)
|
if (probenum >= listsz)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* Destination unreachable. */
|
||||||
if ((hdr.proto == IPPROTO_ICMP && ping->type == 3)
|
if ((hdr.proto == IPPROTO_ICMP && ping->type == 3)
|
||||||
|| (hdr.proto == IPPROTO_ICMPV6 && ping->type == 1)) {
|
|| (hdr.proto == IPPROTO_ICMPV6 && ping->type == 1)) {
|
||||||
/* Destination unreachable. */
|
// If it's Port or Proto unreachable and the address matches, it's up.
|
||||||
if (sockaddr_storage_cmp(&target_dst, &hdr.src) == 0) {
|
if (((hdr.proto == IPPROTO_ICMP && (ping->code == 2 || ping->code == 3))
|
||||||
|
|| (hdr.proto == IPPROTO_ICMPV6 && ping->code == 4))
|
||||||
|
&& sockaddr_storage_cmp(&target_dst, &hdr.src) == 0) {
|
||||||
/* The ICMP or ICMPv6 error came directly from the target, so it's up. */
|
/* The ICMP or ICMPv6 error came directly from the target, so it's up. */
|
||||||
goodone = true;
|
goodone = true;
|
||||||
newstate = HOST_UP;
|
newstate = HOST_UP;
|
||||||
} else {
|
|
||||||
goodone = true;
|
|
||||||
newstate = HOST_DOWN;
|
|
||||||
}
|
|
||||||
if (o.debugging) {
|
if (o.debugging) {
|
||||||
if ((hdr.proto == IPPROTO_ICMP && ping->code == 3)
|
log_write(LOG_STDOUT, "Got port/proto unreachable for %s\n", hss->target->targetipstr());
|
||||||
|| (hdr.proto == IPPROTO_ICMPV6 && ping->code == 4))
|
}
|
||||||
log_write(LOG_STDOUT, "Got port unreachable for %s\n", hss->target->targetipstr());
|
}
|
||||||
else
|
else {
|
||||||
|
/* For other codes, see RFC 1122:
|
||||||
|
* A Destination Unreachable message that is received with code
|
||||||
|
* 0 (Net), 1 (Host), or 5 (Bad Source Route) may result from a
|
||||||
|
* routing transient and MUST therefore be interpreted as only
|
||||||
|
* a hint, not proof, that the specified destination is unreachable
|
||||||
|
*/
|
||||||
|
// Still, it's a response so we should destroy the matching probe.
|
||||||
|
goodone = true;
|
||||||
|
newstate = HOST_UNKNOWN;
|
||||||
|
adjust_timing = false;
|
||||||
|
if (o.debugging) {
|
||||||
log_write(LOG_STDOUT, "Got destination unreachable for %s\n", hss->target->targetipstr());
|
log_write(LOG_STDOUT, "Got destination unreachable for %s\n", hss->target->targetipstr());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if ((hdr.proto == IPPROTO_ICMP && ping->type == 11)
|
} else if ((hdr.proto == IPPROTO_ICMP && ping->type == 11)
|
||||||
|| (hdr.proto == IPPROTO_ICMPV6 && ping->type == 3)) {
|
|| (hdr.proto == IPPROTO_ICMPV6 && ping->type == 3)) {
|
||||||
if (o.debugging)
|
if (o.debugging)
|
||||||
@@ -692,24 +703,28 @@ int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
|
|||||||
newstate = HOST_DOWN;
|
newstate = HOST_DOWN;
|
||||||
/* I don't want anything to do with timing this. */
|
/* I don't want anything to do with timing this. */
|
||||||
adjust_timing = false;
|
adjust_timing = false;
|
||||||
} else if (hdr.proto == IPPROTO_ICMP && ping->type == 4) {
|
} else if (hdr.proto == IPPROTO_ICMP) {
|
||||||
|
if (ping->type == 4) {
|
||||||
if (o.debugging)
|
if (o.debugging)
|
||||||
log_write(LOG_STDOUT, "Got ICMP source quench\n");
|
log_write(LOG_STDOUT, "Got ICMP source quench\n");
|
||||||
usleep(50000);
|
usleep(50000);
|
||||||
} else if (hdr.proto == IPPROTO_ICMPV6 && ping->type == 4) {
|
} else {
|
||||||
if (o.debugging)
|
|
||||||
log_write(LOG_STDOUT, "Got ICMPv6 Parameter Problem\n");
|
|
||||||
} else if (hdr.proto == IPPROTO_ICMP) {
|
|
||||||
if (o.debugging) {
|
if (o.debugging) {
|
||||||
log_write(LOG_STDOUT, "Got ICMP message type %d code %d\n",
|
log_write(LOG_STDOUT, "Got ICMP message type %d code %d\n",
|
||||||
ping->type, ping->code);
|
ping->type, ping->code);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (hdr.proto == IPPROTO_ICMPV6) {
|
} else if (hdr.proto == IPPROTO_ICMPV6) {
|
||||||
|
if (ping->type == 4) {
|
||||||
|
if (o.debugging)
|
||||||
|
log_write(LOG_STDOUT, "Got ICMPv6 Parameter Problem\n");
|
||||||
|
} else {
|
||||||
if (o.debugging)
|
if (o.debugging)
|
||||||
log_write(LOG_STDOUT, "Got ICMPv6 message type %d code %d\n",
|
log_write(LOG_STDOUT, "Got ICMPv6 message type %d code %d\n",
|
||||||
ping->type, ping->code);
|
ping->type, ping->code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (hdr.proto == IPPROTO_TCP && USI->ptech.rawtcpscan) {
|
} else if (hdr.proto == IPPROTO_TCP && USI->ptech.rawtcpscan) {
|
||||||
struct tcp_hdr *tcp = (struct tcp_hdr *) data;
|
struct tcp_hdr *tcp = (struct tcp_hdr *) data;
|
||||||
/* Check that the packet has useful flags. */
|
/* Check that the packet has useful flags. */
|
||||||
|
|||||||
Reference in New Issue
Block a user