From IP to MAC: How ARP Bridges Two Layers of Addressing
In the previous article, Understanding LAN from a Front-End Developer's Perspective: MAC Addresses, Ethernet Frames, and Switches, we built a complete picture of LAN communication: devices identify each other by MAC addresses, data is encapsulated in Ethernet frames, and switches forward frames to the correct port based on the destination MAC address. Here's a simplified frame structure:
┌─────────────────────┐
│ Destination MAC │
├─────────────────────┤
│ Source MAC │
├─────────────────────┤
│ Type │
├─────────────────────┤
│ Payload │
├─────────────────────┤
│ Frame Check Sequence│
└─────────────────────┘This model tells us one thing clearly: to actually deliver data within a LAN, you must know the destination MAC address. Yet as front-end developers, what we deal with daily are domain names, URLs, and IP addresses. Once the browser resolves a target IP (say 192.168.1.20 on your local network or 151.101.2.133 for a remote server), it provides no MAC address information whatsoever. This raises a critical question:
When you already know the target IP address, how do you find its corresponding MAC address?
This is exactly the problem that ARP (Address Resolution Protocol) solves — and it's the crucial link that bridges the IP network layer with the data link layer.
- Why we need MAC addresses even though we have IP addresses, and how the two divide responsibilities
- The ARP request-reply workflow, and the difference between broadcast and unicast in plain terms
- How the ARP cache works and why aging time matters
- The critical difference in ARP behavior when accessing a local device vs. the internet
- The principles behind Gratuitous ARP and ARP spoofing
- Basic understanding of MAC addresses (the unique hardware identifier burned into every network interface)
- Familiarity with the Ethernet frame structure (destination MAC / source MAC / type / payload / FCS)
- A rough idea of what an IP address is (a logical address used to identify devices on a network)
If any of these feel unfamiliar, check out the previous article in this series, Understanding LAN from a Front-End Developer's Perspective.
Picture yourself sitting at your computer at home. You open a terminal and decide to ping your phone, which is connected to the same Wi-Fi:
ping 192.168.1.20You know your phone's IP is 192.168.1.20. You hit Enter. But your computer doesn't just shout into the void, "Hey, is 192.168.1.20 there?" — it has to figure something out first:
Which network interface card does this IP address belong to? What's its MAC address?
Because ultimately, data must be packaged into an Ethernet frame and sent out through the network card, and the destination address field in the Ethernet frame header only accepts MAC addresses, not IP addresses.
Think of it like this: you know your friend's name (IP address), but the courier needs their house number (MAC address). You need a lookup book that maps "name → house number" — and that's exactly what ARP is.
This is a common point of confusion for beginners: if I already know the destination IP address, why go through the extra step of looking up the MAC address? The answer is that the two serve fundamentally different purposes.
Let's use an analogy:
The IP address answers "where you're going." The MAC address answers "who handles this step."
Imagine you're mailing a letter from Beijing to New York. The envelope bears a New York street address (the IP address). But the letter doesn't fly directly to New York — it first goes to the mailbox at your apartment gate (first hop), then to the neighborhood post office, then to the city sorting center, then to an international mail exchange...
At every segment of this chain, the container carrying the letter gets a local shipping label (MAC address) for that segment. The final destination address on the letter itself never changes, but every segment's shipping label changes to match that segment's carrier. The networking parallel:
- The IP address describes the communication's final destination.
- The MAC address handles the current LAN hop — who gets it next.
When data needs to be physically sent within a LAN, it must be packed into an Ethernet frame, and the frame header can only hold a MAC address. Even though higher-layer protocols (like TCP/IP) know the target IP, the moment the frame leaves the network card, the operating system must decide: who is the next recipient of this frame? Is it the target device itself, or the default gateway? The physical identity of this "next hop" is the MAC address.
A concise memory aid: IP is the "destination name"; MAC is "each step's feet."
ARP's function can be summarized succinctly: within the same LAN, given a target IP address, find the target device's MAC address.
There's a crucial limitation baked into this definition: ARP only works within the local LAN. It is not a protocol you can use to query the entire internet. Your computer cannot use ARP to ask for developer.mozilla.org's MAC address, because that server sits on the other side of the internet and will never receive the broadcast you initiate inside your home Wi-Fi network. ARP can only answer questions within a directly connected network, such as:
"Device with IP address
192.168.1.20on this LAN — what's your MAC address?"
ARP is defined in RFC 826, published in 1982. It operates between the link layer and the network layer, and it's a remarkably "thin" protocol — it does one thing, and it does it with brutal simplicity and efficiency.
Let's walk through ARP's interaction flow using a concrete LAN scenario. Imagine the following devices on your home network:
-
Computer A IP:
192.168.1.10MAC:AA:AA:AA:AA:AA:AA -
Phone B IP:
192.168.1.20MAC:BB:BB:BB:BB:BB:BB -
Router R (the default gateway) IP:
192.168.1.1MAC:RR:RR:RR:RR:RR:RR
Computer A now needs to send data to Phone B. It knows Phone B's IP (192.168.1.20), but not its MAC address. Communication cannot begin just yet.
3.1 Step One: ARP Request — Broadcast Query
Computer A's operating system first checks its own ARP cache table and finds no entry for 192.168.1.20. So it constructs an ARP Request and sends it out onto the LAN. The meaning of this request is:
"I'm
192.168.1.10, my MAC address isAA:AA:AA:AA:AA:AA. Device with IP192.168.1.20, what's your MAC address?"
Since Computer A has no idea which physical device 192.168.1.20 maps to, this frame can't be sent as a directed transmission — it must use broadcast. It gets wrapped in an Ethernet frame with the destination MAC set to FF:FF:FF:FF:FF:FF, which means "all devices on this LAN."
┌───────────────────────────────────────┐
│ Destination MAC: FF:FF:FF:FF:FF:FF │ (broadcast)
├───────────────────────────────────────┤
│ Source MAC: AA:AA:AA:AA:AA:AA │
├───────────────────────────────────────┤
│ Type: 0x0806 (ARP) │
├───────────────────────────────────────┤
│ Data: Who has 192.168.1.20? │
│ (contains sender's IP & MAC) │
└───────────────────────────────────────┘When the switch receives this broadcast frame, it performs a flood operation — copying the frame to every port except the one it arrived on — ensuring every device on the LAN sees it.
Here's the actual internal structure of an ARP Request packet:
┌──────────────────────────────────────────┬──────────────────┐
│ Hardware Type (1 = Ethernet) 2 bytes │ Protocol Type │
│ │ (0x0800 = IPv4) │
├──────────────────────────────────────────┴──────────────────┤
│ │ │ │
│ Protocol Type (cont.) 2 bytes │ HW Len │ PLen │
│ │ │ (6) │ (4) │
├──────────────────────────────┴─────────────────┴────────────┤
│ HW Len (6) │ Proto Len (4)│ Operation │
│ │ │ (1 = Request, 2 = Reply) │
├───────────────────────────────┴─────────────────────────────┤
│ │
│ Sender Hardware Address (6 bytes) │
│ e.g. AA:AA:AA:AA:AA:AA │
│ │
├─────────────────────────────────────────────────────────────┤
│ │
│ Sender Protocol Address (4 bytes) │
│ e.g. 192.168.1.10 │
│ │
├─────────────────────────────────────────────────────────────┤
│ │
│ Target Hardware Address (6 bytes) │
│ all 0 = unknown │
│ │
├─────────────────────────────────────────────────────────────┤
│ │
│ Target Protocol Address (4 bytes) │
│ e.g. 192.168.1.20 │
│ │
└─────────────────────────────────────────────────────────────┘Key fields explained:
- Operation: 1 for ARP Request, 2 for ARP Reply
- Sender Hardware Address: the sender's MAC address (telling the world "who I am")
- Sender Protocol Address: the sender's IP address
- Target Hardware Address: the target's MAC address — all zeros in a request (because we don't know it)
- Target Protocol Address: the target's IP address (this is what you're querying for)
3.2 Step Two: ARP Reply — Unicast Response
Every device on the LAN inspects the ARP request. Phone B notices that the queried IP 192.168.1.20 matches its own, so it knows: "They're asking about me." Other devices (like Router R) see the IP doesn't match theirs and simply discard the request.
Phone B immediately constructs an ARP Reply:
"I'm
192.168.1.20, my MAC address isBB:BB:BB:BB:BB:BB."
This reply doesn't need to be broadcast, because Phone B already learned Computer A's MAC address from the Source MAC field of the ARP request. So the ARP Reply is a unicast frame, sent directly to AA:AA:AA:AA:AA:AA.
┌───────────────────────────────────────┐
│ Destination MAC: AA:AA:AA:AA:AA:AA │ (unicast)
├───────────────────────────────────────┤
│ Source MAC: BB:BB:BB:BB:BB:BB │
├───────────────────────────────────────┤
│ Type: 0x0806 (ARP) │
├───────────────────────────────────────┤
│ Data: 192.168.1.20 is at BB:BB... │
│ (contains responder's IP & MAC) │
└───────────────────────────────────────┘In the ARP Reply packet, the Operation field is set to 2, and the Target Hardware Address field is filled with the queried device's real MAC address.
Once Computer A receives this reply, it now knows that 192.168.1.20 maps to MAC BB:BB:BB:BB:BB:BB. Only after this mapping is established can Computer A construct a valid data frame and send the actual application data to Phone B. At this point, ARP's job is done — it is not responsible for transporting any subsequent application data.
If every communication required a broadcast query beforehand, the LAN would quickly drown in ARP requests and communication efficiency would plummet. So the operating system caches ARP query results, forming an ARP table (ARP cache).
This table records IP-to-MAC mappings:
IP Address MAC Address Type
192.168.1.1 RR:RR:RR:RR:RR:RR dynamic
192.168.1.20 BB:BB:BB:BB:BB:BB dynamicThe next time Computer A needs to send data to 192.168.1.20, it first consults the local ARP table. If it finds an unexpired mapping, it can use it directly to construct the Ethernet frame, bypassing the entire ARP request-reply dance.
4.1 Dynamic Entries and Aging Time
There are two types of entries in an ARP table:
- Dynamic entries: learned automatically through ARP request-reply; they expire
- Static entries: added manually; they never expire
For dynamic entries, each record has an aging time. Once expired, the entry is automatically removed. Different operating systems use different default aging times:
- Linux: typically configured in
/proc/sys/net/ipv4/neigh/default/gc_stale_time, default around 60 seconds - macOS / Windows: typically 15–45 seconds, with adjustments based on activity
Why does aging time exist? Because LAN topology is dynamic. Devices may disconnect, swap network cards, or obtain new IP addresses. The aging mechanism ensures ARP table entries don't point to a network card that no longer exists forever.
4.2 How to View Your Computer's ARP Table
The command is essentially the same across operating systems:
# macOS / Linux
arp -a
# Sample output (macOS)
# ? (192.168.1.1) at xx:xx:xx:xx:xx:xx on en0 ifscope [ethernet]
# ? (192.168.1.20) at bb:bb:bb:bb:bb:bb on en0 ifscope [ethernet]
# Windows
arp -a
# Sample output
# Internet Address Physical Address Type
On Linux/macOS, you can also use the more powerful ip neigh command:
# Linux
ip neigh show
# Sample output
# 192.168.1.1 dev eth0 lladdr xx:xx:xx:xx:xx:xx REACHABLE
# 192.168.1.20 dev eth0 lladdr bb:bb:bb:bb:bb:bb STALEip neigh shows richer states than arp:
- REACHABLE: recently communicated, confirmed reachable
- STALE: unused for a while but not yet expired
- DELAY: waiting for confirmation
- PROBE: actively sending probe requests
This is the single most important point for understanding how ARP ties into real-world network behavior. When your computer needs to access a remote server on the internet — say, developer.mozilla.org (let's assume IP 151.101.2.133) — it does not broadcast "Who has 151.101.2.133?" on the LAN.
The reason is straightforward: your computer uses the subnet mask to determine that 151.101.2.133 is not on the local LAN.
Your IP: 192.168.1.10 → 11000000.10101000.00000001.00001010
Subnet Mask: 255.255.255.0 → 11111111.11111111.11111111.00000000
Your Network: 192.168.1.0 → 11000000.10101000.00000001.00000000
Target IP: 151.101.2.133 → 10010111.01100101.00000010.10000101
Subnet Mask: 255.255.255.0 → 11111111.11111111.11111111.00000000
Target Net: 151.101.2.0 → 10010111.01100101.00000010.00000000
Result: 192.168.1.0 ≠ 151.101.2.0 → different networksFor any non-local target IP, the operating system uniformly hands the packet to the default gateway. In a home network, the default gateway is usually the router's IP address — for example, 192.168.1.1. So what the computer actually needs to ARP-query is:
"Who has
192.168.1.1? Tell me your MAC address."
Router R responds to this ARP request with its MAC address RR:RR:RR:RR:RR:RR. After that, the data frame Computer A sends to the remote server looks like this:
┌─────────────────────────────────────┐
│ Destination MAC: RR:RR:RR:RR:RR:RR │ ← Router R's MAC
├─────────────────────────────────────┤
│ Source MAC: AA:AA:AA:AA:AA:AA │ ← Computer A's MAC
├─────────────────────────────────────┤
│ Type: 0x0800 (IPv4) │
├─────────────────────────────────────┤
│ ┌───────────────────────────────┐ │
│ │ Source IP: 192.168.1.10 │ │
│ ├───────────────────────────────┤ │
│ │ Destination IP: 151.101.2.133 │ │ ← Remote server's IP
│ ├───────────────────────────────┤ │
│ │ TCP segment + HTTP data │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘This demonstrates the beauty of layered separation: the Ethernet frame's destination MAC is the LAN's "next hop" (the router), while the IP packet's destination IP is the final server thousands of miles away. The two can point to entirely different devices.
When the router receives this frame, it decapsulates it to see the IP packet, then consults its routing table to determine the next-hop path, re-encapsulates it into a new link-layer frame, and forwards it onward. This leads to a broader principle:
Throughout a packet's journey, the IP packet's destination address typically stays the same (ignoring NAT), but the link-layer frame carrying it changes its destination MAC address at every hop along the way.
A common misconception is that the switch is responsible for resolving IP addresses to MAC addresses. That's not the case. In the standard model, responsibilities are divided as follows:
- ARP: a protocol used by hosts and routers to discover the MAC address corresponding to an IP address.
- Switch: a pure Layer 2 device that reads only the destination MAC address in the Ethernet frame header and forwards based on its self-learned MAC address table. It never looks at the IP layer.
When a host sends an ARP broadcast request, the frame's destination MAC is FF:FF:FF:FF:FF:FF. The switch recognizes this as a broadcast address and performs its standard action: flood the frame to all other ports in the same broadcast domain. The switch couldn't care less which IP address the ARP request is asking about. When the ARP reply comes back as a unicast, the switch forwards it precisely based on the destination MAC. As you can see, the switch merely provides reliable transport for ARP messages — it doesn't participate in the "resolution" itself.
Here's another way to think about their collaboration:
| Actor | What It Says |
|---|---|
| ARP | "I don't know where the target is — can you broadcast for me?" |
| Switch | "Sure, you want a broadcast? I'll knock on every door." |
| ARP | "The target replied! I know its MAC now. Send directly." |
| Switch | "I've got that MAC on record. Delivering precisely." |
ARP doesn't only work when "I need to communicate." There's another very common scenario called Gratuitous ARP — a device proactively broadcasts a "special ARP request," but the IP it's querying is not someone else's — it's its own.
What does this mean? A device sends an ARP request in which:
- Sender IP = Target IP = its own IP
- Target MAC = all zeros
"I'm
192.168.1.20, my MAC isBB:BB:BB:BB:BB:BB. Who has IP192.168.1.20? — Oh, that's me."
This sounds like talking to yourself, but it serves two important purposes:
Purpose 1: IP address conflict detection. When a device is newly assigned (or manually configured with) an IP address, it sends a gratuitous ARP to ask whether any other device on the LAN is already using that IP. If another device responds, an IP address conflict exists, and the current device should abandon the IP.
Purpose 2: Updating other devices' ARP caches. In failover scenarios, when a backup server takes over the primary server's IP address, it sends a gratuitous ARP to notify every device on the LAN: "The MAC address for this IP has changed — please update your ARP tables!" This quickly redirects traffic to the new device without waiting for each host's ARP cache to naturally expire.
ARP is elegantly simple and efficient, but it also has an inherent security flaw: it unconditionally trusts any reply it receives. When a device receives an ARP reply, it updates the IP-MAC mapping in its ARP table — even if it never sent a request in the first place.
This opens the door for ARP spoofing attacks. An attacker on the LAN can send forged ARP replies, claiming that the gateway's IP (e.g., 192.168.1.1) maps to the attacker's own MAC address. The victim host updates its ARP table and erroneously sends all traffic destined for the gateway to the attacker instead, leading to traffic interception or disruption.
Normal state:
192.168.1.1 → RR:RR:RR:RR:RR:RR (real router)
After attacker sends forged ARP reply:
192.168.1.1 → XX:XX:XX:XX:XX:XX (attacker's MAC)
Result: all of the victim host's outbound traffic passes through the attacker's NICUnderstanding ARP's lack of authentication is foundational to recognizing man-in-the-middle attacks within a LAN. While advanced switches support security features like DAI (Dynamic ARP Inspection), ARP's trust model is what it is.
As a final note: ARP is an IPv4 protocol. In IPv6 networks, its function is replaced by a more comprehensive protocol called NDP (Neighbor Discovery Protocol), which uses ICMPv6 messages to handle address resolution, neighbor tracking, and router discovery — all without relying on broadcast. That's a topic for another day, which we'll cover in a future article on IPv6.
-
Inspect your computer's ARP table Open a terminal and run
arp -a(orip neigh show). Can you identify which entry corresponds to your router? -
Observe ARP requests in action Use
pingto contact a device on your LAN that you've never communicated with before (a roommate's computer, or your router's IP). Then capture packets with Wireshark or tcpdump to find the ARP request and reply.# macOS/Linux packet capture (requires sudo) sudo tcpdump -i en0 arp -n # In another terminal, ping the gateway ping 192.168.1.1
-
Manually add a static ARP entry On Linux or macOS, add a static ARP record manually:
# macOS sudo arp -s 192.168.1.100 aa:bb:cc:dd:ee:ff # Linux sudo ip neigh replace 192.168.1.100 lladdr aa:bb:cc:dd:ee:ff dev eth0 nud permanentCheck the change with
arp -aand observe why static entries have no expiration time. -
Simulate an IP address conflict Assign the same IP address to two devices on the same LAN and use Wireshark to observe the gratuitous ARP interactions. See if the operating system detects the conflict and shows a warning.
This chapter revolved around one core question: Given an IP address, how do you obtain the MAC address needed for communication? The answer is ARP.
- ARP's role: operates within the local link, responsible for resolving IP addresses to MAC addresses. It's the "glue protocol" connecting the network layer and the data link layer.
- Workflow: the host sends an ARP request via broadcast; the target device responds with an ARP reply via unicast. Results are cached in the ARP table for future use.
- Accessing the internet: when the host determines a target is a remote IP, the ARP query's target is the default gateway, not the final server. This clearly illustrates the division of labor: MAC address (next hop) vs. IP address (final destination).
- Relationship with switches: switches do not participate in address resolution; they merely forward frames containing ARP messages based on the destination MAC.
- Gratuitous ARP: a device proactively announces its own IP-MAC mapping, used for conflict detection and failover.
- Security: ARP is built on unconditional trust and is vulnerable to spoofing attacks; NDP serves as the IPv6 replacement.
ARP MAC Address IP Address Broadcast/Unicast ARP Cache Default Gateway ARP Spoofing Gratuitous ARP NDP
With this chapter, we've filled the critical gap between "knowing the IP" and "sending the Ethernet frame." Following this thread, the next question naturally arises: how exactly does a host determine whether a target IP belongs to the local LAN or a remote network — so it can decide whether to ARP-query the target directly, or ARP-query the gateway instead?
That leads us to our next topic — IP Addresses, Subnet Masks, and Subnetting.
In the next article, we'll dive into the structure of IP addresses, the bitwise logic behind subnet masks, CIDR notation, and how routers use this information to make forwarding decisions.
