The Art of IPv4 Subnetting
There are plenty of calculators out there to help you figure out IP ranges, important values, etc. However, when I took an introductory Cisco networking class I built a subnetting calculator in excel. It might be worth copying that calculator to follow along with the article. The calculator could probably be more accurately described as a base-two calculator. It worked by limiting certain values to 0 or 1 - on or off - in a row of cells and assigning a value between 1 to 27 to the cell below, and adding up all the actual values. I'm no mathematician, but the math is pretty easy.
However, before I go into all that I want to address the concept of subnetting. Subnetting is a way of systematically segregating large networks into smaller bitesized portions. Think of it like a university, where each school houses classes and faculties who specialize in fields specific to a certain group of majors or school of thought. While there may be some overlap, it is generally segregated. The end result is generally a more streamlined and higher quality product, whether that product is network design or a degree. With that in mind, let's see how we can computationally describe segments of a network using math and Python.
To really dig into the computational side of things it's probably worth explaining logic and binary anding. Programmers and philosophers use a similar technique for determining the true or false value of an argument. The way it works is that every argument can be broken down into statements and symbols that join those statements, with a value of true or false (or 1 or 0) to each statement. Then whether or not the combination of those statements are true is dependent on how they're combined. Philosophically it can get a lot deeper here, but programmers also do not worry about implicature so I'm going to leave that for another person. The following tables, however, will show how the 'and' and 'or' operators evaluate given true/false values. Let true = 1, false = 0 in the example.
|Value 1||Operator||Value 2||Result|
The table above illustrates that an argument that relies on 'and' will only evaluate to true when both sides of and evaluate to true. In the context of math, each side of the and must be '1' in order for the result to be '1', otherwise it is '0'. Keep this point in mind because it will be important for evaluating IPs and analyzing networks computationally. However, just for reference I'd like to throw in a table for 'or'. In the following example let True = 1, False = 0.
|Value 1||Operator||Value 2||Result|
The above tables show a contrast between 'and' and 'or', in that only one value must evaluate to true for 'or' to evaluate to true, whereas both values must evaluate to true for 'and' to evaluate to true. However, if you ever need 'or' to evaluate to true whenever exactly one value is true, you can just use 'exclusive or'. Here's what that looks like below:
|Value 1||Operator||Value 2||Result|
Anywho, all of this is important because you use binary operators to find the important addresses in a subnetwork, which are the network address and broadcast address. First though, you need the subnet mask. They are commonly denoted in "slash" notation, which is a '/' followed by a number between 0-32, because an IPV4 address has 4 octets separated by periods. The number tells us how many bits are 'on', and an octet is just a value between 0-255. First let's get a look at the anatomy of an octet before we explore slash notation:
The above octet's value is 160. This is because only the first and third bit are on (or set to 1). Now when you do that four times over you get a full IP. Every bit can either be 0 or 1, and you just add up the values. There is no special math or anything aside from the fact a bit can be either 0 or 1. So now, keeping in mind that a subnet mask follows the same rules as normal IPs there are going to be a total of 32 bits that can be 'turned on'. When you keep this in mind, and that the highest value an octet can have is 255 figuring out subnets can be very easy. Here is a pattern:
/8 = 255.0.0.0
/16 = 255.255.0.0
/24 = 255.255.255.0
/32 = 255.255.255.255
The amount of times 8 goes into a number (without a remainder) will tell you how many full octets are on. Keeping this trick in mind makes weird values like /27 easy to figure out too. Let's do it real quick. We know that 27 % 24 = 3, so 8 goes into 27 cleanly 3 times. As a result, our subnet mask will at least look like:
Now, what about the final value? Well we know that 3 out of the 8 bits are on for that last value. I did not mention it previously, but we work backwards when doing the addition. That means we start at the 27 position and work towards 20. Therefore, the math for the final octet becomes: 27 + 26 + 25, which gives us 224. Therefore, the subnet mask is:
In the table below each individual octet is represented by a row. The first octet is the highest row, and the final octet is the lowest row. This is meant to help visualize how the subnet mask looks in terms of bits.
From here, we can figure out quite a few things. For example, since the highest possible value a slash subnetmask can have is 32, and ours is 27, we can work out how many computers can exist on this subnet. That equation was: 2n - 2, where n in this case will be (32 - 27). So let's work through the math real quick:
2(32 - 27) - 2
25 - 2
32 - 2
There can be 30 devices on this network, because two addresses are always reserved on any subnetwork for broadcasting messages to every device on the subnetwork, and for identification of the subnetwork. This information is also useful because it tells us what the reverse subnetmask will be.
If our subnet mask is: 11111111.11111111.11111111.111 00000
Then our reverse subnetmask will be: 00000000.00000000.00000000.000 11111
When you've got the 'n' in this equation, you can work backwards through the subnetmask setting the bits to 1 until you've hit n-bits. You don't even need the original subnet mask, I only used it to make a point. Onto the fun part, let's figure out the broadcast address for the following IP on a /27 subnetmask:
The first step is to figure out what this translates to in binary. This step is probably easier to just use the binary calculator, or on a piece of scratch paper. I have the answer below though just in case.
Now that we've done that, we can start to work on the math. BUT, before we do that, let's eyeball things real quick because there's a nice shortcut. Using the rule of 'or', we know that an equation will be true IFF at least one side is true. Likewise, it is false IFF both sides are false. This means, whenever we have a one we will keep that one, and whenever both sides are zero it will be unchanged. In other words, the first three octets of our IP will remain the same, because the reverse subnetmask is entirely zeroed out for those octets. So the only time we really need to work is on the final octet.
Now we have to find x, but that's easy!
192.168.32.31 is our final answer. There's still more information we can get from this, remember back up above when we deduced that we can have a maximum of 30 devices on this network? That's because two are reserved. The broadcast and network address are always reserved, and the broadcast address is the final address on a network. What's the network address then? Well, we know there are 32 addresses on this network in total because only 30 can be assigned, and only 5 bits were unused by the subnetmask in the final octet.
So the entire network should be: 192.168.32.0-192.168.32.31, but only 192.168.32.1-192.168.32.30 can be used by devices. And that, my friends, is how you figure out the structure of a subnet. There are fancy tidbits I left out like CIDR notation and classes, but those can be easily googled. IPs are just grouped into classes mostly for convenience and stuff anyway.
While this article is geared toward IPv4, a lot of the same ideas apply for IPv6. There's just a lot more reserved addresses due to its address space, the use of hexadecimal instead of binary opens up a lot of options. In general, as long as you understand how subnetting works you're all set. But now that you know how, let's go over why real quick. It does come up in CompTIA exams, and there are two major reasons. Primarily, it helps prevent traffic collision between packets by breaking down large networks into much smaller chunks.
Unsegmented networks can risk data loss through packet collision or too much data going to one place at the same time. However, it is also safer against internal and external attackers if the network is broken up properly. If a worm gets into the network, IT has a chance of shutting it down before it wrecks the entire network. Of course, it's not safe enough to rely on subnetworking alone. There needs to be backups because you never know what you're facing. But it is a pretty simple way of making things safer and more effective across the entire network. Further, in Supply Chain or Manufacturing environments it is a simple technique to help deter Supply Chain attacks. Lastly, it can also make it easier for IT to address connectivity issues if entire departments are having connectivity issues.