Subnet masks explained
255.255.255.0 looks arbitrary until you see it in binary. Then it is obvious and stays obvious.
A mask is a line, written awkwardly
A subnet mask says exactly what a CIDR prefix says: where the network part of an address ends and the host part begins. It says it in dotted decimal instead of a count, which is why it looks like a magic number.
So 255.255.255.0 is 24 ones followed by 8 zeros, which is a /24. They are two spellings of one thing, and modern tooling accepts either.
The nine values, which is all you need to memorize
Because a mask is always ones followed by zeros, an octet cannot hold an arbitrary number. There are exactly nine possibilities, and recognizing them on sight removes most of the work.
| Decimal | Binary | Ones | Block size in that octet |
|---|---|---|---|
0 | 00000000 | 0 | 256 |
128 | 10000000 | 1 | 128 |
192 | 11000000 | 2 | 64 |
224 | 11100000 | 3 | 32 |
240 | 11110000 | 4 | 16 |
248 | 11111000 | 5 | 8 |
252 | 11111100 | 6 | 4 |
254 | 11111110 | 7 | 2 |
255 | 11111111 | 8 | 1 |
The last column is just 256 minus the decimal value. For 255.255.255.192, that is 256 minus 192 = 64, so blocks are 64 addresses and start at .0, .64, .128, .192. This is the fastest route to an answer under time pressure and it is not a hack: it is the same arithmetic as counting host bits.
A mask with anything else in it is invalid. 255.255.255.100 is not a mask, because 100 is 01100100 in binary and the ones are not contiguous. If you see one, something has been typed wrong.
Binary without a calculator
You need this rarely, and when you do you need it quickly. An octet is eight bit positions with fixed values:
128 64 32 16 8 4 2 1 192 = 128 + 64 = 1 1 0 0 0 0 0 0 130 = 128 + 2 = 1 0 0 0 0 0 1 0 168 = 128 + 32 + 8 = 1 0 1 0 1 0 0 0 10 = 8 + 2 = 0 0 0 0 1 0 1 0
The method is greedy and takes seconds: start at 128, subtract it if it fits, move right, repeat. Going the other way, add up the positions holding a one.
Hex, for IPv6
IPv6 is written in hexadecimal, where each digit is exactly four bits. That one-to-one mapping is the reason hex is used at all, and it makes conversion mechanical rather than arithmetic.
0 = 0000 4 = 0100 8 = 1000 c = 1100 1 = 0001 5 = 0101 9 = 1001 d = 1101 2 = 0010 6 = 0110 a = 1010 e = 1110 3 = 0011 7 = 0111 b = 1011 f = 1111 db8 = 0000 1101 1011 1000
Split the binary into groups of four from the right, and read each group off the table. No division, no remainders.
Wildcard masks, which are backwards on purpose
Access lists on Cisco equipment and some firewall syntaxes use a wildcard mask, which is a subnet mask with every bit flipped. A zero means "this bit must match" and a one means "ignore this bit".
subnet mask 255.255.255.192
wildcard mask 0. 0. 0. 63 255 minus each octet
Subtract each octet from 255 and you have it. The reason for the inversion is historical, and the practical consequence is that a wildcard does not have to be contiguous, so it can express things a subnet mask cannot, such as "every odd-numbered address".
Reading a mask you have been handed
Given 255.255.240.0, what do you have?
- Two full octets of 255 gives 16 bits, plus 240 which is four ones, so
/20. - Host bits are 32 minus 20 = 12, so 212 = 4,096 addresses, 4,094 usable.
- The interesting octet is the third, and 256 minus 240 = 16, so blocks start at
x.x.0.0,x.x.16.0,x.x.32.0and so on.
That is the entire procedure, and it is the same three steps for any mask you will ever be given.