Why this matters
Someone asks "is 10.0.3.200 inside 10.0.3.192/26?" or "how big is a /20?". Every networking question in the next two chapters comes down to that kind of check. Tools can answer it, but you need to understand the answer - and the trick is that an IP address is just a 32-bit number.
What you need to know already: Ch 1 · Network identity (1.9) - your box has the address 10.64.0.2/24 on the interface enp0s1, and /24 marks which part is "the network". This lesson explains what that /24 really means.
A few words first
- A bit is one binary digit: 0 or 1. Binary is writing numbers with only those two digits.
- An IPv4 address (the "IP address" you met in Ch 1; v4 = version 4) is 32 bits long. We write it as four numbers separated by dots.
- Each of those four numbers is an octet: 8 bits, so a value from 0 to 255.
Four octets, 32 bits
10 .64 .0 .2
00001010 .01000000 .00000000 .00000010
The top line is how you normally write it. The bottom line is the same address in bits. Inside one octet, each bit position has a value. Left to right:
128 64 32 16 8 4 2 1
To turn a number into bits, walk left to right and take each value that still fits. For 168: 128 fits (40 left), 64 does not, 32 fits (8 left), 16 does not, 8 fits (0 left). So 168 is 10101000. Do a few until it is boring:
0 = 00000000 128 = 10000000 192 = 11000000
64 = 01000000 224 = 11100000 240 = 11110000
100 = 01100100 248 = 11111000 252 = 11111100
255 = 11111111 254 = 11111110
The right-hand column is worth knowing by heart, for a reason you will see in a minute.
The network part and the host part
An address has two parts:
- the network part (the first bits) - which network the machine is on, like the street name;
- the host part (the remaining bits) - which machine on that network, like the house number. These are the host bits.
A netmask marks where the split is: 1s over the network bits, 0s over the host bits. A prefix length (the /24) just counts the 1s. They are two spellings of the same fact:
255.255.255.0 = 11111111.11111111.11111111.00000000 = /24
255.255.255.192 = 11111111.11111111.11111111.11000000 = /26
255.255.240.0 = 11111111.11111111.11110000.00000000 = /20
255.255.0.0 = 11111111.11111111.00000000.00000000 = /16
A mask is always a run of 1s followed by a run of 0s. That is why a mask octet can only be one of the values in the right-hand column above (plus 0).
/26 is 24 + 2: three full octets of 1s and two more bits. Linux uses the prefix form. You still meet dotted masks in older configs and on Windows.
$ ip -4 -br a
lo UNKNOWN 127.0.0.1/8
enp0s1 UP 10.64.0.2/24
ip -4 -br a: show addresses (a), IPv4 only (-4), brief, one line per interface (-br). Columns: interface name, state, address/prefix. 10.64.0.2/24 says two things: this interface's address, and that the first 24 bits (10.64.0) are the network it sits on.
Network address = address AND mask
AND is a bit-by-bit rule: the result is 1 only where both inputs are 1. Doing an AND with the mask keeps the network bits and forces every host bit to
- What is left is the network address - the name of the whole network:
address 10.0.3.200 00001010.00000000.00000011.11001000
mask /26 11111111.11111111.11111111.11000000
AND 00001010.00000000.00000011.11000000 = 10.0.3.192
So 10.0.3.200/26 lives in the network 10.0.3.192/26.
The broadcast address is the opposite: every host bit set to 1. It means "everyone on this network" (a message sent to it reaches every machine there):
network 10.0.3.192 ...00000011.11 000000
host bits all 1 ...00000011.11 111111 = 10.0.3.255
Every address strictly between the two is a usable host address: .193 to .254.
Let ipcalc show you the bits
ipcalc is a small calculator for exactly this. You install it with apt, like tree in Ch 1. It prints the binary with a space where the network part ends, which is the whole point:
$ sudo apt install -y ipcalc
$ ipcalc 10.0.3.200/26
Address: 10.0.3.200 00001010.00000000.00000011.11 001000
Netmask: 255.255.255.192 = 26 11111111.11111111.11111111.11 000000
Wildcard: 0.0.0.63 00000000.00000000.00000000.00 111111
=>
Network: 10.0.3.192/26 00001010.00000000.00000011.11 000000
HostMin: 10.0.3.193 00001010.00000000.00000011.11 000001
HostMax: 10.0.3.254 00001010.00000000.00000011.11 111110
Broadcast: 10.0.3.255 00001010.00000000.00000011.11 111111
Hosts/Net: 62 Class A, Private Internet
Read it line by line:
- Address - what you typed, split at bit 26.
- Netmask - 26 ones.
= 26is the prefix. - Wildcard - the mask with every bit flipped (1s over the host bits). Some firewalls and network gear want this form:
0.0.0.63means "the last six bits can be anything". - Network - left of the space kept, right of it all zeros.
- HostMin / HostMax - the first and last address you can give a machine.
- Broadcast - host bits all ones.
- Hosts/Net - how many machines fit: 2^6 - 2 = 62 (six host bits, minus the network and broadcast addresses).
- "Class A" is ipcalc being old-fashioned (address classes stopped mattering in 1993). "Private Internet" is useful: the next lesson explains it.
When the split falls inside an octet
This is the only case that needs thought. /20 = 16 + 4, so the split is four bits into the third octet:
$ ipcalc -b 172.20.77.9/20
Address: 172.20.77.9
Netmask: 255.255.240.0 = 20
Wildcard: 0.0.15.255
=>
Network: 172.20.64.0/20
HostMin: 172.20.64.1
HostMax: 172.20.79.254
Broadcast: 172.20.79.255
Hosts/Net: 4094 Class B, Private Internet
(-b = brief: skip the binary columns.) 77 in binary is 0100 1101. Keep the top four bits (0100 = 64), zero the rest: the third octet of the network is
- The mask octet 240 is
1111 0000; its lowest 1 is worth 16, so the network
is 16 wide in that octet: 64 to 79.
That width is the block size, and there is a shortcut: 256 minus the mask octet. The next lesson builds on it:
mask octet 240 -> block 16 mask octet 192 -> block 64
mask octet 248 -> block 8 mask octet 128 -> block 128
mask octet 252 -> block 4 mask octet 224 -> block 32
The mistake everyone makes once
Writing a network with host bits set:
10.0.3.200/26 <- an address inside a network: right on an interface
10.0.3.192/26 <- the network itself: what a route or a firewall rule wants
Some tools quietly fix it, some reject it. Linux fixes it silently, which surprises you later. A route is a line in the kernel's table that says "to reach this network, go this way" (routes get their own lesson, 8.11); here is one added with host bits set:
$ sudo ip route add 10.0.3.200/26 via 10.64.0.1
$ ip route | grep 10.0.3
10.0.3.192/26 via 10.64.0.1 dev enp0s1
You typed .200, the kernel stored .192. If you later try to delete "the route you typed", it is not there under that name.
Special addresses worth recognising
0.0.0.0/0 "every address" - the default route, or "any" in a firewall
0.0.0.0 as a listen address: every interface on this box
127.0.0.0/8 loopback (this box talking to itself). 127.0.0.53 is the
local DNS helper (8.16); 127.0.1.1 is Ubuntu's alias for
its own hostname in /etc/hosts
169.254.0.0/16 link-local: a machine gives itself one of these when DHCP
failed - so seeing one means "no DHCP answer"
255.255.255.255 broadcast to the local network
169.254.169.254 deserves a note: cloud providers answer on that one address from inside every virtual machine they rent you, with details about the machine and even login tokens. Anything on the machine that can make a web request can read it, so security teams care who can reach it.
Later (Ch 16): blocking 169.254.169.254 for applications is a standard rule in shared clusters.
What you can now do
- Convert an octet to binary and back.
- Read
/26as a netmask, and find the network and broadcast of an address. - Read every line of
ipcalcoutput.