Appearance
5.3.1 — IP Addresses, Subnets & CIDR
Chapter 5.2 ended with a network that works beautifully and cannot grow. MAC addresses are flat and random, so a device in Tokyo has no way to work out which direction Sydney is. Every device would need to know where every other device on Earth is, and broadcasts would drown everything.
The internet layer fixes this with one idea: give addresses a structure that encodes location, so a router can decide direction from the address alone, without knowing the destination.
That is the whole of this page. The structure is called a subnet, the notation is called CIDR, and once you can do the binary in your head, half of networking and most of cloud configuration stops being mysterious.
1. An IP address is one 32-bit number wearing a disguise
An IPv4 address looks like 192.168.1.42. It is not four things. It is one 32-bit number, written as four 8-bit chunks in decimal because 3232235818 is unreadable and 192.168.1.42 is not.
Each chunk is called an octet (8 bits, so 0–255), and the dotted form is dotted-decimal notation.
192 . 168 . 1 . 42
11000000 10101000 00000001 00101010 ← the actual 32 bitsEverything on this page becomes obvious in binary and stays confusing in decimal, so it is worth spending a minute getting comfortable converting. Each octet is eight bit positions worth 128, 64, 32, 16, 8, 4, 2, 1:
192 = 128 + 64 → 11000000
168 = 128 + 32 + 8 → 10101000
1 = 1 → 00000001
42 = 32 + 8 + 2 → 0010101032 bits gives 2^{32} = about 4.3 billion addresses. That sounded limitless in 1981. Chapter 5.3.3 is about what happened when it was not.
2. The split that makes routing possible
Here is the central idea. An IP address is divided into two parts: a prefix identifying the network, and a suffix identifying the host within it.
192.168.1.42 with a /24 split:
11000000 10101000 00000001 | 00101010
└──────── network ────────┘ └─ host ─┘
24 bits 8 bitsThe /24 says: the first 24 bits are the network, the remaining 8 are the host.
Why this matters is the whole point of the layer. A router in Frankfurt does not store a route for 192.168.1.42. It stores a route for a whole prefix — "anything starting with these bits goes that way". One table entry covers millions of addresses.
This is the postcode idea. A sorting office in Manchester does not have a list of every house in Britain. It has a rule: "anything starting with EH goes to Edinburgh". The Edinburgh office then looks at more of the postcode. Each level only needs to know the next hop for a prefix, and the detail is somebody else's problem further down. Without that hierarchy, every sorting office would need a list of every address in the country, which is exactly the position MAC addresses are in.
3. The subnet mask, and what the AND is doing
The split between network and host is expressed by a subnet mask: a 32-bit number that is all 1s for the network part and all 0s for the host part.
/24 → 11111111 11111111 11111111 00000000 → 255.255.255.0
/16 → 11111111 11111111 00000000 00000000 → 255.255.0.0
/26 → 11111111 11111111 11111111 11000000 → 255.255.255.192The mask must be a contiguous run of 1s followed by a contiguous run of 0s — you cannot have 11110000 11110000. That constraint is what makes the arithmetic work.
To find which network an address belongs to, AND the address with the mask. Bitwise AND keeps a bit only where both inputs have a 1 (Chapter 4.29), so ANDing with the mask keeps the network bits and zeroes the host bits.
address 192.168.1.42 11000000 10101000 00000001 00101010
mask 255.255.255.0 11111111 11111111 11111111 00000000
AND ─────────────────────────────────────
network 192.168.1.0 11000000 10101000 00000001 00000000This single operation is the most-executed calculation in networking. Every time your machine sends anything, it does exactly this to answer one question:
Is the destination on my own network, or do I hand it to the router?
It ANDs its own address with its mask, ANDs the destination with the same mask, and compares. Same result means local — ARP for the destination directly (Chapter 5.2). Different result means remote — ARP for the default gateway instead.
Worked example. Your laptop is 192.168.1.42/24.
Sending to 192.168.1.99:
192.168.1.42 AND 255.255.255.0 = 192.168.1.0
192.168.1.99 AND 255.255.255.0 = 192.168.1.0 same → local, ARP directlySending to 142.250.187.238:
192.168.1.42 AND 255.255.255.0 = 192.168.1.0
142.250.187.238 AND 255.255.255.0 = 142.250.187.0 different → send to the routerThat is it. Everything about "why can this machine not reach that machine" comes back to this comparison, and when a cloud VM cannot reach a database, this is the first thing to check.
4. CIDR: the notation, and why classes died
/24 is CIDR notation (classless inter-domain routing, pronounced "cider"), introduced in 1993. The number after the slash is simply how many leading bits are the network.
What it replaced was worse. The original design carved the address space into fixed classes:
| Class | First octet | Network bits | Hosts per network |
|---|---|---|---|
| A | 1–126 | 8 | 16,777,214 |
| B | 128–191 | 16 | 65,534 |
| C | 192–223 | 24 | 254 |
The network size was determined by the address itself, with no middle ground. A company with 300 machines could not use a class C (254 hosts, too few) so it was given a class B — 65,534 addresses, of which it used 300 and wasted 65,234. Multiply that across thousands of organisations and you have the reason the address space was being consumed far faster than the number of connected machines suggested.
CIDR removed the classes and allowed any prefix length, so that company gets a /23 (510 hosts) and wastes 210 instead of 65,234.
It also enabled route aggregation, which is the reason the internet's routing tables did not explode. If a provider owns 10.0.0.0/16 through 10.15.0.0/16, it advertises them to the rest of the internet as the single prefix 10.0.0.0/12. Sixteen routes become one. Without aggregation the global routing table would be far larger than any router could hold — as of the mid-2020s it holds roughly a million prefixes, and that is after aggregation.
5. Doing subnet arithmetic in your head
Three quantities, and they all fall out of the host-bit count.
\text{host bits} = 32 - \text{prefix} \qquad \text{total addresses} = 2^{\text{host bits}} \qquad \text{usable hosts} = 2^{\text{host bits}} - 2
Why minus two. Two addresses in every subnet are reserved:
- All host bits 0 is the network address, the name of the subnet itself.
192.168.1.0/24refers to the network, not to a machine. - All host bits 1 is the broadcast address. A packet sent to
192.168.1.255goes to every host on that subnet.
Neither can be assigned to a device. This is why a /30 gives you two usable addresses out of four — which is exactly enough for a point-to-point link between two routers, and is why /30 and /31 links are common.
The table worth memorising:
| CIDR | Mask | Total | Usable | Typical use |
|---|---|---|---|---|
| /32 | 255.255.255.255 | 1 | 1 | a single host, a firewall rule |
| /31 | 255.255.255.254 | 2 | 2 | router-to-router link |
| /30 | 255.255.255.252 | 4 | 2 | router-to-router link |
| /29 | 255.255.255.248 | 8 | 6 | a tiny subnet |
| /28 | 255.255.255.240 | 16 | 14 | small cloud subnet |
| /24 | 255.255.255.0 | 256 | 254 | the standard office or home LAN |
| /22 | 255.255.252.0 | 1,024 | 1,022 | a floor of a building |
| /16 | 255.255.0.0 | 65,536 | 65,534 | a whole cloud network |
| /8 | 255.0.0.0 | 16,777,216 | 16,777,214 | a very large private range |
The two shortcuts that let you do this without a calculator:
Every bit you take from the host part halves the subnet. A /24 has 256 addresses, /25 has 128, /26 has 64, /27 has 32, /28 has 16. Count down from 256 by halving and you can read any prefix between 24 and 32 instantly.
The mask's last non-zero octet tells you the block size. For a /26 the mask is 255.255.255.192, and 256 - 192 = 64. So subnets start every 64 addresses: .0, .64, .128, .192. This works for every prefix.
Worked example — split 10.0.0.0/24 into four equal subnets.
Four subnets need two extra network bits (2^2 = 4), so the prefix goes from /24 to /26. Block size is 256 - 192 = 64:
| Subnet | Network | First usable | Last usable | Broadcast |
|---|---|---|---|---|
| 1 | 10.0.0.0/26 | 10.0.0.1 | 10.0.0.62 | 10.0.0.63 |
| 2 | 10.0.0.64/26 | 10.0.0.65 | 10.0.0.126 | 10.0.0.127 |
| 3 | 10.0.0.128/26 | 10.0.0.129 | 10.0.0.190 | 10.0.0.191 |
| 4 | 10.0.0.192/26 | 10.0.0.193 | 10.0.0.254 | 10.0.0.255 |
Check it in binary and the whole thing becomes obvious. The two bits that were freed by moving /24 to /26 are the two most significant bits of the last octet: 00, 01, 10, 11 — giving 0, 64, 128, 192. Subnetting is not arithmetic. It is deciding where to put the line between network bits and host bits.
6. The addresses that are not ordinary addresses
Several ranges are reserved, and knowing them prevents real confusion.
| Range | Name | What it means |
|---|---|---|
10.0.0.0/8 | private | not routable on the internet |
172.16.0.0/12 | private | not routable — note it is 172.16–172.31, not all of 172 |
192.168.0.0/16 | private | not routable |
127.0.0.0/8 | loopback | this machine; 127.0.0.1 is localhost |
169.254.0.0/16 | link-local | self-assigned when DHCP fails |
100.64.0.0/10 | carrier-grade NAT | an ISP's internal shared range |
224.0.0.0/4 | multicast | a group of interested receivers |
0.0.0.0/0 | the default route | "everything", used as a catch-all |
The three private ranges come from RFC 1918 and are the reason 192.168.1.x looks familiar. They are guaranteed never to be assigned to anyone on the public internet, so every home and office can reuse them freely. Chapter 5.3.3 explains how a machine with a private address reaches the internet at all.
127.0.0.1 is a whole /8, which means sixteen million loopback addresses. 127.0.0.2 also works and also means this machine. That is a fossil of the classful era — the whole class A block was reserved when one address would have done.
169.254.x.x is the address you have when something is broken. If a machine asks for an address by DHCP and nothing answers, it picks one from this range at random. So seeing a 169.254 address means "DHCP failed", which is a genuinely useful diagnostic.
0.0.0.0 means two different things depending on where it appears, and this trips people up constantly. As a destination in a routing table, 0.0.0.0/0 is the default route — a prefix of length zero matches every address, so it is the fallback when nothing more specific matches. As a bind address for a server, 0.0.0.0 means "listen on every network interface this machine has", as opposed to 127.0.0.1 which means "listen only on loopback, so nothing outside this machine can connect". That distinction is the single most common cause of "my server works locally but nothing can reach it", and Chapter 5.9 covers it at the code level.
7. Longest prefix match: how a router chooses
A router's table holds prefixes, and an address will often match several of them:
10.0.0.0/8 → interface A
10.1.0.0/16 → interface B
10.1.2.0/24 → interface C
0.0.0.0/0 → interface D (the default route)A packet for 10.1.2.55 matches all four. The rule is longest prefix match: the most specific route wins, so it goes out interface C.
The reasoning is hierarchical delegation. /8 says "somewhere in this large region". /24 says "this exact street". More bits means more specific knowledge, and specific knowledge is more likely to be correct. The default route 0.0.0.0/0 has zero prefix bits, so it always loses to anything else — which is precisely what makes it a sensible fallback.
This rule has two consequences worth knowing.
It is why a /32 route overrides everything. Adding a single-host route is how you pin one destination to a specific path, and it is a standard operational tool.
It is why route hijacking works, and BGP security is hard. If an operator advertises a more specific prefix than the legitimate owner — a /24 inside someone's /16 — every router that believes the advertisement will prefer it. Chapter 5.3.2 covers this.
Implementing longest prefix match at line rate is not trivial. A router receiving 100 million packets per second cannot scan a million-entry table per packet. The classic software structure is a trie over the address bits — exactly the structure from Chapter 4.13.4, which is why that chapter named IP routing as the real use of longest-prefix matching. Hardware routers use content-addressable memory that compares against every entry simultaneously.
8. Where addresses come from: DHCP in four steps
Your laptop does not have an IP address burned into it. It asks for one, using DHCP (dynamic host configuration protocol), and the exchange is four messages remembered as DORA:
- Discover — the client broadcasts, from source
0.0.0.0(it has no address yet) to255.255.255.255: "is there a DHCP server?" - Offer — a server replies with a proposed address, mask, gateway and DNS servers.
- Request — the client broadcasts its acceptance. Broadcast, not unicast, so that any other DHCP server that also made an offer learns it was not chosen and can release the address it had held.
- Acknowledge — the server confirms and records the lease, an expiry time after which the address returns to the pool.
The lease is the part people forget. An address is borrowed, not owned. A client renews at half the lease time, and if it disappears without releasing, the address is reclaimed at expiry. This is why a device that has been off for a week may come back with a different address — and why anything that other machines connect to needs either a static address or a DHCP reservation tied to its MAC.
Note that DHCP hands over four things, not just an address: the address, the subnet mask, the default gateway and the DNS servers. Those four are exactly what a machine needs to reach anything, and Chapter 5.5 covers the fourth.
DHCP is also a link-layer broadcast, so it does not cross routers. A network with many subnets needs a DHCP relay on each one, forwarding requests to a central server. In cloud networks the provider does this invisibly, which is why an instance simply has an address when it boots (Chapter 5.10).
What the interviewer will push on
"What does a subnet mask do?" Not "it defines the subnet" — say the operation. It is ANDed with an address to extract the network part, and a machine compares its own network against the destination's to decide whether to send directly or hand the packet to the router. Being able to name the AND is the difference between having read about it and having used it.
"Split a /24 into subnets for 50, 20 and 10 hosts." They are testing whether you round up to powers of two and allow for the two reserved addresses. 50 hosts needs a /26 (62 usable), 20 needs a /27 (30), 10 needs a /28 (14). Then allocate from the largest down so the blocks align: .0/26, .64/27, .96/28. Starting with the smallest produces misaligned blocks that do not fit.
"Why is a /30 only two usable addresses?" Network address and broadcast address are reserved in every subnet. Then volunteer that /31 links exist precisely to reclaim those two on point-to-point links where neither is meaningful.
"A packet matches both a /16 and a /24 route. Which wins?" Longest prefix match — the /24, because a more specific route reflects more specific knowledge. Then connect it: this is why 0.0.0.0/0 works as a default, and why advertising a more specific prefix is how BGP hijacking works.
"What is the difference between binding a server to 127.0.0.1 and to 0.0.0.0?" Loopback only versus every interface. This is asked because it is the actual cause of most "works on my machine, unreachable in the container" incidents.
"Your VM cannot reach the database. Where do you start?" The subnet comparison: are they in the same subnet, and if not is there a route? Then the gateway, then the firewall rules. Starting from the AND operation rather than from guesswork is what a strong answer looks like.
One thing to volunteer: mention that CIDR's real contribution was not flexible subnet sizes but route aggregation — collapsing many prefixes into one advertisement, without which the global routing table would be far beyond what any router could hold. Most people know CIDR as notation; knowing it as a scaling mechanism is the deeper answer.
Recall
- An IPv4 address is one 32-bit number; the split into a network prefix and a host suffix is what lets a router decide direction from the address alone, the way a postcode does.
- The subnet mask is ANDed with an address to extract the network. A machine ANDs its own address and the destination's and compares — same means local (ARP directly), different means send to the gateway.
- CIDR replaced fixed classes, which wasted enormous ranges, and — more importantly — enabled route aggregation, without which the global routing table would be unmanageable.
- Usable hosts is 2^{32-\text{prefix}} - 2; the two reserved are the network address (all host bits 0) and the broadcast address (all host bits 1).
- Two shortcuts: each extra prefix bit halves the subnet, and 256 - \text{last mask octet} gives the block size, so subnets start at multiples of it.
10/8,172.16/12and192.168/16are private;169.254.x.xmeans DHCP failed;0.0.0.0/0is the default route as a destination and "every interface" as a bind address.- Longest prefix match picks the most specific route, which is why the default route always loses and why advertising a more specific prefix hijacks traffic.
- DHCP is Discover–Offer–Request–Acknowledge and hands over four things: address, mask, gateway and DNS servers, on a lease.
Self-test: AND 10.1.5.9 with 255.255.252.0 and give the network · How many usable hosts in a /27, and why not 2^5? · Split 192.168.4.0/24 for 50, 20 and 10 hosts, in the right order · Which route wins for 10.1.2.55 given a /8, a /16 and a /24 that all match? · What does a 169.254.x.x address tell you has gone wrong? · Why must the DHCP Request be a broadcast?
Next: 5.3.2 follows a single packet from your laptop to a server on another continent, showing what each router actually does to it, how the routes got into those routers in the first place, and why the whole system runs on operators trusting each other's announcements.