IP Basics - Routing 101

IP subnetting: Carving up address space

Carving Up IP Address Space with CIDR
Sometimes you will need to take address space allocated to you and divvy it up into several IP subnets. You have to choose either the number of separate subnets you want to create, or how many hosts should be in each subnet. To divide the original subnet, you add bits to the network address (thereby removing bits from the host portion of the address) until you have the desired number of subdivisions in the original address space. It should come as no surprise that everything happens in powers of 2, and that more base–2 math is lurking around the corner.

If you choose to create N subnets, you need an additional m = log2 N 1's in the subnet mask. An easier way to think about the math is to realize that adding m bits to the subnet mask will result in 2m additional subnets.

Example A
Let's take the address space 192.168.18.0/24 and carve it up into 8 subnets. N = 8, so m = log2 8 = 3, which is the number of bits to add to the subnet mask. The result is 8 subnets with network addresses of 192.168.18.x/27.

Now we need the 8 values for x: x1, x2, x3, x4, x5, x6, x7, x8, so that we can write out the network address for each subnet. The first one always starts where the original address space started, in this case 0. The subsequent values for xn are found by adding the number of hosts in each subnet to the preceding value of x. To calculate the number of hosts, refer back to the equation in Calculating with CIDR. In this case, the number of host addresses is 2 (32 -27) = 25 = 32, and we can write out our network addresses accordingly:

 x1 192.168.18.0/27 x2 192.168.18.32/27 x3 192.168.18.64/27 x4 192.168.18.96/27 x5 192.168.18.128/27 x6 192.168.18.160/27 x7 192.168.18.192/27 x8 192.168.18.224/27

The number of usable host addresses in each subnet is 30. You could calculate the broadcast address for each of these, although they can be written down by inspection. Since the broadcast address is the last address in the subnet, it must be one lower than the next network address. For x1, it would be 192.168.18.31; for x6, 192.168.18.191, and for the special case, x8, 192.168.18.255 (because the next network address would be 192.168.19.0/255).

You won't be able to use the maskbits representation of the subnet mask for most networking commands, so you should go ahead and convert it back to decimal (using the chart in Table 2-1: Subnet Mask Lookup Table, if needed). Remember that the 27 bits must be contiguous, from left to right, so they must be 11111111.11111111.11111111.11100000, which is 255.255.255.224. You don't really have to write out the full 32 bits each time, just start subtracting 8 from the maskbits. Each time you can subtract 8, copy down 255. When you are left with a number less than 8, look it up in the table and copy down the decimal representation. If you have not yet written down 4 decimal values, then write down "0"s for the rest.

Before we move on to the next example, let's look at one more property of the subnet mask and the network address that you can use to double-check your work.

 11000000 . 10101000 . 00010010 . 01100000 network address (192.168.18.96) 11111111 . 11111111 . 11111111 . 11100000 subnet mask (255.255.255.224)

Notice, when you line up the network address and the subnet mask, that the network address is all "0"s to the right of the subnet mask's last "1". This will always be the case. If it's not, then you have made a mistake. Simply put, you are in a completely different subnet. Recall that the purpose of the subnet mask is to divide the IP address into network and host fields. The bits in the host field are reserved for hosts, so let not network bits appear there, lest the stack complain bitterly and functioneth not. J

Example B
When we started this section, I said that you could also pick the number of hosts you would like in the subnet and use this to calculate the subnet mask and network address. Let's assume that you need a subnet with at least 1400 addresses. Since we have to pick a power of two, and 1024 is not large enough, we have to take 2048. A subnet that has 2048 host addresses in it needs to have log2 2048 = 11 bits to hold the host address. There are 32 bits total, so this leaves 21 bits for the network address.

Now that you know the subnet mask, chances are good that you'll need to carve it out of some private address space. If you want to take this space from the RFC 1918 allocation for private class A (10.x.x.x) or class B (172.16–31.x.x) networks, you have no worries. The class A network space has 24 bits of host address--more than plenty. The same is true for any of the 16 different private class B networks. They each have 16 bits of host address. (Remember that we need only 11.) Just choose an unused one, slap on the /21, and start CIDRing.

However, if you want to use an aggregate of private class Cs (the 192.168.x.x address space), things can get a little sticky. The last example included a prologue which showed that the network bits cannot run over into the host portion of the IP address. That wasn't so tough when we had a network and wanted to carve out addresses. But now we have addresses and want to fit them into a network. The first thing to do is to write out the subnet mask in binary.

11111111.11111111.11111000.00000000

Now, we want to find a network address that does not have a "1" in any of the last 3 bits of the third octet. (If a "1" appears here, the network address is spilling into the host position.) This is not as difficult as it sounds once you write out the subnet mask in binary. Using 0 (binary 00000000) for the third octet will meet the criterion. If this address space is not available, then the next choice is to copy down the octet with the right-most "1" in the subnet mask intact, and everything else "0"--so in this case 00001000 (8). Any multiple of this value will also meet the requirements, up to copying down the octet from the subnet mask itself (11111000). So we are free to choose from:

 192.168.0.0/21 11000000 . 10101000 . 00000000 . 00000000 192.168.8.0/21 11000000 . 10101000 . 00001000 . 00000000 192.168.16.0/21 11000000 . 10101000 . 00010000 . 00000000 192.168.24.0/21 11000000 . 10101000 . 00011000 . 00000000 - - 192.168.248.0/21 11000000 . 10101000 . 11111000 . 00000000

Each of these has room for 2046 hosts and will have its own broadcast address. If you are still unclear on calculating the broadcast address, try calculating it for 192.168.64.0/21. You should come up with 192.168.71.255.

If you try to start anywhere in the address space, e.g., at 192.168.2.0/21, you'll have problems. Let's write this network address out in binary and align it with the subnet mask:

 network address 11000000 . 10101000 . 00000010 . 00000000 subnet mask 11111111 . 11111111 . 11111000 . 00000000

As you can see, the network address spills over into the host portion of the address (to the right of the last "1" in the netmask). By doing this, you specified a host within the subnet, and not a network address. If you ever try something like this with Linux, it will let you know: