ARP-SCAN(1)

๐Ÿ“ฆ
version 1.10.0 ยท 5 versions
, in alpine 3.24, debian bookworm, debian trixie, epel 10, epel 9, fedora 43, fedora 44, ubuntu noble, ubuntu resolute, ubuntu stonking

๐Ÿ’– ARP-SCAN(1) โ€” General Commands Manual ๐Ÿ’–

okay bestie, sit down, hydrate, and let me tell you about arp-scan, aka the glow-up your local network has been waiting for โœจ


๐ŸŒธ NAME ๐ŸŒธ

arp-scan โ€” bestie, it sends ARP requests to target hosts and displays the responses. that's the whole vibe. ๐Ÿ’…


๐Ÿฆ‹ SYNOPSIS ๐Ÿฆ‹

arp-scan [options] [hosts...]

so here's the tea: you must put your target hosts on the command line โ€” unless you're using the --file or --localnet option. those two are your hall passes. ๐ŸŽ€

and what can those targets even be? so many options, queen:

  • plain old IPv4 addresses โœ…
  • hostnames โœ…
  • CIDR notation like 10.0.0.0/24 โ€” yes, network and broadcast included, she's thorough
  • ranges like 10.0.0.1-10.0.0.10
  • network:mask like 10.0.0.0:255.255.255.0

๐Ÿ‘‘ DESCRIPTION ๐Ÿ‘‘

arp-scan sends ARP request packets to the hosts you specified and displays any responses received. iconic behaviour, truly.

๐ŸŽ€ Picking your interface

want a specific network interface? say it with your chest via the --interface option. if you don't specify one, arp-scan will just pick the lowest numbered, configured up interface โ€” and no, she's not gonna pick loopback, that's not the moment. ๐Ÿ’€

๐Ÿ” Privileges (aka the "why do I need perms" part)

arp-scan uses raw sockets, which on some systems means you need privileges. here's the breakdown, no gatekeeping:

  • Linux with POSIX.1e capabilities support using libcap:
    • arp-scan is capabilities aware. it needs CAP_NET_RAW in the permitted set, and it only enables that capability for the functions that actually need it. โœจ
    • use setcap cap_net_raw+p /path/to/arp-scan to add CAP_NET_RAW to the permitted set of the arp-scan executable.
    • also, capabilities support makes SUID root much safer, because arp-scan will drop all capabilities except CAP_NET_RAW and will not run with full root privileges. she's responsible like that. ๐Ÿซถ
  • BSD and macOS:
    • you need read/write access to /dev/bpf*. that's the whole requirement, periodt.
  • Any operating system:
    • running as root or SUID root will work on any OS, but other methods are preferable where possible. like, it works, but we're aiming higher, bestie. ๐Ÿ’…

๐ŸŒˆ The ARP tea

ARP only operates on the local network, and cannot be routed. it does not do cross-network journeys. sorry. ๐Ÿ˜ญ

and here's a fun little plot twist: although the ARP protocol uses IPv4 addresses, it is not an IP protocol โ€” and arp-scan can be used on interfaces without an IPv4 address. she's flexible, she contains multitudes. ๐Ÿฆ‹

๐Ÿ” Requests and retries

One ARP request is sent for each target. if a host doesn't respond, the request gets re-sent once more. you can change the number of retries with the --retry option.

reducing the number of retries will reduce the scanning time โ€” at the risk of missing some results due to packet loss. speed vs. accuracy, the eternal struggle. ๐Ÿ’€

โšก Bandwidth and timing

you can specify the bandwidth arp-scan will use with the --bandwidth option. the default is 256000 bits per second.

  • bumping the bandwidth up = less scanning time ๐Ÿ”ฅ
  • but setting the bandwidth too high may cause a high broadcast packet rate โš ๏ธ
  • another way to specify the packet rate is with the --interval option โœจ

