
In the preceding articles, we've understood MAC-based switching within a LAN, ARP address resolution, why we need hierarchical IP addresses, and how subnet masks let computers decide "is the target on my local network?" Now, the entire chain is missing one final link:
After a packet is handed to the gateway, what happens next? How does the router know where to forward it? How many times does a packet go through "strip frame, check table, rebuild frame" between your home and GitHub's servers?
This chapter opens up the internals of a router and shows you the complete mechanism by which data packets traverse the Internet.
/24 takes priority over /00.0.0.0/0 — the Internet's ultimate fallbackUnderstand IP addresses, subnet masks, and CIDR
Understand MAC addresses, switch forwarding, and ARP
Understand the fundamental difference between routers and switches
Open your terminal and look at your routing table:
# macOS
netstat -rn | head -10
# You'll see output similar to this (simplified):
# Destination Gateway Flags Netif
# default 10.43.56.1 UGSc en0
# 10.43.56/24 link#19 UCS en0
# 127.0.0.1 127.0.0.1 UH lo0It looks like a phone book — destination networks on the left, "who to hand it to" on the right. When you ping github.com, your operating system doesn't guess — it consults this table.
Now, let's say the target IP is 151.101.2.133 (one of GitHub's addresses). Your OS uses the subnet check you just learned to determine it's not in 10.43.56/24, so it matches the first entry default and hands the packet to 10.43.56.1 (your gateway).
Then what? That's exactly what this chapter answers — what the gateway does after receiving the packet.
A router's core data structure is the same as your computer's — the routing table. But its contents are far richer, because it must handle not just a binary "local or remote" decision, but multi-hop directional choices between networks.
A typical routing table entry looks like this:
┌──────────────────┬──────────────┬──────────────┐
│ Destination │ Next Hop │ Interface │
├──────────────────┼──────────────┼──────────────┤
│ 10.43.56.0/24 │ (directly │ en0 │
│ │ connected) │ │
│ 192.168.0.0/16 │ 10.43.56.1 │ en0 │
│ 0.0.0.0/0 │ 100.64.0.1 │ en1 │
└──────────────────┴──────────────┴──────────────┘Three pieces of information determine the packet's direction:
Destination: A CIDR-format network prefix, representing "which IP range does this entry cover?" When a router receives a packet, it performs longest prefix matching between the target IP and each entry's destination. It picks the most specific match and follows its instructions.
Next Hop (Gateway): The IP address the packet should be forwarded to next. If the next hop is marked "directly connected" (the router itself is on that network), there's no need to go through another router — ARP resolves the target IP's MAC and the frame is sent directly.
Interface: Which physical port on the router the packet should exit through. The WAN port or LAN port? Fiber or copper? This is the hardware-level "which door to leave from."
The interplay between these three can be compared to an airport connection:
Destination = "New York" (which direction to head)
Next Hop = "Beijing Capital Airport T3" (which hub to reach next)
Interface = "Depart from Gate A" (which specific door to walk through)
/24 Takes Priority Over /0A router doesn't "stop at the first match" when looking up its table. Instead, it finds every matching entry and picks the one with the longest prefix length. This rule is called Longest Prefix Match.
Example: a router receives a packet destined for 10.43.56.127, and the routing table contains:
10.43.56.0/24 → Next Hop A
10.0.0.0/8 → Next Hop B
0.0.0.0/0 → Next Hop CAll three match (because this IP falls within 10.43.56.0/24, 10.0.0.0/8, and 0.0.0.0/0). But /24 matches 24 bits, /8 matches only 8 bits, and /0 matches 0 bits. The router picks /24 and routes through Next Hop A.
This is like an address on an envelope:
1 Zhongguancun St, Haidian, Beijing → Haidian Post Office (/16 specificity)
1 Zhongguancun St, Haidian, Beijing → Zhongguancun Post Office (/24 specificity)
1 Zhongguancun St, Haidian, Beijing → National Postal HQ (/0 — catch-all)
All three post offices could handle the letter, but the more specific one wins — the Zhongguancun Post Office is closest and most precise, so it takes the delivery.
The importance of this rule cannot be overstated: precisely because of longest prefix matching, network admins can split large prefixes into smaller ones, giving smaller prefixes higher priority than larger ones. This enables traffic engineering, load balancing, and security policies.
You've definitely noticed these two routing table entries:
default 10.43.56.1 UGSc en0 ← your computer
0.0.0.0/0 100.64.0.1 en1 ← inside your routerBoth are essentially the same thing: 0.0.0.0/0 (CIDR prefix length 0, matching any IP) is the default route. It is the shortest possible prefix — 0 bits matched — so it is always selected last, as the final fallback.
Without a default route, your computer and router become "blind creatures that only know their neighbors." Your computer's routing table typically has only two entries: one for the local subnet (e.g. 10.43.56/24) and one for default. Every IP outside the local subnet — GitHub, Google, any public address — follows the default route to the gateway 10.43.56.1.
Similarly, your gateway (the router) has its own default route, pointing upstream to the ISP's router at 100.64.0.1. The ISP's backbone routers also have default routes pointing further upstream... and so on. The Internet's global routing system is an onion of nested layers, where each layer uses a default route to pass unmatched traffic to a higher-tier router. Only the top-tier (Tier 1 ISP core routers) have no default route — their routing tables contain the complete paths to every autonomous system on the Internet, so they never need a fallback.
Now we can tie everything together. Suppose you ping github.com, and the target IP resolves to 151.101.2.133. Here is the complete journey of the data packet:
Your Computer (10.43.56.171/24, gateway 10.43.56.1)
│
│ ① Subnet check: 151.101.2.133 & 255.255.255.0 = 151.101.2.0
│ Not 10.43.56.0 → Send to gateway
│
│ ② ARP for gateway MAC: Who is 10.43.56.1?
│
│ ③ Build frame:
│ Dest MAC = Gateway LAN port MAC
│ Src MAC = Your MAC
│ IP Packet:
│ Src IP = 10.43.56.171
│ Dest IP = 151.101.2.133
│
▼
Your Gateway (Router, LAN port 10.43.56.1, WAN port 100.64.0.2)
│
│ ④ Receive frame → Strip frame → Read dest IP: 151.101.2.133
│
│ ⑤ Check routing table:
│ 10.43.56.0/24 → No match
│ 100.64.0.0/10 → No match (assuming)
│ 0.0.0.0/0 → Match! Next hop 100.64.0.1
│
│ ⑥ ARP for ISP router MAC: Who is 100.64.0.1?
│
│ ⑦ Rebuild frame: New MACs, IP packet unchanged
│ Dest MAC = ISP router MAC
│ Src MAC = Your router's WAN port MAC
│
▼
ISP Router (100.64.0.1)
│
│ ⑧ Strip frame → Check table → Match more specific route
│ (e.g. 151.101.0.0/16 learned via BGP)
│ → Next hop to backbone node
│
│ ⑨ Rebuild frame → Forward
│
▼
... (8~15 hops through multiple ISPs, backbone networks, CDN nodes)
│
│ Every hop repeats: strip frame → check table → decide next hop → rebuild frame
│ MAC changes every hop; IP packet remains untouched the entire way
│
▼
Last Router in GitHub's Server Network
│
│ ⑩ Dest IP 151.101.2.133 matches local subnet → Directly connected!
│ ARP for 151.101.2.133's MAC → Encapsulate → Deliver directly
│
▼
GitHub Server (151.101.2.133)
│
│ Receives ICMP Echo Request → Replies with ICMP Echo Reply
│ The reply follows the same hop-by-hop process, with src/dst IPs swapped
│
▼
Your Computer receives the Ping reply ✓Two key principles are demonstrated throughout this journey:
Hop-by-Hop: Every time a packet passes through one router, it counts as one hop. A router is only responsible for "tell me the next hop" — it doesn't plan the entire path. Each router makes an independent decision; the chain of all independent decisions forms the final path.
Next hop must be on the same link: The "next hop" IP that a router's table yields must be on the same subnet as one of the router's own interfaces. If the next hop
100.64.0.1isn't in any directly connected network, the packet can't be sent at all — because ARP must first resolve the next hop's MAC, and ARP only works within the local subnet.
By now, you might be wondering: who actually populates those routing table entries? Surely an administrator can't configure every router by hand?
The answer comes in two flavors:
When you assign an IP and subnet mask to an interface, the operating system or router automatically generates a directly connected route. Your home router's 192.168.1.0/24 is a directly connected route — it appears automatically the moment the LAN port is plugged in.
For networks that need to be reached but aren't directly connected, an administrator can manually add static routes. For instance, if a company has two office locations each with their own subnet, the administrator writes a rule on the connecting router: "To 10.20.0.0/16, go via 192.168.0.2." Static routes work well for simple, stable topologies, but adding every new subnet manually becomes unsustainable at scale.
The Internet-scale routing system cannot be maintained by hand. The solution is for routers to automatically exchange routing information. This is what dynamic routing protocols do.
The two most widely used:
OSPF (Open Shortest Path First): Used within an enterprise network (inside an Autonomous System). Each router advertises its directly connected networks to its neighbors, and every router computes the shortest path to each network using Dijkstra's algorithm. OSPF reacts to link failures quickly (converges in seconds), making it suitable for a few hundred routers within a single organization.
BGP (Border Gateway Protocol): Used on the Internet backbone (between Autonomous Systems). ISP routers use BGP to announce to other ISPs: "I host these IP prefixes, and you can reach them through me." BGP doesn't aim for the shortest path — it selects routes based on business policies (peering agreements, transit costs, traffic contracts). The Internet's global routing table (~1 million entries) is formed by ISPs exchanging and aggregating routes via BGP.
A simple way to remember:
If you've ever run traceroute, you've noticed each hop shows a response time in milliseconds. Behind this tool lies a clever field in the IP header: TTL (Time to Live).
TTL is an 8-bit number, set by the sender (typically 64), decremented by 1 at every router. When TTL reaches 0, the router discards the packet and sends an ICMP Time Exceeded message back to the source IP.
The original purpose was to prevent misconfigured routing tables from causing packets to loop forever. But engineers realized it could be exploited for diagnostics: deliberately send packets with TTL=1 —
This is exactly how traceroute works — using incrementally increasing TTL values to knock on every door along the path and discover each hop.
So far we've focused on "how routers forward." But don't forget — your laptop, phone, and servers all have IP addresses and make routing decisions too.
Every machine with an IP address maintains a routing table. Before sending any packet, the OS performs longest-prefix matching against this table to decide two things: which interface to use, and who the next hop is. This is exactly why ARP behaves differently for local vs. remote destinations — it's not hardcoded; it's the routing table at work.
The netstat -rn output from the opening scenario is your Mac's routing table. Where do these routes come from? They're not static — most are automatically maintained.
When you configure en0 with IP 192.168.1.10/24 (or DHCP assigns it), the OS automatically derives a direct route from the IP and subnet mask:
192.168.1.0/24 link#6 UC en0This means: "all IPs in the 192.168.1.x range can be reached directly through en0, no gateway needed — the destination is in the same broadcast domain as this interface." This route exists as long as the IP address exists on that interface.
When you connect to Wi-Fi, the DHCP server (usually the router) provides not just your IP address but also the default gateway. The OS automatically adds a default route:
0.0.0.0/0 192.168.1.1 UG en00.0.0.0/0 matches every IP but has the lowest priority (prefix length 0). Any packet that doesn't match a more specific entry falls through to this. When you access 8.8.8.8 and the routing table finds no better match, it hits the default route — next hop is 192.168.1.1. That's why ARP queries the gateway's MAC for internet destinations.
When DHCP disconnects or the lease expires, this route is automatically removed — at which point the host loses internet access (unless another default route exists).
When your VPN client starts, it adds a route:
10.0.0.0/24 utun3 UCAll traffic to 10.0.0.x now goes through the encrypted tunnel interface utun3, not en0. When the VPN disconnects, this route is removed.
Similarly, starting Docker adds:
172.17.0.0/16 bridge0 UCEnsuring container traffic goes through the Docker bridge.
None of these are manually configured — software adds and removes them through system calls to the kernel routing table.
When you ping 8.8.8.8:
1. OS looks up 8.8.8.8 in the routing table (longest prefix match)
2. 8.8.8.8 doesn't match 192.168.1.0/24 (local)
3. 8.8.8.8 doesn't match 10.0.0.0/24 (VPN)
4. 8.8.8.8 doesn't match 172.17.0.0/16 (Docker)
5. 8.8.8.8 hits 0.0.0.0/0 (default route) → next hop 192.168.1.1, interface en0
6. OS sends an ARP request for 192.168.1.1 on interface en0
7. After getting the gateway MAC, builds the Ethernet frame:
Source MAC = en0's MAC
Destination MAC = gateway's MAC
IP packet destination = 8.8.8.8
8. Sends the frameThe routing table decides which interface to use; ARP and source MAC are mechanical execution after the routing decision. The source MAC isn't "the device's identity" — it's "the MAC of whichever interface the routing table selected." When you have multiple NICs, the OS runs this decision process for every single packet.
| Host (your laptop) | Router | |
|---|---|---|
| Table size | Dozens of entries | Thousands to millions (core routers) |
| Primary source | Auto (interface config + DHCP + software) | Auto + dynamic routing protocols (OSPF/BGP) |
| Default route | One (points to gateway) | May or may not have one (core routers have full internet routes) |
| Forwards others' packets? | No | Yes (core function) |
| Runs dynamic routing? | No | Yes (OSPF/BGP) |
A host doesn't need BGP or OSPF — it only needs to know "local subnet: send directly; everything else: throw at the gateway."
Decode your computer's routing table
Run netstat -rn or route print (Windows). Find and explain:
127.0.0.1 (what's its purpose?)traceroute to a target and observe the hop count
traceroute github.comLook at the first hop — is it your gateway? Are there hops showing * * *? (That usually means a firewall is blocking ICMP.) How many hops total?
Simulate "next hop must be on the same link"
If your machine's IP is 192.168.1.10/24, which of these next hops are valid?
192.168.1.1192.168.2.110.0.0.1Use traceroute to detect path changes
Run traceroute to the same target at three different times (e.g. an hour apart). Did any router IPs change? Did the ordering shift? What does this reveal about the nature of Internet routing?
Simulate traceroute with manual TTL values
On macOS, ping can set TTL:
ping -c 1 -m 1 github.com # TTL=1, first hop will timeout
ping -c 1 -m 2 github.com # TTL=2, second hop will timeoutObserve the source IP in each returned ICMP Time Exceeded message — each one comes from a different router along the path.
/24 has higher priority than /8, which has higher priority than /0.0.0.0.0/0) matches any IP and is the ultimate fallback. Without it, routers can only forward to directly connected networks. Both your home router and ISP routers rely on default routes pointing "further upstream."traceroute's path discovery.Congratulations! At this point, we've covered the complete journey from the Data Link Layer (MAC/switching/ARP) through the Network Layer (IP/subnet/CIDR/routing). You can now describe, end to end, how a data packet travels from your computer to GitHub's servers.
But a side question naturally arises: we've been talking about IP addresses throughout this layer — but who allocates them? When you buy a cloud server and see 129.211.82.148, who decided that's your address and not someone else's? How does the global Internet ensure every public IP is unique?
The next article takes a brief detour to answer this: how IP addresses are allocated and managed from global authorities like IANA and APNIC down to your cloud server.