Skip to content

arp scan User Guide

Roy Hills edited this page Mar 17, 2023 · 24 revisions

This has been converted from the old mediawiki based arp-scan wiki to github wiki and is in the process of being updated

Introduction to arp-scan

arp-scan is a command-line tool for IPv4 host discovery and fingerprinting. It sends ARP requests for the specified hosts and displays the responses received. arp-scan allows you to:

  • Send ARP packets to any number of destination hosts, using a configurable output bandwidth or packet rate, permitting efficient scanning of large address ranges.
  • Construct the outgoing ARP packet in a flexible way. arp-scan gives control of all of the fields in the ARP packet, the fields in the Ethernet frame header and any padding data after the ARP packet.
  • Decode and display any returned packets. arp-scan will decode and display any received ARP packets and lookup the vendor using the MAC address.
  • Fingerprint IP hosts using the arp-fingerprint tool.

Using arp-scan for system discovery

arp-scan can be used to discover IPv4 hosts on the local Ethernet or wireless network, including hosts that block IP traffic.

Scanning the local network with --localnet

The simplest way to scan the local network is with arp-scan --localnet. This will scan all IPv4 addresses within the network defined by the interface IP address and netmask (network and broadcast addresses included). For example:

$ arp-scan --localnet
Interface: eth0, type: EN10MB, MAC: 50:65:f3:f0:70:a4, IPv4: 192.168.1.104
Target list from interface network 192.168.1.0 netmask 255.255.255.0
Starting arp-scan 1.10.1 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.1.68    00:0c:29:67:b9:12       VMware, Inc.
192.168.1.69    00:0c:29:f7:56:b6       VMware, Inc.
192.168.1.70    00:0c:29:44:f7:70       VMware, Inc.
192.168.1.71    00:0c:29:a1:ad:df       VMware, Inc.
192.168.1.73    00:0c:29:20:21:e2       VMware, Inc.
192.168.1.74    00:0c:29:90:07:e9       VMware, Inc.
192.168.1.75    00:0c:29:66:9e:c2       VMware, Inc.
192.168.1.76    00:0c:29:d0:e1:ea       VMware, Inc.
192.168.1.82    9c:b6:54:bb:f3:ec       Hewlett Packard
192.168.1.83    00:9c:02:a5:7b:26       Hewlett Packard
192.168.1.84    00:21:9b:fd:b9:b3       Dell Inc.
192.168.1.85    00:02:b3:eb:5a:f8       Intel Corporation
192.168.1.91    00:9c:02:a5:7b:29       Hewlett Packard
192.168.1.92    d4:ae:52:d0:07:6f       Dell Inc.
192.168.1.93    d4:ae:52:d0:04:9b       Dell Inc.
192.168.1.94    9c:b6:54:bb:f3:ee       Hewlett Packard
192.168.1.96    9c:b6:54:bb:f5:35       Hewlett Packard
192.168.1.97    00:0c:29:0e:95:20       VMware, Inc.
192.168.1.102   00:80:91:cd:a7:45       TOKYO ELECTRIC CO.,LTD
192.168.1.106   50:65:f3:f0:6d:7c       Hewlett Packard
192.168.1.107   50:65:f3:f0:6d:7e       Hewlett Packard
192.168.1.202   08:f1:ea:af:f6:08       Hewlett Packard Enterprise
192.168.1.203   08:f1:ea:af:f6:b8       Hewlett Packard Enterprise
192.168.1.204   08:f1:ea:af:f6:0b       Hewlett Packard Enterprise
192.168.1.205   08:f1:ea:af:f6:bb       Hewlett Packard Enterprise
192.168.1.206   00:08:a2:11:89:d8       ADI Engineering, Inc.
192.168.1.208   b8:cb:29:e6:b7:1f       Dell Inc.

29 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.1: 256 hosts scanned in 2.322 seconds (110.25 hosts/sec). 27 responded

arp-scan will use the first available network interface by default. This can be changed with the --interface (-I) option. The example below shows an ISP router:

