๐งฎ Subnetting and CIDR Without the Pain
Subnetting and CIDR Without the Pain
Subnetting has a reputation for being hard. It is not โ it is one idea (a boundary inside a 32-bit number) plus a table of powers of two that you will have memorised after about twenty minutes of practice. Everything else follows: firewall rules, routing tables, cloud VPC design, and reading a log line and knowing instantly whether an address is internal.
The binary you actually need
An IPv4 address is 32 bits written as four 8-bit octets. Inside an octet the bit values are always 128 64 32 16 8 4 2 1. That is the whole refresher:
192 . 168 . 10 . 0
11000000.10101000.00001010.00000000
^128+64 ^128+32+8 ^8+2
A prefix length โ the /24 in 192.168.10.0/24 โ is simply how many leading bits are fixed. Those bits identify the network; the remaining bits identify hosts inside it. The subnet mask is the same information written as an address: a run of ones followed by a run of zeros.
/24 11111111.11111111.11111111.00000000 = 255.255.255.0 โ 8 host bits
/26 11111111.11111111.11111111.11000000 = 255.255.255.192 โ 6 host bits
The three addresses that define a subnet
- Network address โ all host bits zero. It names the subnet and is never assigned to an interface.
- Broadcast address โ all host bits one. Traffic to it reaches every host on the subnet, so it is also not assignable.
- Usable hosts โ everything in between:
2(32 โ prefix) โ 2.
The arithmetic is bitwise. Network = address AND mask. Broadcast = network OR the inverted mask. The shortcut that makes it mental arithmetic: the block size is 256 โ (last non-zero mask octet). For a /26, that is 256 โ 192 = 64, so subnets start at 0, 64, 128 and 192.
Worked example: 192.168.10.0/24 split into four /26s
Borrowing two host bits from a /24 gives 2ยฒ = 4 subnets, each with 2โถ = 64 addresses and 62 usable hosts. Mask 255.255.255.192 throughout.
| Subnet | Network | First host | Last host | Broadcast |
|---|---|---|---|---|
| 192.168.10.0/26 | 192.168.10.0 | 192.168.10.1 | 192.168.10.62 | 192.168.10.63 |
| 192.168.10.64/26 | 192.168.10.64 | 192.168.10.65 | 192.168.10.126 | 192.168.10.127 |
| 192.168.10.128/26 | 192.168.10.128 | 192.168.10.129 | 192.168.10.190 | 192.168.10.191 |
| 192.168.10.192/26 | 192.168.10.192 | 192.168.10.193 | 192.168.10.254 | 192.168.10.255 |
Read the pattern rather than memorising the rows: each network address is the previous broadcast plus one, the first host is network + 1, and the broadcast is the next network โ 1. The intermediate step of splitting the same /24 into two /25s gives 192.168.10.0/25 (hosts .1โ.126, broadcast .127) and 192.168.10.128/25 (hosts .129โ.254, broadcast .255) โ halving again gives the four rows above.
You do not have to split evenly. VLSM means using different prefix lengths inside the same block: a /25 for 100 desktops, a /28 for 12 servers, and /30s or /31s for point-to-point links. Also note that "subnet zero" and the all-ones subnet are perfectly usable on any equipment made this century; the old rule against them is a relic.
The table worth memorising
| Prefix | Mask | Addresses | Usable hosts |
|---|---|---|---|
| /16 | 255.255.0.0 | 65,536 | 65,534 |
| /17 | 255.255.128.0 | 32,768 | 32,766 |
| /18 | 255.255.192.0 | 16,384 | 16,382 |
| /19 | 255.255.224.0 | 8,192 | 8,190 |
| /20 | 255.255.240.0 | 4,096 | 4,094 |
| /21 | 255.255.248.0 | 2,048 | 2,046 |
| /22 | 255.255.252.0 | 1,024 | 1,022 |
| /23 | 255.255.254.0 | 512 | 510 |
| /24 | 255.255.255.0 | 256 | 254 |
| /25 | 255.255.255.128 | 128 | 126 |
| /26 | 255.255.255.192 | 64 | 62 |
| /27 | 255.255.255.224 | 32 | 30 |
| /28 | 255.255.255.240 | 16 | 14 |
| /29 | 255.255.255.248 | 8 | 6 |
| /30 | 255.255.255.252 | 4 | 2 |
| /31 | 255.255.255.254 | 2 | 2 (point-to-point, RFC 3021) |
| /32 | 255.255.255.255 | 1 | 1 (single host route) |
/31 is the exception to the minus-two rule: RFC 3021 allows both addresses on a point-to-point link, because a two-node link has no need for a broadcast address. Check any of these rows in the subnet calculator โ, and use the CIDR toolkit โ to summarise or split blocks and test whether an address falls inside one.
Ranges to recognise on sight
| Range | Name | Reference |
|---|---|---|
| 10.0.0.0/8 | Private | RFC 1918 |
| 172.16.0.0/12 | Private โ 172.16.0.0 to 172.31.255.255, not all of 172.x | RFC 1918 |
| 192.168.0.0/16 | Private | RFC 1918 |
| 100.64.0.0/10 | Carrier-grade NAT (100.64.0.0 to 100.127.255.255) | RFC 6598 |
| 169.254.0.0/16 | Link-local โ self-assigned when DHCP fails | RFC 3927 |
| 127.0.0.0/8 | Loopback | RFC 1122 |
| 224.0.0.0/4 | Multicast | RFC 1112 |
| 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24 | Documentation โ safe to use in examples | RFC 5737 |
Seeing 169.254.x.x on an interface means DHCP failed. Seeing 100.64.x.x as your "public" address means your ISP has put you behind CGNAT. Both diagnoses come free once you know the ranges.
IPv6: different maths, easier answers
IPv6 addresses are 128 bits, written as eight groups of four hex digits. Because each hex digit is exactly 4 bits, prefix lengths on multiples of 4 line up with digit boundaries โ which is why real-world IPv6 designs stick to nibble boundaries: /48, /52, /56, /60, /64.
Notation is standardised by RFC 5952: lowercase hex, leading zeros in a group suppressed, and one run of all-zero groups replaced by ::. The double colon may appear only once, must be used on the longest run of zero groups (the leftmost such run if there is a tie), and must not be used to shorten a single zero group.
2001:0db8:0000:0000:0000:ff00:0042:8329 full form
2001:db8::ff00:42:8329 RFC 5952 canonical form
2001:db8:0:0:0:ff00:42:8329 legal, but not canonical
2001:db8::acad::1 INVALID โ two "::" is ambiguous
The structural difference is that IPv6 subnetting is not about conserving addresses. A LAN is a /64, always. That is not a convention someone picked for tidiness: stateless address autoconfiguration (SLAAC) builds an address from a 64-bit prefix plus a 64-bit interface identifier, so a longer prefix silently breaks SLAAC and privacy addressing. A site typically receives a /48 or /56 and carves /64s out of it โ a /48 holds 65,536 of them, one per VLAN, with no arithmetic beyond incrementing the fourth group:
2001:db8:acad::/48 the site allocation
2001:db8:acad:0000::/64 VLAN 0 (management)
2001:db8:acad:0001::/64 VLAN 1 (users)
2001:db8:acad:0002::/64 VLAN 2 (servers)
โฆ up to 2001:db8:acad:ffff::/64
There is no broadcast address in IPv6 โ its jobs are done by multicast โ and no "minus two" for hosts. The all-zeros interface identifier in a subnet is reserved as the subnet-router anycast address (RFC 4291), so a /64 gives you 264 addresses minus a handful of reserved ones, which is not a number anyone needs to compute. Worth recognising: fe80::/10 link-local (always present on every interface), fc00::/7 unique local โ in practice fd00::/8 with a randomly generated 40-bit global ID โ and 2001:db8::/32, the documentation range used throughout this page (RFC 3849). Work an IPv6 prefix in the calculator โ to see expansion, compression and subnet counts side by side.
- The prefix length is the count of fixed leading bits. Mask, block size and host count all fall out of it.
- Block size = 256 โ last non-zero mask octet. For /26 that is 64, so subnets begin at .0, .64, .128, .192.
- Usable hosts = 2(32โprefix) โ 2, except /31 (both usable, RFC 3021) and /32 (a host route).
- Recognise 10/8, 172.16/12, 192.168/16 (private), 100.64/10 (CGNAT) and 169.254/16 (DHCP failed) instantly.
- IPv6 LANs are /64 because SLAAC needs a 64-bit interface identifier. Design on nibble boundaries and stop counting hosts.