June 24, 2011
A while ago, there was a question on the /r/sysadmin subreddit asking for help learning IPv4 subnetting (in IPv6, there isn't any subnetting unless you're a provider or a large enterprise. Your networks are /64.)
While a lot of the replies were helpful, a disturbing number of sysadmins there expressed that they had no idea how to do it. They considered it "mysterious". One commenter even said that he was hoping to skirt the issue for long enough until IPv6 was the dominant networking tool!
I answered the question, and a lot of people seemed to like the way I phrased it, so I thought I'd post a modified version of my answer here. Yes, IPv6 is coming, but we'll all be running dual-stacks externally for a while, I'm afraid, so knowing how to manage subnets in IPv4 is still important.
The first step to really understanding IP addresses and subnetting is to let go of decimal notation. We understand base-10 because we have used it since we were first introduced to numbers, but really, an IP address is a string of 32 binary digits, and the same goes for a subnet mask.
An IP address has two parts: the network portion, which you can think of as a network identifier, and the host portion, which identifies that specific host in the network that it belongs to.
In order to know which part of the IP is the network portion and which part is the host portion, you MUST know the subnet mask, because in the binary representation of the subnet mask, everything that's a 1 is the network portion of the address.
Lets look at the most typical case, where you have a home router setup with the router's IP address being 192.168.0.1 and there's a subnet mask of 255.255.255.0. The first step to understanding what's going on is to convert both to binary:
192.168.0.1 = 11000000.10101000.00000000.00000001 255.255.255.0 = 11111111.11111111.11111111.00000000
So, what this tells us is that the first 24 bits (each number, either 1 or 0, is a bit) of the IP address are the network portion, and the last 8 bits are the host portion...so you would say the network is 192.168.0.0, with a subnet mask of 255.255.255.0 (incidentally, this subnet mask can be called either 255.255.255.0 or /24, since there are 24 bits used, so it's common to see 192.168.0.0/24 - this latter notation is called CIDR (pronounced 'cider'), short for Classless Interdomain Routing, not that it matters to this discussion). This implies some things...
Since there are only 32 bits possible in an IPv4 address, and with that network, 24 of them are used up by the network section, that leaves 8 bits for the host addresses. 28 is 256, but we start numbering at 0 (because in binary, 00000000 is 0), so the highest IP address we could have on the 192.168.0.0/24 network is 192.168.0.255 (because 11111111 is 255 in decimal).
Alright, that's pretty straight forward, right? Right.
What becomes interesting is that getting a /24 isn't common anymore. There aren't many available (which is why we're moving to IPv6). It's much more likely that you'll be given a much smaller network block, say, a /28. How does that map?
Well, suppose for a second that you are given 192.168.0.0/28. How does that work out? Lets convert to binary and see...but first, lets figure out what a /28 is...
/28 looks like this in binary: 11111111.11111111.11111111.11110000 And each octet, converted: 255 . 255 . 255 . 240
This means the subnet mask, in decimal, is 255.255.255.240. So, lets do the comparison we did before:
192.168.0.0 = 11000000.10101000.00000000.00000000 255.255.255.240 = 11111111.11111111.11111111.11110000
So, what is the network portion, and what is the host portion? Remember, the network portion is anything where the subnet mask is a 1, and the host portion is anything where the subnet mask is a 0.
What this means for a /28 is that we have 16 possible host addresses (because there are 4 bits in the host portion, and 24 is 16). This means the first IP address is going to be 192.168.0.0 (because 0000 is still 0) through 192.168.0.15 (because 15 in binary is 1111).
Now, there are 16 addresses in that network, right? The problem is that, because of how IPv4 was designed, that you can't use the first one and you can't use the last one. The first address (where the host portion is all 0s, like 0000 in this example) is called the "network address". The "network address" is what you use to refer to the entire network (in this case, 192.168.0.0/28, and remember to include the subnet mask!), so a single host can't use it.
You also can't use the last address, either, because that's what is called the "broadcast address". The broadcast address is always the address where all of the bits in the host section are 1s in the IP address (so in this case, it would be 192.168.0.15, since the last octet is 11110000 in the subnet mask, but in the IP address, it's 00001111).
What you end up with, when putting it all together, is that there are 32 bits in an IP address. A good deal of them are taken up by the network portion assigned to you by your provider. If you get a /27, you instantly know that you can only have 30 hosts on that network (remember, you know because the network portion takes up 27 bits, leaving 5 for the host portion, and 25 is 32, but you can't use the first and the last).
So, this covered the basics. Tell me, did it make it better or worse? Please let me know in the comments if (how?) I screwed up, and what I could do to make it better. Thanks!