cheat sheet
arp
Display, add, and delete entries in the Windows ARP (Address Resolution Protocol) cache — map IP addresses to MAC addresses, detect IP conflicts, and diagnose Layer 2 connectivity issues.
arp — ARP Cache Viewer and Editor
What it is
arp is a built-in Windows command that displays and manipulates the ARP (Address Resolution Protocol) cache — the table that maps IPv4 addresses to MAC addresses on the local network segment. When a host sends a packet to an IP on the same subnet, it first checks the ARP cache; if the mapping is unknown, it broadcasts an ARP request. Use arp -a to see resolved mappings, arp -s to add a static entry (useful for preventing ARP spoofing against a critical host), and arp -d to flush stale entries. The PowerShell equivalent is Get-NetNeighbor.
Availability
arp ships as C:\Windows\System32\arp.exe on all Windows versions.
arp /?
Output:
Displays and modifies the IP-to-Physical address translation tables used by
address resolution protocol (ARP).
ARP -s inet_addr eth_addr [if_addr]
ARP -d inet_addr [if_addr]
ARP -a [inet_addr] [-N if_addr] [-v]
-a Displays current ARP entries by interrogating the current
protocol data. If inet_addr is specified, the IP and Physical
addresses for only the specified computer are displayed.
-v Displays current ARP entries in verbose mode.
-N if_addr Displays the ARP entries for the network interface specified
by if_addr.
-d inet_addr Deletes the host specified by inet_addr.
-s inet_addr Adds a permanent static entry to the ARP cache.
eth_addr Specifies a physical address.
if_addr Specifies the internet address of the interface whose address
translation table should be modified.
Syntax
arp -a [inet_addr] [-N if_addr] [-v]
arp -s inet_addr eth_addr [if_addr]
arp -d inet_addr [if_addr]
Output: (ARP table or operation result)
Essential options
| Switch | Meaning |
|---|---|
-a | Display all ARP cache entries for all interfaces |
-g | Alias for -a — identical behaviour, retained from BSD-style arp tooling |
-a <ip> | Display the ARP entry for a specific IP address |
-N <if_addr> | Limit display to entries for the interface with this IP |
-v | Verbose — include skipped entries (e.g. loopback) |
-s <ip> <mac> | Add a static ARP entry |
-s <ip> <mac> <if_addr> | Add a static entry on a specific interface |
-d <ip> | Delete the ARP entry for an IP |
-d * | Delete all ARP cache entries (requires Administrator) |
Displaying the ARP cache
arp -a shows the current ARP table for all network interfaces. Each entry shows the IP address, the corresponding MAC address, and whether the entry is dynamic (learned by ARP) or static (manually added).
arp -a
Output:
Interface: 192.168.1.100 --- 0x4
Internet Address Physical Address Type
192.168.1.1 00-14-22-01-23-45 dynamic
192.168.1.10 00-50-56-ab-cd-ef dynamic
192.168.1.255 ff-ff-ff-ff-ff-ff static
224.0.0.22 01-00-5e-00-00-16 static
255.255.255.255 ff-ff-ff-ff-ff-ff static
Looking up a specific IP
arp -a 192.168.1.1
Output:
Interface: 192.168.1.100 --- 0x4
Internet Address Physical Address Type
192.168.1.1 00-14-22-01-23-45 dynamic
Viewing by interface
When a machine has multiple network interfaces (e.g. Ethernet + Wi-Fi), -N filters the ARP table to entries learned on the interface with the given IP address.
arp -a -N 192.168.1.100
Output:
Interface: 192.168.1.100 --- 0x4
Internet Address Physical Address Type
192.168.1.1 00-14-22-01-23-45 dynamic
192.168.1.10 00-50-56-ab-cd-ef dynamic
Adding a static entry
A static ARP entry bypasses the dynamic resolution process for the target IP — the OS always uses the specified MAC without sending an ARP broadcast. Use this to harden the gateway mapping and prevent ARP spoofing attacks against a critical address.
arp -s 192.168.1.1 00-14-22-01-23-45
Output:
(none — exits 0 on success)
Verify the entry is now static:
arp -a 192.168.1.1
Output:
Interface: 192.168.1.100 --- 0x4
Internet Address Physical Address Type
192.168.1.1 00-14-22-01-23-45 static
Deleting an entry
-d removes a single dynamic entry from the cache, forcing a fresh ARP resolution the next time the address is contacted. Use * to flush all entries (requires Administrator on Vista+).
arp -d 192.168.1.10
Output:
(none — exits 0 on success)
rem Flush all ARP cache entries
arp -d *
Output:
(none — exits 0 on success)
Detecting IP conflicts
ARP is the primary tool for diagnosing duplicate IP address conflicts on a LAN. If two machines claim the same IP, arp -a may show the MAC flipping between two values, or ping followed by arp -a will reveal the MAC of whichever host responded.
ping -n 1 192.168.1.50 >NUL
arp -a 192.168.1.50
Output:
Interface: 192.168.1.100 --- 0x4
Internet Address Physical Address Type
192.168.1.50 00-50-56-ab-cd-ef dynamic
Compare the MAC address shown against the MAC you expect. If it differs, another device has the same IP.
ARP entry states and ageing
Windows tracks each ARP cache entry through several internal states that govern how long the mapping is trusted and when it is re-validated. The state column is not shown by arp -a (which only reports dynamic or static) but it is visible in the PowerShell view via Get-NetNeighbor.
| State | Meaning |
|---|---|
Reachable | Confirmed live within the last BaseReachableTime (default 30 s) |
Stale | Entry exists but has not been confirmed recently — next packet triggers re-resolution |
Probe | A unicast ARP request has been sent and the OS is waiting for a reply |
Delay | Re-resolution is queued; entry still usable for a few more packets |
Permanent | Static entry from arp -s or netsh ... add neighbors |
Incomplete | Initial broadcast sent, no reply yet — used for IPs that never responded |
Unreachable | Verified failure to resolve; next attempt restarts the cycle |
Get-NetNeighbor -AddressFamily IPv4 | Select-Object IPAddress,LinkLayerAddress,State,InterfaceIndex
Output:
IPAddress LinkLayerAddress State InterfaceIndex
--------- ---------------- ----- --------------
192.168.1.1 00-14-22-01-23-45 Reachable 12
192.168.1.10 00-50-56-AB-CD-EF Stale 12
192.168.1.255 FF-FF-FF-FF-FF-FF Permanent 12
224.0.0.22 01-00-5E-00-00-16 Permanent 12
The default reachable time is randomised between 15 s and 45 s and can be tuned per-interface (see "Tuning ARP cache timers" below).
PowerShell equivalents
PowerShell exposes the ARP/neighbor cache through the NetTCPIP module, with cmdlets that are scriptable and return structured objects rather than text.
# List all IPv4 neighbors (equivalent to `arp -a`)
Get-NetNeighbor -AddressFamily IPv4
# Add a static neighbor entry (equivalent to `arp -s`); persists across reboots
New-NetNeighbor -InterfaceIndex 12 -IPAddress 192.168.1.1 `
-LinkLayerAddress "00-14-22-01-23-45" -State Permanent
# Remove a specific neighbor (equivalent to `arp -d`)
Remove-NetNeighbor -InterfaceIndex 12 -IPAddress 192.168.1.10 -Confirm:$false
# Flush all dynamic IPv4 neighbors on every interface
Get-NetNeighbor -AddressFamily IPv4 -State Reachable,Stale | Remove-NetNeighbor -Confirm:$false
Output:
ifIndex IPAddress LinkLayerAddress State PolicyStore
------- --------- ---------------- ----- -----------
12 192.168.1.1 00-14-22-01-23-45 Permanent ActiveStore
New-NetNeighbor -State Permanent is the modern replacement for arp -s and is the only way to create a static entry that survives a reboot without a startup script.
IPv6 neighbor cache (ND)
ARP is IPv4-only. IPv6 uses the Neighbor Discovery protocol (NDP) defined in RFC 4861, with its own cache that has the same role but a different syntax. arp does not show IPv6 neighbors — use netsh or Get-NetNeighbor -AddressFamily IPv6.
netsh interface ipv6 show neighbors
Output:
Interface 12: Ethernet
Internet Address Physical Address Type
-------------------------------------------- ----------------- -----------
fe80::1 00-14-22-01-23-45 Stale (Router)
fe80::1a2b:3c4d:5e6f:7a8b 00-50-56-ab-cd-ef Reachable
ff02::1 33-33-00-00-00-01 Permanent
Get-NetNeighbor -AddressFamily IPv6 | Where-Object State -ne 'Permanent'
To add a static IPv6 neighbor entry:
netsh interface ipv6 add neighbors "Ethernet" fe80::1 00-14-22-01-23-45
Output:
Ok.
Tuning ARP cache timers
Windows exposes per-interface ARP cache timers via the registry and netsh. The two values that matter most are the reachable time (BaseReachableTime, default ~30 s) and the dead gateway detection interval. Lowering them speeds up failover when a neighbor's MAC changes; raising them reduces ARP broadcast traffic on stable networks.
rem View per-interface neighbor cache settings (Vista+)
netsh interface ipv4 show interfaces
netsh interface ipv4 show interface "Ethernet"
Output:
Interface "Ethernet" Parameters
-------------------------------------------------
IfLuid : ethernet_32768
IfIndex : 12
State : connected
Metric : 25
...
Base Reachable Time : 30000 ms
Retransmission Interval : 1000 ms
DAD Transmits : 3
rem Lower reachable time to 5 s for a specific interface (Admin)
netsh interface ipv4 set interface "Ethernet" basereachable=5000
Output:
Ok.
The corresponding registry key is HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\<GUID>\ReachableTime for per-interface override.
Detecting ARP spoofing
ARP has no authentication: any host on the LAN can claim any IP by sending a gratuitous ARP. An attacker performing a man-in-the-middle attack will typically poison the cache so that the gateway IP resolves to the attacker's MAC. Detect this by comparing the live cache against a known-good baseline.
rem Snapshot the cache after boot (trusted)
arp -a > C:\Audit\arp_baseline.txt
rem Later, diff against the live cache
arp -a > C:\Audit\arp_current.txt
fc C:\Audit\arp_baseline.txt C:\Audit\arp_current.txt
Output:
Comparing files C:\AUDIT\arp_baseline.txt and C:\AUDIT\arp_current.txt
***** C:\AUDIT\arp_baseline.txt
192.168.1.1 00-14-22-01-23-45 dynamic
***** C:\AUDIT\arp_current.txt
192.168.1.1 de-ad-be-ef-00-01 dynamic
*****
A change in the gateway MAC is the canonical sign of ARP poisoning. Pin the legitimate MAC with arp -s (or New-NetNeighbor -State Permanent) and audit periodically. Enterprise switches with DAI (Dynamic ARP Inspection) and DHCP snooping enforce this at the network layer.
Sending a gratuitous ARP
Windows does not expose a direct "send gratuitous ARP" command, but you can force one by toggling the IP off and on (which triggers Duplicate Address Detection) or by adding a temporary static neighbor on a foreign IP. The PowerShell Test-NetConnection cmdlet also exercises the ARP layer.
# Force an ARP probe by querying connectivity to a fresh neighbor
Test-NetConnection -ComputerName 192.168.1.10 -InformationLevel Quiet
# Re-announce the local IP after a clean release/renew
ipconfig /release "Ethernet"
ipconfig /renew "Ethernet"
Output:
True
Re-renewing a DHCP lease performs DAD which is observable on the wire as a gratuitous ARP — useful when a switch's MAC table needs refreshing after a port move.
Interface-index targeting
When the same subnet appears on two interfaces (multi-homed servers, VPN clients, Hyper-V hosts), arp -s ... <if_addr> pins the static entry to the interface whose IP matches if_addr. Always supply this on multi-homed machines — without it, the static entry is created on every matching interface, with unpredictable wins.
rem Add a static entry only on the interface with IP 10.0.0.5
arp -s 10.0.0.1 00-aa-bb-cc-dd-ee 10.0.0.5
Output:
(none — exits 0 on success)
To find the right interface IP, list adapters with ipconfig or read the index from route PRINT.
Proxy ARP
Proxy ARP is a mechanism where a router answers ARP requests for IPs that are not its own — typically used on point-to-point links, hub-spoke VPNs, and some virtualization stacks. Windows enables it per-interface via the registry; it is rarely needed on workstations but appears on RRAS gateways.
rem Check whether Proxy ARP is enabled on an interface (PowerShell)
powershell -NoProfile "Get-NetIPInterface -InterfaceIndex 12 | Format-List Forwarding"
Output:
Forwarding : Disabled
To enable proxy ARP on an interface, set EnableProxy=1 under the interface's TCP/IP registry parameters and restart the interface. This is almost never required on a desktop and is a security risk on untrusted networks because it can mask Layer-2 misconfigurations.
Reading ARP traffic with pktmon
When the cache is misbehaving and you need to confirm what is actually on the wire, pktmon (built into Windows 10 1809+) can capture ARP frames without third-party tools.
rem Filter to ARP (EtherType 0x0806)
pktmon filter add -t ARP --ether-type 0x0806
pktmon start --capture --pkt-size 0
rem Reproduce the problem, then
pktmon stop
pktmon format PktMon.etl -o arp.txt
Output:
Logger Name: PktMon
Provider Name: Microsoft-Windows-PktMon
...
The resulting arp.txt lists each ARP request/reply with source and destination MAC/IP, identifying who is replying for a given address and exposing spoofers or misconfigured hosts.
Common pitfalls
- Static ARP entries do not survive a reboot by default —
arp -sentries are stored only in the in-memory cache; to make them persistent, add them in a startup script or useNew-NetNeighbor -State Permanent(modern) /netsh interface ipv4 add neighbors(legacy). arp -d *requires elevation on Vista+ — running without Administrator returns "The requested operation requires elevation"; right-click cmd.exe → Run as administrator.- ARP operates per-interface — on multi-homed machines, the same remote IP may appear in different interface tables with different entries; use
-Nto target the correct one. - Dynamic entries expire automatically — Windows expires dynamic ARP entries after a few minutes of inactivity; if a host keeps changing IP (e.g. DHCP lease renewal), the cached entry updates automatically.
- ARP does not cross routers —
arp -aonly shows Layer 2 neighbours on directly connected subnets; hosts behind a router appear only with the router's MAC (the next-hop gateway), not the host's own MAC. arp -son Win10+ may report "The ARP entry addition failed: Access is denied" — Windows requires the interface to be administratively up and the address family enabled; verify withnetsh interface ipv4 show interfaces.- MAC format is dash-separated —
arp -saccepts00-14-22-01-23-45(dashes) but rejects00:14:22:01:23:45(colons); PowerShellNew-NetNeighboraccepts both. - Hyper-V/WSL bridged adapters add noise —
arp -alists every virtual interface; pipe throughfindstrto focus on the physical adapter. arp -sdoes not validate the MAC against the actual host — you can pin any MAC to any IP; double-check the MAC matches a real device on the segment before locking it in.- ARP is IPv4 only — for IPv6, use
netsh interface ipv6 show neighborsorGet-NetNeighbor -AddressFamily IPv6;arp -areturns no IPv6 entries.
Real-world recipes
Confirm MAC address of the default gateway
for /f "tokens=3" %G in ('ipconfig ^| findstr "Default Gateway"') do set GW=%G
ping -n 1 %GW% >NUL
arp -a %GW%
Output:
Interface: 192.168.1.100 --- 0x4
Internet Address Physical Address Type
192.168.1.1 00-14-22-01-23-45 dynamic
Pin the gateway MAC to prevent ARP spoofing
@echo off
set GW_IP=192.168.1.1
set GW_MAC=00-14-22-01-23-45
arp -d %GW_IP% 2>NUL
arp -s %GW_IP% %GW_MAC%
echo Static ARP entry set for gateway %GW_IP% → %GW_MAC%
Output:
Static ARP entry set for gateway 192.168.1.1 → 00-14-22-01-23-45
List all dynamic ARP entries
arp -a | findstr "dynamic"
Output:
192.168.1.1 00-14-22-01-23-45 dynamic
192.168.1.10 00-50-56-ab-cd-ef dynamic
Build a CSV inventory of all neighbors
A typed inventory is far easier to diff than arp -a text. PowerShell can produce a CSV with hostname enrichment for asset management.
Get-NetNeighbor -AddressFamily IPv4 |
Where-Object State -in 'Reachable','Stale' |
Select-Object @{n='Host';e={$env:COMPUTERNAME}}, IPAddress, LinkLayerAddress, State,
@{n='Interface';e={(Get-NetAdapter -InterfaceIndex $_.InterfaceIndex).Name}} |
Export-Csv -NoTypeInformation -Path C:\Audit\arp_inventory.csv
Output:
(none — writes CSV)
Audit gateway MAC and alert on change
A scheduled task can compare the live gateway MAC against a pinned expected value and write an event to the log when they diverge — a poor man's IDS for ARP spoofing.
@echo off
setlocal
set GW_IP=192.168.1.1
set EXPECTED_MAC=00-14-22-01-23-45
for /f "tokens=2" %%m in ('arp -a %GW_IP% ^| findstr %GW_IP%') do set ACTUAL_MAC=%%m
if /i "%ACTUAL_MAC%"=="%EXPECTED_MAC%" (
echo Gateway MAC OK: %ACTUAL_MAC%
) else (
echo *** GATEWAY MAC CHANGED *** expected %EXPECTED_MAC%, got %ACTUAL_MAC%
eventcreate /T WARNING /ID 800 /L APPLICATION /SO ARPAudit /D "Gateway MAC changed to %ACTUAL_MAC%"
)
endlocal
Output:
Gateway MAC OK: 00-14-22-01-23-45
Sweep a subnet to populate the cache
Force ARP entries for every live host on the LAN by pinging each address once. Useful before running arp -a to take a snapshot.
@echo off
for /l %%i in (1,1,254) do (
start /b /min ping -n 1 -w 200 192.168.1.%%i >NUL
)
ping -n 5 127.0.0.1 >NUL
arp -a | findstr dynamic
Output:
192.168.1.1 00-14-22-01-23-45 dynamic
192.168.1.5 00-50-56-aa-bb-01 dynamic
192.168.1.10 00-50-56-ab-cd-ef dynamic
192.168.1.50 de-ad-be-ef-00-01 dynamic
...
Force re-resolution of a single host
Removing the cache entry forces Windows to broadcast a fresh ARP request on the next packet, which is the cheapest way to refresh a stale mapping without disturbing other entries.
arp -d 192.168.1.50
ping -n 1 192.168.1.50 >NUL
arp -a 192.168.1.50
Output:
Interface: 192.168.1.100 --- 0x4
Internet Address Physical Address Type
192.168.1.50 00-50-56-aa-bb-02 dynamic
Persist a pinned gateway entry across reboots
Static entries added with arp -s are wiped on reboot. To make the entry permanent, register a scheduled task at startup or use New-NetNeighbor -State Permanent directly — the latter is registry-backed and survives reboots without any helper script.
# Run once as Administrator
$ifIdx = (Get-NetAdapter -Name "Ethernet").ifIndex
New-NetNeighbor -InterfaceIndex $ifIdx -IPAddress 192.168.1.1 `
-LinkLayerAddress "00-14-22-01-23-45" -State Permanent
Output:
ifIndex IPAddress LinkLayerAddress State PolicyStore
------- --------- ---------------- ----- -----------
12 192.168.1.1 00-14-22-01-23-45 Permanent ActiveStore
Capture ARP storms
A flood of ARP requests can indicate a misbehaving switch, a loop, or a scanning worm. Quickly count the ARP request rate to confirm.
pktmon filter add ARP --ether-type 0x0806
pktmon start --capture --pkt-size 0
timeout /t 10 >NUL
pktmon stop
pktmon format PktMon.etl | findstr /c:"who has" | find /c /v ""
Output:
247
247 ARP queries in 10 seconds (~25/s) is well above the 1–2/s baseline of a quiet LAN and warrants investigation. Identify the source by formatting the capture: pktmon format PktMon.etl -o storm.txt and inspect the sender MAC distribution.
Compare two snapshots over time
A daily snapshot enables drift detection — useful in security-conscious environments where a stable LAN should not see MAC changes.
@echo off
set TS=%date:~-4,4%-%date:~-10,2%-%date:~-7,2%
arp -a > C:\Audit\arp_%TS%.txt
forfiles /p C:\Audit /m arp_*.txt /d -7 /c "cmd /c del @path" 2>NUL
echo Snapshot saved: arp_%TS%.txt
Output:
Snapshot saved: arp_2026-05-24.txt
Sources
Microsoft Learn — arp command — Official syntax, parameter table, examples, and remarks for the Windows arp command.
See also
- ipconfig — view interface IPs and DNS configuration
- ping — trigger ARP resolution by sending an ICMP echo
- route — IP routing table (Layer 3 forwarding decisions)
- getmac — read the local machine's MAC addresses
- netstat — active TCP/UDP connections, often used alongside ARP
- netsh —
netsh interface ipv4 show neighborsis the netsh equivalent ofarp -a