network

If we think of network as a big region in which we have a lot of houses (analogous to devices in the network), subnets are just smaller sub-regions inside the big region. Houses are separated according to those sub-regions, which determines how they can talk to each other. This is the basic idea of subnet. Given two IP addresses, we want to first deterime whether they belong to the same subnet before worrying about the communication between them. It is like posting service in our daily life – given two house addresses and a letter that we want to send from house A to house B, we may need to first check the two addresses and figure out whether they are actually in the same neighborhood by checking the city, ZIP code, and street name, etc. If they do belong the same neighborhood, the communication is straightforward and if not, we need to go through post offices. The situation for sure can become more complicated – for example, we may want to mail a letter from our house to another location in another country, in which case the whole communication chain will become way more complicated. However, down to the very first step, still we need to check whether the two given addresses or IP addresses belong to the same neighborhood or subnet, anyhow. This is where the subnet mask comes to help and in this post, I will be writing down my understanding of how the subnet mask works with several simple examples and I hope the idea can be delivered clearly.

First, let’s start with the simplest example – the subnet mask of 255.255.255.0, which, in the CIDR (Classless Inter-Domain Routing) [1], is written as /24, inferring that the first 24 bits of the IP address is used for the network address. Here, it should be mentioned that for a given IP address, we can figure out its network part and the actual address part. The network part tells which subnet that the IP address belongs to and the actual address part is attached to devices and used for telling the address of the device in the subnet network. The subnet mask is just used for figuring out the network part from the IP address. The reason why /24 is used for naming the subnet mask is because in its binary form, the subnet mask example given here can be written as,

11111111.11111111.11111111.00000000

in which all the first three parts, i.e., 11111111.11111111.11111111, are used for labeling the network address (we will see what this means soon) and in total there are 24 bits there (why we need the / there will also become clear soon). Let’s assume two IP addresses 192.168.2.11 and 192.168.2.111 and try to apply the subnet mask to both and see what we get. What we mean by ‘apply’ here is we are going to perform the bit-by-bit AND operation. Specifically, we first write both the subnet mask and the IP address in their binary form,

255.255.255.0 => 11111111.11111111.11111111.00000000
192.168.2.11 => 11000000.10101000.00000010.00001011

Operating the two with the bit-by-bit AND operation yields (1 AND 1 = 1, 1 AND 0 = 0, 0 AND 1 = 0, 0 AND 0 = 0),

11000000.10101000.00000010.00000000 = 192.168.2.0

With the same approach, we apply the subnet mask to the other IP address, yielding,

11000000.10101000.00000010.00000000 = 192.168.2.0

Then we can clearly see that by applying the subnet mask to both, we arrive at the same result 192.168.2.0. In fact, we can pick up any IP addresses that fall into the range 192.168.2.0 - 192.168.2.255 and apply the subnet mask here, and we will always get back the same result 192.168.2.0. Then we know why and how the subnet mask is useful – it gives us a way to figure out whether IP addresses belong to the same subnet. We simply apply the subnet mask to any IP addresses we want to check following exactly the way as described here, and we check the resulted address and compare across. If the resulted addresses are the same, they belong to the same subnet, and vice versa. The resulted address, e.g., 192.168.2.0 here in the example, is the network address. Further, since the address 192.168.2.0 will be used to label the subnet, this specific address will then not be used for devices in the IP address block. Also, the last IP address 192.168.2.255 is usually reserved for broadcasting purposes. Therefore, IP addresses ranging from 192.168.2.1 to 192.168.2.254 in this block can be assigned to devices, and again, all those addresses in this range belong to the network 192.168.2.0.

Having all the explanations here, we can understand why usually the subnet is written as something like 192.168.2.0/24 – the first part 192.168.2.0 is just the network address and the /24 refers to the subnet mask and now we see why / is being used in /24 mentioned earlier – it is simply just a separator in the notation like 192.168.2.0/24 and when we separate out the subnet maks part, we keep the separator for the sake of clarity. Such a notation is called CIDR notation [1].

Let’s now take a bit more complicated subnet mask, 255.255.252.0,

255.255.252.0 = 11111111.11111111.11111100.00000000

First, with such a subnet mask, the first 22 bits (corresponding to the number of those 1’s in the subnet mask) of an IP address will always be used for the network address. The reason is that values in the first 22 bits of the IP address will be kept as is, with the binary AND operations, and therefore, if two IP addresses are different in the first 22 bits, we know that the resulted network address will be different between them. Accordingly, they just belong to different subnets. By comparison, the last 10 bits will not be used for the network address since no matter how different two IP addresses are in those 10 bits, the binary AND operation will always zero them out anyhow, resulting exactly the same last 10 bits of the address. The subnet with the mask 255.255.252.0 is accordingly named as /22.

Now let’s take some specific IP addresses to see how this works out. The first two parts of the IP address is trivial – any different values will label different subnets and we can just pick the same as above, 192.168. For the third part, it is a bit different from the simple /24 example above – in this case, we know that the last two bits in the third part will not be used for labeling the network address. Accordingly, the first subnet block starts from 192.168.0.0 and stops at 192.168.3.255. Why? Let’s write down its binary form,

192.168.0.0 = 192.168.00000000.00000000
192.168.3.255 = 192.168.00000011.11111111


Here I only write down the last two parts in their binary form for the sake of simplicity.

The next block then starts from 192.168.4.0,

192.168.4.0 = 192.168.00000100.00000000

and it can all the way to 192.168.7.255,

192.168.7.255 = 192.168.00000111.11111111

Again, for each block, the first address is reserved for the network address and the last one is reserved for broadcasting purposes. Therefore, the IP addresses that can be assigned to devices for the first two blocks are, 192.168.0.1 - 192.168.3.254 and 192.168.4.1 - 192.168.7.254, respectively. To confirm, we can grab an arbitrary IP address falling in the range and check its network address. For example, let’s take 192.168.7.55 and write down its binary form,

11000000.10101000.00000111.00110111

Applying the subnet mask, we have the result of the binary AND operation as,

11000000.10101000.00000100.00000000 = 192.168.4.0

Taking another IP address in the range, e.g., 192.168.4.1 and perform the same operation, we will also get back the network address of 192.168.4.0 and then we know the two IP addresses 192.168.4.1 and 192.168.7.55 belong to the same subnet, with the networks address of 192.168.4.0.

To continue, the third block of subnet will be the network,

192.168.00001000.00000000

One may wonder that now we have the last 11 bits that be of any values and therefore this block size will be much larger, i.e., \(2^{11}\) > \(2^{10}\), as compared to the previous two blocks we have been discussing. However, don’t forget that we are now worrying about only the third block and therefore ‘x’ in the third part ‘00001x00’ can only be ‘0’ since otherwise ‘00001100’ will bring us to the fourth block 192.168.12.0. Keeping this in mind, the logic will then be exactly the same as above for the first two blocks – IP addresses belonging to the third block will go from 192.168.00001000.00000000 to 192.168.00001011.11111111, i.e., from 192.168.8.0 to 192.168.11.255. Accordingly, the usable IP addresses for devices go from 192.168.8.1 to 192.168.11.254.

From the three blocks above, we can see that no matter for which one, the block size is the same, \(2^{10} = 1024\), corresponding to all possible values for any of the last 10 bits in the IP address. By comparison, the block size of the /24 subnet is much smaller, \(2^{8} = 256\).


References

[1] https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing