ARP is the unsung hero of local network communication, silently translating IP addresses into the MAC addresses your network interface cards (NICs) actually speak. tcpdump can be your detective, eavesdropping on this crucial conversation, and here’s how to make it trace ARP requests and replies.

Let’s see ARP in action. Imagine two machines on the same subnet, 192.168.1.100 and 192.168.1.101. If 192.168.1.100 wants to send a packet to 192.168.1.101 but doesn’t know its MAC address, it broadcasts an ARP request.

sudo tcpdump -i eth0 -nn arp

Run this on 192.168.1.100 before trying to ping 192.168.1.101. You’ll see something like this:

16:00:01.123456 IP 0.0.0.0.42095 > 255.255.255.255.42095: ARP, Request who-has 192.168.1.101 tell 192.168.1.100, length 28

This packet is a broadcast (destination 255.255.255.255) asking, "Who has 192.168.1.101? Tell 192.168.1.100." The 0.0.0.0 source IP means it doesn’t know its own IP yet, or it’s a fresh request. The source MAC address, however, is its own.

Now, if 192.168.1.101 is listening (and it should be, ARP requests are broadcast to everyone on the local segment), it will respond:

16:00:01.124567 IP 192.168.1.101.42095 > 192.168.1.100.42095: ARP, reply 192.168.1.101 is-at 00:1a:2b:3c:4d:5e (oui Unknown), length 28

This is a directed reply, specifically to 192.168.1.100. It says, "I am 192.168.1.101, and my MAC address is 00:1a:2b:3c:4d:5e." The 42095 port number is arbitrary for ARP; it’s just the source port the sender happened to use.

The -i eth0 flag tells tcpdump to listen on the eth0 interface. Replace eth0 with your actual network interface name (e.g., enp0s3, wlan0). The -nn flag prevents tcpdump from resolving IP addresses and port numbers to hostnames and service names, which is usually what you want when looking at raw ARP packets. The arp filter is the key, instructing tcpdump to only show ARP traffic.

The ARP Cache

When 192.168.1.100 receives that ARP reply, it stores the mapping of 192.168.1.101 to 00:1a:2b:3c:4d:5e in its ARP cache. This cache is a crucial performance optimization; subsequent packets to 192.168.1.101 won’t trigger a new ARP request. They’ll be sent directly using the MAC address from the cache.

You can inspect this cache on Linux with:

ip neigh show

Or on macOS/BSD:

arp -a

You’ll see entries like:

192.168.1.101 dev eth0 lladdr 00:1a:2b:3c:4d:5e REACHABLE

If you stop tcpdump and then try to ping 192.168.1.101 again, you won’t see an ARP request from 192.168.1.100 in tcpdump output. This is because the information is already in the ARP cache.

To force another ARP request for testing, you can clear the ARP cache entry for that IP:

sudo ip neigh delete 192.168.1.101 dev eth0

Then, run your tcpdump command again and repeat the ping. You’ll see the ARP request and reply sequence reappear.

ARP Proxying

tcpdump can also reveal ARP proxying, a feature where a router answers ARP requests on behalf of other machines on different subnets. If 192.168.1.100 (on subnet A) tries to reach 192.168.2.101 (on subnet B), and the router 192.168.1.1 is configured for ARP proxying, the router will respond to 192.168.1.100’s ARP request for 192.168.2.101 with its own MAC address.

On 192.168.1.100 (with tcpdump -i eth0 -nn arp running):

ping 192.168.2.101

You might see:

16:05:10.789012 IP 0.0.0.0.54321 > 255.255.255.255.54321: ARP, Request who-has 192.168.2.101 tell 192.168.1.100, length 28
16:05:10.790123 IP 192.168.1.1.54321 > 192.168.1.100.54321: ARP, reply 192.168.2.101 is-at 00:01:02:03:04:05 (oui Unknown), length 28

Notice the ARP reply comes from 192.168.1.1 (the router), but it claims to be 192.168.2.101. This is ARP proxying in action. The router then knows to forward the IP packet to 192.168.2.101 on the other interface.

ARP Spoofing Detection

tcpdump is also invaluable for detecting ARP spoofing, a malicious attack where an attacker sends forged ARP messages to associate their MAC address with the IP address of another host, often the default gateway.

If you’re running tcpdump -i eth0 -nn arp and see an ARP reply for an IP address you aren’t expecting to hear from, or if you see multiple MAC addresses claiming to be the same IP address within a short period, it’s a red flag.

For example, if 192.168.1.1 is your gateway, and you suddenly see an ARP reply like this:

16:10:20.555555 IP 192.168.1.105.12345 > 192.168.1.100.12345: ARP, reply 192.168.1.1 is-at 00:aa:bb:cc:dd:ee (oui Unknown), length 28

Where 00:aa:bb:cc:dd:ee is not the MAC address of your legitimate gateway (00:01:02:03:04:05 in our previous example), you’ve likely caught an ARP spoofing attempt. The machine 192.168.1.105 is trying to impersonate your gateway.

To capture ARP traffic specifically, you can use tcpdump with the arp filter. If you want to see all packets on the wire and then filter them later, you can omit the arp filter and use tcpdump -i eth0 -nn and then grep "arp" on the output, but the direct arp filter is more efficient.

The next logical step after understanding ARP tracing is to dive into how TCP establishes connections, which relies on ARP to get the initial packets to the right destination.

Want structured learning?

Take the full Tcpdump course →