1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-07 13:11:28 +00:00

The ARP host discovery scan now filters ARP packets based on their

target address address field, not the destination address in the
enclosing ethernet frame. Some operating systems, including Windows
7 and Solaris 10, are known to at least sometimes send their ARP
replies to the broadcast address and Nmap wouldn't notice them. The
symptom of this was that root scans wouldn't work ("Host seems
down") but non-root scans would work. Thanks to Mike Calmus and
Vijay Sankar for reporting the problem, and Marcus Haebler for
suggesting the fix.
This commit is contained in:
david
2009-07-22 15:13:48 +00:00
parent d0179addd1
commit a76689b17f
2 changed files with 28 additions and 8 deletions

View File

@@ -1,5 +1,15 @@
# Nmap Changelog ($Id$); -*-text-*-
o The ARP host discovery scan now filters ARP packets based on their
target address address field, not the destination address in the
enclosing ethernet frame. Some operating systems, including Windows
7 and Solaris 10, are known to at least sometimes send their ARP
replies to the broadcast address and Nmap wouldn't notice them. The
symptom of this was that root scans wouldn't work ("Host seems
down") but non-root scans would work. Thanks to Mike Calmus and
Vijay Sankar for reporting the problem, and Marcus Haebler for
suggesting the fix.
o The -fno-strict-aliasing option is now used unconditionally when
using GCC. It was already this way, in effect, because a test
against the GCC version number was reversed: <= 4 rather than >= 4.

View File

@@ -5011,7 +5011,6 @@ static void begin_sniffer(UltraScanInfo *USI, vector<Target *> &Targets) {
string pcap_filter="";
/* 20 IPv6 addresses is max (45 byte addy + 14 (" or src host ")) * 20 == 1180 */
string dst_hosts="";
char macstring[100];
unsigned int len = 0;
unsigned int targetno;
bool doIndividual = Targets.size() <= 20; // Don't bother IP limits if scanning huge # of hosts
@@ -5028,15 +5027,26 @@ static void begin_sniffer(UltraScanInfo *USI, vector<Target *> &Targets) {
}
USI->pd = my_pcap_open_live(Targets[0]->deviceName(), 100, (o.spoofsource)? 1 : 0, pcap_selectable_fd_valid()? 200 : 2);
if(USI->ping_scan_arp){
if (USI->ping_scan_arp){
/* Some OSs including Windows 7 and Solaris 10 have been seen to send their
ARP replies to the broadcast address, not to the (unicast) address that
the request came from, therefore listening for ARP packets directed to
us is not enough. Look inside the ARP reply at the target address field
instead. The filter string will look like
arp and arp[18:4] = 0xAABBCCDD and arp[22:2] = 0xCCDD */
char macstring[2 * ETH_ADDR_LEN + 1];
const u8 *mac = Targets[0]->SrcMACAddress();
assert(mac);
pcap_filter="arp and ether dst host ";
len = Snprintf(macstring, sizeof(macstring),
"%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
if(len>=sizeof(macstring))
fatal("macstring too long");
pcap_filter+=macstring;
len = Snprintf(macstring, sizeof(macstring), "%02X%02X%02X%02X%02X%02X",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
if (len != sizeof(macstring) - 1)
fatal("macstring length is %d, should be %u", len, sizeof(macstring) - 1);
/* First four bytes of MAC. */
pcap_filter = "arp and arp[18:4] = 0x";
pcap_filter.append(macstring, 0, 4 * 2);
/* Last two bytes. */
pcap_filter += " and arp[22:2] = 0x";
pcap_filter.append(macstring, 4 * 2, 2 * 2);
//its not arp, so lets check if for a protocol scan.
} else if(USI->prot_scan || (USI->ping_scan && USI->ptech.rawprotoscan)){
if (doIndividual){