By the end you'll know
- What a router does, and what a routing table is
- What the default route is, and why your computer almost always uses it
- How to measure and trace the path to a server, with
pingandtraceroute - How NAT lets every device in a home share one public address
- Why private addresses can't be reached from the internet
Where you are
Lessons 1 to 5 followed one request from a name to an address to a port to an answer. But they skipped over the journey itself. Your laptop is in your home; api.civicgrid.org is somewhere else entirely. How does data get from one to the other?
And there's a loose end from Lesson 2. Your laptop has a private address, like 192.168.1.23, which the internet can't reach. Yet websites answer you just fine. Something is translating between your private address and your home's public one. This lesson covers both: routing, how data crosses networks, and NAT, how private addresses get out and back.
Routers: one hop at a time
A parcel sent across the country doesn't follow a route planned in advance. The local sorting office looks at the address and sends it to the regional hub. The hub sends it to a hub nearer the destination. That one sends it to the local office at the other end. No office knows the whole route; each one only knows the best next step.
The internet works the same way. A router is a device that connects networks and passes data between them. When data arrives, the router looks at the destination address and sends it one step closer, to the next router. Each step is called a hop. Your home router is the first hop for everything that leaves your house.
Each router decides using its routing table: a list of address ranges and, for each one, where to send data for that range. Ranges are written in CIDR, from Lesson 3, which is a big part of why Lesson 3 matters.
Your computer's routing table
Routers aren't the only ones with routing tables. Your own computer has one too, and it's short. On a Mac:
netstat -rn -f inet
netstat shows network information; -rn asks for the routing table, with numbers instead of names, and -f inet keeps it to IPv4. On Linux or WSL, use ip route; on Windows, route print. Here's a real one, with the first few lines:
Destination Gateway Flags Netif Expire
default 192.168.1.1 UGScg en0
127 127.0.0.1 UCS lo0
127.0.0.1 127.0.0.1 UH lo0
169.254 link#14 UCS en0 !
192.168.1 link#14 UCS en0 !
Each line is a rule: "for addresses in this range, send them here". The Mac shortens ranges by leaving off the zeros, so 192.168.1 means 192.168.1.0/24. Reading from the bottom up:
192.168.1is your home network.link#14means "it's right here, on the Wi-Fi": no router needed, send it straight to the device.169.254is the self-assigned range from Lesson 2, also handled directly.127is localhost, sent tolo0, the loopback interface that never leaves the machine.defaultis everything else, sent to the gateway192.168.1.1: your home router.
When two rules match, the most specific one wins, the one with the longest prefix. 192.168.1.40 matches both 192.168.1 and default, so it goes straight to the device. 104.21.69.165 only matches default, so it goes to the router. That last line is the default route, and almost everything you do on the internet uses it: your computer doesn't need to know where api.civicgrid.org is, only that the router does. You can ask about it directly:
route -n get default
route to: default
destination: default
mask: default
gateway: 192.168.1.1
interface: en0
The gateway line is your router's address. If you've ever been asked for your "default gateway" when fixing a network, this is it.
How far away is it? ping
ping sends a tiny message that asks a machine to reply, and times how long the round trip takes. Try your router first, then the API:
ping -c 3 192.168.1.1
-c 3 means send 3 and stop; without it, ping runs until you press Ctrl+C.
64 bytes from 192.168.1.1: icmp_seq=0 ttl=64 time=8.889 ms
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=10.477 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=5.116 ms
ping -c 3 api.civicgrid.org
64 bytes from 104.21.69.165: icmp_seq=0 ttl=58 time=13.198 ms
64 bytes from 104.21.69.165: icmp_seq=1 ttl=58 time=15.021 ms
64 bytes from 104.21.69.165: icmp_seq=2 ttl=58 time=16.410 ms
The router is a few milliseconds away; Cloudflare, across the internet, is only a little further, because it has servers close to most people. Ping uses ICMP (Internet Control Message Protocol), a third protocol alongside TCP and UDP from Lesson 4, used for messages about the network itself rather than data. It has no ports. Some servers and firewalls ignore it, so "no reply to ping" doesn't always mean "down".
Look at the ttl numbers: 64 from the router, 58 from the API. That's a different TTL from DNS in Lesson 5, confusingly with the same name.
The hop limit
Every piece of data sent across the internet carries a number called its hop limit, which is also called TTL (time to live). It often starts at 64, though some systems use 128. Every router it passes through takes 1 off, and a router that takes it to 0 throws the data away and sends a short "time exceeded" message back to whoever sent it. It's a safety net: if routers ever send data round in a loop by mistake, it dies after 64 hops instead of circling forever.
That explains the 58 above: the reply started at 64 and passed through about six routers on its way back. Your router's reply arrived with 64, because there was nothing in between.
You can set the limit yourself. Send one ping that's only allowed one hop:
ping -c 1 -m 1 api.civicgrid.org
-m 1 sets the hop limit to 1 on a Mac; on Linux the option is -t 1. Your router takes it to 0 and sends a message back. Your router may show its name here too:
PING api.civicgrid.org (104.21.69.165): 56 data bytes
92 bytes from 192.168.1.1: Time to live exceeded
That "time exceeded" message tells you who the first router is. Set the limit to 2 and the second router answers; 3, and the third. Do that again and again and you get a map of the whole route, and that's exactly what the next tool does.
Watch the journey: traceroute
traceroute sends messages with a hop limit of 1, then 2, then 3, and so on, and lists every router that replies, until it reaches the destination:
traceroute -n -q 1 -w 2 -m 20 api.civicgrid.org
-n shows addresses only, without looking up names, which is faster. -q 1 sends one message per hop instead of three, -w 2 waits at most 2 seconds for each reply, and -m 20 gives up after 20 hops. On Linux, install traceroute or use the similar tracepath; on Windows the command is tracert. Here's a real trace from a home in the US. The middle hops belong to the home's internet provider, so they've been swapped for example addresses; the timings, the hop count, and the Cloudflare hops are real:
traceroute to api.civicgrid.org (104.21.69.165), 20 hops max, 40 byte packets
1 192.168.1.1 5.943 ms
2 203.0.113.1 6.844 ms
3 198.51.100.56 10.023 ms
4 *
5 198.51.100.122 19.249 ms
6 173.245.63.109 13.159 ms
7 173.245.63.205 16.426 ms
8 104.21.69.165 10.348 ms
Eight hops, in about 10 milliseconds:
- Hop 1 is the home router: the default route, as promised.
- Hops 2 to 5 are the internet provider's network: first its router nearest the home, then deeper in, then the hand-off towards Cloudflare. Hop 4 shows
*, meaning that router didn't reply in time. Many routers are set to ignore these messages or answer them last, so a single*in the middle of a trace that carries on is normal. - Hops 6 and 7 are inside Cloudflare's network. The provider handed the data straight to Cloudflare, which is part of why the trip is so short.
- Hop 8 is
api.civicgrid.orgitself.
Run it twice and the routers in the middle may change: the internet often has several good paths, and routers pick between them as conditions change.
NAT: one public address for the whole house
Now the loose end from Lesson 2. The trace started from 192.168.1.23, a private address. Private addresses are reused in millions of homes, so routers on the internet refuse to carry data addressed to them: they'd have no idea which home you meant. So how does the API's reply find its way back?
Think of an office with a receptionist and one main phone number. When someone at a desk calls out, the person they ring sees only the main number. The receptionist notes down "desk 23 called this number", and when the call comes back, puts it through to desk 23. Nobody outside ever sees the desk numbers.
Your home router is that receptionist. The trick is called NAT (network address translation):
- Your laptop sends a request from
192.168.1.23, port52344, to104.21.69.165, port443. - On the way out, the router rewrites the "from": the address becomes its own public address, say
203.0.113.45, and the port becomes one it picks, say61001. - It writes the swap in its NAT table: "port 61001 is really
192.168.1.23, port 52344". - Cloudflare sees a request from
203.0.113.45:61001and replies there, a perfectly ordinary public address. - The reply reaches your router, which looks up port 61001 in its table, rewrites the "to" back to
192.168.1.23:52344, and passes it in.
Every device in the house does this at once, each with its own entries in the table, which is how a whole household shares one public address. This is what's kept IPv4 going since the addresses ran out, as Lesson 2 described: millions of homes and offices, each using one public address and private ones behind it.
There's a catch built into this. The NAT table only gets an entry when a device inside starts a conversation. When something on the internet tries to start one with you, the router has no entry for it, has no idea which device it's for, and drops it. That makes NAT a rough kind of protection: by default, nothing on the internet can reach into your home. It's also the first case below.
You'll see this again
Cloud networks use exactly this pattern on purpose. Servers that should never be reached from the internet, like databases, go in a private subnet. When they need to reach out, for updates for example, they go through a NAT gateway, the cloud's version of your home router. Lesson 7 builds that.
Break it on purpose
Three cases, all from real traces. Work out the cause before you read the explanation.
A private address, far away. 10.255.255.1 is a private address, but not one on your home network. Trace it:
traceroute -n -q 1 -w 2 -m 6 10.255.255.1
traceroute to 10.255.255.1 (10.255.255.1), 6 hops max, 40 byte packets
1 192.168.1.1 9.119 ms
2 203.0.113.1 10.650 ms
3 *
4 *
5 *
6 *
Your computer had no specific route for 10., so it used the default route, and your router passed it on to your provider. The provider's first router took one look at a private address and dropped it: private addresses are never routed across the internet, because they mean something different in every network. If you ever need to reach a private address in another network, like a server in your company's cloud, you need a private link into that network: a VPN, from Lesson 3, or the peering in Lesson 7.
A trace that goes quiet. Trace this site instead:
traceroute -n -q 1 -w 2 -m 20 kwamib.dev
traceroute to kwamib.dev (216.198.79.1), 20 hops max, 40 byte packets
1 192.168.1.1 8.804 ms
2 203.0.113.1 7.583 ms
3 198.51.100.58 9.095 ms
4 *
5 *
6 *
...
20 *
Stars from hop 4 to the end. Is the site down? Open it in your browser: it works fine. The routers along that path, and Vercel's servers, simply don't answer traceroute's messages. Traceroute only shows the routers that choose to reply, so a trace that goes quiet tells you very little on its own. Only trust stars when the site really isn't working too, and check with curl from Lesson 1 or the troubleshooting steps in Lesson 12.
A server at home nobody can reach. You run Python's web server from Lesson 4 on your laptop, listening on 0.0.0.0:8000. On the same Wi-Fi, your phone can open http://192.168.1.23:8000/. You send a friend across town your public address, http://203.0.113.45:8000/, and it times out. Why? Their request reaches your router, but nobody inside started that conversation, so there's nothing in the NAT table for it, and the router drops it. To allow it, you'd set up port forwarding on the router: a permanent entry saying "anything for port 8000, send to 192.168.1.23". It's how people host game servers at home, and it's worth being careful with, because it opens a door from the whole internet into your network. For anything real, a cloud server is usually the better home.
Where you are now
You can read your computer's routing table, find your default gateway, measure distance with ping, map a route with traceroute, and explain how NAT gets private addresses out to the internet and back. That's how networks connect. Next, you'll build one: Lesson 7 is cloud networks, where the subnets from Lesson 3, the routing tables from this lesson, and NAT gateways all come together in a VPC.
Check yourself
What does a router do with data that arrives?
Your laptop sends data to 104.21.69.165. Which route does it use?
A ping reply says ttl=58. What does that tell you?
traceroute shows * at hop 4, then carries on. What does that mean?
What does a home router's NAT do to outgoing data?
A friend can't reach a server on your laptop through your public address. Why?
Key terms
- Router: a device that connects networks and passes data one hop closer to its destination.
- Hop: one step from one router to the next.
- Routing table: a list of address ranges and where to send data for each one.
- Default route: the rule for everything else, usually pointing at your router, the default gateway.
- ICMP (Internet Control Message Protocol): messages about the network itself, used by ping and traceroute.
- Hop limit (TTL): a number that drops by 1 at every router. At 0, the data is thrown away.
- NAT (network address translation): a router rewriting private addresses into its public one, and back.
- Port forwarding: a permanent NAT entry that lets the internet reach one device inside.
Go deeper
- Cloudflare's Learning Center on what routing is (opens in a new tab).
- Julia Evans's zine Bite Size Networking (opens in a new tab), which covers ping, traceroute and friends in comic form.