On this page
ARP and NDP
Translation from IP addresses to MAC addresses—IPv4 uses ARP (broadcast request + unicast reply + cache aging), IPv6 uses NDP (multicast neighbor discovery + SLAAC auto-configuration). This bridge between Layer 2 and Layer 3 is the first step in local network communication.
Overview
Without ARP, IP packets cannot be transmitted over Ethernet—ARP is the glue protocol that translates IP addresses into MAC addresses. An ARP request ("Who is 192.168.1.1?") is sent as a broadcast frame, and the target host replies with its MAC address. IPv6 replaces ARP with NDP, which is based on ICMPv6 and provides not only address resolution but also router discovery (RS/RA) and automatic address configuration (SLAAC). Designed in 1982, ARP's "trust everyone on the LAN" security model appears quite fragile today, but its low overhead and simplicity make it still efficient in closed networks.
ARP Protocol (RFC 826)
Frame Format
ARP is encapsulated directly in an Ethernet frame (EtherType=0x0806), without an IP layer:
Hardware Type: 2 bytes — 1 = Ethernet
Protocol Type: 2 bytes — 0x0800 = IPv4
HW Addr Len: 1 byte — 6 (MAC)
Protocol Addr Len: 1 byte — 4 (IPv4)
Operation: 2 bytes — 1=Request, 2=Reply, (also RARP 3/4, rarely used)
Sender HW Addr: 6 bytes (MAC)
Sender Protocol Addr: 4 bytes (IPv4)
Target HW Addr: 6 bytes (0-padded for Request)
Target Protocol Addr: 4 bytes (IPv4)
Requests are sent to the broadcast MAC address (ff:ff:ff:ff:ff:ff), while replies are unicast. The total length of an ARP message is 28 bytes + 18 bytes Ethernet header = 46 bytes—exactly the minimum Ethernet payload (no padding required).
Kernel ARP State Machine
Each neighbor entry has the following states (include/net/neighbour.h):
NUD_NONE: Newly created, no state
NUD_INCOMPLETE: ARP request sent, waiting for reply — retries after timeout
NUD_REACHABLE: Recently confirmed reachable (normal state)
NUD_STALE: Expired but not cleaned up — transitions to DELAY on next use
NUD_DELAY: Waiting for TCP acknowledgment during this period (5s)
NUD_PROBE: Sending ARP probe (up to 3 times, 1s interval)
NUD_FAILED: 3 probe failures — entry deleted
State transitions:
Key: The NUD_STALE state after base_reachable_time (default 30s) does not proactively send ARP. The kernel only confirms connectivity via the DELAY → PROBE chain when there is actual data to send to that neighbor. This avoids generating large amounts of meaningless ARP traffic when the network is idle.
/proc Tuning
Gratuitous ARP
An ARP Request where sender IP = target IP and sender MAC != 0. This "self-asking and self-answering" special form, sent as an Ethernet broadcast with the target IP being its own IP, serves the following purposes:
- IP failover (VRRP/HSRP/CARP): A virtual IP is taken over from one physical host to another → sends gratuitous ARP → updates switch and neighbor ARP caches → new owner immediately receives traffic
- Duplicate IP detection: Just configured IP → sends gratuitous ARP → if someone responds → IP conflict
- Refresh ARP cache: Proactively notifies "my MAC hasn't changed, but you should refresh your cache" (rarely used)
Proxy ARP
A router answers ARP Requests on behalf of a target that is not on the same physical subnet:
Host A: (ping 10.0.1.100, but it's not in its own subnet)
→ ARP "Who has 10.0.1.100?"
Router: (sees Host A's ARP, has route to 10.0.1.0/24)
→ ARP Reply (with its own MAC): "10.0.1.100 is at <router_MAC>"
Host A: → Sends IP packet to router's MAC
Router: → Forwards according to routing table
Not recommended — it masks configuration errors (Host A should have a route pointing to the router instead of assuming 10.0.1.100 is locally reachable). Linux defaults to proxy_arp=0.
NDP (IPv6 Neighbor Discovery, RFC 4861)
NDP carries 5 types of messages using ICMPv6, replacing all ARP functionality and adding automatic address configuration:
ICMPv6 Message Format
All NDP messages share the same ICMPv6 header format (after IPv6 Next Header=58):
Type (1 byte): 133=RS, 134=RA, 135=NS, 136=NA, 137=Redirect
Code (1 byte): 0 (except for Redirect)
Checksum: ICMPv6 pseudo-header checksum (includes IPv6 src/dst)
Reserved: (4 bytes, zero)
Message Body: type-specific options
Options (TLV format):
[Type 1] [Length 1] [Value...]
Length = 8-byte units (including Type+Length itself)
→ Type=1 Len=1 → 8 bytes total, Value=6 bytes
Key Options:
Type 1: Source/Target Link-Layer Address (MAC)
Type 2: Prefix Information (in RA: prefix + prefix_len + flags)
Type 3: Redirected Header
Type 5: MTU (in RA)
Neighbor Solicitation (NS, type 135)
Target: "Who has this IPv6? Tell me your MAC"
Sent to the solicited-node multicast address of the target IPv6:
ff02::1:ff<low 24 bits of target IPv6 address>
Source address: Link-local of the sending interface (or unicast, if already available)
Option: Source Link-Layer Address (own MAC)
Neighbor Advertisement (NA, type 136)
Target: "I have this IPv6, my MAC is X"
Sent to the source address of the NS (unicast) or all nodes (multicast, if DAD conflict)
Flags:
R (Router): Sender is a router (based on RA's Router Lifetime)
S (Solicited): This is a response to an NS (set to 1)
O (Override): Overwrite existing NCE (if 0, receiver can keep old entry)
Option: Target Link-Layer Address
SLAAC (Stateless Address Auto-Configuration, RFC 4862)
Host:
1. Generate link-local address: fe80::/64 prefix + IID
2. Send RS (Router Solicitation, type 133)
Source: :: (unspecified address) or link-local
Destination: ff02::2 (all-routers multicast)
Router:
3. Respond with RA (Router Advertisement, type 134)
Source: Router's link-local
Destination: If responding to RS → send to RS source address (unicast)
If periodic → ff02::1 (all-nodes multicast)
RA contains Prefix Information (Option 2):
Prefix: (e.g., 2001:db8:abcd::)
Prefix Len: (e.g., 64)
L (on-link): This prefix is on the same link → direct communication possible
A (autonomous): Use this prefix for SLAAC → generate global address
Valid Lifetime: Address validity period (usually 2592000s = 30 days)
Preferred Lifetime: Address "preferred" period (after which it becomes deprecated but not removed)
RA contains Router Lifetime:
0: This router is not available as a default gateway
>0: Valid seconds for default route (max 65535 ≈ 18h)
SLAAC Address Generation
EUI-64 (deprecated, exposes MAC):
MAC: aa:bb:cc:dd:ee:ff
→ IID: aa:bb:cc:ff:fe:dd:ee:ff
(insert fffe, flip U/L bit)
→ Full address: 2001:db8:abcd:0:a8bb:ccff:fedd:eeff/64
Privacy Extensions (RFC 8981, Linux default):
Random IID + short lifetime → periodically generate new addresses
→ Old addresses become deprecated but are retained (existing connections remain)
→ New addresses become preferred → new connections use new addresses
→ Prevents cross-network tracking
DAD (Duplicate Address Detection)
Any newly generated IPv6 address (link-local or global) must undergo DAD before use:
1. Send NS: target = address to verify, source = :: (unspecified address)
2. If anyone replies with NA (DAD conflict) → address cannot be used
3. Send up to DupAddrDetectTransmits times (default 1)
4. Receive 0 NAs → address is usable → transition from tentative to preferred
Note: DAD must be executed immediately after address configuration and network connection
→ If two devices generate the same address (extremely low collision probability) → the second detects it → disables it
ARP Attack Surface and Defenses
ARP spoofing (Man-in-the-Middle):
Attacker: Sends forged ARP Reply → maps target's IP to attacker's MAC
→ Traffic is redirected to the attacker
Defenses:
1. DAI (Dynamic ARP Inspection): Switch checks ARP validity
(DHCP snooping DB + static binding) — Enterprise networks
2. Encrypted tunnels: Even if ARP is poisoned → traffic is encrypted → MITM cannot see it
This is actually the only complete solution — if your traffic
is encrypted via WireGuard/Tailscale, ARP spoofing is ineffective
3. Static ARP: `ip neigh add 192.168.1.1 lladdr xx:xx:xx dev eth0 nud permanent`
Most secure but not scalable for large-scale management
References
- RFC: 826 (ARP), 4861 (NDP), 4862 (SLAAC), 8981 (Privacy Extensions)
- Source Code:
net/ipv4/arp.c,net/core/neighbour.c(ARP state machine),net/ipv6/ndp.c - Tools:
ip neigh,arp -a,arping -I eth0 192.168.1.1,tcpdump arp/tcpdump icmp6
Keywords: ARP, NUD state machine, gratuitous ARP, proxy ARP, NDP, NS/NA, RS/RA, SLAAC, EUI-64, DAD, solicited-node multicast