## Subnetting for fun and profit

Subnetting is the process of dividing a network into smaller chunks, or subnetworks. I always found that being able to tell if a specific IP is part of a subnet or not is important for a network engineer. For example: if we take the network 10.10.4.0/22, would you be able to determine which addresses listed here below belong to that subnet?

`10.10.4.123`

`10.10.8.1`

`10.10.5.31`

`10.10.3.231`

`10.10.7.45`

Sometimes a network engineer needs to perform this task during a network troubleshooting session on the spot, without a subnet calculator. For this reason, I would like to share a method I use to subnet with the hope it will help other network engineers.

Before I introduce the subnetting method that worked easily for me, there are three concepts that you need to familiarize with. Subnetting requires being able to:

- Recognize consecutive IPv4 addresses
- Convert a decimal to binary and vice versa
- Work with modular arithmetic and subnet masks

## Recognize consecutive IPv4 addresses

When subnetting, you need to be able to identify consecutive IPv4 addresses as well as boundaries between one subnet and another one. If you need more context and are not familiar with IPv4 subnets, read the post that Steven wrote. That could help shed some light on their use and need.

Put simply, IPv4 addresses are built by concatenating four consecutive 8-bit words. The dotted notation with decimal numbers looks like:

`0-255 . 0-255 . 0-255 . 0-255`

To list and recognize consecutive addresses, you can think of an IPv4 address as a counter that goes from 0.0.0.0 to 255.255.255.255. To list all possible addresses and identify consecutive one, you start with all zeros, and increment by one starting from the rightmost octet. When you reach 255, you increment by one the octet on the left and set to 0 the current octet, and so on. The following example may explain better how this works:

`0.0.0.0`

`0.0.0.1`

`0.0.0.2`

`…`

`0.0.0.255`

`0.0.1.0`

`0.0.1.1`

`0.0.1.2`

`…`

`0.0.1.255`

`0.0.2.0`

`0.0.2.1`

`…`

`0.0.2.255`

`…`

.. and so on until you get to 255.255.255.255. Now that you know how to recognize consecutive IPv4 addresses, let’s see how to convert a decimal number to binary.

## Binary Conversion

As I mentioned before, IPv4 addresses are four 8-bit words concatenated. For example, the IP address in dotted decimal notation 192.168.0.1 will look like the following in 8-bit words:

`11000000.10101000.00000000.00000001`

I was able to write the following binary IP without using any calculator. To do the conversion, you will do the math like an 8-bit processor. Here’s an easy reference table that shows the decimal value of a bit given its position within an 8-bit word:

bit_position | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

If value = 1 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |

To convert a binary to a decimal number you have to do the sum of 2^{bit_position} if you find a 1 in the bit_position, add 0 otherwise. For example, the binary number 10101111 is calculated with the addition 128 + 0 + 32 + 0 + 8 + 4 + 2 + 1 which is equal to the number 175. When I convert in binary, I often count using the fingers of my hand and sum the numbers that correspond to that position if I see 1s.

To convert a decimal into a binary, you simply start breaking the binary number down by multiples of 2^{bit_position} (128, 64, 32, …) where bit_position is between 0 and 7.

## Modular Arithmetic and Subnet Masks

Now that we learned how to recognize consecutive IP addresses, and convert decimal to binary, let’s see how modular arithmetic applies to subnet masks. First of all, it’s important to remember that a subnet mask is used to identify within IP address what is the network portion, that is common to all hosts in the same network, and which is the host one, unique to a host.

If we take classful subnet masks (e.g. /8, /16, and /24 in CIDR notation), which are easy to recognize because they fall within the octets boundaries, it’s easy to sort out the network portion from the host portion. For example, in the following examples we’ll highlight in bold the network portion:

**192.168.0.**0/24 which includes any host from 192.168.0.1 to 192.168.0.254 (the last IP of a subnet is reserved for broadcast)**10.**0.0.0/8 which includes any host from 10.0.0.1 to 10.255.255.254**172.16.**0.0/16 which includes any host from 172.16.0.1 to 172.16.255.254

However, when you have to carve out networks that are not classful, that’s when you need to start doing some math.

Let’s take the subnet 10.10.4.0/22 that we picked at the beginning of this post. Here’s how the method I use works:

- First of all, we translate the /22 mask to binary by adding as many leading ones (22) as the number that is present after the /. To do that, it’s easy if you think in modulus 8: the first two octets will be ones (8 + 8 = 16), and then you need to add six more ones in the third octet to get to 22 (8 + 8 + 6 = 22). We obtain: 11111111.11111111.11111100.00000000
- We then identify the position of the last bit of the subnet mask in binary that is equal to 1. In the above example (11111111.11111111.11111
**1**00.00000000) is bit_position 2 (starting from the rightmost bit_position = 0 within that 8-bit word), which corresponds to the decimal number 4 (2^{2}* 1). - Finally, we can tell that all the subnets will be multiples of 4 (think modulus) in the third octet, starting from 0, for example:
- 10.10.0.0
- 10.10.4.0
- 10.10.8.0
- and so on …

- To conclude, IP ranges will be:
- 10.10.0.1 – 10.10.3.254
- 10.10.4.1 – 10.10.7.254
- 10.10.8.1 – 10.10.11.254

**Conclusion**

I hope that this article proved how easy it is to subnet without using a calculator. I’d love to hear from you if you found this method useful or not, or have a different one that works better for you.