ARP and Neighbor Discovery: From an IP to a Local MAC
A host that knows the next hop’s IP still needs its MAC to build the frame: IPv4 asks with an ARP broadcast and caches the answer; IPv6 replaces ARP entirely with Neighbor Discovery over ICMPv6 multicast, which also carries router advertisements and lets hosts configure their own addresses.
The problem
10.0.0.1. The Ethernet header needs a MAC address, and nothing in the IP address says what it is. Who knows, how do you ask, and how do you avoid asking on every packet?The gap between IP and the frame
Routing produces a next hop IP: either the destination itself, if it is on the local subnet, or the default gateway, if it is not. Either way the link layer needs that machine’s MAC address and the IP layer has no idea what it is — the two address spaces are independent by design. Something has to resolve one into the other, on the local segment, without a server, and quickly enough not to matter.
The key move for off-link destinations bears repeating because it is where beginners stall: to reach 203.0.113.10 the host resolves the MAC of 10.0.0.1 (the gateway), not of the server. The IP header says 203.0.113.10; the Ethernet header says the gateway. It is the router’s job to take it from there. If you ip neigh on your laptop you will see entries for your gateway and a few local devices, and never for any internet host.
ARP: ask everyone, remember the answer
The Address Resolution Protocol is a request/reply over raw Ethernet frames (EtherType 0x0806), not over IP. The host broadcasts a request to ff:ff:ff:ff:ff:ff: "who has 10.0.0.1? tell 10.0.0.4". Every interface on the segment receives it; the one that owns 10.0.0.1 replies unicast: "10.0.0.1 is at aa:bb:cc:00:00:0a". Everyone else drops it (though many stacks opportunistically learn the requester’s mapping from the request, since it was free). The exchange costs one broadcast and one unicast, well under a millisecond on a LAN.
The answer goes into the ARP cache (ip neigh on Linux, arp -a elsewhere) with a state: REACHABLE while recently confirmed, STALE after a timeout (typically 30–60 s of no positive confirmation), DELAY/PROBE while being re-verified with a unicast request, FAILED if nothing answers. The cache is why ARP is cheap: one request per neighbour per minute or so, not per packet. Packets that need an unresolved entry are queued (a few of them) until the reply arrives — which is the small stall you see on the first ping to a new host and the reason ping sometimes reports the first reply as slower.
Gratuitous ARP — announcing your own IP → MAC without being asked — is how a host checks for duplicate addresses when it comes up and how a failover pair tells the switches and neighbours that a virtual IP has moved to a new MAC. Proxy ARP is a router answering for addresses it can reach, used to glue subnets together in ways best avoided.
# tcpdump -e -n arp aa:bb:cc:00:00:01 > ff:ff:ff:ff:ff:ff, ARP, Request who-has 10.0.0.1 tell 10.0.0.4 aa:bb:cc:00:00:0a > aa:bb:cc:00:00:01, ARP, Reply 10.0.0.1 is-at aa:bb:cc:00:00:0a # ip neigh 10.0.0.1 dev wlan0 lladdr aa:bb:cc:00:00:0a REACHABLE 10.0.0.7 dev wlan0 lladdr aa:bb:cc:00:00:07 STALE 10.0.0.99 dev wlan0 FAILED
ARP spoofing: the cost of trusting a broadcast
ARP has no authentication. Any host on the segment can send a reply — solicited or not — claiming 10.0.0.1 is-at <attacker MAC>, and most stacks will update their cache. From then on the victim sends every off-link packet to the attacker, who forwards it to the real gateway and reads or alters everything in between: a textbook on-path attack, and the reason TLS matters even on "trusted" networks. The same trick against the gateway captures the return direction.
Defences live in the switches (dynamic ARP inspection, which validates replies against the DHCP lease table), in static ARP entries for critical hosts, and above the link layer in encryption. The symptom of an attack or a misconfiguration is the same: an ARP entry for the gateway whose MAC changes, and arp-scan or ip neigh showing two IPs with the same MAC.
IPv6 does not use ARP
IPv6 dropped ARP and replaced it with Neighbor Discovery (NDP, RFC 4861), a set of ICMPv6 messages carried *inside IPv6 packets* rather than in raw frames. The resolution step is the same shape with two differences. A Neighbor Solicitation is sent not to broadcast (IPv6 has no broadcast) but to the target’s solicited-node multicast address, ff02::1:ffXX:XXXX where the last 24 bits are copied from the target IP; that maps to the Ethernet multicast 33:33:ff:XX:XX:XX, so only interfaces whose addresses share those 24 bits process it — usually exactly one. The target answers with a Neighbor Advertisement carrying its link-layer address, and the requester stores it in the neighbor cache (ip -6 neigh), with the same REACHABLE/STALE/PROBE states.
Neighbor Discovery does more than ARP. Router Solicitation / Router Advertisement let a host find its gateway without DHCP: routers periodically multicast (and answer requests) with their address, the on-link prefix, the MTU, and whether the host should use DHCPv6. From the advertised prefix a host can build its own address — SLAAC (stateless address autoconfiguration): prefix + a 64-bit interface identifier, once derived from the MAC (EUI-64) and now usually random and rotated for privacy (RFC 8981 temporary addresses). Duplicate address detection is a Neighbor Solicitation for your own tentative address; silence means it is yours. Redirects tell a host of a better first hop. All of this is ICMPv6, all of it multicast, none of it ARP.
The practical consequences: filtering ICMPv6 breaks IPv6 *completely* — not just ping, but address resolution and gateway discovery — which is the most common way IPv6 is accidentally disabled. And the ARP spoofing problem returns as rogue Router Advertisements: any host on the segment can advertise itself as a router and become the default gateway for everyone; RA Guard on switches is the counterpart to ARP inspection.
# tcpdump -n -i eth0 icmp6 IP6 fe80::1c2a:...:04 > ff02::1:ff00:1: ICMP6, neighbor solicitation, who has fe80::1 IP6 fe80::1 > fe80::1c2a:...:04: ICMP6, neighbor advertisement, tgt is fe80::1 IP6 fe80::1 > ff02::1: ICMP6, router advertisement, prefix 2001:db8:1::/64, MTU 1500 # ip -6 neigh fe80::1 dev eth0 lladdr aa:bb:cc:00:00:0a router REACHABLE
Side by side
Both protocols solve "IP → local MAC", both cache, both trust the segment. The differences are where the messages travel (raw frames vs ICMPv6 inside IP), who hears the question (everyone vs a tiny multicast group), and how much else the protocol does (nothing vs gateway discovery, autoconfiguration and duplicate detection).
| ARP (IPv4) | Neighbor Discovery (IPv6) | |
|---|---|---|
| Carried in | raw Ethernet frames, EtherType 0x0806 | ICMPv6 inside IPv6 packets |
| Question sent to | broadcast ff:ff:ff:ff:ff:ff (everyone) | solicited-node multicast ff02::1:ffXX:XXXX (almost only the target) |
| Messages | Request, Reply (+ gratuitous) | NS, NA, RS, RA, Redirect |
| Cache | ARP cache (ip neigh) | neighbor cache (ip -6 neigh) |
| Finds the gateway? | no — DHCP or static config | yes — Router Advertisements |
| Address autoconfig? | no | yes — SLAAC from the RA prefix |
| Duplicate detection | gratuitous ARP (optional) | DAD (mandatory) |
| Attack | ARP spoofing | NA spoofing, rogue RAs |
| Broken by filtering | nothing (no IP involved) | any ICMPv6 filter |
Key points
- ARP resolves an IPv4 next-hop address to a MAC with a broadcast request and a unicast reply, cached for tens of seconds.
- For off-link destinations the resolved MAC is the gateway’s; the IP header still names the far destination.
- The first packet to a new neighbour waits for resolution; the cache makes every later packet free.
- ARP is unauthenticated: any host can poison a cache and sit on-path. Encryption above the link layer is the real defence.
- IPv6 does not use ARP. Neighbor Discovery runs over ICMPv6 with solicited-node multicast, and also handles gateway discovery (RAs), SLAAC and duplicate detection.
- Filtering ICMPv6 breaks IPv6 entirely; filtering ICMP on IPv4 breaks only PMTUD and diagnostics.
Why does this exist?
Mechanisms are answers to constraints. Open each question before reading the answer.
▸Why not put the MAC in the IP address, or vice versa?
They are assigned by different parties for different scopes: the MAC by a manufacturer for one segment, the IP by a network operator for global routing. Coupling them would mean renumbering the internet whenever a NIC is replaced. A resolution step keeps them independent.
▸Why does IPv6 use multicast instead of broadcast?
Broadcast wakes every interface on the segment for every question. Solicited-node multicast is computed from the target address so that, in practice, only the target’s NIC processes the frame. On a segment with thousands of hosts (or battery-powered ones) this matters.
▸Why fold gateway discovery into Neighbor Discovery?
IPv4 needed DHCP for a host to learn its router. IPv6 wanted a host to be usable with no server at all: the router announces itself and the prefix, and the host builds an address. DHCPv6 then becomes optional.
ARP and Neighbor Discovery
(empty)
How it fails
What the failure looks like from inside real software.
- Gateway ARP entry stuck
FAILEDorINCOMPLETE: everything off-link times out while local hosts work. Cable, VLAN or a gateway that is down. - ARP cache poisoned: the gateway’s MAC changes in
ip neigh, latency rises, TLS warnings appear on sites that were fine — someone is on-path. - Two hosts with the same IP: ARP replies alternate, both get intermittent connectivity; gratuitous ARP on boot logs "duplicate address".
- IPv6 works for a minute after boot then dies: the router advertisement lifetime expired and a firewall is dropping the periodic RAs; the default route vanishes.
- A rogue RA from a misconfigured laptop or VM: every IPv6 host on the segment routes through it; Windows machines sharing internet connection are a classic source.
- First packet to a new neighbour is slow or lost: normal resolution latency, but a busy or rate-limited neighbour can drop the queued packets; UDP callers see the loss, TCP retransmits.