IPv4 Subnetting

IPv4 subnetting was originally very simple, before CIDR. It is now quite complex. This is one of the more difficult areas of networking for people learning to work with IPv4. All addresses have two “parts”, the first part being the address of the network (e.g. 192.168.0.0), and the second being the node within that network (e.g. 0.0.2.5). These two parts can be split apart along some “bit boundary”. In this case, the address of the network is in the first 16 bits, and the node within network is in the last 16 bits. The addresses of all nodes in such a network share the same first 16 bits, but each has a unique last 16 bits. So, such a network might have nodes with addresses 192.168.2.5, 192.168.3.7 and 192.168.200.12, but not one with the address 192.169.2.1 (that address is in network 192.169.0.0, not network 192.168.0.0).

A subnet mask is a 32 bit value in which the first n bits (n=1 to 32) have the value 1, and the remaining 32-n bits have the value 0. It is used to split an IPv4 address into its two parts (the first n bits, and the last 32-n bits). In the network just described, the subnet mask is 255.255.0.0 (the first 16 bits have the value 1, the last 16 bits have the value 0). You do a Boolean “AND” function of the address with the subnet mask to get the address of the network, and a Boolean “AND” of the address with the one’s complement of the subnet mask (in this case 0.0.255.255) to get the node within subnet. This is difficult to visualize in dotted decimal. It is rather more obvious in binary. The Boolean “AND” function produces a 1 if both inputs are 1, else it produces a 0. The “one’s complement” (Boolean “NOT”) function changes each 0 to a 1, and each 1 to a 0. With the “AND” function, where there is a 1 in the mask, the corresponding bit of the address “flows through” to the result. Where there is a 0 in the mask, the corresponding bit of the address is blocked (forced to the value 0). The following example (with addresses and mask shown in both dotted decimal and binary) should make this clear:

Getting the network address by AND-ing with the subnet mask

Address 192.168.2.5  1100 0000 1010 1000 0000 0010 0000 0101
Subnet mask 255.255.0.0 1111 1111 1111 1111 0000 0000 0000 0000
AND —- —- —- —- —- —- —- —-
Network address 192.168.0.0  1100 0000 1010 1000 0000 0000 0000 0000

Getting the node within subnet address by AND-ing with the complement of the subnet mask

Address 192.168.2.5 1100 0000 1010 1000 0000 0010 0000 0101
NOT mask 0.0.255.255 0000 0000 0000 0000 1111 1111 1111 1111
AND —- —- —- —- —- —- —- —-
Node within subnet 0.0.2.5 0000 0000 0000 0000 0000 0010 0000 0101

For subnet mask 255.0.0.0 (Class A), the first 8 bits are network address, the last 24 are node within subnet.

For subnet mask 255.255.0.0 (Class B), the first 16 bits are network address, the last 16 are node within subnet.

For subnet mask 255.255.255.0 (Class C), the first 24 bits are network address, the last 8 are node within subnet.

Subnetting was easy when the three IP address classes (A, B & C) were used. The first few bits of the address determined the subnet mask. If the first bit of the 32 bit address was “0”, then the address was Class A, and the subnet mask was 255.0.0.0. If the first two bits of the address were “10”, then the address was class B, and the subnet mask for 255.255.0.0. If the first three bits of the address were “110”, then the address was class C, and the subnet mask was 255.255.255.0. This could actually be done automatically, so no one worried about subnet masks.

One of the changes made in the IPv4 addressing model in the mid 1990’s was to introduce Classless Inter-Domain Routing, in RFC 1519, “Classless Inter-domain Routing (CIDR)”, September 1993. It was later replaced by RFC 4632 “Classless Inter-domain Routing (CIDR)”, August 2006.

When CIDR was introduced, there were two consequences. First, the split between the two parts of the address could come at any bit boundary, not just after 8, 16 and 24 bits. Second, several small blocks (e.g. /28 blocks) could be carved out of a bigger block anywhere in the address space (perhaps from an old Class A block, such as 7.x.x.x), so you could no longer determine the correct subnet mask by looking at the first few bits of an address. For example, a “/8” (Class A) block might be carved up into 65,536 “/24” (Class C) subnets, which could be allocated to different organizations.

Let’s say your ISP, instead of giving you a Class C block, only gives you a “/28” block of real (routable) IPv4 addresses, which would be 16 real IPv4 addresses, e.g. 123.45.67.0 through 123.45.67.15. First, two of these addresses are not usable (may not be assigned to nodes). 123.45.67.0 is the “network address”, and 123.45.67.15 is the “broadcast address”. That leaves 14 usable addresses (123.45.67.1 through 12.45.67.14). So what is your subnet mask? If you check the above table of useful CIDR block sizes, a /28 subnet has a subnet mask of 255.255.255.240. In binary that is 1111 1111 1111 1111 1111 1111 1111 0000 (first 28 bits are 1, last 4 bits are 0). However, by the old rules (first bit is a 0) these are really from a “Class A” block, so the automatically generated subnet mask would have been 255.255.255.0, which is not correct.

Now, what if your organization really has 100 nodes that need IP addresses? How do you give each of them unique addresses if you only have 14 usable addresses to work with? That’s where Network Address Translation (NAT) comes in (covered in the next chapter). If you think CIDR made your life more “interesting”, wait until you see what NAT does to it! Getting rid of NAT and complex subnetting are one of the big wins in IPv6. In fact, you will find that the entire subject of subnets has become totally trivial.