$ arp-scan --localnet -I eth1
Interface: eth1, type: EN10MB, MAC: 50:65:f3:f0:70:a5, IPv4: 10.0.1.82
Target list from interface network 10.0.1.80 netmask 255.255.255.252
Starting arp-scan 1.10.1 with 4 hosts (https://github.com/royhills/arp-scan)
10.0.1.81    04:5e:a4:90:ae:40       SHENZHEN NETIS TECHNOLOGY CO.,LTD

1 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.1: 4 hosts scanned in 1.555 seconds (2.57 hosts/sec). 1 responded

Specifying the Target IP Addresses

You can specify the target IP addresses instead of using --localnet. The following target specifications are supported:

  • A single IP address, e.g. 192.168.1.1 or hostname. Use the --numeric (-n) option to prevent DNS resolution of target hostnames.
  • A network in CIDR format, e.g. 192.168.1.0/24 (includes network and broadcast addresses).
  • A network in <network>:<netmask> format, e.g. 192.168.1.0:255.255.255.0 (includes network and broadcast addresses).
  • An inclusive range in <start>-<end> format, e.g. 192.168.1.3-192.168.1.27

The targets can be specified in two ways:

  • As command line arguments, e.g. arp-scan 192.168.1.1 192.168.1.2 192.168.1.3 or arp-scan 192.168.1.0/24
  • Use the --file (-f) option to read from the specified file. One target specification per line. Use - for standard input. e.g. echo 192.168.1.0/24 | arp-scan -f -

For example here is a scan of the 16 addresses in 10.133.170.16/28:

$ arp-scan 10.133.170.16/28
Interface: eth0, type: EN10MB, MAC: a0:b3:cc:e8:0e:94, IPv4: 10.133.170.8
Starting arp-scan 1.10.0 with 16 hosts (https://github.com/royhills/arp-scan)
10.133.170.16   bc:30:5b:e8:da:76       Dell Inc.
10.133.170.17   00:0c:29:25:cc:09       VMware, Inc.
10.133.170.18   a0:b3:cc:e2:1b:e8       Hewlett Packard
10.133.170.19   a0:b3:cc:ea:8c:72       Hewlett Packard
10.133.170.20   a0:b3:cc:df:a6:00       Hewlett Packard
10.133.170.23   94:18:82:ab:1b:8f       Hewlett Packard Enterprise
10.133.170.24   28:92:4a:30:76:0b       Hewlett Packard
10.133.170.25   00:0c:29:5a:89:4d       VMware, Inc.
10.133.170.27   84:34:97:11:8d:40       Hewlett Packard
10.133.170.29   9c:b6:54:bb:dc:e0       Hewlett Packard
10.133.170.31   00:0c:29:c4:89:eb       VMware, Inc.

11 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.0 16 hosts scanned in 1.833 seconds (8.73 hosts/sec). 11 responded

Output Formats

The default output format is designed to be readable and informative. Each responding host is displayed like this:

<IP Address> <Hardware Address> <Vendor Details>

The IP address, Hardware address and vendor details are each separated by a single TAB character. There is always a single blank line between the last responding system and the statistics display.

arp-scan will never report the scanning host's own IP address, because the testing system won't respond to its own ARP request.

Although arp-scan reports the datalink type as EN10MB, this does not necessarily mean that it is 10Mbit Ethernet; it could by any type (10Mbit, 100Mbit, 1Gbit or 802.11 wireless). EN10MB is the name used by libpcap for all types of Ethernet.

Omitting Header and Footer with --plain

The --plain option omits the header and footer, only displaying one line for each responding host. For example:

$ arp-scan -l --plain
192.168.1.2    00:50:56:e4:9a:83       VMware, Inc.
192.168.1.1    00:50:56:c0:00:08       VMware, Inc.
192.168.1.254  00:50:56:f6:22:db       VMware, Inc.

This is recommended for scripts, pipelines and any other situations where the extraneous output is not desired.

Custom Output Formats with --format

The --format (-F) option permits flexible custom format options to be specified. For example:

Using an interface without an IP address

You can still use arp-scan even if the interface does not have an IP address. If you use arp-scan in this way, it will use the IP address of 0.0.0.0 for the ar$sha field in the ARP packet unless you specify the IP address to use with the -arpsha option.

Some operating systems will only respond to ARP requests if the IP address specified in the ar$sha field is plausible. The exact rules vary between operating systems, but the most common is that the address in ar$sha must be within the IP network of the interface that the ARP request is received on. This is explored further in the fingerprinting section.

Timing and bandwidth usage

One ARP packet is sent for each for each target host, with the target protocol address (the ar$tpa field) set to the IP address of this host. If a host does not respond, then the ARP packet will be re-sent once more. The maximum number of retries can be changed with the --retry option. Reducing the number of retries will reduce the scanning time at the possible risk of missing some results due to packet loss.

You can specify the bandwidth that arp-scan will use for the outgoing ARP packets with the --bandwidth option. By default, it uses a bandwidth of 256000 bits per second. Increasing the bandwidth will reduce the scanning time, but setting the bandwidth too high may result in an ARP storm which can disrupt network operation. Another way to specify the outgoing ARP packet rate is with the --interval option, which is an alternative way to modify the same underlying parameter.

The time in seconds to perform a single-pass scan (i.e. with --retry=1) is given by:

time = n*i + t + o

Where n is the number of hosts in the list, i is the time interval between packets (specified with --interval, or calculated from --bandwidth), t is the timeout value (specified with --timeout) and o is the overhead time taken to load the targets into the list and read the MAC/Vendor mapping files. For small lists of hosts, the timeout value will dominate, but for large lists the packet interval is the most important value.

With 65,536 hosts, the default bandwidth of 256,000 bits/second (which results in a packet interval of 2ms), the default timeout of 100ms, and a single pass (--retry=1), and assuming an overhead of 1 second, the scan would take 65536*0.002 + 0.1 + 1 = 132.172 seconds, or about 2 minutes 12 seconds.

arp-scan uses the select() system call to wait for a specified period or until a reponse packet is received, and gettimeofday() to get the current time. arp-scan measures elapsed time in microseconds using 64-bit integer values.

select() does not provide precise delays for the small intervals arp-scan requires: the interval is rounded up to the system clock granularity, kernel scheduling delays can increase the interval, and receiving a response packet causes it to return early.

The graph below shows the timings of four arp-scan runs with different interval settings. In each case, the network 10.0.0.0/24 (256 hosts) was scanned from a Raspberry pi 4B running Linux kernel 5.15.84-v8+. The timing data was gathered by running tcpdump with the -ttt option to print inter-packet delta times with microsecond resolution.

The desired interval is shown by the horizontal lines at 2000, 1000, 500 and 250 microseconds. Arp-scan aims to keep as close to this line as possible and to be symmetric around it (equal amounts above and below the line).

arp-scan timings

The relationship between the inter-packet interval and the corresponding bandwith utilisation is given by the following table. The ARP request packets are all 64 bytes long. The default interval is 2000 microseconds if the --interval option is not given.

microseconds K bits/s
2000 256
1000 512
500 1024
250 2028

Using arp-scan for system fingerprinting

In addition to system discovery, you can also use arp-scan to perform various types of system fingerprinting as detailed below. This is particually useful on Firewalls and systems employing IP ingress filtering that do not have any accessible IP network services.

MAC Vendor Decoding

Unless the --quiet option is specified, arp-scan decodes the vendor details from the MAC address and displays these details in the third column, after the MAC address. Below is an example using a Cisco router where the vendor details are Cisco Systems, Inc.

192.168.1.251   00:04:27:6a:5d:a1       Cisco Systems, Inc.

arp-scan uses data from two files to decode the vendor details:

  • ieee-oui.txt - This the IEEE registry list, which is obtained from the IEEE website and can be updated with the get-oui script that is included with arp-scan It contains the data from the MA-L, MA-M, MA-S and IAB registries.
  • mac-vendor.txt - This is a list of other MAC address / vendor mappings. This list is manually maintained, and is much smaller than the OUI listing.

When arp-scan starts up it reads the contents of all files into a hash table, and it matches the MAC addresses of any ARP replies that it receives against this hash table to decode the vendor string.

The vendor details can often help to identify the device type. In the example above, the vendor string Cisco Systems, Inc. suggests that the device is a Cisco.

The vendor details depend on the manufacturer of the network interface, which may well be different from the manufacturer of the entire system, e.g. a 3COM Ethernet card in an HP server.

Differences in responses to non-standard ARP packets

Different IP stack implementations respond differently to non-standard ARP packets. arp-scan includes the arp-fingerprint tool that uses these differences to fingerprint the implementation. arp-fingerprint is a Perl script, which uses arp-scan to send and receive the ARP packets. The table below shows the tests that arp-fingerprint performs:

No. Description arp-scan option Notes
1 source protocol address = localhost --arpspa=127.0.0.1 IP address 127.0.0.1 should never appear as a source address on the LAN
2 source protocol address = zero --arpspa=0.0.0.0
3 source protocol address = broadcast --arpspa=255.255.255.255
4 source protocol address = non-local --arpspa=1.0.0.1 IP network 1.0.0.0/8 is reserved by IANA, so should never belong on the target's local LAN
5 Invalid Opcode --arpop=255 Opcode 255 is not defined
6 Hardware Type = IEEE_802.2 --arphrd=6 Most systems respond to this as well as the default hardware type 1
7 Invalid hardware type --arphrd=255
8 Invalid protocol type --arppro=0xffff
9 Protocol type = IPX --arppro=0x8137
10 Invalid protocol address length --arppln=6 The protocol address length is normally four bytes
11 Invalid hardware address length --arphln=8 The hardware address length is normally six bytes

Each of these tests results in a yes/no answer depending on whether the target host responded or not. arp-fingerprint constructs a string of binary digits from the responses to the tests, with a response being encoded as "1" and no response being "0", and uses the resultant binary string to match against a list of known fingerprints.

Below are some examples of arp-fingerprint being used against some different targets. arp-fingerprint displays the IP address, the binary fingerprint string, and a list of known systems that match this fingerprint:

$ arp-fingerprint -o "--interface=eth0 --numeric" 192.168.1.1
192.168.1.1     01000100000     Linux 2.2, 2.4, 2.6
$ arp-fingerprint -o "--interface=eth0 --numeric" 192.168.1.204
192.168.1.204   11110100000     FreeBSD 5.3, Win98, WinME, NT4, 2000, XP, 2003
$ arp-fingerprint -o "--interface=eth0 --numeric" 192.168.1.251
192.168.1.251   00000100000     Cisco IOS 11.2, 11.3, 12.0, 12.1, 12.2, 12.3, 12.4
$ arp-fingerprint -o "--interface=eth0 --numeric" 192.168.1.155
192.168.1.155   01000111111     ScreenOS 5.0, 5.1, 5.3, 5.4

In each of the examples above we use arp-fingerprint's -o option to pass the --interface=eth0 --numeric option string to arp-scan The -o option can be used to pass any options to arp-scan with the two most common ones being --interface to specify the network interface and --numeric to avoid DNS lookups.

Many of the fingerprint strings are shared by several operating systems, so there is not always a one-to-one mapping between fingerprint strings and operating systems. Also the fact that a system's fingerprint matches a certain operating system (or list of operating systems) does not necessarily mean that the system being fingerprinted is that operating system, although it is quite likely. This is because the list of operating systems is not exhaustive; it is just what I have discovered to date, and there are bound to be operating systems that are not listed.

Sometimes, an operating system can give different fingerprints depending on the configuration. An example is Linux, which will respond to a non-local source IP address if that IP is routed through the interface being tested. This is both good and bad: on one hand it makes the fingerprinting task more complex; but on the other, it can allow some aspects of the system configuration to be determined.

Sometimes the fact that two different operating systems share a common ARP fingerprint string points to a re-use of networking code. One example of this is Windows NT and FreeBSD.

If you find a system that arp-fingerprint reports as UNKNOWN, and you know what operating system it is running, please report it as an issue on github so I can include it in future versions. Please include the exact version of the operating system if you know it, as fingerprints sometimes change between versions.

Changing the destination MAC Address

arp-scan sends the ARP requests to the Ethernet broadcast address ff:ff:ff:ff:ff:ff by default, but this can be changed with the --destaddr option.

An interface that is not in promiscuous mode will pass Ethernet packets to the operating system if the destination address is one of:

  • The Ethernet broadcast address ff:ff:ff:ff:ff:ff;
  • The interface's unicast address; or
  • An Ethernet multicast address that the system is listening on.

You can always use the target system's MAC address as the target if you know it. This can be useful to check that a given system with known IP and MAC addresses is present on the LAN, and it has the advantage that it is quieter than using the broadcast because it won't be received by all network stations.

Below is an example of using a host's unicast MAC address. In this example, we first use arp-scan with the default broadcast destination to determine the host's MAC address, and then run arp-scan again specifying the host's MAC address as the detination.

$ arp-scan --interface=eth0 192.168.1.1
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.5.2 with 1 hosts (http://www.nta-monitor.com/tools/arp-scan/)
192.168.1.1   00:c0:9f:09:b8:db       QUANTA COMPUTER, INC.
$ arp-scan --interface=eth0 --destaddr=00:c0:9f:09:b8:db 192.168.1.1
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.5.2 with 1 hosts (http://www.nta-monitor.com/tools/arp-scan/)
192.168.1.1   00:c0:9f:09:b8:db       QUANTA COMPUTER, INC.

If you send the ARP requests to an Ethernet multicast address it will only be received by those systems that are listening on that multicast address, or have set their Ethernet interface into promiscuous mode (and therefore receive all packets). This can be used to find systems that are running in promiscuous mode, or listen on particular multicast addresses.

The table below shows some common Ethernet multicast addresses:

Multicast Address Description
01:00:0c:cc:cc:cc CDP (Cisco Discovery Protocol)
01:00:0c:cc:cc:cd SSTP (Shared Spanning Tree Protocol)
01:80:c2:00:00:00 Spanning Tree
01:00:5e:00:00:05 OSPF
01:00:5e:00:00:12 VRRP
03:00:c7:00:00:ee HP network teaming

Detecting Systems Listening to OSPF Multicasts

This example shows the use of the --destaddr option with the OSPF multicast address to detect systems listing to OSPF multicasts.

First we scan three systems using the default options. The IP addresses are 192.168.1.1, 192.168.1.204 and 192.168.1.254, which are running Linux 2.6.19, Windows 2003 and Cisco IOS 12.2(29) respectively. All three systems respond as expected.

$ arp-scan --interface=eth0 192.168.1.1 192.168.1.204 192.168.1.254
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.6.2 with 3 hosts (http://www.nta-monitor.com/tools/arp-scan/)
192.168.1.1   00:c0:9f:09:b8:db       QUANTA COMPUTER, INC.
192.168.1.204 00:11:43:0f:f2:dd       DELL INC.
192.168.1.254 00:60:5c:f4:c6:f4       CISCO SYSTEMS, INC.

Next we scan the same systems, but specify --destaddr=01:00:5e:00:00:05 to set the Ethernet destination address to the OSPF multicast address. Only the Cisco router responds, because that is the only system that is listening to the OSPF multicast address.

$ arp-scan --interface=eth0 --destaddr=01:00:5e:00:00:05 192.168.1.1 192.168.1.204 192.168.1.254
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.6.2 with 3 hosts (http://www.nta-monitor.com/tools/arp-scan/)
192.168.1.254 00:60:5c:f4:c6:f4       CISCO SYSTEMS, INC.

Detecting Promiscuous Mode Interfaces

First we scan three systems using the default options. The IP addresses are 192.168.1.1, 192.168.1.204 and 192.168.1.254, which are running Linux 2.6.19, Windows 2003 and Cisco IOS 12.2(29) respectively. All three systems respond as expected.

$ arp-scan --interface=eth0 192.168.1.1 192.168.1.204 192.168.1.254
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.6.2 with 3 hosts (http://www.nta-monitor.com/tools/arp-scan/)
192.168.1.1   00:c0:9f:09:b8:db       QUANTA COMPUTER, INC.
192.168.1.204 00:11:43:0f:f2:dd       DELL INC.
192.168.1.254 00:60:5c:f4:c6:f4       CISCO SYSTEMS, INC.

Next we scan the same systems, but specify --destaddr=01:00:01:02:03:04 to set the Ethernet destination address to an unassigned multicast address. Only the Linux system responds, because it is running tcpdump which has put its Ethernet interface into promiscuous mode.

$ arp-scan --interface=eth0 --destaddr=01:00:01:02:03:04 192.168.1.1 192.168.1.204 192.168.1.254
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.6.2 with 3 hosts (http://www.nta-monitor.com/tools/arp-scan/)
192.168.1.1   00:c0:9f:09:b8:db       QUANTA COMPUTER, INC.

ARP Ethernet Frame Padding

All ARP packets are 28 bytes long, which is less than 46 byte minimum Ethernet frame length. So each ARP packet will be followed by at least 18 bytes of padding. If the ARP implementation doesn't pad the outgoing ARP frames, the operating system will do so.

Below is an ARP packet within an Ethernet frame with zero padding to achieve the minimum frame size:

Ethernet-padding

arp-scan can add arbitary padding data to the outgoing ARP requests with the --padding option. With the --verbose option, arp-scan will report any non-zero padding on ARP responses.

Most implementations will pad up to the minimum frame length with zero bytes, but not all implementations do this. Below are some examples of systems that return non-zero padding bytes:

$ arp-scan --padding=0102030405060708 --verbose 192.168.1.0/24 | grep Padding
192.168.1.147   00:11:24:84:a1:b2   Apple Computer          Padding=555555555555555555555555555555555555
192.168.1.153   00:10:db:26:4d:52   Juniper Networks, Inc.  Padding=888888888888888888888888888888888888
192.168.1.158   08:00:20:a0:09:a4   SUN MICROSYSTEMS INC.   Padding=555555555555555555555555555555555555
192.168.1.190   00:00:aa:84:eb:0c   XEROX CORPORATION       Padding=01020304050607080000000000000000000000000000
192.168.1.192   00:30:c1:cd:3a:13   HEWLETT-PACKARD         Padding=010203040506070800000000000000000000
192.168.1.249   00:90:27:57:c1:f3   INTEL CORPORATION       Padding=000000000000000000000000000089322ba2
192.168.1.250   00:06:d7:55:0f:40   Cisco Systems, Inc.     Padding=00000000000000000000000000000000000005060708

The associated operating systems are:

IP Address Operating System Notes
192.168.1.147 MacOS 10.4 pads with 18 bytes of 0x55 (0b01010101)
192.168.1.153 NetScreen ScreenOS 5.0.0 pads with 18 bytes of 0x88 (0b10001000)
192.168.1.158 Solaris 8/SPARC, qfe Ethernet pads with 18 bytes of 0x55
192.168.1.190 Xerox Phaser 6200 re-uses the padding from the ARP request frame
192.168.1.192 HP JetDirect re-uses the padding from the ARP request frame
192.168.1.249 Linux with eepro100 driver adds four non-zero bytes at the end of the padding
192.168.1.250 Cisco Catalyst IOS 12.0 adds part of the padding from the request frame

Here is another example from a 2022 vintage Maxis VDSL router. It has two padding values, which it seems to choose at random:

192.168.1.1    04:5e:a4:90:ae:40       SHENZHEN NETIS TECHNOLOGY CO.,LTD       Padding=000000000000666000006660000000050001
192.168.1.1    04:5e:a4:90:ae:40       SHENZHEN NETIS TECHNOLOGY CO.,LTD       Padding=000800000000000070000000000001340000

802.2 LLC/SNAP Framing

By default, arp-scan sends ARP requests using Ethernet-II Ethernet framing, which is the standard Ethernet framing for TCP/IP. If the --llc (-L) option is specified, then arp-scan will send ARP requests using IEEE 802.2 LLC/SNAP Framing instead, as defined in RFC 1042 Standard for the transmission of IP datagrams over IEEE 802 networks.

Ethernet-snap-frame

Irrespective of whether the --llc option is specified, arp-scan will always receive ARP responses in either Ethernet-II or 802.2 format, and will display (802.2 LLC/SNAP) to indicate an 802.2 format ARP response.

The 802.2 LLC/SNAP framing detailed in RFC 1042 is applicable to three underlying physical networks: 802.3 (Ethernet), 802.4 (Token Bus) and 802.5 (Token Ring). However the current version of arp-scan only supports Ethernet.

The 802.2 LLC framing is obsolete, and is almost never seen on a real world network. But some network stacks still support it, especially routers, which need to be able to communicate with a diverse range of equipment, and operating systems with a history of use on networks using 802.2 LLC.

The following operating systems have been found to support ARP requests with 802.2 LLC/SNAP framing:

  • Cisco IOS on routers and Catalyst switches (tested IOS 12.1 and 12.2).

  • All versions of Windows (tested 95, NT4, 2000, XP, 2003, Vista).

Here is an example from Windows Vista SP1. Although Windows systems support ARP requests with SNAP framing, they respond with standard Ethernet-II framing.

$ arp-scan --llc 192.168.1.50
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.7 with 1 hosts (http://www.nta-monitor.com/tools/arp-scan/)
192.168.1.50    00:1d:09:94:3e:5f       Dell Inc

Here is an example from a Cisco router running IOS 12.2. Cisco IOS will respond to an ARP request in SNAP format with an ARP reply in SNAP format.

$ arp-scan --llc 192.168.124.251
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.7.1 with 1 hosts (http://www.nta-monitor.com/tools/arp-scan/)
192.168.124.251 00:04:27:6a:5d:a1       Cisco Systems, Inc. (802.2 LLC/SNAP)

Other Techniques

Identifying secondary IP addresses

If two or more IP addresses respond with the same MAC address then, assuming it's not proxy ARP or an interface on a different network segment, this indicates that the IP addresses are on the same network interface.

Here is an example from a Linux system:

$ arp-scan --interface=eth0 192.168.1.68 192.168.1.69
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.5.2 with 2 hosts (http://www.nta-monitor.com/tools/arp-scan/)
192.168.1.68    00:0b:db:1c:59:e7       Dell ESG PCBA Test
192.168.1.69    00:0b:db:1c:59:e7       Dell ESG PCBA Test

And here is the interface configuration from the system that produced this output:

eth0      Link encap:Ethernet  HWaddr 00:0B:DB:1C:59:E7
          inet addr:192.168.1.68  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:14874 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4822 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1274872 (1.2 MiB)  TX bytes:361344 (352.8 KiB)
          Interrupt:7

eth0:1    Link encap:Ethernet  HWaddr 00:0B:DB:1C:59:E7
          inet addr:192.168.1.69  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          Interrupt:7

Identifying interfaces on the same system

Systems with multiple interfaces often (but not always) have MAC addresses that are very close together. This is because the interface cards in a batch typically have sequential addresses. When a system is built, the interface cards are typically all sourced from the same batch. Also, multi-port network cards invariably have sequential MAC addresses for the individual ports.

Here is an example taken from the arp-scan output from six different scans on different Ethernet network segments:

192.168.4.94   00:a0:8e:33:81:f0       Nokia Internet Communications
10.5.40.2      00:a0:8e:33:81:f1       Nokia Internet Communications
192.168.4.30   00:a0:8e:33:81:f8       Nokia Internet Communications
192.168.5.30   00:a0:8e:33:81:fc       Nokia Internet Communications
192.168.5.45   00:a0:8e:33:81:fd       Nokia Internet Communications
192.168.5.145  00:a0:8e:33:81:ff       Nokia Internet Communications

We can see that all six of the MAC addresses are very close together. They all belong to a single Nokia firewall, which connects the six networks.

Identifying Proxy ARP

Many routers will issue proxy arp replies for addresses that belong on a different interface. Cisco routers do this by default.

Here is an example of proxy ARP responses from a Cisco router:

$ arp-scan 172.18.0.0/28
Interface: eth0, type: EN10MB, MAC: a0:b3:cc:e8:0e:94, IPv4: 10.133.170.8
Starting arp-scan 1.10.0 with 16 hosts (https://github.com/royhills/arp-scan)
172.18.0.0      00:fc:ba:77:0f:4d       Cisco Systems, Inc
172.18.0.1      00:fc:ba:77:0f:4d       Cisco Systems, Inc
172.18.0.2      00:fc:ba:77:0f:4d       Cisco Systems, Inc
172.18.0.3      00:fc:ba:77:0f:4d       Cisco Systems, Inc
172.18.0.4      00:fc:ba:77:0f:4d       Cisco Systems, Inc
172.18.0.5      00:fc:ba:77:0f:4d       Cisco Systems, Inc
172.18.0.6      00:fc:ba:77:0f:4d       Cisco Systems, Inc
172.18.0.7      00:fc:ba:77:0f:4d       Cisco Systems, Inc
172.18.0.8      00:fc:ba:77:0f:4d       Cisco Systems, Inc
172.18.0.9      00:fc:ba:77:0f:4d       Cisco Systems, Inc
172.18.0.10     00:fc:ba:77:0f:4d       Cisco Systems, Inc
172.18.0.11     00:fc:ba:77:0f:4d       Cisco Systems, Inc
172.18.0.12     00:fc:ba:77:0f:4d       Cisco Systems, Inc
172.18.0.13     00:fc:ba:77:0f:4d       Cisco Systems, Inc
172.18.0.14     00:fc:ba:77:0f:4d       Cisco Systems, Inc
172.18.0.15     00:fc:ba:77:0f:4d       Cisco Systems, Inc

16 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.0 16 hosts scanned in 0.608 seconds (26.32 hosts/sec). 16 responded

It is easy to spot proxy ARP replies because:

  • You get responses for all addresses in the IP network
  • All responses use the same Ethernet MAC address
  • The MAC address belongs to a router device

Because proxy ARP is enabled by default on some routers, you can use arp-scan to determine the IP networks behind these routers. This can be a useful network mapping technique, especially when the router blocks ping and traceroute traffic.

Load balancing protocol MAC Addresses

Load balancing and failover protocols including VRRP (Virtual Router Redundancy Protocol), HSRP (Hot Standby Routing Protocol) and WLBS (Windows NT Load Balancing Service) encode additional data within the MAC address. There are probably other protocols that do the same thing.

Here are the entries for these protocols from mac-vendor.txt:

# From RFC 5798: "IPv4 case: 00-00-5E-00-01-{VRID}"
# OpenBSD's CARP protocol uses VRRP's IPv4 MAC addresses.
00:00:5e:00:01  VRRP/CARP (last octet is VRID/VHID)
# From RFC 5798: "IPv6 case: 00-00-5E-00-02-{VRID}"
00:00:5e:00:02  IPv6 VRRP (last octet is VRID)
# Microsoft WLBS (Windows NT Load Balancing Service)
# http://www.microsoft.com/technet/prodtechnol/acs/reskit/acrkappb.mspx
02:bf   Microsoft WLBS (last four octets are IP address)
# Cisco HSRP (Hot Standby Routing Protocol)
# 00-00-0c-07-ac-XX, where XX is the HSRP group number (0 to 255)
00:00:0c:07:ac  HSRP (last octet is group number)

When arp-scan displays MAC addresses associated with these protocols, you can determine additional information from the MAC address. For VRRP you can determine the VRID (Virtual Router IDentifier) from the last octet, and for WLBS you can determine the IP address from the last four octets.

Here are some examples of arp-scan output for VRRP IP addresses:

192.168.6.20   00:00:5e:00:01:65       VRRP (last octet is VRID)
192.168.6.227  00:00:5e:00:01:72       VRRP (last octet is VRID)
192.168.6.228  00:00:5e:00:01:40       VRRP (last octet is VRID)

In this example, the first IP address belongs to VRID 101 (0x65), the second to VRID 114 (0x72) and the last to VRID 64 (0x40).

If anyone is aware of any other protocols that store additional information in the MAC address, please let me know so that I can include them in mac-vendor.txt.

Linux IP Routing

Linux, like many other operating systems, will only respond to an ARP request if the IP address in ar$spa is within the IP network of the interface that the ARP is received on.

However, Linux also replies if the IP address in ar$spa is routed through the interface that the ARP request is received on. This allows you to determine the IP networks that are routed via a given interface on Linux, and any other operating systems that behave in the same way.

802.11 wireless networks

You can scan 802.11 wireless as well as wired Ethernet. The main differences are:

  • You must associate with the network before scanning.
  • Wireless networks may use MAC address filtering. Changing the Ethernet source address with the --srcaddr option might help.
  • Wireless host are more transient than wired hosts, so it often worth scanning a few times with a time gap between scans.

Here is a scan on a 802.11ac network using Linux on a laptop with a Broadcom BCM43602 SoC:

$ iwconfig wlp2s0
wlp2s0    IEEE 802.11  ESSID:"what ever you want"
          Mode:Managed  Frequency:5.22 GHz  Access Point: 38:D5:47:E5:6A:4C
          Bit Rate=39 Mb/s   Tx-Power=31 dBm
          Retry short limit:7   RTS thr:off   Fragment thr:off
          Power Management:on
          Link Quality=32/70  Signal level=-78 dBm
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

$ ifconfig wlp2s0
wlp2s0: flags=4163  mtu 1500
        inet 192.168.1.234  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::da2f:a5f3:3acd:dce5  prefixlen 64  scopeid 0x20
        ether 44:1c:a8:e3:08:79  txqueuelen 1000  (Ethernet)
        RX packets 35853  bytes 41777304 (41.7 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 21431  bytes 2194504 (2.1 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

$ arp-scan --localnet
Interface: wlp2s0, type: EN10MB, MAC: 44:1c:a8:e3:08:79, IPv4: 192.168.1.234
Target list from interface: network 192.168.1.0 netmask 255.255.255.0
Starting arp-scan 1.10.1-git with 256 hosts (https://github.com/royhills/arp-scan)
192.168.1.1     00:0d:b9:3f:74:be       PC Engines GmbH
192.168.1.2     38:d5:47:e5:6a:48       ASUSTek COMPUTER INC.
192.168.1.3     a8:a1:59:e0:17:f8       ASRock Incorporation
192.168.1.11    b8:27:eb:6f:a6:79       Raspberry Pi Foundation
192.168.1.13    aa:a1:59:14:fa:0a       (Unknown: locally administered)
192.168.1.115   3c:2a:f4:73:b5:f6       Brother Industries, LTD.
192.168.1.213   90:11:95:dd:94:00       Amazon Technologies Inc.
192.168.1.215   ac:ae:19:a2:20:cc       Roku, Inc
192.168.1.217   b4:2e:99:1d:cd:0d       GIGA-BYTE TECHNOLOGY CO.,LTD.
192.168.1.219   d8:be:65:cb:ab:02       Amazon Technologies Inc.
192.168.1.235   e4:75:dc:0b:87:50       Arcadyan Corporation
192.168.1.237   58:03:fb:ce:0f:76       Hangzhou Hikvision Digital Technology Co.,Ltd.
192.168.1.238   74:7a:90:9f:5d:dd       Murata Manufacturing Co., Ltd.
192.168.1.212   10:96:93:a7:ed:f9       Amazon Technologies Inc.
192.168.1.216   64:90:c1:02:5c:70       Beijing Xiaomi Mobile Software Co., Ltd
192.168.1.211   5c:e5:0c:46:3e:10       Beijing Xiaomi Mobile Software Co., Ltd

16 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.1-git: 256 hosts scanned in 2.134 seconds (119.96 hosts/sec). 16 responded

Determining the interface netmask

Some systems only answer ARP requests where the address in ar$spa is within the IP network of the interface that the request is received on. You can use this behaviour to determine the interface netmask on these systems as follows:

  • First discover the system's IP address - this gives you an address that is within the system's interface network;
  • Next use a binary search to locate the lowest address in the interface network. For this search, use zero as the lower bound, and the interface IP as the upper bound;
  • Finally use the binary search algorithm to locate the highest address, using the interface IP as the lower bound and 255.255.255.255 (0xFFFFFFFF or 4,294,967,295) as the upper bound. An alternative method is to test network address bounds based on likely netmasks rather than using the general binary search technique.

Below is an example using a Cisco router as the target. In this example, the configuration of the router's Ethernet interface is:

interface Ethernet0
 ip address 192.168.1.254 255.255.255.240

The arp-scan runs below show that the router will only respond when the address in the ar$spa field is within the connected IP network of the interface, including the network and broadcast addresses. In this example the IP network is 192.168.1.240/28, so the IP addresses within the network are 192.168.1.240 - 192.168.1.255 inclusive.

$ arp-scan --interface=eth0 --arpspa=192.168.1.239 192.168.1.254
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.5.2 with 1 hosts (http://www.nta-monitor.com/tools/arp-scan/)

2 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.5.2: 1 hosts scanned in 0.865 seconds (1.16 hosts/sec).  0 responded
$ arp-scan --interface=eth0 --arpspa=192.168.1.240 192.168.1.254
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.5.2 with 1 hosts (http://www.nta-monitor.com/tools/arp-scan/)
192.168.1.254   00:60:5c:f4:c6:f4       CISCO SYSTEMS, INC.

3 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.5.2: 1 hosts scanned in 0.618 seconds (1.62 hosts/sec).  1 responded
$ arp-scan --interface=eth0 --arpspa=192.168.1.255 192.168.1.254
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.5.2 with 1 hosts (http://www.nta-monitor.com/tools/arp-scan/)
192.168.1.254   00:60:5c:f4:c6:f4       CISCO SYSTEMS, INC.

3 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.5.2: 1 hosts scanned in 0.608 seconds (1.64 hosts/sec).  1 responded
$ arp-scan --interface=eth0 --arpspa=192.168.2.0 192.168.1.254
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.5.2 with 1 hosts (http://www.nta-monitor.com/tools/arp-scan/)

2 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.5.2: 1 hosts scanned in 0.863 seconds (1.16 hosts/sec).  0 responded

Discovering other interface addresses

Some systems will respond to ARP requests for any interface, not only the interface that the request was received on. For these systems we can use arp-scan to discover the IP addresses of any other interfaces they may have.

The ARP response from such systems will always use the MAC address of the local interface, not the remote one. This is a type of proxy arp that allows a host to reach any of the interface addresses of systems connected to the same network without requiring an IP route entry.

The example below shows the response from a Linux system with two ethernet interfaces:

$ arp-scan --interface=eth0 192.168.1.1 10.0.105.225

192.168.1.1     00:c0:9f:09:b8:db       QUANTA COMPUTER, INC.
10.0.105.225    00:c0:9f:09:b8:db       QUANTA COMPUTER, INC.
eth0      Link encap:Ethernet  HWaddr 00:C0:9F:09:B8:DB
          inet addr:192.168.1.1  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:5286713 errors:0 dropped:0 overruns:0 frame:0
          TX packets:13479278 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1140473784 (1.0 GiB)  TX bytes:4259317135 (3.9 GiB)

eth1      Link encap:Ethernet  HWaddr 00:D0:B7:40:D1:61
          inet addr:10.0.105.225  Bcast:10.0.105.255  Mask:255.255.255.224
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2673325 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2409354 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2218626602 (2.0 GiB)  TX bytes:417690392 (398.3 MiB)

Here is another example, this time from a Cisco router that is using 802.1Q VLAN sub-interfaces:

$ arp-scan --interface=eth0 192.168.1.251 172.18.0.1 172.18.2.1

192.168.1.251   00:04:27:6a:5d:a1       Cisco Systems, Inc.
172.18.0.1      00:04:27:6a:5d:a1       Cisco Systems, Inc.
172.18.2.1      00:04:27:6a:5d:a1       Cisco Systems, Inc.
interface FastEthernet0/1.50
 encapsulation dot1Q 50
 ip address 172.18.0.1 255.255.255.0
!
interface FastEthernet0/1.100
 encapsulation dot1Q 100
 ip address 192.168.1.251 255.255.255.0
!
interface FastEthernet0/1.300
 encapsulation dot1Q 300
 ip address 172.18.2.1 255.255.255.0

Here is a negative example from a Solaris 9 system that does not exhibit this behaviour. In this case, the system only responds to the request for the local interface IP:

$ arp-scan --interface=eth0 192.168.1.150 10.0.0.1
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.2 (ether-scan-engine 1.3) with 2 hosts
192.168.1.150   08:00:20:a0:09:a4       SUN MICROSYSTEMS INC.

3 packets received by filter, 0 packets dropped by kernel
Ending arp-scan: 2 hosts scanned in 0.749 seconds (2.67 hosts/sec).  1 responded
qfe0: flags=1000843 mtu 1500 index 2
        inet 192.168.1.150 netmask ffffff00 broadcast 192.168.1.255
qfe1: flags=1000803 mtu 1500 index 3
        inet 10.0.0.1 netmask ff000000 broadcast 10.255.255.255

So far, I know of the following operating systems that respond to ARP requests for remote interface addresses:

  • Linux
  • Cisco IOS

The following operating systems are known not to respond to ARP requests for remote interface addresses:

  • Solaris
  • Windows NT 4

Setting ar$spa to the destination address

WARNING: Setting ar$spa to the destination IP address can disrupt target system operation

You can use the --arpspa=dest option to set the ar$spa field in the ARP request to the same IP address as the target. For single targets you could achieve the same effect by specifying the same IP address in the arpspa option and also the target IP address, but --arpspa=dest has the advantage that it works for multiple targets too.

Many systems interpret this as a promiscuous ARP, and assume there must be an IP address clash if they receive an ARP request for their own address. For this reason you should use --arpspa=dest with care, as it can disrupt some systems. In some ways this is an ARP version of the 1997-vintage LAND attack.

Here is an example of this against a Windows XP SP2 system. The windows system responds to the ARP request, but also logs an IP address conflict error.

$ arp-scan --interface=eth0 --arpspa=dest 192.168.124.11
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.5.2 with 1 hosts (http://www.nta-monitor.com/tools/arp-scan/)
192.168.124.11  00:0f:1f:5c:d1:13       WW PCBA Test

Windows_xp_ip_address_conflict

Debugging with --verbose

The --verbose (-v) option causes arp-scan to display additional debugging output. It can be used more than once for greater effect: -v turns on a few additional messages and is suitable for general use; -vv adds messages about sending and receiving ARP packets; and -vvv also displays the host list (intended for make check self-tests). For example:

$ arp-scan -v --localnet
Interface: ens33, type: EN10MB, MAC: 00:0c:29:d3:97:e8, IPv4: 192.168.14.128
Using 192.168.14.0:255.255.255.0 for localnet
Starting arp-scan 1.10.1-git with 256 hosts (https://github.com/royhills/arp-scan)
192.168.14.2    00:50:56:e4:9a:83       VMware, Inc.
192.168.14.1    00:50:56:c0:00:08       VMware, Inc.
192.168.14.163  00:0c:29:8d:a1:4d       VMware, Inc.
192.168.14.254  00:50:56:e1:a0:41       VMware, Inc.
---     Pass 1 complete
---     Pass 2 complete

6 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.1-git: 256 hosts scanned in 2.057 seconds (124.45 hosts/sec). 4 responded
$ arp-scan -vv 192.168.14.1
Interface: ens33, type: EN10MB, MAC: 00:0c:29:d3:97:e8, IPv4: 192.168.14.128
DEBUG: pcap filter string: "ether dst 00:0c:29:d3:97:e8 and (arp or (ether[14:4]=0xaaaa0300 and ether[20:2]=0x0806) or (ether[12:2]=0x8100 and ether[16:2]=0x0806) or (ether[12:2]=0x8100 and ether[18:4]=0xaaaa0300 and ether[24:2]=0x0806))"
DEBUG: Loaded 47430 IEEE OUI/Vendor entries from ieee-oui.txt.
DEBUG: Loaded 8 MAC/Vendor entries from mac-vendor.txt.
DEBUG: pkt len=64 bytes, bandwidth=256000 bps, interval=2000 us
Starting arp-scan 1.10.1-git with 1 hosts (https://github.com/royhills/arp-scan)
---     Sending packet #1 to host 192.168.14.1 tmo 500000
---     Received packet #1 from 192.168.14.1
192.168.14.1    00:50:56:c0:00:08       VMware, Inc.
---     Removing host 192.168.14.1 - Received 60 bytes

5 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.1-git: 1 hosts scanned in 0.140 seconds (7.14 hosts/sec). 1 responded

802.1Q VLAN Hopping

Specifying the --vlan (-Q) option causes an 802.1Q header containing the specified VLAN number to be added to the outgoing ARP request frames as shown in the diagram below.

Ethernet-8021q-frame

Irrespective of whether the --vlan option was specified, arp-scan will always receive ARP replies either with or without an 802.1Q header, and will display (802.1Q VLAN=<n>) to indicate a response containing a 802.1Q header and show the VLAN number.

If the system running arp-scan is on a switch trunk port, then the --vlan option can be used to scan systems in any VLAN.

Writing responses to a PCAP Savefile

If the --pcapsavefile (-W) option is used, then the received ARP replies are written to the specified PCAP savefile in addition to being displayed in the normal way.

This option can be useful if you want to perform additional analysis on the received ARP responses.

Here is an example showing the use of the --pcapsavefile option, and analysis of the PCAP savefile with tcpdump.

$ arp-scan -I eth0 --pcapsavefile=arp-pcap 192.168.124.1
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.7 with 1 hosts (http://www.nta-monitor.com/tools/arp-scan/)
192.168.124.1   00:c0:9f:09:b8:db       QUANTA COMPUTER, INC.
$ tcpdump -n -r arp-pcap
reading from file arp-pcap, link-type EN10MB (Ethernet)
10:53:33.029285 arp reply 192.168.124.1 is-at 00:c0:9f:09:b8:db

Unusual Behaviour

Here is a list of strange behaviour that I've noticed while using arp-scan.

Duplicate ARP replies

Some systems have been observed to send multiple ARP responses to a single ARP request. arp-scan flags these duplicate responses as DUP: n in the output, where n is the number of times we've seen this reply.

Here is an example from an arp-scan against a Class-C network. The -N option is the short form of --nodns, which prevents any DNS lookups; and -r 1 is the short form for --retry=1, which ensures that only one ARP request is sent.

% arp-scan -N -r 1 -s 192.168.1.40 192.168.1.0/24
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.2 (ether-scan-engine 1.3) with 256 hosts
192.168.1.33    00:00:5e:00:01:ca       USC INFORMATION SCIENCES INST
192.168.1.34    00:0b:46:e4:8d:6d       Cisco
192.168.1.34    00:0b:46:e4:8d:6d       Cisco (DUP: 2)
192.168.1.45    00:0a:b7:9b:b7:7a       Cisco Systems
192.168.1.46    00:0a:b7:9b:b7:01       Cisco Systems

We see that the Cisco system with IP address 192.168.1.34 and MAC address 00:0b:46:e4:8d:6d responds twice to the single ARP request.

Here is the tcpdump output from another example:

00:0b:db:1c:59:e7 > ff:ff:ff:ff:ff:ff, ethertype ARP, length 42: arp who-has 192.168.1.99 tell 192.168.1.102
                         0001 0800 0604 0001 000b db1c 59e7 c0a8
                         0166 0000 0000 0000 c0a8 0163
00:e0:b6:06:9d:1d > 00:0b:db:1c:59:e7, ethertype ARP, length 60: arp reply 192.168.1.99 is-at 00:e0:b6:06:9d:1d
                         0001 0800 0604 0002 00e0 b606 9d1d c0a8
                         0163 000b db1c 59e7 c0a8 0166 0000 0000
                         0000 0000 0000 0000 0000 0000 0000
00:e0:b6:06:9d:1d > 00:0b:db:1c:59:e7, ethertype ARP, length 60: arp reply 192.168.1.99 is-at 00:e0:b6:06:9d:1d
                         0001 0800 0604 0002 00e0 b606 9d1d c0a8
                         0163 000b db1c 59e7 c0a8 0166 0000 0000
                         0000 0000 0000 0000 0000 0000 0000

Here the ARP request is sent, and the first reply comes back in 252us followed by a second reply 262us after the first. The vendor OUI for this device is "Entrada Networks".

I do not know what causes this behaviour, and suspect that it is a bug in the IP stack. If anyone knows the cause, please let me know.

Keeping the vendor data up to date

The data used to decode the vendor string from the Ethernet MAC address is kept in two files:

  • ieee-oui.txt - MAC/Vendor mappings from the IEEE MA-L (OUI), MA-M, MA-S (OUI36) and IAB registries.
  • mac-vendor.txt - Manual MAC/Vendor mappings

The first of these are generated from the data on the IEEE website; the second is manually maintained by the arp-scan author.

Each new release of arp-scan will contain updated versions of all three files. However you can also update them yourself between releases, and it is suggested that you update from time to time to ensure that the data is up to date.

You can update the file using the Perl script get-oui, which is included in the arp-scan distribution.

To use this script, first change directory to the place where these files are stored. The exact location depends on what was selected when arp-scan was configured, but it is generally /usr/local/share/arp-scan or /usr/share/arp-scan. Ensure that you have write access in this directory (which normally means that you'll need to be root).

Then run the script. If you specify the -v (verbose) option, it will display progress messages. The script will rename any existing ieee-oui.txt file to .bak.

Below is an example of this script being run.

$ get-oui -v
Opening ieee-oui.txt for output
Processing IEEE IAB registry data from https://standards-oui.ieee.org/iab/iab.csv
        Downloaded 381510 bytes
        4575 IAB entries written to ieee-oui.txt
Processing IEEE MAM registry data from https://standards-oui.ieee.org/oui28/mam.csv
        Downloaded 510751 bytes
        4633 MAM entries written to ieee-oui.txt
Processing IEEE OUI registry data from https://standards-oui.ieee.org/oui/oui.csv
        Downloaded 3107922 bytes
        33371 OUI entries written to ieee-oui.txt
Processing IEEE OUI36 registry data from https://standards-oui.ieee.org/oui36/oui36.csv
        Downloaded 483060 bytes
        5308 OUI36 entries written to ieee-oui.txt

Total of 47887 MAC/Vendor mappings written to ieee-oui.txt

Appendices

Introduction to the ARP protocol

ARP (Address Resolution Protocol) is a protocol that determines the link-layer (layer-2) address for a given network layer (layer-3) address. ARP is defined in RFC 826 An Ethernet Address Resolution Protocol.

The ARP protocol is designed to allow it to be used for any link-layer and network-layer protocols. However in practice it is only used for Ethernet (including 802.11 wireless) and IPv4, and we assume these protocols throughout this document. IPv6 uses NDP (neighbour discovery protocol) instead, which is a different protocol.

ARP is a non-routable protocol, and can therefore only be used between systems on the same Ethernet network.

ARP Packet Diagram

The diagram below shows an example ARP packet within an Ethernet frame:

Arp-frame

The Ethernet frame contains the MAC header followed by the ARP packet data. Both the MAC header and ARP packet data consist of a number of fields, each of which contains sample data in hexadecimal and a field name. The field names in the ARP packet data are from RFC 826. The numbers in multi-byte fields are in network byte order (big endian).

In the diagram, the packet is an ARP request (ar$op = 0001) for the IP address 10.0.0.2 (ar$tpa). It was sent from the system with MAC address 00:C0:9F:09:B8:DB (both MAC source address and ar$sha) and IP address 10.0.0.1 (ar$spa). The packet is sent to the all stations broadcast address FF:FF:FF:FF:FF:FF (MAC destination address).

This packet is displayed by tcpdump as follows:

00:c0:9f:09:b8:db > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: arp who-has 10.0.0.2 tell 10.0.0.1

Here is a raw hex dump of the packet, including Ethernet MAC header:

ff ff ff ff ff ff 00 c0 9f 09 b8 db 08 06 00 01
08 00 06 04 00 01 00 c0 9f 09 b8 db 0a 00 00 01
00 00 00 00 00 00 0a 00 00 02

The two tables below describe the fields in the Ethernet MAC header and the ARP protocol data.

MAC Header Fields

Field Name Size (Bits) Function Notes
Dest Address 48 Frame destination address By default ARP requests are sent to the broadcast address ff:ff:ff:ff:ff:ff
Source Address 48 Frame source address Default is the address of the outgoing interface
Protocol Type 16 Ethernet protocol type The ARP protocol type is 0806

The length of the MAC header is 14 bytes (112 bits).

ARP Protocol Data Fields

Field Name Size (Bits) Function Notes
ar$hrd 16 ARP Hardware Type Default is 0001 (Ethernet)
ar$pro 16 ARP Protocol Type Default is 0800 (IPv4)
ar$hln 8 Link Layer Hardware Address Length Default is 6 bytes (48 bits)
ar$pln 8 Network Protocol Address Length Default is 4 bytes (32 bits)
ar$op 16 ARP Opcode 0001 for ARP Request or 0002 for ARP Reply
ar$sha 48 Sender Hardware Address Default is the address of the outgoing interface
ar$spa 32 Sender Network Protocol Address Default is the IP address of the outgoing interface
ar$tha 48 Target Hardware Address Default is zero for ARP requests
ar$tpa 32 Target Network Protocol Address For ARP requests, this is the IP address that we wish to find

The length of the ARP protocol data is 28 bytes (224 bits). This is less than the minimum Ethernet data length of 46 bytes, so the ARP data will always be followed by at least 18 bytes of padding.

Memory Usage

The list of target hosts is stored in memory. Each host in this list uses 28 bytes of memory, so scanning a Class-B network (65,536 hosts) requires about 1.75MB of memory for the list, and scanning a Class-A (16,777,216 hosts) requires about 448MB.

Each host entry is described by the following C structure:

typedef struct {
   unsigned timeout;            /* Timeout for this host in us */
   struct in_addr addr;         /* Host IP address */
   struct timeval last_send_time; /* Time when last packet sent to this addr */
   unsigned short num_sent;     /* Number of packets sent */
   unsigned short num_recv;     /* Number of packets received */
   unsigned char live;          /* Set when awaiting response */
} host_entry;

Plotting the Timing Graphs

Rough notes for my own use.

tcpdump save: tcpdump -w <pcap-savefile> -i <interface> arp and ether src <my-mac-address> and ether dst ff:ff:ff:ff:ff:ff

tcpdump analyse: tcpdump -ttt -n -r <pcap-savefile> | sed -e 's/^ 00:00://' -e 's/ ARP, Request .*//' > <datafile>

edit to remove leading zeros, then use paste(1) to combine multiple datafiles into a file with multiple columns.

gnuplot:

set yrange [0:2500]
set xrange [0:256]
set border lw 1 lc rgb "#525252"
set key samplen 1
set key spacing 0.75
set encoding utf8
set key outside
set key textcolor rgb "#525252"
set xtics textcolor rgb "#525252"
set ytics textcolor rgb "#525252"
set title "arp-scan timing" textcolor rgb "#525252"
set ylabel "Microseconds" textcolor rgb "#525252"
set xlabel "Packets" textcolor rgb "#525252"
set mxtics 2
set mytics 2
plot for [col=1:4] 'arp-scan-0x.dat' using 0:col with lines title columnheader, 2000 notitle lt rgb "#525252", 1000 notitle lt rgb "#525252", 500 notitle lt rgb "#525252", 250 notitle lt rgb "#525252"

Misc Notes

My notes for things to add to this document

Responses are printed in the order the packets are received, not the order in which they were sent.