๐Ÿงฎ The math (yes, there's math, stay with me)

the time for a single-pass scan (i.e. with --retry=1) is:

time=nร—i+t+o

where, bestie:

  • n is the number of hosts
  • i is the interval (given with --interval or calculated from --bandwidth)
  • t is the timeout (specified with --timeout)
  • o is the overhead time taken to load the target list and read the MAC/Vendor mapping files

the overhead is normally negligible (typically around 100ms) but can be reduced further by the --quiet option. ๐ŸŽ€

for small lists of hosts, the timeout value will dominate. for large lists, the packet interval is the most important value. iykyk. ๐Ÿ’…


๐ŸŒŸ ARP Request Packet Options

any part of the ARP request may be modified through the use of the --arpXXX options, as shown in the table below (which i have lovingly de-tabled for you, you're welcome ๐Ÿซถ):

  • ar$hrd โ€” 16 bits โ€” --arphrd โ€” default 1 (ARPHRD_ETHER)
  • ar$pro โ€” 16 bits โ€” --arppro โ€” default 0x0800
  • ar$hln โ€” 8 bits โ€” --arphln โ€” default 6 (ETH_ALEN)
  • ar$pln โ€” 8 bits โ€” --arppln โ€” default 4 (IPv4)
  • ar$op โ€” 16 bits โ€” --arpop โ€” default 1 (ARPOP_REQUEST)
  • ar$sha โ€” 48 bits โ€” --arpsha โ€” default interface h/w address
  • ar$spa โ€” 32 bits โ€” --arpspa โ€” default interface IPv4 address
  • ar$tha โ€” 48 bits โ€” --arptha โ€” default 00:00:00:00:00:00
  • ar$tpa โ€” 32 bits โ€” None โ€” default target host IPv4 address

the most common option is --arpspa, which sets the source IPv4 address in the ARP request, letting the ARP request use a different source address from the interface address. this is how you get arp-scan working on interfaces with no IPv4 address. slay. ๐Ÿ”ฅ

โš ๏ธ Note: setting ar$spa to the target's IP address causes some operating systems to report an address clash when they receive an ARP request for their own address. dramatic, but fair. ๐Ÿ’€

๐ŸŒˆ Ethernet Header Options

you can also change the values in the Ethernet frame header, bestie:

  • Dest Address โ€” 48 bits โ€” --destaddr โ€” default ff:ff:ff:ff:ff:ff
  • Source Address โ€” 48 bits โ€” --srcaddr โ€” default interface address
  • Protocol Type โ€” 16 bits โ€” --prototype โ€” default 0x0806 (ARP)

the --destaddr option, which sets the destination Ethernet address, is the only one that is commonly used. the others are just there for the girlies who like to go deep. ๐ŸŽ€


๐Ÿ“ Output format

by default, ARP responses are displayed in the following format:

<IPv4 Address>   <MAC Address>   <Vendor Details>

where:

  • <IPv4 Address> is the IP address of the responding target
  • <MAC Address> is its link-layer address
  • <Vendor Details> are the vendor details decoded from the hardware address

the output fields are separated by a single tab character. you can change the output format with the --format option. โœจ

responses are displayed in the order they are received โ€” which can be different from the order the requests were sent, because some hosts just respond quicker than others. main character energy, honestly. ๐Ÿ’…

๐Ÿงš Vendor decoding

the vendor decoding uses the files ieee-oui.txt and mac-vendor.txt.

  • ieee-oui.txt is generated from the IEEE MA-L (OUI), MA-M, MA-S (OUI36) and IAB registries.
  • mac-vendor.txt contains additional MAC to Vendor mappings, and can be used to add custom mappings.
  • get-oui can be used to update ieee-oui.txt with the latest data from the IEEE registries. keep her fresh. ๐ŸŒธ

โญ the big finish

All IPv4 hosts should respond to ARP request packets โ€” including hosts with packet filtering such as firewalls. which is exactly why arp-scan is such a useful tool to discover all active IPv4 hosts on the local network. no cap. ๐Ÿ‘‘

โœจ OPTIONS โœจ

okay bestie, so whenever an option wants a value, the manpage tells you what kind of value by putting a lil letter in angle brackets. here's the decoder ring ๐Ÿ’–

  • <s> โ€” a character string, aka just some text.
  • <i> โ€” a decimal integer, or hex if you put 0x in front of it, like 2048 or 0x800.
  • <f> โ€” a floating point decimal number.
  • <m> โ€” a MAC address, like 01:23:45:67:89:ab or 01-23-45-67-89-ab (case insensitive, don't stress about caps).
  • <a> โ€” an IPv4 address, like 10.0.0.1.
  • <h> โ€” hex encoded binary data. no leading 0x (also case insensitive).
  • <x> โ€” something else, so go read that option's description, bestie.

๐ŸŒธ General Options ๐ŸŒธ

  • --help or -h โ€” shows you this usage message and then dips. that's it, that's the whole thing.
  • --verbose or -v โ€” gives you verbose progress messages. you can pass it more than once to crank up the verbosity. max is 3, so like, don't go wild.
  • --version or -V โ€” prints the program version and exits. it shows the version, the license details, the libpcap version, and whether POSIX.1e capability support is compiled in. receipts, basically.
  • --interface=<s> or -I <s> โ€” use network interface <s>. if you don't say which one, arp-scan goes through the system interface list and picks the lowest numbered, configured-up interface (loopback is excluded, she's not invited ๐Ÿ’…).

๐ŸŒธ Host Selection ๐ŸŒธ

  • --file=<s> or -f <s> โ€” read hostnames or addresses from the file you name. one name or address pattern per line. use "-" for stdin.
  • --localnet or -l โ€” generate the addresses straight from the interface config. it builds the list from the interface address and netmask (network and broadcast included, periodt). heads up: you cannot use the --file option or give targets on the command line when you do this. use --interface to pick the interface.

๐ŸŒธ MAC/Vendor Mapping Files ๐ŸŒธ

  • --ouifile=<s> or -O <s> โ€” use the IEEE registry vendor mapping file <s>. the default is ieee-oui.txt in the current directory, and if that's not there, /usr/share/arp-scan/ieee-oui.txt gets used instead.
  • --macfile=<s> or -m <s> โ€” use a custom vendor mapping file <s>. the default is mac-vendor.txt in the current directory, and if that one's missing, /etc/arp-scan/mac-vendor.txt is the fallback.

๐ŸŒธ Output Format Control ๐ŸŒธ

  • --quiet or -q โ€” minimal output for every host that responds. only the IP address and the MAC address show up. it also saves you like 5MB of memory because the vendor mapping files never get loaded. warning tho: if you're using --format, only the ${ip} and ${mac} fields are available when --quiet is on. that's the whole menu.
  • --plain or -x โ€” suppresses the header and footer text, so all you get is the responding host details. iconic if a script is gonna parse your output.
  • --ignoredups or -g โ€” don't show duplicate packets. by default duplicates get flagged with (DUP: n), where n is how many times that host has responded.
  • --rtt or -D โ€” calculate and display the packet round-trip time. it's shown in milliseconds plus fractional microseconds. this is what unlocks the ${rtt} field for --format.
  • --format=<s> or -F <s> โ€” give her the output format string. this string gets output once for each responding host. you pull in host details by inserting field references using the syntax ${field[;width]}. fields are displayed right-aligned by default, unless the width is negative, in which case you get left alignment. these case-insensitive field names are the ones she recognizes:
    • IP โ€” host IPv4 address in dotted quad format
    • Name โ€” host name, if the --resolve option was given
    • MAC โ€” host MAC address xx:xx:xx:xx:xx:xx
    • HdrMAC โ€” Ethernet source addr, if it's different
    • Vendor โ€” the vendor details string
    • Padding โ€” padding after the ARP packet, in hex, if nonzero
    • Framing โ€” framing type, if it's not Ethernet_II
    • VLAN โ€” 802.1Q VLAN ID, if present
    • Proto โ€” ARP protocol, if it's not 0x0800
    • DUP โ€” packet number for duplicate packets (>1)
    • RTT โ€” round trip time, if the --rtt option was given

reminder bestie: only the ${ip} and ${mac} fields are available if you specified the --quiet option.

anything that isn't a field just gets output verbatim. and a \ introduces escapes:

  • \n โ€” newline
  • \r โ€” carriage return
  • \t โ€” tab
  • \ โ€” suppresses the special meaning of the following character

you should wrap the --format argument in 'single quotes' so the shell doesn't eat your special characters. protect her ๐Ÿซถ

example: --format='${ip}\t${mac}\t${vendor}'

๐ŸŒธ Host List Randomisation ๐ŸŒธ

  • --random or -R โ€” randomises the target host list. shuffle era.
  • --randomseed=<i> โ€” seeds the pseudo random number generator. super useful if you want a --random order you can actually reproduce.

๐ŸŒธ Output Timing and Retry ๐ŸŒธ

  • --retry=<i> or -r <i> โ€” set the total number of attempts per host to <i>, default is 2.
  • --backoff=<f> or -b <f> โ€” set the backoff factor to <f>, default is 1.50. it multiplies the timeout by <f> for each pass.
  • --timeout=<i> or -t <i> โ€” set the initial per-host timeout to <i> ms, default is 500. this timeout is for the first packet sent to each host. subsequent timeouts get multiplied by the backoff factor, which you set with --backoff.
  • --interval=<x> or -i <x> โ€” set the minimum packet interval to <x>. this controls outgoing bandwidth usage by capping the packet rate. if you just wanna use up to a given bandwidth, honestly it's easier to use --bandwidth instead. the interval is in milliseconds, or microseconds if you tack a "u" on the end.
  • --bandwidth=<x> or -B <x> โ€” set the outbound bandwidth to <x>, default is 256000. the value is in bits per second. append K for kilobits or M for megabits (decimal multiples, not the confusing binary ones). and no, you cannot specify both --interval and --bandwidth, pick a lane ๐ŸŒˆ

๐ŸŒธ DNS Resolution ๐ŸŒธ

  • --numeric or -N โ€” targets must be IP addresses, not hostnames. this can cut down startup time for big target lists.
  • --resolve or -d โ€” resolves responding addresses to hostnames. the default output format will show the hostname instead of the IPv4 address. this option is what makes the ${name} field available for --format.

๐ŸŒธ Output ARP Packet ๐ŸŒธ

  • --arpsha=<m> or -u <m> โ€” set the ARP source Ethernet address. this sets the 48-bit ar$sha field, but it does not change the hardware address in the frame header โ€” for that, see --srcaddr. default is the Ethernet address of the outgoing interface.
  • --arptha=<m> or -w <m> โ€” set the ARP target Ethernet address. sets the 48-bit ar$tha field. default is zero, because this field isn't used for ARP request packets anyway.
  • --arphrd=<i> or -H <i> โ€” set the ARP hardware type, default is 1. sets the 16-bit ar$hrd field. the default is 1 (ARPHRD_ETHER). a lot of operating systems also respond to 6 (ARPHRD_IEEE802).
  • --arppro=<i> or -p <i> โ€” set the ARP protocol type, default is 0x0800. sets the 16-bit ar$pro field. most operating systems only respond to 0x0800 (IPv4), jsyk.
  • --arphln=<i> or -a <i> โ€” set the hardware address length, default is 6. sets the 8-bit ar$hln field. important: the lengths of the ar$sha and ar$tha fields do not change because of this option โ€” it only changes the ar$hln field itself.
  • --arppln=<i> or -P <i> โ€” set the protocol address length, default is 4. sets the 8-bit ar$pln field. same deal: the lengths of the ar$spa and ar$tpa fields are not changed by this option, it only changes ar$pln.
  • --arpop=<i> or -o <i> โ€” specify the ARP operation, default is 1. sets the 16-bit ar$op field. most operating systems only respond to the value 1 (ARPOP_REQUEST).
  • --arpspa=<a> or -s <a> โ€” set the source IPv4 address. it should be in dotted quad format, or the string "dest", which sets the source address to the target host address. default is the outgoing interface address. sets the 32-bit ar$spa field. some operating systems only respond if the source address is inside the network of the receiving interface. and heads up: setting ar$spa to the destination IP address can make some operating systems report an address clash. dramatic, but fr fr.

๐ŸŒธ Output Ethernet Header ๐ŸŒธ

  • --srcaddr=<m> or -S <m> โ€” set the source Ethernet MAC address. default is the interface MAC address. this sets the address in the Ethernet header. it does not change the address in the ARP packet โ€” use --arpsha for that one, bestie.
  • --destaddr=<m> or -T <m> โ€” set the destination MAC address. this sets the destination address in the Ethernet header. default is ff:ff:ff:ff:ff:ff (broadcast). hosts also respond if the request goes to their unicast address, or to a multicast address they're listening on.
  • --prototype=<i> or -y <i> โ€” sets the Ethernet protocol type, default is 0x0806. this sets the protocol type field in the Ethernet header.
  • --llc or -L โ€” use RFC 1042 LLC/SNAP encapsulation for 802.2 networks. arp-scan will decode and display ARP responses in both Ethernet-II and IEEE 802.2 formats no matter what this option is set to.
  • --vlan=<i> or -Q <i> โ€” use 802.1Q tagging with VLAN id <i>. the id should be in the range 0 to 4095. arp-scan will decode and display ARP responses in 802.1Q format no matter what this option is set to.

๐ŸŒธ Misc Options ๐ŸŒธ

  • --limit=<i> or -M <i> โ€” exit after the specified number of hosts have responded. arp-scan will exit with status 1 if the number of responding hosts is less than the limit. this is chef's kiss for scripts, because you can check whether fewer hosts responded without having to parse the output at all.
  • --pcapsavefile=<s> or -W <s> โ€” write received packets to pcap savefile <s>. ARP responses get written to the file you name and decoded and displayed like normal.
  • --snap=<i> or -n <i> โ€” set the pcap snap length to <i>, default is 64. this specifies the frame capture length, Ethernet header included. the default is normally plenty.
  • --retry-send=<i> or -Y <i> โ€” set the number of send attempts, default is 20.
  • --retry-send-interval=<i> or -E <i> โ€” set the interval between send attempts. the interval is in milliseconds, or microseconds if "u" is appended. default is 5.
  • --padding=<h> or -A <h> โ€” specify padding after the packet data. this sets the padding after the ARP request to the hex value <h>.

๐Ÿ’ฅ EXIT STATUS ๐Ÿ’ฅ

okay so here's the tea on how arp-scan says goodbye ๐Ÿ‘‹

  • arp-scan will exit with 0 when it finishes successfully, or >0 if it ran into an error. no cap.
  • bonus plot twist: if you used the --limit option, arp-scan will also exit with a non-zero exit code if the number of responding hosts comes in less than the limit you specified. like, it's not just gonna shrug at you. it's gonna tell you via exit code bestie ๐Ÿ’…

๐Ÿ—‚๏ธ FILES ๐Ÿ—‚๏ธ

  • /usr/share/arp-scan/ieee-oui.txt โ€” the list of IEEE OUI (Organisationally Unique Identifier) to vendor mappings. this is where the whole "ooh that MAC belongs to Dell" magic lives โœจ
  • /etc/arp-scan/mac-vendor.txt โ€” the list of other Ethernet MAC to vendor mappings, and yes, it includes your local additions too ๐Ÿซถ

๐ŸŒธ EXAMPLES ๐ŸŒธ

โœจ Simple Scan โœจ

Scan the default network using the interface IPv4 configuration to generate the list of hosts to scan. it's giving effortless. it's giving default behavior. iconic.

$ arp-scan --localnet
Interface: eth0, type: EN10MB, MAC: 50:65:f3:f0:6d:7c, IPv4: 10.0.0.106
Starting arp-scan 1.9.9 with 256 hosts (https://github.com/royhills/arp-scan)
10.0.0.14       a4:1f:72:7f:25:bb       Dell Inc.
10.0.0.22       10:60:4b:73:43:de       Hewlett Packard
10.0.0.74       00:0c:29:90:07:e9       VMware, Inc.
10.0.0.75       00:0c:29:66:9e:c2       VMware, Inc.
10.0.0.76       00:0c:29:d0:e1:ea       VMware, Inc.
10.0.0.82       9c:b6:54:bb:f3:ec       Hewlett Packard
10.0.0.84       00:21:9b:fd:b9:b3       Dell Inc.
10.0.0.85       00:02:b3:eb:5a:f8       Intel Corporation
10.0.0.91       00:9c:02:a5:7b:29       Hewlett Packard
10.0.0.92       d4:ae:52:d0:07:6f       Dell Inc.
10.0.0.93       d4:ae:52:d0:04:9b       Dell Inc.
10.0.0.96       9c:b6:54:bb:f5:35       Hewlett Packard
10.0.0.97       00:0c:29:0e:95:20       VMware, Inc.
10.0.0.104      50:65:f3:f0:70:a4       Hewlett Packard

15 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9.9: 256 hosts scanned in 1.532 seconds (167.10 hosts/sec). 14 responded

look at that little summary line at the end. 14 responded. main character energy fr fr ๐ŸŽ€


๐Ÿ’… Output Formatting ๐Ÿ’…

Scan all hosts in 10.0.0.0/24 using interface eth0. Calculate round-trip time and display in aligned columns using a custom format. yes we're doing custom format now, we're fancy, we're thriving.

$ arp-scan -I eth0 --rtt --format='|${ip;-15}|${mac}|${rtt;8}|' 10.0.0.0/24
Interface: eth0, type: EN10MB, MAC: 50:65:f3:f0:6d:7c, IPv4: 10.0.0.106
Starting arp-scan 1.9.9 with 256 hosts (https://github.com/royhills/arp-scan)
|10.0.0.14      |a4:1f:72:7f:25:bb|   0.280|
|10.0.0.22      |10:60:4b:73:43:de|   0.293|
|10.0.0.74      |00:0c:29:90:07:e9|   0.380|
|10.0.0.75      |00:0c:29:66:9e:c2|   0.311|
|10.0.0.76      |00:0c:29:d0:e1:ea|   0.326|
|10.0.0.82      |9c:b6:54:bb:f3:ec|   0.216|
|10.0.0.84      |00:21:9b:fd:b9:b3|   0.244|
|10.0.0.85      |00:02:b3:eb:5a:f8|   0.244|
|10.0.0.91      |00:9c:02:a5:7b:29|   0.209|
|10.0.0.92      |d4:ae:52:d0:07:6f|   0.289|
|10.0.0.93      |d4:ae:52:d0:04:9b|   0.278|
|10.0.0.96      |9c:b6:54:bb:f5:35|   0.255|
|10.0.0.97      |00:0c:29:0e:95:20|   0.288|
|10.0.0.104     |50:65:f3:f0:70:a4|   0.263|

14 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9.9: 256 hosts scanned in 2.032 seconds (125.98 hosts/sec). 14 responded

the pipes?? the alignment?? we ATE that formatting bestie ๐Ÿ”ฅ


๐Ÿ“ CSV Output ๐Ÿ“

--plain removes extraneous output. that's it, that's the whole note. clean, minimal, aesthetic.

$ arp-scan -I eth0 --plain --format='${ip},${mac},"${vendor}"' 10.0.0.0/24
10.0.0.14,a4:1f:72:7f:25:bb,"Dell Inc."
10.0.0.22,10:60:4b:73:43:de,"Hewlett Packard"
10.0.0.74,00:0c:29:90:07:e9,"VMware, Inc."
10.0.0.75,00:0c:29:66:9e:c2,"VMware, Inc."
10.0.0.76,00:0c:29:d0:e1:ea,"VMware, Inc."
10.0.0.82,9c:b6:54:bb:f3:ec,"Hewlett Packard"
10.0.0.84,00:21:9b:fd:b9:b3,"Dell Inc."
10.0.0.85,00:02:b3:eb:5a:f8,"Intel Corporation"
10.0.0.91,00:9c:02:a5:7b:29,"Hewlett Packard"
10.0.0.92,d4:ae:52:d0:07:6f,"Dell Inc."
10.0.0.93,d4:ae:52:d0:04:9b,"Dell Inc."
10.0.0.96,9c:b6:54:bb:f5:35,"Hewlett Packard"
10.0.0.97,00:0c:29:0e:95:20,"VMware, Inc."
10.0.0.104,50:65:f3:f0:70:a4,"Hewlett Packard"

note how "VMware, Inc." gets quoted and "Dell Inc." gets quoted โ€” that's the ${vendor} doing its thing inside the quotes, iykyk ๐Ÿ’œ


๐Ÿ‘€ SEE ALSO ๐Ÿ‘€


and that's a wrap on the whole page, bestie!! ๐ŸŽ€โœจ this manual page is dated November 9, 2022 and it's the man page for ARP-SCAN(1) โ€” arp-scan version 1.9.9 if you were clocking the examples, which, obsessed. thanks for reading the entire thing, you're literally a networking queen now ๐Ÿ‘‘๐ŸŒˆ go scan something (responsibly, on your own network, periodt ๐Ÿ’…).