The arp command and the ARP cache
Before your computer can send a packet to 192.168.1.1 it must know the MAC address behind that IP. ARP asks, the answer is cached, and arp shows the cache. It is the layer where "I can see the router but can't reach it" problems live.
What ARP does
Address Resolution Protocol works only on the local segment. To reach 192.168.1.1, your machine broadcasts who has 192.168.1.1? tell 192.168.1.42 to ff:ff:ff:ff:ff:ff. The router replies 192.168.1.1 is at d4:6e:0e:11:22:33. The mapping goes into the ARP cache for a few minutes (Windows: about 15 to 45 seconds of inactivity before re-verification, up to a couple of minutes; Linux: 60 seconds base reachable time, randomised; macOS: 20 minutes). Every off-subnet packet is addressed to the router's MAC, so the only entries you normally need are the gateway and any local devices you talk to. IPv6 does the same job with Neighbour Discovery (NDP), shown by the same modern tools.
Show the cache
arp -a
arp -a -N 192.168.1.42 # one interface, by its IP
arp -a 192.168.1.1 # one entryInterface: 192.168.1.42 --- 0xc
Internet Address Physical Address Type
192.168.1.1 d4-6e-0e-11-22-33 dynamic
192.168.1.10 3c-22-fb-aa-bb-cc dynamic
192.168.1.20 00-1e-8f-12-34-56 dynamic
192.168.1.255 ff-ff-ff-ff-ff-ff static
224.0.0.22 01-00-5e-00-00-16 static
224.0.0.251 01-00-5e-00-00-fb static
239.255.255.250 01-00-5e-7f-ff-fa static0xc is the interface index in hex (12). dynamic entries were learned; static ones are built in (broadcast, multicast) or added by hand. PowerShell: Get-NetNeighbor -AddressFamily IPv4 | Where-Object State -ne Unreachable, with states Reachable, Stale, Delay, Probe, Permanent, Unreachable.
ip neigh # the modern command
ip -4 neigh show dev enp3s0
ip -6 neigh # IPv6 neighbours (NDP)
arp -n # net-tools, numeric
arp -a # net-tools, BSD-style with names
arp -e # Linux-style table
cat /proc/net/arp # works with no tools installed$ ip neigh
192.168.1.1 dev enp3s0 lladdr d4:6e:0e:11:22:33 REACHABLE
192.168.1.10 dev enp3s0 lladdr 3c:22:fb:aa:bb:cc STALE
192.168.1.99 dev enp3s0 FAILED
fe80::1 dev enp3s0 lladdr d4:6e:0e:11:22:33 router REACHABLEnet-tools flags: C complete, M permanent (static), P published (proxy ARP). ip neigh states →
arp -a # all entries with names (slow if DNS is broken)
arp -an # numeric
arp -n 192.168.1.1 # one entry
ndp -an # IPv6 neighbours? (192.168.1.1) at d4:6e:e:11:22:33 on en0 ifscope [ethernet]
? (192.168.1.10) at 3c:22:fb:aa:bb:cc on en0 ifscope [ethernet]
? (192.168.1.99) at (incomplete) on en0 ifscope [ethernet]
? (192.168.1.255) at ff:ff:ff:ff:ff:ff on en0 ifscope [ethernet]macOS prints MAC bytes without leading zeros (e for 0e). (incomplete) means a request got no reply.
Clear the cache
Useful after a device changed its NIC or address, after replacing a router, or when an entry looks wrong.
arp -d * :: Windows (admin): everything
arp -d 192.168.1.10 :: Windows: one entry
netsh interface ip delete arpcache :: Windows: alternative
sudo ip neigh flush all # Linux
sudo ip neigh flush dev enp3s0
sudo ip neigh del 192.168.1.10 dev enp3s0
sudo arp -d 192.168.1.10 # Linux/macOS net-tools style
sudo arp -d -a # macOS: everythingEntries come back as soon as you talk to the host again, so a flush is harmless.
Static entries
A static entry pins an IP to a MAC and never expires. Used for devices that do not answer ARP (some embedded gear during configuration), for Wake-on-LAN across subnets, and occasionally as a crude ARP-spoofing defence for the gateway.
arp -s 192.168.1.5 00-11-22-33-44-55 :: Windows (admin; on Windows 8+ use netsh)
netsh interface ipv4 add neighbors "Ethernet" 192.168.1.5 00-11-22-33-44-55
netsh interface ipv4 delete neighbors "Ethernet" 192.168.1.5
New-NetNeighbor -InterfaceAlias Ethernet -IPAddress 192.168.1.5 -LinkLayerAddress 001122334455 -State Permanent
sudo ip neigh add 192.168.1.5 lladdr 00:11:22:33:44:55 dev enp3s0 nud permanent # Linux
sudo ip neigh replace 192.168.1.5 lladdr 00:11:22:33:44:55 dev enp3s0 nud permanent
sudo arp -s 192.168.1.5 00:11:22:33:44:55 # Linux/macOS
sudo arp -S 192.168.1.5 00:11:22:33:44:55 # macOS: replace if exists
sudo arp -s 192.168.1.5 00:11:22:33:44:55 temp # macOS: expires normallyarping: ping at the ARP layer
ICMP ping can be blocked by a firewall; ARP cannot, if the host is on your segment and has a working stack. arping also detects duplicate addresses.
sudo arping -I enp3s0 192.168.1.1 # Linux (iputils): is the gateway answering ARP?
sudo arping -c 3 -I enp3s0 192.168.1.42
sudo arping -D -I enp3s0 -c 3 192.168.1.50 # duplicate address detection: any reply = in use
sudo arping -U -I enp3s0 192.168.1.42 # gratuitous ARP: announce yourself (after changing MAC)
# macOS: brew install arping (Thomas Habets' version, different flags)
sudo arping -c 3 192.168.1.1
# Windows: no built-in; use 'arp -a' after 'ping', or the arp-ping tool from Sysinternals-style utilitiesARPING 192.168.1.1 from 192.168.1.42 enp3s0
Unicast reply from 192.168.1.1 [D4:6E:0E:11:22:33] 0.612ms
Unicast reply from 192.168.1.1 [D4:6E:0E:11:22:33] 0.588ms
Unicast reply from 192.168.1.1 [D4:6E:0E:11:22:33] 0.601ms
Sent 3 probes (1 broadcast(s))
Received 3 response(s)Two different MACs replying to one arping is the definitive proof of a duplicate IP.
arp-scan and other ways to populate the cache
The cache only holds hosts you have talked to. To see everything on the segment, ask them all:
sudo arp-scan --localnet # Linux/macOS (package arp-scan): every host with vendor
sudo arp-scan -I enp3s0 192.168.1.0/24
sudo nmap -sn 192.168.1.0/24 # ping sweep that also uses ARP on the local segment
# Windows: sweep with ping, then read the cache
for /L %i in (1,1,254) do @ping -n 1 -w 50 192.168.1.%i >nul
arp -aDevices with Wi-Fi client isolation enabled, and sleeping phones, will not appear. Finding every device on your network →
Diagnosing with ARP
| Symptom in the cache | Meaning | Do |
|---|---|---|
| Gateway missing, or incomplete / FAILED | The router did not answer ARP: wrong subnet, VLAN, cable, or the router is down | Check link and addressing; ping the gateway; arping it |
| Gateway MAC changes between lookups, or two devices share a MAC | Duplicate IP or ARP spoofing (a device impersonating the router, e.g. a rogue "security" app, a captive portal, or an attacker) | Find the second device via its MAC/OUI and the switch; consider a static entry for the gateway |
| Gateway MAC belongs to an unexpected vendor | A second router or a mesh node is answering as the gateway | Compare with the router's sticker; look for a rogue DHCP server |
| Entry exists but the host does not respond to ping | Firewall on the host, or a stale entry after the host changed NIC | Flush the entry; test a TCP port instead |
| Many entries for addresses you never contacted | Something on your machine is scanning (a network monitor, a game, malware) | netstat -ano / ss -p to find the process |
| Large numbers of incomplete entries | A scan hit addresses that do not exist, or an application is retrying dead hosts | Usually harmless; flush |
Proxy ARP and gratuitous ARP
Proxy ARP is a router answering ARP on behalf of hosts on another network, so that clients with a wrong or oversized mask still work. Linux enables it with sysctl net.ipv4.conf.eth0.proxy_arp=1; the P flag in arp -n marks published entries. Gratuitous ARP is an unsolicited announcement ("I am 192.168.1.42 at this MAC") sent when an interface comes up, after failover in HA pairs, and by DHCP clients after receiving a lease; it updates caches on every host and is also what duplicate-address detection listens for.