IP Subnetworking mini-HOWTO: CIDR, netmasks and IPv6 /64s explained
A subnet is a block of IP addresses that share the same leading bits. The number after the slash, as in 192.168.10.0/24, says how many bits are fixed; the rest number the hosts. Once you can turn a prefix into a block size, every subnetting question becomes simple arithmetic. This page shows how, with worked examples and the Linux tools that check your answers.
Addresses, prefixes and masks
An IPv4 address is 32 bits, written as four numbers from 0 to 255 (“dotted quad”). A prefix of /24 means the first 24 bits are the network part and the last 8 bits are the host part. The same thing written as a netmask has ones for the network bits: /24 is 255.255.255.0.
In every IPv4 subnet, the first address (all host bits 0) is the network address and the last (all host bits 1) is the broadcast address. Neither can be given to a host. So a subnet with h host bits has 2ʰ addresses and 2ʰ − 2 usable host addresses.
| Prefix | Netmask | Addresses | Usable hosts |
|---|---|---|---|
| /8 | 255.0.0.0 | 16,777,216 | 16,777,214 |
| /16 | 255.255.0.0 | 65,536 | 65,534 |
| /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 links only) |
| /32 | 255.255.255.255 | 1 | 1 (a single host route) |
A /31 is a special case: on a link with exactly two ends, both addresses can be used as host addresses and there is no broadcast address. Both ends must support it; current Linux kernels accept a /31 address.
The block-size method
You do not need binary for everyday subnetting. Find the octet where the mask is not 255 or 0 (the “interesting” octet) and work there:
- Block size = 256 − the mask value in that octet.
- Network address: round the address down to a multiple of the block size in that octet.
- Broadcast address: network address + block size − 1 in that octet.
- Hosts: everything between them.
Example 1: which subnet is 192.168.10.77/26 in?
- /26 is 255.255.255.192. The interesting octet is the fourth.
- Block size: 256 − 192 = 64. Subnets start at .0, .64, .128 and .192.
- 77 rounded down to a multiple of 64 is 64, so the network is 192.168.10.64.
- Broadcast: 64 + 64 − 1 = 192.168.10.127.
- Hosts: 192.168.10.65 to 192.168.10.126, which is 64 − 2 = 62 hosts.
Check it with ipcalc (Debian and Ubuntu package ipcalc; -n turns off colors):
$ ipcalc -n -b 192.168.10.77/26
Address: 192.168.10.77
Netmask: 255.255.255.192 = 26
Wildcard: 0.0.0.63
=>
Network: 192.168.10.64/26
HostMin: 192.168.10.65
HostMax: 192.168.10.126
Broadcast: 192.168.10.127
Hosts/Net: 62 Class C, Private Internet
Without -b, ipcalc also prints each address in binary, which shows exactly where the network bits end. Fedora and RHEL ship a different program under the same name, with different options and output; sipcalc or Python (below) work the same everywhere.
Example 2: a /22 across octets
10.20.0.0/22 has the mask 255.255.252.0, so the interesting octet is the third. Block size: 256 − 252 = 4. The network covers 10.20.0.0 to 10.20.3.255: 4 × 256 = 1,024 addresses, of which 1,022 are usable (10.20.0.1 to 10.20.3.254). Note that 10.20.1.0 and 10.20.2.255 are ordinary host addresses here.
$ sipcalc 10.20.0.0/22
...
Network mask - 255.255.252.0
Broadcast address - 10.20.3.255
Addresses in network - 1024
Network range - 10.20.0.0 - 10.20.3.255
Usable range - 10.20.0.1 - 10.20.3.254
Splitting a network
Example 3: four equal subnets
You have 192.168.10.0/24 and need four separate LANs. Four subnets need 2 extra network bits (2² = 4), so each is a /26 with 62 hosts: 192.168.10.0/26, .64/26, .128/26 and .192/26. ipcalc does this when you give a second mask:
ipcalc -n -b 192.168.10.0/24 /26
Example 4: subnets of different sizes
Real networks are uneven. Say you need room for 100 office PCs, 50 Wi-Fi devices, 20 servers and one router-to-router link. Give each group the smallest block that fits, and allocate the biggest first so the blocks line up:
| Need | Prefix (usable hosts) | Subnet | Host range |
|---|---|---|---|
| 100 PCs | /25 (126) | 192.168.10.0/25 | .1 – .126 |
| 50 Wi-Fi | /26 (62) | 192.168.10.128/26 | .129 – .190 |
| 20 servers | /27 (30) | 192.168.10.192/27 | .193 – .222 |
| Link | /30 (2) | 192.168.10.224/30 | .225 – .226 |
That leaves 192.168.10.228/30, .232/29 and .240/28 free for later. ipcalc -n -b 192.168.10.0/24 -s 100 50 20 2 prints the same plan, including the unused blocks. Always leave growth room: the 100-PC subnet is already 79% full on day one (100 of 126).
Is this address on my subnet?
A host decides whether to send a packet directly or to its gateway by comparing network parts. With 192.168.10.77/26, the address 192.168.10.130 is in a different block (.128–.191), so the packet goes to the gateway. If one machine has the wrong mask, say /24 instead of /26, it thinks .130 is local, sends ARP requests that nobody answers, and the connection fails. The routing table shows what the kernel believes:
$ ip -br addr show enp3s0
enp3s0 UP 192.168.10.77/26
$ ip route
default via 192.168.10.65 dev enp3s0
192.168.10.64/26 dev enp3s0 proto kernel scope link src 192.168.10.77
Python's standard library answers the same questions on any distribution:
$ python3 -c 'import ipaddress as i; n = i.ip_interface("192.168.10.77/26").network; print(n, n.broadcast_address, i.ip_address("192.168.10.130") in n)'
192.168.10.64/26 192.168.10.127 False
Classes are history; special ranges are not
Old guides talk about class A, B and C networks (/8, /16 and /24 on fixed boundaries). Classless Inter-Domain Routing (CIDR) replaced that system from 1993 on, and today any prefix length can be used. ipcalc still prints a “Class” label, but it has no effect on routing.
Some ranges have fixed meanings:
- Private (RFC 1918): 10.0.0.0/8, 172.16.0.0/12 (172.16.0.0 to 172.31.255.255) and 192.168.0.0/16. Use them inside your networks; they are not routed on the Internet.
- Shared address space: 100.64.0.0/10, used by providers for carrier-grade NAT. Do not use it for your LAN.
- Link-local: 169.254.0.0/16. A machine gives itself one of these when DHCP fails, which is a useful clue.
- Loopback: 127.0.0.0/8.
- Documentation: 192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24, safe for examples.
IPv6 subnets
IPv6 addresses are 128 bits, written as eight groups of four hex digits (2001:0db8:abcd:0012:0000:0000:0000:0001, shortened to 2001:db8:abcd:12::1). The rule for LANs is simple: every subnet is a /64. The last 64 bits are the interface identifier, and automatic address configuration (SLAAC) only works with 64-bit identifiers. You do not count hosts in IPv6; a /64 is always big enough.
The planning question is how many /64s you have. A provider typically gives a site a /48 or a /56:
- /4865,536 subnets of /64 (2⁶⁴⁻⁴⁸ = 2¹⁶)
- /56256 subnets of /64 (2⁸), common for homes
- /64one LAN
Example 5: numbering LANs from a /56
With 2001:db8:abcd:ff00::/56, the fourth group runs from ff00 to ffff, giving 256 LANs: 2001:db8:abcd:ff00::/64, 2001:db8:abcd:ff01::/64, and so on up to 2001:db8:abcd:ffff::/64. A tidy habit is to match the IPv4 plan: VLAN 10 gets ff0a, VLAN 20 gets ff14. sipcalc lists the subnets:
$ sipcalc 2001:db8:abcd:ff00::/56 -S 64 | head -6
-[ipv6 : 2001:db8:abcd:ff00::/56] - 0
[Split network]
Network - 2001:0db8:abcd:ff00:0000:0000:0000:0000 -
2001:0db8:abcd:ff00:ffff:ffff:ffff:ffff
Network - 2001:0db8:abcd:ff01:0000:0000:0000:0000 -
Other IPv6 ranges to know: fe80::/10 is link-local (every interface has one), fc00::/7 holds unique local addresses (the IPv6 counterpart of private ranges; in practice fd00::/8), and 2001:db8::/32 is for documentation.
Common mistakes
- Giving a host the network or broadcast address (.64 or .127 in example 1).
- Mismatched masks on the same segment: one host on /24, another on /26. Some traffic works, some does not.
- Overlapping subnets: 192.168.10.0/25 and 192.168.10.64/26 overlap. Check every new block against the plan.
- Using a prefix longer than /64 on an IPv6 LAN: SLAAC stops working, and clients that rely on it alone get no IPv6 address.
- Picking the same private range as a VPN or the ISP modem, which breaks routing between them. Choose less common ranges such as 10.47.0.0/16 for your own networks.
Sources
- RFC 4632: Classless Inter-domain Routing (CIDR)
- RFC 1918: Address allocation for private internets
- RFC 3021: Using 31-bit prefixes on IPv4 point-to-point links
- RFC 6890: Special-purpose IP address registries
- RFC 6177: IPv6 address assignment to end sites
- RFC 7421: Analysis of the 64-bit boundary in IPv6 addressing
- ipcalc(1), Debian 13 manual pages
- sipcalc(1), Debian 13 manual pages
- ip-route(8), man7.org
The ipcalc (0.51) and sipcalc (1.1.6) output on this page was produced on Debian 13.