← Interview Prep

Life of a Packet — Fundamentals

Three scenarios, walked field by field: what changes, what stays, and why.

A whiteboard-friendly format: at every hop, write down what changed, what stayed the same, and why. The one principle to state out loud before anything else:

The L2 header lives exactly one hop (hop-by-hop) and is rewritten at every router. L3 addresses live end-to-end and never change — until NAT appears. L4 is touched by no one except NAT and MSS clamping.

Scenario A — One L2 segment (single subnet)

H1 ──────── SW1 ──────── H2
10.0.10.11/24           10.0.10.22/24
aa:aa:aa:00:00:11       aa:aa:aa:00:00:22
        VLAN 10, both ports access

A.1 The sender's decision: local or via the gateway

H1 applies its own mask to the destination address:

They match → the destination is on my subnet → send it directly, destination MAC = H2's own MAC, the gateway is not involved at all.

This is the key fork of the whole walkthrough, and it must be said explicitly: the router is neither needed nor involved in this scenario, even if one exists on the network.

A.2 ARP (if the cache is empty)

ARP Request — broadcast:

FieldValue
DST MACff:ff:ff:ff:ff:ff
SRC MACaa:aa:aa:00:00:11
EtherType0x0806 (ARP)
Sender IP / MAC10.0.10.11 / aa:aa:aa:00:00:11
Target IP / MAC10.0.10.22 / 00:00:00:00:00:00

ARP Reply — now unicast, from H2 to H1, with the Target filled in.

Side effect: at this moment the switch learned H1's MAC on its port (from the request's SRC MAC), and H2's MAC from the reply.

A.3 The data frame

FieldValue
DST MACaa:aa:aa:00:00:22the receiver itself
SRC MACaa:aa:aa:00:00:11
EtherType0x0800 (IPv4)
SRC IP / DST IP10.0.10.11 / 10.0.10.22
TTL64 — and stays 64
L4unchanged

A.4 What the switch does

A.5 If there is a trunk between them

On a trunk an 802.1Q tag is inserted — +4 bytes between SRC MAC and EtherType:

FieldValue
TPID0x8100
PCPpriority 0–7 (this is CoS)
DEI1 bit
VID10

The maximum frame becomes 1522 bytes. On the egress access port the tag is stripped. This is the only modification a "plain" switch makes to a frame.

A.6 Going deeper

Scenario B — Routing, multiple hops

H1 ── R1 ══ R2 ══ R3 ── H2
10.0.10.11/24                        10.0.30.22/24
GW 10.0.10.1                         GW 10.0.30.1

R1: e0 10.0.10.1/24   (MAC bb:...:01)   e1 10.0.255.0/31 (MAC bb:...:11)
R2: e0 10.0.255.1/31  (MAC cc:...:01)   e1 10.0.255.2/31 (MAC cc:...:11)
R3: e0 10.0.255.3/31  (MAC dd:...:01)   e1 10.0.30.1/24  (MAC dd:...:11)

B.1 The sender's decision

10.0.30.22 AND 255.255.255.0 = 10.0.30.010.0.10.0different subnet → send to the default gateway's MAC.

A critical detail people trip on: ARP is done for the gateway's IP (10.0.10.1), not the receiver's IP. H1 will never learn H2's MAC, and it shouldn't.

B.2 The frame on the first hop (H1 → R1)

FieldValue
DST MACbb:...:01 — the gateway's MAC, not the receiver's
SRC MACaa:aa:aa:00:00:11
SRC IP / DST IP10.0.10.11 / 10.0.30.22
TTL64

B.3 What happens at every router

The same loop, repeated on R1, R2, R3:

  1. Verify the DST MAC is mine (otherwise drop, unless promiscuous).
  2. Strip the L2 header, check the FCS.
  3. Take the DST IP → LPM lookup in the FIB → egress interface and next-hop.
  4. TTL − 1. If it hits 0 → drop and return ICMP Time Exceeded (type 11).
  5. Recompute the IP header checksum (incrementally, RFC 1624 — the whole header is not re-summed).
  6. Find the next-hop MAC (ARP / neighbor cache); no entry → ARP request, the packet waits in a queue.
  7. Build a new L2 header: SRC MAC = my egress interface, DST MAC = next-hop.
  8. Recompute the FCS and send.

