ARP — Resolving IP → MAC, ARP Cache, Gratuitous ARP
A host about to transmit knows the destination IP address but cannot put a frame on the wire without a destination MAC address — two different addressing worlds, and nothing connects them. ARP (Address Resolution Protocol, RFC 826) is that connective tissue: it broadcasts a question to the entire local segment, receives one unicast answer, and caches the result. The whole protocol is three moves, resolves only the next hop, and authenticates nothing — which is why it is also the foundation of most LAN man-in-the-middle attacks.
Key Components
- ARP (Address Resolution Protocol)
- A protocol that maps a local IP address (layer 3, logical, end-to-end) to the MAC address (layer 2, physical, one link) of the machine holding it. ARP rides directly on Ethernet under EtherType
0x0806— it is not carried inside an IP packet, even though it carries IP addresses. It straddles the two layers rather than sitting in either. - Next hop
- The one machine on the local link a frame is physically handed to next — which is the final destination only when that destination shares the sender's subnet. When the destination is off-subnet, the routing decision names the default gateway (the router) as the next hop instead. ARP always resolves the next hop, never the far end of the conversation.
- Broadcast domain
- The set of devices a broadcast frame — one addressed to
ff:ff:ff:ff:ff:ff, meaning "everyone" — actually reaches. It is bounded by VLAN and router boundaries. A unicast frame, by contrast, carries one specific destination MAC and is delivered to exactly one machine. - ARP cache
- A per-host table of learned
IP → MACmappings, consulted before every transmission so the broadcast only has to happen once per destination. Entries expire after minutes, so mappings that go stale correct themselves — slowly. - Gratuitous ARP
- An unprompted ARP message announcing a host's own
IP → MACmapping when nobody asked. Used to announce arrival, to detect address conflicts, and — most importantly — to instantly rewrite every cache on the segment when a standby device takes over a shared IP.
Concrete Example
Start from an empty table. A laptop at 192.168.1.5 has just joined the network and has spoken to nobody:
$ arp -a
? (192.168.1.1) at (incomplete) on en0 ifscope [ethernet]
Now ping a machine on the same subnet. The first packet cannot leave until the MAC is known, so ARP runs first — which is why the very first ping in a fresh session is often measurably slower than the rest:
$ ping -c 1 192.168.1.10
64 bytes from 192.168.1.10: icmp_seq=0 ttl=64 time=4.81 ms <- includes the ARP round trip
$ arp -a
? (192.168.1.10) at dd:dd:dd:44:44:44 [ether] on en0 <- learned just now
? (192.168.1.1) at a4:5e:60:12:34:56 [ether] on en0 <- the gateway
Two frames crossed the wire between those two commands. The first was addressed to everyone; the second to exactly one machine:
FRAME 1 — ARP REQUEST FRAME 2 — ARP REPLY
dst MAC ff:ff:ff:ff:ff:ff (broadcast) dst MAC aa:aa:aa:11:11:11 (unicast)
src MAC aa:aa:aa:11:11:11 src MAC dd:dd:dd:44:44:44
EtherType 0x0806 (ARP) EtherType 0x0806 (ARP)
opcode 1 = request opcode 2 = reply
sender 192.168.1.5 / aa:aa:aa:11:11:11 sender 192.168.1.10 / dd:dd:dd:44:44:44
target 192.168.1.10 / 00:00:00:00:00:00 target 192.168.1.5 / aa:aa:aa:11:11:11
"Who has 192.168.1.10? Tell 192.168.1.5." "192.168.1.10 is at dd:dd:dd:44:44:44."
The asymmetry is forced by what each side knows. The requester does not have the target's MAC — that is the entire point of asking — so it has no choice but to address the question to ff:ff:ff:ff:ff:ff and let every device on the segment decide for itself whether the question is about it. The responder is in a completely different position: the request carried the asker's IP and MAC in its sender fields, so the answer can go straight back as a unicast. One question to everybody; one answer to one machine.
Now change one digit and the behaviour changes completely. Ping something off-subnet:
$ ping -c 1 93.184.215.14 # a public server, not on 192.168.1.0/24
$ arp -a
? (192.168.1.1) at a4:5e:60:12:34:56 [ether] on en0
# ...and nothing whatsoever for 93.184.215.14
There is no entry for the server, and there never will be. Layer 3 decides first: "is this destination on my subnet?" No — so the packet goes to the default gateway, and it is the gateway's IP that gets handed to ARP. The IP header still says 93.184.215.14 the whole way; only the frame around it is addressed to the router. ARP is subordinate to the routing decision — the host picks a next hop first, and ARP merely fetches that next hop's MAC.
Deleting an entry forces the exchange to happen again, which is the cleanest way to watch it live in a packet capture:
arp -a # view the cache (macOS / Linux / Windows)
ip neigh # modern Linux equivalent (the neighbour table)
arp -d 192.168.1.1 # delete an entry, forcing a fresh request/reply
Switch# show ip arp
Switch(config)# ip arp inspection vlan 10 # enable Dynamic ARP Inspection
Visual Model
Picture yourself in a room full of people. You know someone in here is called Ana, but you have never met her and cannot pick her out. So you shout to the whole room: "Is Ana here? It's Sam, by the door." Everyone hears you; almost everyone ignores you, because they are not Ana. Ana walks over and answers you — quietly, directly, to you alone — because your shout told her exactly where you were standing. And you write her face down, so you never have to shout again. That is ARP, complete: shout once, get one private answer, remember it.
The shape worth carrying away is the asymmetry. The request is expensive and disruptive — it interrupts every device in the broadcast domain, and every one of them burns a little CPU deciding the question is not about it. The reply is cheap and precise. Step through the exchange below and watch the traffic go from "everyone" to "exactly one", ending with the cache entry that makes the whole dance unnecessary next time.
Loading…
Notice what the diagram does not show: any host outside this segment. The request frame is a broadcast, so it dies at the first VLAN or router boundary it meets. Routers do not forward ARP — each hop along a path runs its own local ARP for its own next hop. This is the same "resolve once, then cache with an expiry" shape as DNS name resolution, but at the opposite end of the stack: DNS maps a name to an IP globally, ARP maps an IP to a MAC across a single link.
Deeper — Edge Cases & Gotchas
Gratuitous ARP, and why failover depends on it
A gratuitous ARP is an announcement nobody requested — a host stating its own IP → MAC mapping into the void. It has three jobs, and the third is the one that matters operationally:
- Announce presence. On boot, or after a NIC replacement, refresh everyone's cache rather than waiting for their entries to expire.
- Detect address conflicts. ARP for your own IP. Silence means the address is free; a reply means somebody else already has it.
- Failover. When a standby device takes over a shared IP — a redundant gateway, a load-balancer virtual IP — the IP has not changed but the MAC behind it has. A gratuitous ARP rewrites every cache on the segment at once.
Skip that third one and the redundancy is worthless. Every host on the segment still holds the dead device's MAC against the gateway IP, and the ARP cache is not consulted for correctness — it is consulted for speed, and it has no way to know its answer is now wrong. Traffic keeps being addressed to a machine that is no longer listening until each entry independently ages out, minutes later. The backup was ready the entire time; nobody was told to look at it.
The protocol authenticates nothing at all
There is no field in an ARP message for proving the claim it makes, and no state machine that requires a reply to correspond to a request. Any device can assert that any IP belongs to its MAC, and every host that hears it will simply write that down — unsolicited replies are accepted. That is not a bug in an implementation; it is the protocol as specified in 1982, on a network where every attached machine was assumed to be trustworthy.
The consequence is ARP spoofing (or poisoning), the basis of most LAN man-in-the-middle attacks. Two forged messages are enough to sit invisibly in the middle of a conversation:
Attacker → Victim : "192.168.1.1 (the gateway) is at ATTACKER_MAC"
Attacker → Gateway : "192.168.1.10 (the victim) is at ATTACKER_MAC"
victim ──▶ attacker ──▶ gateway (attacker reads / rewrites in transit)
gateway ──▶ attacker ──▶ victim
Both ends now believe they are talking to each other and both are talking to the attacker, who forwards the traffic on so nothing appears broken. Note what this defeats: a switch normally gives a degree of privacy by delivering unicast frames only to the port that owns the destination MAC. Spoofing sidesteps that entirely, because it poisons the endpoints' own maps rather than the switch's forwarding table. The frames really are addressed to the attacker, so the switch is doing its job perfectly while delivering them.
Defences work at three different levels. Dynamic ARP Inspection makes the switch validate every ARP message on untrusted ports against a trusted binding table (typically built by DHCP snooping) and drop the ones that lie. Static ARP entries pin critical mappings — the gateway, most often — so no announcement can overwrite them, at the cost of manual maintenance and broken failover. And TLS gives up on preventing interception altogether, ensuring instead that intercepted traffic is unreadable and untamperable.
wrong: laptop 192.168.1.5 ──ARP──> "who has 93.184.215.14?"
(nobody on this link owns it; nothing answers)
right: 1. routing decision: 93.184.215.14 is off-subnet → next hop = 192.168.1.1
2. ARP: "who has 192.168.1.1?" → gateway's MAC
3. frame: dst MAC = gateway, dst IP = 93.184.215.14
Why it breaks: ARP is a broadcast confined to one link, so the only IPs it can ever resolve are IPs on that link. A remote server is not there and cannot answer. This is the mechanical consequence of "IP is end-to-end, MAC is hop-to-hop": the IP header carries the true destination unchanged across the whole path, while the frame around it is rebuilt at every hop for the next machine only. The routing decision picks that next hop; ARP is only ever called afterwards, to look up its MAC.
DNS: name → IP | layer 7 | global scope | queries a configured server
ARP: IP → MAC | layer 2 | one link only | queries the whole local segment
Why it breaks: the "resolve then cache with an expiry" pattern really is shared, which is exactly what makes the mismatch easy to miss. But DNS reaches across the internet to a server you configured, whereas ARP shouts into a single broadcast domain and stops there. Expecting to resolve a distant address with ARP, or expecting ARP traffic to appear anywhere beyond the local segment, both follow from the same confusion.
Two boundaries worth remembering
ARP is IPv4-only. IPv6 does not use it at all; the equivalent job is done by the Neighbor Discovery Protocol (NDP), which runs over ICMPv6 and uses multicast rather than broadcast — the same concept of resolving a next hop on the local link, with a different and considerably more capable mechanism.
And ARP is link-local by construction. Its scope is exactly the broadcast domain, which means the segmentation that VLANs impose also segments ARP: hosts in different VLANs never see each other's requests, and reaching between them requires a router, whose MAC each side resolves separately.
See Also
Encapsulation & Decapsulation Explains why a destination MAC is mandatory before a frame can be built — the exact gap in the header that ARP exists to fill. Ethernet — Frame Format, MAC Addresses & EtherType The frame ARP rides in: where0x0806 and ff:ff:ff:ff:ff:ff live, and the MAC-spoofing weakness that ARP spoofing compounds.
How Switches Work — MAC Learning, CAM Table, Forward/Flood/Filter
What actually delivers the broadcast request and the unicast reply — and the forwarding privacy that ARP spoofing bypasses by poisoning endpoints instead.
VLANs — Segmentation, Access vs Trunk Ports, 802.1Q Tagging
Defines the broadcast domain that bounds every ARP request, and therefore how far address resolution can reach.
How the Internet Works End-to-End — A Packet's Journey
Where next-hop-only resolution sits in the full journey: "IP end-to-end, MAC hop-to-hop", with ARP run afresh at every hop.
Sources consulted
- RFC 826 — An Ethernet Address Resolution Protocol (1982)
Test Yourself
A laptop at 192.168.1.10, with default gateway 192.168.1.1, opens a connection to 93.184.215.14. Whose MAC address does it resolve with ARP?
Why is the ARP request a broadcast while the reply is a unicast — what asymmetry in knowledge forces it?
A backup router takes over the gateway IP after the primary fails, but sends no gratuitous ARP. Connectivity is down for several minutes even though the backup is healthy. Trace exactly why, and why the outage eventually ends on its own.