Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
Obviously doing an ARP scan of an address which isn't in the current subnet doesn't make a whole lot of sense, but it still shouldn't cause a crash.
I'm guessing this is due to d8ff55b which deferred starting the timeout clock until the first probe is sent, and in this case, no probes are sent, so when Nmap tries to stop the clock the assertion fails?
This is with Nmap built from the current master. It doesn't happen in Nmap 7.70.
Wow, this is a weird one. You're correct, d8ff55b is what turned this into an assertion failure, but there was a problem before that. Essentially, here's what happens:
What's happening in this case is that the target address is not directly-connected according to the routing tables, so ARP ping is never done. Instead, it falls through to number 3, and a regular ping scan is done. But that scan is done according to the options on the command line, so it's really a ARP ping scan, but without proper setup. The target has no probes to send (
Here some approaches we could take to fix this:
I'm not sure which of these I will do, but I'm leaning towards 1 and 3 (with assert). It turns out there is a way to force an ARP host discovery for addresses on networks that are not configured on your system: use the
I actually think option 2 would be preferable, from a pen-tester perspective.
Sometimes a client might give you a static IP address and subnet mask for your test device, say 10.0.4.51, 255.255.255.192 (10.0.4.51/26), a default gateway address (say 10.0.4.1), and a list of targets to assess, say 10.0.4.0/22.
But what if the layer 2 subnet is actually bigger than they've said (say, /24, or the whole /22 that is to be assessed)?
It would be nice to be able to determine that with a set of ping scans. E.g.
etc. etc. with the other ping options.
(I often do something like the above to get an initial feel for the network before doing more thorough host discovery with larger TCP and UDP scans).
In this case, an actual ARP scan would show that the subnet is bigger than we've been told, which might be useful to know for subsequent testing.
I just tested this scenario, and Nmap won't ARP scan the other hosts, whereas something like
The trouble with that approach is that Nmap then has to make the assumption of what source address and interface to use for those targets. For the ones in the /26 net that you configured in the OS, it can consult the routing tables to know what to use. For the others, it can't know. On a system that only has one non-loopback IP address, it seems like you could use that, but that would have to be handled as an edge case, with the default being to fail without knowing the source address to use. I think option 2 is out because of this.
Fortunately for your use case, providing
I like Dan's #1 approach--just make -PR do nothing since it is already the default behavior now whenever Nmap detects that it can use ARP scan. It's already not in the nmap -h output and we should probably remove it from the man page (or at least just put a sentence noting that it was removed since it is the default). But we should probably keep some of the text from -PR describing the process, and just move that to where we describe the default host discovery techniques.
@dmiller-nmap Thanks for the detailed responses.
I just cloned from Git to test your change, and there still seems to be one case where I can't get it to work as you described. Here's all the output which hopefully can help.
In these scenarios 192.168.1.1 is the gateway host in our subnet, 192.168.1.2 is our own IP address on eth0 in the subnet, 18.104.22.168 is an IP address outside of the subnet, and 10.99.99.99 is a spoofed source address not within our actual subnet nor within the subnet of the target host.
Unspecified ping method of host within the subnet. Uses ARP (as expected), and host is deemed to be up (as expected).
Unspecified ping method of host outside the subnet. Uses default ICMP + TCP pings (as expected), and host is deemed to be up (as expected).
Unspecified ping method for host within the subnet, using a spoofed source address which is not in the current subnet, nor the subnet of the target host. Uses ARP (as you said it would), and host is deemed to be up (as expected, despite not controlling the source IP address, due to the ARP response being a layer 2 broadcast).
Unspecified ping method of host outside the subnet, using a spoofed source address which is not in the current subnet, nor the subnet of the target host. Uses ARP (as you said it would), and host is deemed to be down (as expected).
Unspecified ping method of host within the current subnet, setting the source IP address as our actual IP address on eth0. Uses ARP (as expected), and host is deemed to be up (as expected).
Unspecified ping method of host outside the current subnet, setting the source IP address to be our actual IP address on eth0. Uses ICMP + TCP pings (unexpected), and host is deemed to be up (expected given the actual ping method used, but not the intention of the scan).
Is that last example expected? My intention is to have a command syntax I can use in a script where I can force ARP to be used as the ping method, but ideally using my actual IP address as the source IP address in the ARP packets, rather than having to spoof it to a random address.
@dmiller-nmap To clarify, this is to cover the case of when the target list contains a mix of IP addresses which are on the local subnet and IP addresses which aren't. Currently with Nmap 7.70 a
Now, the scan takes longer, by doing an actual ICMP / TCP ping for the other hosts, making it slower and more difficult to determine whether a particular target responds to ARP or not (rather than just seeing if the host is "Up" in a
The use case of this is categorising and grouping hosts by the type of pings that they respond to. I'd prefer to keep using Nmap for this if possible.