B.4 Per-hop summary

HopDST MACSRC MACSRC IPDST IPTTL
H1 → R1bb:…:01aa:…:1110.0.10.1110.0.30.2264
R1 → R2cc:…:01bb:…:1110.0.10.1110.0.30.2263
R2 → R3dd:…:01cc:…:1110.0.10.1110.0.30.2262
R3 → H2aa:…:22dd:…:1110.0.10.1110.0.30.2261

In one sentence: L2 changes completely at every hop, L3 addresses change nowhere, TTL decreases, the IP checksum is recomputed, and no one touches L4.

B.5 The subtleties that separate levels

B.6 If there is MPLS/VXLAN between hops

Scenario C — L2 + L3 + Internet via NAT

H1 ── SW1 ── R(NAT/FW) ══ ISP ══ Internet ── Server
192.168.1.11/24          WAN 203.0.113.5              93.184.216.34:443
GW 192.168.1.1

H1 opens a TCP session to 93.184.216.34:443, source port 51514.

C.1 Inside the LAN (H1 → R)

As in Scenario B: different subnet → ARP for the gateway → frame to the gateway's MAC.

FieldValue
DST MAC / SRC MACMAC of R / MAC of H1
SRC IP : port192.168.1.11 : 51514
DST IP : port93.184.216.34 : 443
TTL64

C.2 At the NAT router — what changes on top

First ordinary routing (TTL−1, new L2, IP checksum recompute), and on top of that:

WhatBeforeAfter
SRC IP192.168.1.11203.0.113.5
SRC port5151462001 (chosen by NAT, under PAT)
DST IP : port93.184.216.34 : 443unchanged
IP checksumrecomputed (address changed)
TCP checksumrecomputed, because the pseudo-header contains SRC IP, which changed

The key point to state explicitly: NAT is the only place in this walkthrough where an L3 address changes and, as a consequence, an L4 checksum must be touched. That is what separates NAT from routing fundamentally, not quantitatively.

A translation-table (conntrack) entry appears:

192.168.1.11:51514  ⇄  203.0.113.5:62001  →  93.184.216.34:443   TCP  ESTABLISHED

C.3 The packet on the Internet

FieldValue
SRC MAC / DST MACMAC of R's WAN interface / MAC of the ISP router
SRC IP : port203.0.113.5 : 62001
DST IP : port93.184.216.34 : 443
TTL63, decreasing at every hop after

The server sees only the public address; it knows nothing about the existence of 192.168.1.11.

C.4 The return path

The reply arrives at 203.0.113.5:62001. The router looks up the translation table:

Then ordinary LAN delivery: ARP for 192.168.1.11, frame to H1's MAC.

C.5 Variants and details

Cheat sheet: what changes where

FieldL2 switchRouterNAT
DST MACselects a port, doesn't changerewritesrewrites
SRC MACdoesn't changerewritesrewrites
802.1Q tagmay add/removeusually removes
FCSrecomputes (S&F, tag)recomputesrecomputes
SRC IP / DST IPdoesn't touchdoesn't touchrewrites one of them
TTLdoesn't touch−1−1
IP checksumdoesn't touchrecomputesrecomputes
L4 portsdoesn't touchdoesn't touchrewrites (PAT)
TCP/UDP checksumdoesn't touchdoesn't touchrecomputes
Payloaddoesn't touchdoesn't touchdoesn't touch (except ALG)

How to present it at the whiteboard

  1. Start with the fork: my subnet or someone else's — everything else depends on it. Show the AND-with-the-mask operation.
  2. State separately: ARP is always for the next-hop, not the final address.
  3. Keep two columns — "changes" and "doesn't change." The interviewer is usually looking for exactly this understanding of the hop-by-hop vs. end-to-end boundary.
  4. Call out the side effects: MAC learning, ARP-cache population, conntrack entry creation. State is what breaks later.
  5. Finish with a clarifying question: "want me to show what changes if we insert MPLS/VXLAN between hops, or if the path is asymmetric?" — this turns the walkthrough into a dialogue and shows depth.

Likely follow-up questions

Part 1 of 2 · continue with Life of a Packet — Advanced (MPLS L3VPN, IPv6, EVPN/VXLAN, multicast).