4.9 KiB
Understanding IP Addresses, Subnet Masks, and CIDR
Disclaimer: Most, if not all, information in this article applies to both
IPv4 and IPv6. However, an IPv6 address is 4
times the size of an IPv4
address, which is 4 times the math the author is willing to do. Due to this, all
examples will be in the context of IPv4.
Cloudflare owns the number 16843009
. At least, as far as networks are
concerned they do. You'd be more likely to recognize it in the form 1.1.1.1
.
So how does the number 16843009
relate to the IP address 1.1.1.1
? Let's
start with what an IP address really is.
An IPv4 address is normally expressed as A.B.C.D
, where each letter represents
an octet in decimal form. Since there are 4
octets, an IPv4 address is exactly
32
-bits long. If you take the IP address 10.42.7.19
and write it in binary
form, you get 00001010.00101010.00000111.00010011
. This is referred to as a
bit string, which you'll notice contains exactly 32
bits as expected. Since
an octet will always be 8
bits, the dot separators aren't needed in a bit
string. This means that the bit string should really be written as
00001010001010100000011100010011
. These bit strings can also be referred to as
32
-bit integers. In other words, they are whole numbers that take up exactly
32
bits of memory. The example bit string in this case could be written in
decimal form as the number 170526483
. We now have 3 ways to describe the same
IP address:
10.42.7.19
00001010001010100000011100010011
170526483
You'll likely never need to write an IP address in any other form other than the first one (commonly referred to as dotted decimal form), so why is this important? For computers, it is fast and straight-forward to operate on IP addresses when they are bit strings. Combined with an important tool called a subnet mask, they can quickly compute the start and end of a range an IP address is in.
A subnet mask is a 32-bit string, similar to an IPv4 address, with the
additional constraint that it must be a series of 1
bits immediately followed
by a series of 0
bits. This means that as soon as the first 0
bit appears,
all remaining bits must be 0
. The following bit string is a valid subnet mask:
11111111111111111111111100000000
. If you split up the 32 bits into 4 groups of
octets, and convert those groups to decimal form, you get 255
, 255
, 255
,
and 0
, written as 255.255.255.0
. To drive the point home, both forms
represent the same subnet mask:
11111111111111111111111100000000
255.255.255.0
Another way of writing a subnet mask is CIDR notation, which is of the form
/N
, where N
represents the number of 1
bits at the beginning of the mask.
This means that writing 10.42.7.19/24
indicates you have the IP address
10.42.7.19
with the subnet mask of 11111111111111111111111100000000
(or
255.255.255.0
as we determined above). You'll notice the bit string contains
24 leading 1
bits, the value of N
.
So how does a computer use a subnet mask to obtain information from an IP
address? For finding the first IP in a range defined by a subnet, the equation
is very straightforward. Take the given IP address and subnet mask, and perform
a bitwise AND on them. For example, using the IP address above, 10.42.7.19
,
and the subnet mask 255.255.255.0
, the equation would look like this:
00001010001010100000011100010011 (10.42.7.19)
& 11111111111111111111111100000000 (255.255.255.0)
--------------------------------
00001010001010100000011100000000 (10.42.7.0)
So we now know that the start of the range is 10.42.7.0
. With this
information, finding the end of the range is just as easy. First, compute the
inverse of the subnet mask. This can be done using a bitwise NOT:
~ 11111111111111111111111100000000 (255.255.255.0)
--------------------------------
00000000000000000000000011111111 (0.0.0.255)
Finally, take the inverted subnet mask and the first IP address in the range, and apply a bitwise OR to them:
00001010001010100000011100000000 (10.42.7.0)
| 00000000000000000000000011111111 (0.0.0.255)
--------------------------------
00001010001010100000011111111111 (10.42.7.255)
Putting this all together, we are given the IP address 10.42.7.19
and the
subnet mask 255.255.255.0
, which can be rewritten as 10.42.7.19/24
. The
range this IP address belongs to (with that subnet mask) comes out to
10.42.7.0-10.42.7.255
. What makes these operations even more useful is they
can be applied to any IP address in the range and get the same answer. In
conclusion:
- IPv4 addresses are 32-bit integers.
- Subnet masks define the range an IP address is in.
- The first IP address in the range can be found by applying a bitwise AND to the given IP address and the subnet mask.
- The last IP address in the range can be found by applying a bitwise NOT to the subnet mask, then a bitwise OR to the inverted subnet mask and the first IP address.