Last updated: 20 June 2021

In my article about subnetting and CIDR I looked at how you can identify what part of an IP address is part of the network. This article continues the discussion. I will explain how you can find the number of IP addresses in a subnet and how you can find the first and last IP address in the range. To follow along you need to have a good understanding of base-2 numbers.

Calculating the number of IPs

For this article I will use our Strawberry server as an example. The server has the IP address 84.18.206.207 and a subnet mask of 255.255.254.0. This is a class A IP address, but the mask is used to make the first 23 bits the network part.

As a quick recap of the article about subnetting and CIDR, the interesting part in this example is the third octet. All bits in the first two octets are turned on (255) and the entire fourth octet are nodes (0). The third octet, though, is split. To see where the cut-off point is you can draw an exponent table:

 128 |  64 |  32 |  16 |  8  |  4  |  2  |  1  
-----+-----+:----+-----+-----+-----+-----+-----
  1  |  1  |  1  |  1  |  1  |  1  |  1  |  0  | 254

You get to 254 by adding up the first seven columns. In other words, the first seven bits in the third octet are turned on in a /23 network.

So far, so good. But how do you calculate the number of IPs? To do so, we need to brush up on our knowledge of exponents. The formula to use is as follows:

2(32-23)

We are using 32 because IPv4 addresses are 32-bit numbers, and we are subtracting the number of bits that are turned on (23). So, 2(32-23) translates to 29, or “2 to the power of 9”:

29 = 512 addresses

If you are lost here, 9 is an exponent that defines how many times the base number (2) needs be multiplied. In other words, the calculation is like so:

2*2*2*2*2*2*2*2*2 = 512

Remember, though, that not all 512 IPs can be assigned to nodes, as the first and last IP in the range are reserved. So, in effect a /23 mask gives you 510 usable IPs.

Calculating the first IP

To calculate the first IP address in the range you can use another table. Below, the first row is the IP address 84.18.206.207 in base-2 and the second row is the mask. The third row calculates what the first IP address is by doing a binary and operation between the first two rows. That sounds complicated but it is quite easy. If both the base-2 IP address and the mask have a 1 in a field then you add a 1 in the same field on the last row. If either or the fields have a 0 then you enter a 0 on the third row. You can then translate the binary IP address to a human-readable one. For the IP 84.18.206.207/23 this gives us 84.18.206.0:

01010100.00010010.11001110.11001111  84.18.206.207 (IP)
11111111.11111111.11111110.00000000  255.255.254.0 (Mask)
-------- -------- -------- --------
01010100.00010010.11001110.00000000  84.18.206.0   (First IP)

Calculating the last IP

Calculating the last IP is slightly more complicated. It works roughly the same but you need to perform a bit more base-2 magic. To start, you need to invert the mask so that every 1 become as 0 and vice versa:

11111111.11111111.11111110.00000000  255.255.254.0 (Mask)
00000000.00000000.00000001.11111111  0.0.1.255     (Mask inversed)

Next, you can perform the same binary and trick as before. However, this time you skip the host part of the mask. In the above example the host part is made up of the nine ones at the end of the address. So, you compare the numbers in the first two rows (IP and Mask), but only if the third row contains a 0. If the inverted mask contains a 1 then you always put a 1 in the Last IP column.

01010100.00010010.11001110.11001111  84.18.206.207 (IP)
11111111.11111111.11111110.00000000  255.255.254.0 (Mask)
00000000.00000000.00000001.11111111  0.0.1.255     (Mask inversed)
-------- -------- -------- --------
01010100.00010010.11001111.11111111  84.18.207.255 (Last IP)