Burned into the NIC. Only ever meaningful on the local wire/segment — it identifies "which physical port," not "where on the internet." It is rewritten every time a frame crosses a Layer 3 device.
Identifies the host end to end, across the whole path. A router changes the Ethernet header around a packet, but leaves the source/destination IP inside it untouched — unless NAT is configured.
"Who has this IP, tell me your MAC." Runs only on the local segment — it's a broadcast, and broadcasts don't cross routers. Every device that needs to put a MAC on a frame has to ARP first (or use a cached answer).
Reads only the destination MAC. Learns source MAC → port mappings, forwards known unicasts to one port, floods unknowns/broadcasts everywhere else. Never looks at IP, never runs ARP itself.
Reads the destination IP, ignores the incoming MAC entirely once the frame is stripped. Picks an exit interface from its routing table, then builds a brand-new frame for the next hop.
A frame carries a packet, which carries a segment. Ethernet header → IP header → ICMP/TCP/UDP → data. Each device peels back only the layer it needs and never touches the ones inside.
PC-A (10.0.0.10/24, MAC AAAA.AAAA.AAAA) and PC-B (10.0.0.20/24, MAC BBBB.BBBB.BBBB) are joined by a single Ethernet cable, NIC to NIC — no switch, no hub, nothing in between. Modern NICs auto-negotiate and use Auto-MDIX, so a plain patch cable works without needing a "crossover" cable.
SetupBoth NICs detect a carrier signal and bring the link to UP/UP. There is nothing to "learn" here — with only two devices on the wire, every frame either sent has exactly one possible physical destination.
PC-A's stack checks its ARP cache for 10.0.0.20 — empty on first contact. It sends an ARP request as an Ethernet broadcast: dst MAC FFFF.FFFF.FFFF, "who has 10.0.0.20?" With no switch to flood it selectively, the frame goes straight down the one cable that exists.
There is no switch, so there is no MAC-learning table anywhere in this path. Every "which port does this go out" decision that a switch would normally make simply doesn't exist — the wire itself is the only path, full stop.
CheckpointPC-B recognizes its own IP in the broadcast, replies unicast with its MAC. PC-A caches 10.0.0.20 → BBBB.BBBB.BBBB and sends the ICMP Echo Request directly addressed to it. PC-B answers with an Echo Reply the same way.
ping succeeds. This is the simplest possible topology: one ARP exchange, one ICMP exchange, zero intermediate devices making forwarding decisions of any kind.
Same two PCs, same subnet — but now both plug into a switch instead of each other. The switch adds exactly one new job to the picture: deciding which port to forward a frame out of, using MAC addresses only.
SetupPC-A's ARP request (dst FFFF.FFFF.FFFF) arrives on the switch's Fa0/1. The switch learns AAAA.AAAA.AAAA → Fa0/1 from the source field, then floods the frame out every other port in the VLAN — including Fa0/2 where PC-B sits.
PC-B replies unicast to AAAA.AAAA.AAAA. The switch already has that MAC in its table from step 2, so this time it forwards to Fa0/1 only — no flooding. It also learns BBBB.BBBB.BBBB → Fa0/2 from this frame's source field.
CAM table: AAAA→Fa0/1, BBBB→Fa0/2. That's it — no IP addresses appear anywhere in that table. The switch made every decision so far purely on MAC, and it will keep doing so for the rest of this exchange.
PC-A sends the Echo Request straight to BBBB.BBBB.BBBB (from its ARP cache). The switch looks it up, forwards out Fa0/2 only. PC-B's Echo Reply is switched back to Fa0/1 the same way.
ICMPOne extra device, one extra concept (MAC learning + forward-vs-flood) — but IP addressing, ARP's role, and the fact that no gateway is involved are all identical to the direct-cable case. Full 12-step version with every intermediate detail →
DeliveredPC-A (10.0.0.10/24, gw 10.0.0.1) sits behind SW-A. PC-B (20.0.0.10/24, gw 20.0.0.1) sits behind SW-B. A router, R1, connects both switches — one interface (and IP) on each subnet. The two subnets are now genuinely separate broadcast domains.
SetupPC-A ANDs 20.0.0.10 against its own /24 — not local. It must reach its gateway's MAC, not PC-B's. ARP cache miss on 10.0.0.1 → broadcast ARP request, confined entirely to SW-A's VLAN. R1 replies with its interface MAC.
ARPPC-A sends the ICMP Echo Request: Ethernet dst = R1's MAC, IP dst = 20.0.0.10 (unchanged — this packet is not for R1 itself, R1 is just the next hop). SW-A does a plain CAM lookup and forwards to R1's port. The switch touches neither address.
L2 ForwardR1 receives the frame, sees its own MAC as destination, strips the Ethernet header entirely, and is left holding a bare IP packet: src 10.0.0.10, dst 20.0.0.10. It checks its routing table — a connected route for 20.0.0.0/24 points out its other interface.
CheckpointR1 checks its own ARP cache for 20.0.0.10 on that interface. First time, it's a miss — R1 broadcasts its own ARP request onto SW-B's segment. PC-B replies with its MAC.
ARPR1 constructs a completely new Ethernet header: src MAC = R1's own interface, dst MAC = PC-B's. The IP header inside is untouched — still src 10.0.0.10, dst 20.0.0.10. This is the only point in the whole path where a MAC address actually changes.
L2 Re-frameSW-B does its own plain CAM lookup on the new frame's destination MAC and forwards it to PC-B's port. Again, no address rewriting — a switch never rewrites anything, it only ever reads and forwards.
L2 ForwardPC-B's Echo Reply goes to its own gateway (20.0.0.1), R1 routes it back toward 10.0.0.0/24, rewrites the Ethernet header a second time (src = R1, dst = PC-A's MAC, already learned in step 2), and both switches forward it unchanged. ping completes.
Same PC-A and PC-B, same two switches — but now R1 (edge router, site A) connects to a firewall, which connects to R2 (edge router, site B), which connects to SW-B. Two independent L3 hops plus one stateful inspection point sit in the middle.
SetupARP for the gateway, SW-A forwards unchanged, R1 strips the frame and does its route lookup. Nothing new yet — this half is identical to Scenario 3.
UnchangedR1's routing table points the 20.0.0.0/24 destination out its WAN interface toward the firewall. R1 ARPs for the firewall's inside interface (or already has it cached) and builds a new frame: src MAC = R1, dst MAC = firewall. IP addresses inside are still untouched.
L2 Re-frame #1The firewall strips the frame like any L3 device would, but before routing it also checks its state/session table. First packet of a new flow → no existing session → it's evaluated against policy (zone-to-zone rule, source/destination, service). If the rule permits it, a new session entry is created and the packet proceeds.
StatefulHaving permitted the session, the firewall routes the packet out its far interface toward R2, building yet another new Ethernet header: src MAC = firewall, dst MAC = R2. IP addresses still unchanged — this firewall is doing routing + inspection, not NAT, in this example.
L2 Re-frame #2R2 strips the frame, sees a connected route to 20.0.0.0/24 out its LAN interface, ARPs for PC-B (or uses a cached entry), and builds the final frame: src MAC = R2, dst MAC = PC-B. Three separate re-framing events have now happened — R1, firewall, R2 — each one a fresh Ethernet header around the same untouched IP packet.
L2 Re-frame #3SW-B does a plain CAM lookup, delivers to PC-B. PC-B generates its Echo Reply addressed to its own gateway (R2) — from PC-B's point of view this looks like an ordinary local exchange; it has no visibility into any of the hops behind R2.
ICMPThe reply retraces the path in reverse: R2 → firewall → R1 → SW-A → PC-A, with a fresh Ethernet header built at each L3 hop again. Critically, the firewall does not re-run its full policy lookup this time — it matches the return traffic against the session created in step 4 and fast-paths it through, which is exactly why stateful firewalls don't need a separate "allow the reply" rule.
Stateful ReturnFive devices touched the frame (SW-A, R1, firewall, R2, SW-B); only three of them (R1, firewall, R2) ever rewrote a MAC address, because only those three are Layer 3 devices. The IP addresses PC-A and PC-B put on the very first packet are the exact same ones on the very last.
Delivered| Segment (Scenario 4) | Frame Src MAC | Frame Dst MAC | Packet Src IP | Packet Dst IP | Device's Job |
|---|---|---|---|---|---|
| PC-A → SW-A | PC-A | R1 | 10.0.0.10 | 20.0.0.10 | Originate frame |
| SW-A → R1 | PC-A | R1 | 10.0.0.10 | 20.0.0.10 | CAM lookup only |
| R1 → Firewall | R1 | Firewall | 10.0.0.10 | 20.0.0.10 | Re-frame #1 route lookup |
| Firewall → R2 | Firewall | R2 | 10.0.0.10 | 20.0.0.10 | Re-frame #2 + policy/session check |
| R2 → SW-B | R2 | PC-B | 10.0.0.10 | 20.0.0.10 | Re-frame #3 route lookup |
| SW-B → PC-B | R2 | PC-B | 10.0.0.10 | 20.0.0.10 | CAM lookup only |
Read the pattern: the IP columns never change across the whole table. Only the MAC columns change, and only on rows where an L3 device (router or firewall) is one side of the hop — switch rows are always a pure pass-through. If NAT were configured anywhere in this path, the IP columns would change too, but only at the specific device doing the translation, and only from that point onward.
A switch only ever reads the outermost box (the Ethernet frame). A router opens the outer box, reads the IP box's destination address, then throws away the old outer box and builds a new one. Nobody except the two end hosts ever looks inside the innermost ICMP box.
| Term | Meaning |
|---|---|
| Auto-MDIX | Modern NIC feature that auto-detects and swaps TX/RX pairs — makes a plain patch cable work for direct PC-to-PC links, no crossover cable needed |
| CAM / MAC Table | The switch's memory of which MAC address lives behind which port — built purely by observing source addresses on incoming frames |
| Known / Unknown Unicast | Known = destination MAC is in the table, forwarded to one port. Unknown = not yet learned, flooded to all ports as a fallback |
| Broadcast Domain | The set of ports/hosts that receive a given broadcast (e.g. an ARP request) — bounded by VLAN, never crosses a router |
| Routing Table | The router's map of "which interface/next-hop to use for a given destination network" — built from connected, static, and/or dynamic routes |
| Re-framing | A router or firewall discarding the incoming Ethernet header and building a brand-new one for the outbound interface |
| TTL (Time to Live) | IP header field decremented by 1 at every router hop — packet is discarded and an ICMP error sent back if it hits zero |
| Session / State Table | A stateful firewall's record of already-permitted flows, used to fast-path return traffic without a full policy re-evaluation |
| NAT | Network Address Translation — the one mechanism that actually changes IP addresses mid-path, applied at exactly one device |
| Zone-Based Policy | Firewall rule model that evaluates traffic by source zone → destination zone rather than interface-by-interface |